Gearman如何工做的?php
(寫在前面的話: 工做當中遇到用Gearman來異步發送消息給用戶,對相關原理不太瞭解,因而查詢官網,遂翻譯以下,因爲水平有限,不免有錯誤不足之處,歡迎指出,敬請見諒.)web
A Gearman powered application consists of three parts: a client, a worker, and a job server. The client is responsible for creating a job to be run and sending it to a job server. The job server will find a suitable worker that can run the job and forwards the job on. The worker performs the work requested by the client and sends a response to the client through the job server. Gearman provides client and worker APIs that your applications call to talk with the Gearman job server (also known as gearmand) so you don't need to deal with networking or mapping of jobs. Internally, the gearman client and worker APIs communicate with the job server using TCP sockets. To explain how Gearman works in more detail, lets look at a simple application that will reverse the order of characters in a string. The example is given in PHP, although other APIs will look quite similar.服務器
We start off by writing a client application that is responsible for sending off the job and waiting for the result so it can print it out. It does this by using the Gearman client API to send some data associated with a function name, in this case the function reverse
. The code for this is (with error handling omitted for brevity):網絡
咱們開始, 寫一個 客戶端應用,負責發送 job任務, 並 等待返回結果 這樣就能夠把它打印出來. 它是經過調用Gearman 客戶端接口發送一些數據和一個方法名來實現的,在此處,這個方法叫reverse. 代碼以下(爲了簡潔起見,省略了錯誤處理部分): 數據結構
<?php // Reverse Client Code $client = new GearmanClient(); $client->addServer(); print $client->do("reverse", "Hello World!");
This code initializes a client class, configures it to use a job server with addServer
(no arguments means use 127.0.0.1
with the default port), and then tells the client API to run the reverse
function with the workload 「Hello world!」. The function name and arguments are completely arbitrary as far as Gearman is concerned, so you could send any data structure that is appropriate for your application (text or binary). At this point the Gearman client API will package up the job into a Gearman protocol packet and send it to the job server to find an appropriate worker that can run the reverse
function. Let's now look at the worker code:app
這段代碼初始化了GearmanClient()類的實例,讓這個實例調用addServer方法去使用一個 任務服務器,(此處這個addServer方法沒有攜帶參數,意味着它使用127.0.0.1做爲默認端口),而後告訴 client API 去運行 reverse 方法, 以及 "Hellow world!" 工做流.在Gearman方面,這個(do方法內的參數的) 方法名 和 參數 都是徹底隨意的,因此你能夠發送 對你的項目來講合適的 任何數據結構(文本或者二進制). 此時, Gearman client API 將打包這個 任務 進一個 Gearman協議包,並將它發送到 任務服務, 進而找到一個能夠運行這個 reverse 方法的 合適worker. 咱們如今來看看 worker 的代碼:less
<?php // Reverse Worker Code $worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction("reverse", function ($job) { return strrev($job->workload()); }); while ($worker->work());
This code defines a function addFunction that takes a string and returns the reverse of that string. It is used by a worker object to register a function named reverse
after it is setup to connect to the same local job server as the client. When the job server receives the job to be run, it looks at the list of workers who have registered the function name reverse
and forwards the job on to one of the free workers. The Gearman worker API then takes this request, runs the function addFunction
, and sends the result of that function back through the job server to the client.異步
這段代碼定義了一個 addFunction 方法, 這個方法 接收 一個字符串, 並返回 這個字符串的倒序. 這個方法被一個 任務對象($worker) 調用, 用來註冊一個 reverse 方法, 當它被用來當作客戶端來鏈接 一樣的當地服務服務器 以後. 當 任務服務器 接收到須要運行的任務時, 它會查詢那些註冊了 reverse方法的 workers(工人) 的列表, 將這個 任務 提交給空閒workers(工人)中的一個. 而後 Gearman worker API接受這個請求,運行 addFunction 方法, 並把這個方法的結果經過 任務服務器 發送回給 客戶端.socket
As you can see, the client and worker APIs (along with the job server) deal with the job management and network communication so you can focus on the application parts. There a few different ways you can run jobs in Gearman, including background for asynchronous processing and prioritized jobs. See the documentation available for the various APIs for details.async
就像你看到的那樣,客戶端和 worker API(工人接口)(還有 任務服務器(job server)) 會處理 任務管理 和 網絡通訊,因此你能夠專一於應用/項目部分.你也能夠經過一些不一樣的方式在Gearman中運行任務, 包括 異步處理 和 優先任務 背景.你能夠查看更多接口的 文檔 來獲取詳情.
The reverse example above seems like a lot of work to run a function, but there are a number of ways this can be useful. The simplest answer is that you can use Gearman as an interface between a client and a worker written in different languages. If you want your PHP web application to call a function written in C, you could use the PHP client API with the C worker API, and stick a job server in the middle. Of course, there are more efficient ways of doing this (like writing a PHP extension in C), but you may want a PHP client and a Python worker, or perhaps a MySQL client and a Perl worker. You can mix and match any of the supported language interfaces easily, you just need all applications to be able to understand the workload being sent. Is your favorite language not supported yet? Get involved with the project, it's probably fairly easy for either you or one of the existing Gearman developers to put a language wrapper on top of the C library.
The next way that Gearman can be useful is to put the worker code on a separate machine (or cluster of machines) that are better suited to do the work. Say your PHP web application wants to do image conversion, but this is too much processing to run it on the web server machines. You could instead ship the image off to a separate set of worker machines to do the conversion, this way the load does not impact the performance of your web server and other PHP scripts. By doing this, you also get a natural form of load balancing since the job server only sends new jobs to idle workers. If all the workers running on a given machine are busy, you don't need to worry about new jobs being sent there. This makes scale-out with multi-core servers quite simple: do you have 16 cores on a worker machine? Start up 16 instances of your worker (or perhaps more if they are not CPU bound). It is also seamless to add new machines to expand your worker pool, just boot them up, install the worker code, and have them connect to the existing job server.
Now you're probably asking what if the job server dies? You are able to run multiple job servers and have the clients and workers connect to the first available job server they are configured with. This way if one job server dies, clients and workers automatically fail over to another job server. You probably don't want to run too many job servers, but having two or three is a good idea for redundancy. The diagram to the left shows how a simple Gearman cluster may look.
From here, you can scale out your clients and workers as needed. The job servers can easily handle having hundreds of clients and workers connected at once. You can draw your own physical (or virtual) machine lines where capacity allows, potentially distributing load to any number of machines. For more details on specific uses and installations, see the section on examples.
Updates to come.