Maison > Article > développement back-end > gearman-php的Net_Gearman库学习
按照这个英文帖子学习的
原文代码的备份
例子1:
像我们展示了Net_Geaman的基本架构,client端主要代码:
<code><span>// 一个client对象,需要jobserver信息,一个数组</span><span>$client</span> = <span>new</span> Net_Gearman_Client (gm::<span>$servers</span>); <span>// Example1就是function name</span><span>$client</span>->Example1 (<span>array</span> (<span>'date'</span>));</code>
worker端主要代码:
<code><span>// worker对象,需要jobserver信息</span><span>$worker</span> = <span>new</span> Net_Gearman_Worker (gm::<span>$servers</span>); <span>// 传入function name,给他处理Example1的能力</span><span>$worker</span>->addAbility (<span>'Example1'</span>); <span>// loop</span><span>$worker</span>->beginWork ();</code>
和传统的gearman api略有差别,Net_Geaman需要用户以子类形式实现function,例如Example1.php文件代码片段:
<code><span><span>class</span><span>Net_Gearman_Job_Example1</span><span>extends</span><span>Net_Gearman_Job_Common</span> {</span><span>// arg 是数组,与client里面的入参array对应</span><span>public</span><span><span>function</span><span>run</span><span>(<span>$arg</span>)</span> {</span><span>$cmd</span> = <span>$arg</span>[<span>0</span>]; <span>//...</span><span>return</span><span>$result</span>; } }</code>
例子一中的一个技巧是client调用了Example1这个不存在的方法,使用的是 _call 机制。没啥用。
例子2:
client侧引入task和set概念,这样就可以累加多个任务到一个集合,一起发出,client片段:
<code><span>$set</span><span>=</span><span>new</span> Net_Gearman_Set(); <span>$task</span><span>=</span><span>new</span> Net_Gearman_Task (<span>'Example1'</span>, <span>array</span> (<span>'date'</span>)); <span>$set</span><span>-></span>addTask (<span>$task</span>); <span>$client</span><span>-></span>runSet (<span>$set</span>);</code>
例子3:
增加了完成任务后的回调功能,回调的参数有function name,句柄(包好jobserver:number,主要是唯一标识一下这次任务),还有任务的返回值。
<code>$task->attachCallback (<span>"complete"</span>,Net_Gearman_Task::TASK_COMPLETE); //<span>...</span><span>function</span> complete ($func, $handle, $result) { gm::log_msg (<span>"[gm_client] complete ($handle/$func)"</span>); gm::log_msg (<span>"[gm_client] result: "</span> . $result[<span>'result'</span>]); }</code>
例子4:
主要是展示通过complete回调回传数据。
例子5:
展示client端添加fail回调,当function中抛出Net_Gearman_Job_Exception异常时候,会触发 fail类型的回调,代码片段:
<code><span><span>class</span><span>Net_Gearman_Job_Example3</span><span>extends</span><span>Net_Gearman_Job_Common</span> {</span><span>public</span><span><span>function</span><span>run</span><span>(<span>$arg</span>)</span> {</span><span>if</span> (count (<span>$arg</span>) != <span>1</span>) { <span>throw</span><span>new</span> Net_Gearman_Job_Exception (<span>"must provide exactly one command to run"</span>); } <span>//...</span></code>
<code>$task->attachCallback (<span>"complete"</span>,Net_Gearman_Task::TASK_COMPLETE); $task->attachCallback (<span>"fail"</span>,Net_Gearman_Task::TASK_FAIL); //<span>...</span><span>function</span> fail ($task) { gm::log_msg (<span>"[gm_client] fail, task: "</span> . print_r ($task, true)); }</code>
但异常内容并不会回传给fail回调函数,所以还是建议使用正常的complete回调,用户可以自己捕获失败信息放到返回值里面。
例子6:
worker里面使用了monitor功能,代码片段:
<code><span>$worker</span>->beginWork (<span>'monitor'</span>); <span>// ...</span><span><span>function</span><span>monitor</span><span>(<span>$idle</span>, <span>$time_of_last_job</span>)</span> {</span><span>$idle_str</span> = (<span>$idle</span>) ? <span>'idle'</span> : <span>'not idle'</span>; <span>$time_of_last_job_str</span> = date (<span>'r'</span>, <span>$time_of_last_job</span>); gm::log_msg (<span>"[gm_worker] status: $idle_str, time of last job: $time_of_last_job_str"</span>); }</code>
其触发事件有:
job开始前。
job完成后。
等待job时候,一分钟触发一次。
例子7:
主要是在worker端添加了任务的start,complete和fail回调,可以在里面做点事情,代码片段:
<code><span>$worker</span><span>-></span>attachCallback (<span>'job_start'</span>, Net_Gearman_Worker<span>::JOB_START</span>); <span>$worker</span><span>-></span>attachCallback (<span>'job_complete'</span>, Net_Gearman_Worker<span>::JOB_COMPLETE</span>); <span>$worker</span><span>-></span>attachCallback (<span>'job_fail'</span>, Net_Gearman_Worker<span>::JOB_FAIL</span>);</code>
例子8:
是一个大综合,主要有以下几点值得注意:
1. 作者虽然很喜欢php,但也认为让php承担一个daemon的worker不是很保险的事情,可能涉及异常退出啊、内存使用不合理呀什么的,有可能影响性能,所以他提供了一个策略:每个worker有个实例编号,使用文件锁来确保一个实例编号只有一个worker运行,worker在处理了一定数目的job后自动退出,使用crontab任务秒级拉起worker。
2. worker的beginWorker退出可以在monitor回调中判断,monitor回调有这种特性:回调函数返回false则worker继续loop,返回true则loop退出,这个在worker的源码中也得到证实:
<code><span>if</span> (call_user_func(<span>$monitor</span>, <span>$idle</span>, <span>$lastJob</span>) == <span>true</span>) { <span>$working</span> = <span>false</span>; }</code>
以上就介绍了gearman-php的Net_Gearman库学习,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。