RabbitMQ的是一个庞杂的野兽。
它灵敏,弱小,但也很难完整把控和把握。
很多分歧的运用状况和运用形式都可以树立在这个弱小的软件之上,但在第一次测验考试为一个特定的处理计划编写代码时,过失和设计错误也是习以为常的工作。
在本文中,我将会商 Palermo 的设计和完成,它是一个完成了可以将RabbitMQ用作底层列队机制构建的那些可能的运用形式此中之一:批处置功课处置系统。
经过批处置功课处置系统,我们援用了一种机制因由 功课程序从分歧行列中提取功课的主动履行。客户可以排入新的功课到这些行列,它们终极将被通报给将履行功课的程序。假如在履行一个Task失败了,功课程序线程将会把失败的功课放入一个特别的行列,它可以从头履行,或者反省出来实行错误调试。
创立Palermo的灵感首要来自于Resque ,它是一个功课处置系统,由Github运用Ruby和Redis创立.
关于系统的运用者,Resque让这些变成可能:定义具有分歧名字的行列;功课列队时,在系统中经过某个输出参数适配Ruby类名;在分歧的机械中启开工作者过程--它们将处置功课,实例化Ruby类,并运用供给的输出参数来履行功课.假如功课履行失败,功课将被路由到一个特别的"失败"功课行列.在这个行列中的功课会从头履行或被删除.Resque任务者和底层的操作系统很好的集成在一同,它可以像系统操作者把持功课履行的方法,来处置行将到来的旌旗灯号.它也供给了一个web接口,可以监控功课和任务者的形态,同时也能够履行某种举措,像功课的从头列队或行列中功课的清算.
从一个开发者的角度来说,Resque的首要优势是全部系统的运用超等容易.定义和列队功课只需求几行Ruby代码便可,同时系统以一种不断的和鲁棒的方法运转.
Palermo的目的是针对JVM言语,创立一个容易易用的功课处置系统,像Resque一样的强健,并运用RabbitMQ作为底层的行列技术而不是Redis.
从一个正式的角度来说,一个功课处置系统的行列技术可以定义为一个元组空间(tuple space),一种延续联系关系的内存,一些过程列队功课运用以下的方法编写元组:
write(queue_name, job_type, input_argument)
任务者过程从内存删除元组,一次一个,运用谓词适配行列名:
read(queue_name, ?, ?)
一个唯一的,必需以元组空间,参加到功课处置行列技术模子中的限制是,来自分布式内存中的读函数必需服从进步前辈先出(FIFO)的语义.RabbitMQ行列可以看做是这类类型的,包括FIFO语义的内存.行列名作为第一个参数通报到"读"谓词,用来提取存储在内存中的下一个适配的元组.
为了获得想要读取的元组空间语义,我们需求处置RabbitMQ外部的一些设置,并设置装备摆设以下的选项:
- 行列的耐久性
– 音讯的耐久性
– 服务的质量
– 音讯确认
因为要运用可不断的内存,我们需求为RabbitMQ所管理的行列和音讯增加可不断性.为了到达这个后果,在RabbitMQ当中,行列需求声明为"durable",音讯需求声明为"persistent".经过这类方法,即使RabbitMQ broker解体了,关于曾经创立的行列信息和未决的音讯将在重启时恢复.
当超越一个任务者衔接到统一个行列时,RabbitMQ会运用round robin的方法,在一切的可用任务者平分发音讯.这里首要的问题在于,只需音讯抵达行列,RabbitMQ就将发送一个音讯到下一个任务者,而不论这个任务者能否正在处置一个分歧的音讯.假如一个功课需求很长的时间来处置,到来的音讯将堆叠在这个忙碌任务者的当地缓存中,而其他的任务者将处于闲置形态.我们可使用RabbitMQ的两个特征来处置这类状况:音讯确认和服务质量/预取数目.
起首,任务者采取显式确认的方法处置完音讯后可以告诉RabbitMQ.音讯只要确认后才会从行列删除.假如任务者中止运转而没有确认音讯,RabbitMQ会主动将音讯从头列队.
同时,服务质量(qos)设置装备摆设可以告诉RabbitMQ,发送给特定任务者的最大未确认音讯数.假如设置了这个值,即从预取数目到1,只要最初一条音讯被任务者过程确认,其他音讯才干从行列发送出去.
经过这类方法,可以完成在任务者之间公道的分派功课.
我们依然需求找到一种方法完成写内存的操作.RabbitMQ分歧于其他行列列队系统的一个主要的方面,是激烈的定阅者和花费者别离的考量.在RabbitMQ系统构造中,这点是经过行列和定阅者交流的引见来完成的.定阅者不晓得音讯的终极目标地,他们只晓得一个交流的名字和路由关键字,这个关键字可以看做是发送音讯的地址.
针对分歧的交流类型,RabbitMQ支撑分歧的语义,这将影响一个带有地址的音讯适配一个交流的方法.它将通报到实践的信箱(行列),花费者将从这里接纳音讯.
在我们的例子中,写办法的第一个参数是行列称号。 行列称号也是任务者猜测下一个内存中待处置的Task时运用的参数。
Palermo中该办法下一个参数是一种直接交流类型。 在这类交流类型中,路由关键字必需和传输音讯的行列称号适配。
假如一条音讯被发往 RabbitMQ 实行交流,而且没有行列衔接到交流,那末这条音讯会被抛弃或者被发往相干的备用交流。 为了不这类状况, Palermo中一个发布者每次把一个新的Task参加到行列中时,在发送Task的数据之前,发布者会声明适配路由关键字的行列。 经过这类方法,我们可以断定当没有任务者在等候处置Task时音讯也不会被抛弃。 在 RabbitMQ中,运用类似的参数从头声明一个已存在的行列是一个正当的操作,且没有任何影响。
运用之前为RabbitMQ所描绘的设置,我们可以树立任务处置系统的中心。但是,某些特征,像失败露务的管理或者音讯的序列化,它们不能被编址放到RabbitMQ的特征中。在Palermo中,这个特征曾经被完成,并被作为一个附加的使用软件层,这个层可以被分派作为一个Java库。
重要的问题是怎么处置失败的事务。我们来看它是怎样(任务的),过来我们运用显式的人工确认,在人工处置或超不时,RabbitMQ将会处置致命的错误。这套机制也能够用于处置在事务处置逻辑中(发生的)任何类型的异常前提,除我们希冀的功用需求外,失败信息肯定会发送给一个特殊的失败露务行列,他们可以被查阅,移除和重入队。这个功用曾经在Palermo中被完成,被包装为一个通用的Java事务用来处置try/catch块,并经过管道将失败信息添加到行列中,并添加一些关于事务的错误信息,(例如)重试次数和在音讯元数据的头中的原始行列一并发送音讯给RabbitMQ。
其它翻译版本 (1) 加载中序列化的问题,曾经经过定义一个功课音讯来陈说了,这个音讯包括功课Java类的头信息,功课序列化参数和序列化类型.有关参数抽象化的一小部分外容,经过一个人眼可辨认的字符串,也随音讯一同发送了. Palermo曾经经过支撑插件和去插件的方法,对系统实行分歧的序列化,同时,包括一个基于JSON的序列化转换器.可是,默许的序列化技术是运用JBoss Serialization.只要功课的参数被序列化,并发送给任务者,功课类的字节码必需在任务者的class path中可用,以便准确履行功课.
Palermo任务者只是履行实践功课逻辑的一种通用方法,此中功课逻辑是封装在功课类的定义当中.
Palermo的全部逻辑曾经在Clojure编程言语中完成,可是,多亏Clojure Java inter-op特征,它可以在java代码或其他恣意基于JVM的言语中运用.因为Palermo任务者线程在JVM中运转,它们从底层的操作系统中被隔离出来.像Resque任务者那样,集成在OS当中,很难完成,可是某种水平的集成,在可能的状况下,曾经测验考试过,如,为联系关系到Palermo任务者的RabbitMQ花费者的身份标识,运用过程标识符.一个号令行的接口也曾经完成了,所以,新的任务者,经过剧本和运用者,可以很容易的启动.
本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协议,假如我们的任务有进犯到您的权益,请实时联络我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务