Gearman 基礎 以及 Gearman 使用舉例

<一> Gearman 基礎

Gearman 是什麼?

    Gearman 是一個分佈式的任務分發框架。java

    Gearman 用來把請求委派給機器,提供通用的程序框架來將任務分發在機器運算。同時具有並行工做能力、負載均衡處理的能力,以及跨語言通訊能力。服務器

Client 的工做原理

主要分紅三個部分Client、Job、Worker:

client:負責創建一個工做,發送請求給Job Server,而Job Server 會去找合適的 Worker 去轉發工做。架構

Job Server:瞭解Client 端的請求,並查看哪一個機器能夠處理這項請求,在系統裏它一般是個Daemon。負載均衡

Worker:Worker 經過Job Server 的分派,開始執行Client 端的工做。框架

關於Message Queue

  • 執行 Message Queue 服務的 Job Server 能夠是多臺服務器組成,也就是分佈式架構,在 Job Server 上執行 Worker 程序。異步

  • 這些 Worker 程序會一直循環地等候,直到 Job Server 呼叫它執行工做。分佈式

  • Client 端發送出請求以後,會將須要的資料及動做記錄在 Job Server 上,這時 Job Server 會查看是否有空閒並符合需求的 Worker。ide

  • 在 Worker 結束工做後,會發送通知給 Job Server ,這時 Job Server 就會視情況把結果回傳給 Client。spa

  • Client 端不需等候需求的執行結果,能夠直接繼續執行其餘動做。code


Job Server 負載方式

  • 當 Client 可能同時發出多個請求給 Job Server,由 Message Queue 接手進行處理。

  • 而 Job Server 開始處理多個請求,若其中一個發生問題,能夠 Failover 到其餘的機器。

  • 同時,Worker 會將多個請求一塊兒進行運算,再看是同步或異步模式,回傳結果給 Client。

同步 (Synchronous)

  • 同步(Synchronous) 是指 Client 將請求 (Application) 丟給 Gearmand。

  • 由 Gearmand 分派 Job 給各 Worker 去處理。

  • 並同步 Response 回傳給 Gearmand 告訴 Client 如今進度。

異步 (Asynchronous)

  • 異步 (Asynchronous) 是指 Client 將請求 (Application) 丟給 Gearmand。

  • 由 Gearmand 分派 Job 給各 Worker 去處理。

  • Worker 處理完畢後,纔會將結果回傳給 Gearmand 告訴 Client 如今進度。


<二> Gearman 舉例

來自Google Code  的例子,並作了一些修改 和 添加了一些註釋。

client 提交work 到 server,server 將任務分配給worker。

worker 所作得是將待處理的數據反轉。

1.Gearman server:

public class EchoWorkerServer {
    public static void main(String... args) throws IOException {
        // 建立一個Gearman 實例
	Gearman gearman = Gearman.createGearman();

	try {
            // 啓動一個新的 job server.
            // 在本機啓動
	    // 參數爲監聽端口
	    GearmanServer server = gearman.startGearmanServer(EchoWorker.ECHO_PORT);

	    // 建立一個 gearman worker.
	    // 從server 拉任務,而後執行相應的 GearmanFunction
	    GearmanWorker worker = gearman.createGearmanWorker();

	    // 告訴worker 如何執行工做(主要實現了 GearmanFunction 接口)
	    worker.addFunction(EchoWorker.ECHO_FUNCTION_NAME, new EchoWorker());

	    // worker 鏈接服務器
	    worker.addServer(server);

        } catch (IOException ioe) {
	    // 出現錯誤,關閉 gearman service
    	    gearman.shutdown();
	    throw ioe;
	}
    }
}

2.Gearman worker

public class EchoWorker implements GearmanFunction {
    // function 名稱
    public static final String ECHO_FUNCTION_NAME = "echo";

    // job server 的地址
    // Echo host 爲安裝了Gearman 並開啓Gearman 服務的主機地址
    public static final String ECHO_HOST = "localhost";
    
    // job server監聽的端口  默認的端口
    public static final int ECHO_PORT = 4730;

    public static void main(String... args) {

        // 建立一個Gearman 實例
        Gearman gearman = Gearman.createGearman();

        // 建立一個job server
        // 參數1:job server 的地址
        // 參數2:job server 監聽的端口
        // job server 收到 client 的job,並將其分發給註冊的worker
        GearmanServer server=gearman.createGearmanServer(EchoWorker.ECHO_HOST,EchoWorker.ECHO_PORT);

        // 建立一個 Gearman worker
        GearmanWorker worker = gearman.createGearmanWorker();

        // 告訴 worker 如何執行工做
        worker.addFunction(EchoWorker.ECHO_FUNCTION_NAME, new EchoWorker());

        // worker 鏈接服務器
        worker.addServer(server);
    }

    @Override
    public byte[] work(String function, byte[] data, GearmanFunctionCallback callback) throws Exception {
        // work方法實現了GearmanFunction接口中的work方法,本實例中進行了字符串的反寫
    	if (data != null) {
    	    String str = new String(data);
    	    StringBuffer sb = new StringBuffer(str);
    	    return sb.reverse().toString().getBytes();
    	} else {
    	    return "未接收到data".getBytes();
        }
    }
}

3.Gearman Client

public class EchoClient {
    public static void main(String... args) throws InterruptedException {
        Gearman gearman = Gearman.createGearman();

        // 建立一個 Gearman client
        // 用來向 job server 提交請求
        GearmanClient client = gearman.createGearmanClient();

       // 建立一個 job server 對象,該對象表明 remote job server.
       // job server 從clients 獲得jobs 而後分發給註冊workers
       GearmanServer server = gearman.createGearmanServer(
               EchoWorker.ECHO_HOST, EchoWorker.ECHO_PORT);

       // client 鏈接server
       client.addServer(server);

       // 將 job submit 給server
       // 參數1:function 名稱
       // 參數2:將要傳給server 和 worker 的數據
       // GearmanJobReturn 用來取得 job 的結果
       GearmanJobReturn jobReturn = client.submitJob(
                EchoWorker.ECHO_FUNCTION_NAME, ("Hello World").getBytes());

       // 遍歷job 事件,直到文件末尾
       while (!jobReturn.isEOF()) {
           // 得到下個job,(阻塞操做)
           GearmanJobEvent event = jobReturn.poll();
           switch (event.getEventType()) {
               // success
               case GEARMAN_JOB_SUCCESS: // Job completed successfully
                   // print the result
                   System.out.println(new String(event.getData()));
                   break;

               // failure
               case GEARMAN_SUBMIT_FAIL: // The job submit operation failed
               case GEARMAN_JOB_FAIL: // The job's execution failed
                   System.err.println(event.getEventType() + ": "
                        + new String(event.getData()));
            }
        }
        gearman.shutdown();
    }
}

說明:server 和 worker 都是在local host 運行

相關文章
相關標籤/搜索