Beanstalk是一個(gè)高性能愿伴、輕量級(jí)的、分布式的电湘、內(nèi)存型的消息隊(duì)列系統(tǒng)隔节。最初設(shè)計(jì)的目的是想通過后臺(tái)異步執(zhí)行耗時(shí)的任務(wù)來降低高容量Web應(yīng)用系統(tǒng)的頁(yè)面訪問延遲鹅经。其實(shí)Beanstalkd是典型的類Memcached設(shè)計(jì),協(xié)議和使用方式都是同樣的風(fēng)格怎诫。其基本設(shè)計(jì)思想很簡(jiǎn)單:高性能離不開異步瘾晃,異步離不開隊(duì)列,而內(nèi)部都是生產(chǎn)者-消費(fèi)者模式的幻妓。
背景介紹:
現(xiàn)在市面上有很多消息隊(duì)列系統(tǒng)了蹦误。常用的有ActiveMQ, RabbitMQ,ZeroMA,Kafka,RocketMQ。Redis之父最近又開源了一個(gè)Disque肉津。我之前在樂視用的是apache的qpid强胰。但是之所以各個(gè)系統(tǒng)都在流行,還要看其側(cè)重點(diǎn)妹沙。
其中ActiveMQ可以稱之為傳統(tǒng)型偶洋,它們完全支持JMS和AMQP規(guī)范。
JMS即Java消息服務(wù)(Java Message Service)應(yīng)用程序接口距糖。它是Java平臺(tái)上有關(guān)面向消息中間件(Message Oriented Middleware,縮寫為MOM)的技術(shù)規(guī)范涡真,它便于消息系統(tǒng)中的Java應(yīng)用程序進(jìn)行消息交換,并且通過提供標(biāo)準(zhǔn)的產(chǎn)生肾筐、發(fā)送哆料、接收消息的接口簡(jiǎn)化企業(yè)應(yīng)用的開發(fā)。(*我這里說了吗铐,JMS是應(yīng)用程序接口东亦,就是API,API就意味著是和編程語(yǔ)言綁定的)
JMS的體系架構(gòu)由JMS提供者唬渗、JMS客戶典阵、JMS生產(chǎn)者、JMS消費(fèi)者镊逝、JMS消息壮啊、JMS隊(duì)列、JMS主題組成撑蒜。
JMS對(duì)象模型包含:連接工廠歹啼、JMS連接、JMS會(huì)話座菠、JMS目的狸眼、JMS生產(chǎn)者和消費(fèi)者和JMS消息。其中大家最關(guān)心的是JMS消息的兩種模型:點(diǎn)對(duì)點(diǎn)(point to point, queue)和發(fā)布/訂閱(publish/subscribe, topic)浴滴。這兩者之間的區(qū)別就是點(diǎn)對(duì)點(diǎn)模式是生產(chǎn)者發(fā)送一條消息到queue拓萌,一個(gè)queue可以有很多消費(fèi)者,但是一個(gè)消息只能被一個(gè)消費(fèi)者接收升略,當(dāng)沒有消費(fèi)者可用時(shí)微王,這個(gè)消息會(huì)被保存直到有一個(gè)可用的消費(fèi)者屡限,所以queue實(shí)現(xiàn)了一個(gè)可靠的負(fù)載均衡。而發(fā)布訂閱模式是發(fā)布者發(fā)送到topic的消息炕倘,只有訂閱了topic的訂閱者才會(huì)收到消息钧大。topic實(shí)現(xiàn)了發(fā)布和訂閱,當(dāng)你發(fā)布一個(gè)消息激才,所有訂閱這個(gè)topic的服務(wù)都能得到這個(gè)消息拓型,所以從1到N個(gè)訂閱者都能得到這個(gè)消息的拷貝。
AMQP(高級(jí)消息隊(duì)列協(xié)議)瘸恼,和JMS的區(qū)別在于:JMS只是java平臺(tái)的方案劣挫,AMQP是一個(gè)跨語(yǔ)言的協(xié)議。由于跨語(yǔ)言的特點(diǎn)东帅,降低了企業(yè)和系統(tǒng)集成的開銷压固。所以現(xiàn)在的消息隊(duì)列系統(tǒng)支持AMQP的多,支持JMS的少靠闭。
AMQP的特征是面向消息帐我,隊(duì)列化,消息模型(和JMS一樣:點(diǎn)對(duì)點(diǎn)和發(fā)布訂閱)愧膀,可靠性和安全性拦键。它提供了三種消息傳遞保證方式:最多一次,至少一次和精確一次檩淋。
Beanstalk介紹:
那下面開始說beanstalk了芬为。首先說beanstalk其實(shí)并不是JMS規(guī)范的,也并不嚴(yán)格遵守AMQP協(xié)議蟀悦。有人說Beanstalk之于RabbitMQ媚朦,就好比Nginx之于Apache。它更簡(jiǎn)單日戈,輕量級(jí)询张,高性能,易使用浙炼。但是相比kafka份氧,數(shù)據(jù)處理能力還是有差距,所以我們現(xiàn)在其實(shí)在逐漸替代它鼓拧。但它有些很易用的特殊功能半火,后面會(huì)講到。
Beanstalk主要包括4個(gè)部分季俩。
1>?job:一個(gè)需要異步處理的任務(wù),需要放在一個(gè)tube中梅掠。
2> tube:一個(gè)有名的任務(wù)隊(duì)列酌住,用來存儲(chǔ)統(tǒng)一類型的job店归,是producer和consumer操作的對(duì)象。
3> producer:job的生產(chǎn)者酪我,通過put命令來將一個(gè)job放到一個(gè)tube中消痛。
4> consumer:job的消費(fèi)者,通過reserve都哭、release秩伞、bury、delete命令來獲取job或改變job的狀態(tài)欺矫。
剛才說Beanstalk有一些特殊的好用功能纱新。那就是它支持任務(wù)優(yōu)先級(jí)(priority)、延時(shí)(delay)穆趴、超時(shí)重發(fā)(time-to-run)和預(yù)留(buried)脸爱,能夠很好的支持分布式的后臺(tái)任務(wù)和定時(shí)任務(wù)處理。這些特性是和beanstalk工作過程密切相關(guān)未妹。
Beanstalk的一個(gè)job的生命周期有READY簿废、RESERVED、DELAYED络它、BURIED四種族檬。
當(dāng)producer直接put一個(gè)job時(shí),job就是READY狀態(tài)化戳,等待consumer來處理单料。如果選擇延遲put,job就先到DELAYED狀態(tài)迂烁,到指定時(shí)間再READY看尼。consumer獲取了READY的job,此狀態(tài)就為RESERVED盟步。這樣其他consumer不能再操作此job藏斩。當(dāng)consumer完成該job后,可以選擇delete却盘、release或者bury狰域。
delete之后,job不能再獲取黄橘。release的job可以重新遷移或延遲遷移回READY兆览。bury的job可以被休眠,需要的時(shí)候再READY或者delete掉塞关。
Beanstalk使用場(chǎng)景:
用作延時(shí)隊(duì)列:比如可以用于如果用戶30分鐘內(nèi)不操作抬探,任務(wù)關(guān)閉。
用作循環(huán)隊(duì)列:用release命令可以循環(huán)執(zhí)行任務(wù),比如可以做負(fù)載均衡任務(wù)分發(fā)小压。
用作兜底機(jī)制:比如一個(gè)請(qǐng)求有失敗的概率线梗,可以用Beanstalk不斷重試,設(shè)定超時(shí)時(shí)間怠益,時(shí)間內(nèi)嘗試到成功為止仪搔。
用作定時(shí)任務(wù):比如可以用于專門的后臺(tái)任務(wù)。
用作異步操作:這是所有消息隊(duì)列都最常用的蜻牢,先將任務(wù)仍進(jìn)去烤咧,順序執(zhí)行。