Skip to content

Instantly share code, notes, and snippets.

@dong920740928
Last active August 3, 2017 11:12
Show Gist options
  • Save dong920740928/22f482481962fab7d5a1 to your computer and use it in GitHub Desktop.
Save dong920740928/22f482481962fab7d5a1 to your computer and use it in GitHub Desktop.
gearman_java中的使用

2 用java编写gearman的client端及端程序

2.1 加入包依赖

这里给出maven中应添加的依赖,直接copy进pom.xml即可 org.gearman.jgs java-gearman-service [0.7.0-SNAPSHOT,)

2.2 java api demo

gearman的java api相较于其它语言来讲具有较强的封装性,用户程序员可以只关注client端和worker端要做的事情,而不需要像c那样写大量做铺垫的语句

2.2.1 java client
import org.gearman.Gearman;
import org.gearman.GearmanClient;
import org.gearman.GearmanJobEvent;
import org.gearman.GearmanJobReturn;
import org.gearman.GearmanServer;
 
public class ClientDemo {
 
    public static void main(String... args) throws InterruptedException {
        //创建gearman对象(有开销)
        Gearman gearman = Gearman.createGearman();
 		//创建客户端(有开销)
        GearmanClient client = gearman.createGearmanClient();
 		
 		//形式创建服务器对象(无开销)
        GearmanServer server = gearman.createGearmanServer(
                /*服务器HOST*/, /*PORT*/);
                
		//客户端添加待选服务器(无开销)
        client.addServer(server);
		//提交任务(此处会试图将数据发往gearmanserver,成功提交到服务器后,gearman会自己进行任务调度
        GearmanJobReturn jobReturn = client.submitBackgroundJob(
                /*要执行的函数名,这个名字是client和worker事先协商好的*/,/*参数,byte[]*/);
		//轮询执行结果
        while (!jobReturn.isEOF()) {
 
            // 等待任务状态(这个操作是阻塞性的)
            GearmanJobEvent event = jobReturn.poll();
 
            switch (event.getEventType()) {
 
            // 成功
            case GEARMAN_JOB_SUCCESS: 
                // 输出结果
                System.out.println(new String(event.getData()));
                break;
 
            // 失败
            case GEARMAN_SUBMIT_FAIL: // 提交失败
            case GEARMAN_JOB_FAIL: // 执行失败
                System.err.println(event.getEventType() + ": "
                        + new String(event.getData()));
 
            }
 
        }
 
        //关闭gearman及所有的gearman功能(该gearman创建的所有worker和client)
        //当出现多个任务需要分发的时候,应当重复利用几个instance ,而非create new gearman instance
        gearman.shutdown();
    }
}
2.2.2 java worker

java worker 的编写比client稍加复杂,需要实现一个GearmanFunction接口

public interface GearmanFunction {

	public byte[] work(String function, byte[] data, GearmanFunctionCallback callback) throws Exception;
}

接口的定义简单明了,就是封装了一个work方法,这个work方法就是worker被分配任务时实际执行的代码。 程序员编写worker端时需要实现这个接口的worker方法,代码如下。

import org.gearman.Gearman;
import org.gearman.GearmanFunction;
import org.gearman.GearmanFunctionCallback;
import org.gearman.GearmanServer;
import org.gearman.GearmanWorker;
 
public class Worker implements GearmanFunction {
 
 
    public static void main(String... args) {
    
        Gearman gearman = Gearman.createGearman();
 
        GearmanServer server = gearman.createGearmanServer(
                /*服务器host*/, /*服务器port*/);
         
        //创建一个worker(有开销)
        GearmanWorker worker = gearman.createGearmanWorker();
        
        //给worker添加一组操作名和函数的映射,这意味着服务器知道这个worker可以做某件事,当client提出的某个请求的名字和这个worker添加过的函数名一致时,就有可能把任务分发给这个worker
        //注意第二个参数传入的是一个Worker实体,本质上是将接口GearmanFunction的work方法传入,当某个worker被分配任务的时候,会调用work方法
        //这意味着,work方法的内部逻辑对job server是不可见的,当各个worker之间出现函数名重名但实现逻辑不同的情况时会造成不可预料的后果。
        worker.addFunction(/*函数名*/, new Worker());
        
        //worker添加服务器
        worker.addServer(server);
        
         
    }
 
 
    public byte[] work(String function, byte[] data,
            GearmanFunctionCallback callback) throws Exception {
 
        //干某事
        
        return data;
    }
 
}

上一篇讲过,gearman各个worker之间是多进程的关系,所以work部分的代码必须是进程安全的。另外就是client和worker之间要协商好函数名,各个worker之间原则上不能对同名函数有不同的work实现。 EOF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment