﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Skynet-随笔分类-消息队列</title><link>http://www.blogjava.net/Skynet/category/42483.html</link><description>十一长假 整理 www.blogjava.net/Good-Game 中
打搬家了 
;)</description><language>zh-cn</language><lastBuildDate>Sat, 31 Oct 2009 08:13:20 GMT</lastBuildDate><pubDate>Sat, 31 Oct 2009 08:13:20 GMT</pubDate><ttl>60</ttl><item><title>beanstalkd 消息队列的第一手资料</title><link>http://www.blogjava.net/Skynet/archive/2009/10/30/300325.html</link><dc:creator>刘凯毅</dc:creator><author>刘凯毅</author><pubDate>Fri, 30 Oct 2009 04:05:00 GMT</pubDate><guid>http://www.blogjava.net/Skynet/archive/2009/10/30/300325.html</guid><wfw:comment>http://www.blogjava.net/Skynet/comments/300325.html</wfw:comment><comments>http://www.blogjava.net/Skynet/archive/2009/10/30/300325.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Skynet/comments/commentRss/300325.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Skynet/services/trackbacks/300325.html</trackback:ping><description><![CDATA[<br />
beanstalk 消息队列 小结 <br />
协议说明和各状态转换情况<br />
<br />
<br />
<strong>基本知识点:</strong><br />
&nbsp; 1. 对于beanstalk 消息队列中每条数据都为 job<br />
&nbsp; 2. beanstalk service端 ，会维护 tubes[多个管道]<br />
&nbsp; 3. client端可以监听,使用多 tube<br />
&nbsp; 4. client端可以指定 use 管道[ client生成一个新的job时会把此job提交到 指定管道]<br />
&nbsp; 5. client端可以指定 watch 管道 [ client接收处理job时会到 指定管道得到待处理的job]<br />
<br />
<br />
<strong>官方示意图:</strong><br />
put&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reserve&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete<br />
-----&gt; [READY] ---------&gt; [RESERVED] --------&gt; *poof*<br />
<br />
<strong>一般情况:</strong><br />
1. 任务提交到service端,job 管理放入内存空间并为其标记状态 [READY] <br />
2. client通过轮训竞争得到次状态, job 改为&nbsp; [RESERVED]<br />
&nbsp;&nbsp; 2.1 当在默认时间 120 秒内没处理完 , job.stats.timeouts 就会大于 0 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同时其他 轮训竞争client会拿到这个job【 注意了 每次timeouts时,在轮训的客户端就会得到次job，状态都为 ready,timeouts&gt;0 】<br />
3. 随便其中一台client处理完 job.delete&nbsp;&nbsp; , 其他 client 中的此job 都会&nbsp;&nbsp;&nbsp; *poof*&nbsp; <br />
<br />
<br />
<br />
<br />
<strong>deom - python beanstalkc 中 job.stats 参考:</strong><br />
<strong>使用 easy_install beanstalkc </strong><br />
<strong>API 参考 : http://github.com/earl/beanstalkc/blob/master/TUTORIAL</strong><br />
刚生成的 beanstalk<br />
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120, <br />
'age': 6, 'pri': 2147483648L, 'delay': 0, '<strong>state</strong>': '<strong>reserved</strong>', '<strong>time-left</strong>': <strong>114</strong>, <br />
'kicks': 0, 'id': 2}<br />
<br />
以timeout了的 beanstalk,并且在其他client轮训到 job<br />
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 1, 'ttr': 120, <br />
'age': 417, 'pri': 2147483648L, 'delay': 0, '<strong>state</strong>': '<strong>reserved</strong>', '<strong>time-left</strong>': <strong>110</strong>, <br />
'kicks': 0, 'id': 2}<br />
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 1, 'ttr': 120, 'age': 415, <br />
'pri': 2147483648L, 'delay': 0, '<strong>state</strong>': '<strong>reserved</strong>', '<strong>time-left</strong>': <strong>4294967163L</strong>, <br />
'kicks': 0, 'id': 2}<br />
<br />
当没所有client 的 job 都到期 了 状态<br />
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 2, 'ttr': 120, <br />
'age': 417, 'pri': 2147483648L, 'delay': 0, '<strong>state</strong>': '<strong>ready</strong>', '<strong>time-left</strong>': <strong>4294967161L</strong>, <br />
'kicks': 0, 'id': 2}<br />
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 2, 'ttr': 120, 'age': 415, <br />
'pri': 2147483648L, 'delay': 0, '<strong>state</strong>': '<strong>ready</strong>', '<strong>time-left</strong>': <strong>4294967163L</strong>, <br />
'kicks': 0, 'id': 2}<br />
<br />
其中 client1 job.delete<br />
client1 job.stats&nbsp; *poof*<br />
client2 job.stats&nbsp; *poof*<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
比较全的状态说明 - [官方文档]<br />
http://github.com/kr/beanstalkd/blob/v1.1/doc/protocol.txt?raw=true<br />
<br />
官方示意图:<br />
&nbsp;
<img src="http://www.blogjava.net/images/blogjava_net/skynet/beanstalk.jpg" alt="" border="0" /><br />
<br />
<br />
<strong>先简单说明下（完全自己理解的，欢迎拍砖。本人E人太差~看官档费劲，谅解下）: </strong><br />
job.stats状态 = [READY] 待处理,&nbsp; [RESERVED] 正处理, [DELAYED]延迟状态 ,&nbsp; [BURIED] 隐藏状态<br />
<br />
<strong>1. 延迟提交</strong><br />
py.client1.put&gt;&gt;&gt; beanstalk.put('yes!', delay=10)<br />
py.client3.reserve&gt;&gt;&gt; job = beanstalk.reserve()<br />
# 等待 10&nbsp; 秒<br />
<br />
<strong>2. 管道测试</strong><br />
put-job到service端 可以指定 put的tube管道<br />
如: <br />
<br />
py.client1.put&gt;&gt;&gt; beanstalk.use('foo') <br />
py.client1.put&gt;&gt;&gt; beanstalk.put('hey!')<br />
<br />
py.client2.reserve&gt;&gt;&gt; job = beanstalk.reserve()<br />
# 一直拥塞，应为 他 watch 管道 'default'<br />
<br />
py.client3.reserve&gt;&gt;&gt; beanstalk.watch('foo')<br />
# beanstalk.ignore('bar') 放弃监听 bar<br />
py.client3.reserve&gt;&gt;&gt; job = beanstalk.reserve()<br />
py.client3.reserve&gt;&gt;&gt; job.body #输出 'hey!' <br />
<br />
<br />
<br />
<strong>3. 隐藏状态 现在吧 client 1/2/3 的 use watch 的管道都调回 default</strong><br />
py.client2.reserve&gt;&gt;&gt; job = beanstalk.reserve()<br />
py.client3.reserve&gt;&gt;&gt; job = beanstalk.reserve()<br />
py.client1.put&gt;&gt;&gt; beanstalk.put('隐藏状态!')<br />
py.client2.reserve&gt;&gt;&gt; job.bury() #2 轮训得到 并且 修改 job 为隐藏状态<br />
# 120 秒后 client3 没有轮训得到 此job <br />
py.client2.reserve&gt;&gt;&gt; job.stats() <br />
{'buries': 1, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120, <br />
'age': 188, 'pri': 2147483648L, 'delay': 0, 'state': 'buried',<br />
'time-left': 4294967228L, 'kicks': 0, 'id': 11}<br />
py.client2.reserve&gt;&gt;&gt; beanstalk.kick( job.stats()['id'] ) #修改状态为 reserved<br />
# 立刻 client3 得到 job<br />
py.client3.reserve&gt;&gt;&gt; job.stats()<br />
{'buries': 1, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120, 'age': 313, <br />
'pri': 2147483648L, 'delay': 0, 'state': 'reserved', <br />
'time-left': 110, 'kicks': 1, 'id': 11}<br />
# 这时候 client2 / 3 同时 有 job 11 状态 'buries': 1,'timeouts': 0,'state': 'reserved'<br />
<br />
<strong>4. peek 窥见</strong><br />
&nbsp; 可以得到 一个 stats - read 的 job ，其他 client 可以 job = beanstalk.reserve() <br />
&nbsp; 后马上 job.stats 会变成&nbsp; [RESERVED] <br />
&nbsp; py.client2.reserve&gt;&gt;&gt; job = beanstalk.peek_ready()<br />
&nbsp; 取得 job 并看 本 client 能 处理能<br />
&gt;&gt;&gt; job = beanstalk.peek(3)<br />
&gt;&gt;&gt; job.body<br />
&nbsp;&nbsp;&nbsp; 'yes!'<br />
&gt;&gt;&gt; job.stats()['state']<br />
&nbsp;&nbsp;&nbsp; 'ready'<br />
这种形式西 job 不能 bury 等修改状态，但 可以 delete<br />
<br />
peek 系类<br />
&nbsp;peek_buried<br />
&nbsp;peek_ready<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/Skynet/aggbug/300325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Skynet/" target="_blank">刘凯毅</a> 2009-10-30 12:05 <a href="http://www.blogjava.net/Skynet/archive/2009/10/30/300325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>消息队列  beanstalkd 介绍</title><link>http://www.blogjava.net/Skynet/archive/2009/10/28/300097.html</link><dc:creator>刘凯毅</dc:creator><author>刘凯毅</author><pubDate>Wed, 28 Oct 2009 11:21:00 GMT</pubDate><guid>http://www.blogjava.net/Skynet/archive/2009/10/28/300097.html</guid><wfw:comment>http://www.blogjava.net/Skynet/comments/300097.html</wfw:comment><comments>http://www.blogjava.net/Skynet/archive/2009/10/28/300097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Skynet/comments/commentRss/300097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Skynet/services/trackbacks/300097.html</trackback:ping><description><![CDATA[<br />
首先 好东西 <br />
&nbsp; http://kr.github.com/beanstalkd/<br />
<br />
<br />
其次 真的是好东西 支持 java , python ,perl,ruby,erlang 和我不知道的 语言<br />
&nbsp; 官方的原文介绍：<br />
<div>
<pre>$ ./beanstalkd -d -l 10.0.1.5 -p 11300<br />
<br />
</pre>
</div>
<p>This starts up <code>beanstalkd</code> as a daemon listening on address 10.0.1.5, port 11300.</p>
<h2 id="use_it">Use It</h2>
<p>Here&#8217;s an example in Ruby (see the <a href="http://kr.github.com/beanstalkd/client.html">client libraries</a> to find your favorite language).</p>
<p>First, have one process put a job into the queue:</p>
<div>
<pre>beanstalk = Beanstalk::Pool.new(['10.0.1.5:11300'])<br />
<br />
beanstalk.put('hello')<br />
<br />
</pre>
</div>
<p>Then start another process to take jobs out of the queue and run them:</p>
<div>
<pre>beanstalk = Beanstalk::Pool.new(['10.0.1.5:11300'])<br />
<br />
loop do<br />
<br />
job = beanstalk.reserve<br />
<br />
puts job.body # prints "hello"<br />
<br />
job.delete<br />
<br />
end<br />
<br />
<br />
<br />
</pre>
</div>
<br />
<br />
<h2 id="thanks">Thanks</h2>
<p>Many thanks to <a href="http://www.danga.com/memcached/">memcached</a>
for providing inspiration for simple protocol design and for the
structure of the documentation. Not to mention a fantastic piece of
software!</p>
<br />
<img src ="http://www.blogjava.net/Skynet/aggbug/300097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Skynet/" target="_blank">刘凯毅</a> 2009-10-28 19:21 <a href="http://www.blogjava.net/Skynet/archive/2009/10/28/300097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>