文档章节

Gearman 基础 以及 Gearman 使用举例

平江夜弹
 平江夜弹
发布于 2015/12/14 10:36
字数 1114
阅读 161
收藏 3

<一> Gearman 基础

Gearman 是什么?

    Gearman 是一个分布式的任务分发框架。

    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。

  • 在 Worker 结束工作后,会发送通知给 Job Server ,这时 Job Server 就会视状况把结果回传给 Client。

  • Client 端不需等候需求的执行结果,可以直接继续执行其他动作。


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 运行

© 著作权归作者所有

平江夜弹
粉丝 27
博文 47
码字总数 17530
作品 0
南京
程序员
私信 提问
Calabash+Gearman实现多手机同步测试机制

摘要: Calabash-android是支持android的UI自动化测试框架,但不支持多手机同步测试。本文介绍如何利用任务分发系统Gearman的消息同步机制,配合Gearman实现多手机同步测试机制。 背景介绍 ...

超爱fitnesse
2015/01/09
1K
0
CentOS的Gearman安装与使用无错版

通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用WebService的方式来处理此类集成问题,但不管采用何种风格的WebService,如RPC风格,或者REST风格,其本身都有一定的复杂...

晨曦之光
2012/03/09
2.2K
0
通过Gearman实现MySQL到Redis的数据复制

对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的NoSQL数据库,就...

o0无忧亦无怖
2015/12/04
128
0
用 Gearman 分发 PHP 应用程序的工作负载

尽管一个 Web 应用程序的大部分内容都与表示有关,但它的价值与竞争优势却可能体现在若干专有服务或算法方面。如果这类处理过于复杂或拖沓,最好是进行异步执行,以免 Web 服务器对传入的请求...

红薯
2010/02/02
3.2K
3
redis作为mysql的缓存服务器(读写分离)

一、redis简介 Redis是一个key-value存储系统。和Memcached类似,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且...

mickelfeng
2015/10/15
273
2

没有更多内容

加载失败,请刷新页面

加载更多

新架构、新角色:TiDB Community Upgrade!

作者:Jian Zhang 经过几年的发展,TiDB 社区已经逐渐成熟,但是随着社区的发展壮大,我们逐渐感受到了现在社区架构上的一些不足。经过一系列的思考和总结,我们决定升级和调整目前社区组织架...

TiDB
28分钟前
5
0
jquery qrcode库提示not function

jquery qrcode 这个库能用,但是必须在初始化的时候,官方给的使用方法是 引入qrcode的库文件后,在js中写以下 html <div id="qrcode"></div> js jQuery('#qrcode').qrcode({ render: ......

shikamaru
33分钟前
13
0
MySQL数据库去重的简单方案

利用 distinct 对需要处理的字段进行去重 select distinct 字段名 from 表名 利用group by select * from 表名 group by 字段名 利用having select * from 表名 group by 字段名 having 字段...

FeanLau
35分钟前
9
0
字符串转换成整数

实现一个 atoi 函数,使其能将字符串转换成整数。 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。 当我们寻找到的第一个非空字符为正或者负号时,则将该...

蔚蓝_晴天
47分钟前
8
0
Eureka客户端续约及服务端过期租约清理源码解析

在之前的文章:EurekaClient自动装配及启动流程解析中,我们提到了在构造DiscoveryClient时除了包含注册流程之外,还调度了一个心跳线程: scheduler.schedule( new Ti...

Java学习录
58分钟前
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部