分布式计算之异步计算(Gearman示例)

1、异步计算

分布式计算听起来有点高大上,如果说异步计算,估计了解的人多了。我们在日常的工作和生活中,一般都能遇到或者用到异步计算。

比如年底要做很多的报表,领导把需要的报表安排下来,我和我的团队去做统计。为了不耽误领导的时间,不需要领导站在我们屁股后面亲自督战。对领导来说,这个就是一个简单的异步计算模型了。

我们的团队在统计的时候,数据量很多,系统要运行很久,我们也没必要一直看进度条转圈圈,可以去做一下别的工作,或者吃点零食,这个也是异步计算。

负责统计的系统,也没有必要一直转圈圈,把任务在后台运行,前端还可以执行其他的查询,这个也是异步计算。

一个事情,就牵出来一大堆异步计算,看来生活中,真的是满常见的。:)

异步计算实现了事务的计算的转移,但是并不能降低事务本身的计算时间。

2、异步计算工具:Gearman

注:Gearman强悍的地方就是它可以支持不同语言直接的交互,client端是一种语言,worker端可以是另外一种语言!中间的交互具体转化细节都封装在jobserver中处理。

Gearman是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。

一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。

Client:请求的发起者,可以是 C,PHP,Perl,MySQL
UDF 等等。

Job:请求的调度者,用来负责协调把 Client
发出的请求转发给合适的 Work。

Worker:请求的处理者,可以是 C,PHP,Perl
等等。

因为 Client,Worker
并不限制用一样的语言,所以有利于多语言多系统之间的集成。

甚至我们通过增加更多的 Worker,可以很方便的实现应用程序的异步计算。

3、Gearman样例

下面是例子是官网上面的字符串反转,供需要用的时候参考。

worker.php + client.java或worker.java +client.php

1. 环境:JDK1.7.0_25

所需jar包:java-gearman-service-0.6.6.jar, slf4j-api-1.6.4.jar,slf4j-simple-1.6.4.jar。可以直接到网上去下载。

2.代码:

Java语言

client端代码:

package com.gearman.demo;

import org.gearman.Gearman;

import org.gearman.GearmanClient;

import org.gearman.GearmanJobEvent;

import org.gearman.GearmanJobReturn;

import org.gearman.GearmanServer;

public class EchoClient {

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

// 创建一个Gearman实例

Gearman gearman = Gearman.createGearman();

// 创建一个Gearman client

GearmanClient client = gearman.createGearmanClient();

/*

* 创建一个jobserver

*

* Parameter 1: job server的IP地址 Parameter 2:
job server监听的端口

*

* job server收到client的job,并将其分发给注册worker

*/

GearmanServer server = gearman.createGearmanServer(

EchoWorker.ECHO_HOST, EchoWorker.ECHO_PORT);

// 告诉客户端,提交工作时它可以连接到该服务器

client.addServer(server);

/*

* 向job server提交工作

*

* Parameter 1: gearman function名字 Parameter 2:
传送给job server和worker的数据

*

* GearmanJobReturn返回job发热结果

*/

GearmanJobReturn jobReturn = client.submitJob(

EchoWorker.ECHO_FUNCTION_NAME, ("Hello World!").getBytes());

// 遍历作业事件,直到我们打到最后文件

while (!jobReturn.isEOF()) {

// 下一个作业事件

GearmanJobEvent event = jobReturn.poll();

switch (event.getEventType()) {

case GEARMAN_JOB_SUCCESS: // job执行成功

System.out.println(new String(event.getData()));

break;

case GEARMAN_SUBMIT_FAIL: // job提交失败

case GEARMAN_JOB_FAIL: // job执行失败

System.err.println(event.getEventType() + ": "

+ new String(event.getData()));

default:

}

}

// 关闭

gearman.shutdown();

}

}

worker端代码:

package com.gearman.demo;

import org.gearman.Gearman;

import org.gearman.GearmanFunction;

import org.gearman.GearmanFunctionCallback;

import org.gearman.GearmanServer;

import org.gearman.GearmanWorker;

public class EchoWorker implements GearmanFunction {

// function name

public static final String ECHO_FUNCTION_NAME = "reverse";

// job server地址

public static final String ECHO_HOST = "10.10.115.23";

// job server监听的端口

public static final int ECHO_PORT = 4730;

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

// 创建一个Gearman实例

Gearman gearman = Gearman.createGearman();

/*

* 创建一个jobserver

*

* Parameter 1: job server的IP地址 Parameter 2:
job server监听的端口

*

* job server收到client的job,并将其分发给注册worker

*/

GearmanServer server = gearman.createGearmanServer(

EchoWorker.ECHO_HOST, EchoWorker.ECHO_PORT);

// 创建一个Gearman的worker

GearmanWorker worker = gearman.createGearmanWorker();

// 告诉工人如何执行工作(主要实现了GearmanFunction接口)

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();

}

}

}

*ECHO_HOST = "192.168.1.12"为安装了Gearman并开启geramand服务的主机地址

*int ECHO_PORT = 4730默认端口为4730

例如log4j.properties文件内容如下:

log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender

log4j.appender.R.File=firestorm.log

log4j.appender.R.MaxFileSize=100KB

log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout

log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

log4j.logger.com.codefutures=DEBUG

PHP语言

client端:

<?php

$client = new GearmanClient();

$client->addServer();

print $client->do("reverse","Hello World!");

print "\n";

?>

worker端:

<?php

$worker= new GearmanWorker();

$worker->addServer();

$worker->addFunction("reverse","my_reverse_function");

echo "Starting worker ...";

while($worker->work());

function my_reverse_function($job)

{

return strrev($job->workload());

}

?>

3.测试

注:这里我将php文件放在:/home/user/projects/
文件夹下,另外,*.java的文件在eclipse中新建的工程里面。

测试1:worker.php + EchoClient.java

$php worker.php

然后,再在eclipse中运行:EchoClient.java

eclipse console输出结果:

INFO - [10.10.115.23:4730] :Connected

INFO - [10.10.115.23:4730] : OUT :SUBMIT_JOB

INFO - [10.10.115.23:4730] : IN :JOB_CREATED

INFO - [10.10.115.23:4730] : IN :WORK_COMPLETE

!dlroW olleH

INFO - [10.10.115.23:4730] : Disconnected

运行成功!!

测试2:EchoWorker.java + client.php

先在eclipse中运行,EchoWorker.java

然后,再在命令行下输入:php client.php

命令行下输出结果:

!dlroW olleH

运行成功!!

时间: 2024-10-07 13:28:20

分布式计算之异步计算(Gearman示例)的相关文章

java异步计算Future的使用(转)

从jdk1.5开始我们可以利用Future来跟踪异步计算的结果.在此之前主线程要想获得工作线程(异步计算线程)的结果是比较麻烦的事情,需要我们进行特殊的程序结构设计,比较繁琐而且容易出错.有了Future我们就可以设计出比较优雅的异步计算程序结构模型:根据分而治之的思想,我们可以把异步计算的线程按照职责分为3类: 1. 异步计算的发起线程(控制线程):负责异步计算任务的分解和发起,把分解好的任务交给异步计算的work线程去执行,发起异步计算后,发起线程可以获得Futrue的集合,从而可以跟踪异步

计算字段示例

计算字段示例 ArcGIS 10 使用键盘输入值并不是编辑表中值的唯一方式.在某些情况下,为了设置字段值,可能要对单条记录甚至是所有记录执行数学计算.您可以对所有记录或选中记录执行简单计算和高级计算.此外,还可以在属性表中的字段上计算面积.长度.周长和其他几何属性.以下各部分包括使用字段计算器的若干示例.计算可以通过 Python 或 VBScript 执行. Python 是 ArcGIS 建议使用的脚本语言.如果要访问地理处理功能(包括要素几何),请使用Python.采用 Python 作为

13.FutureTask异步计算

FutureTask     1.可取消的异步计算,FutureTask实现了Future的基本方法,提供了start.cancel 操作,可以查询计算是否完成,并且可以获取计算     的结果.结果只可以计算完成之后去获取,get方法会阻塞当前计算没有完成的线程,一定计算完成则会立即释放. 线程池submit与execute     1.submit()可以传入参数为实现callable接口的实例,返回future实例对象.     2.execute()返回void. package dem

如何给ExecutorService异步计算设置超时

ExecutorService接口使用submit方法会返回一个Future<V>对象,Future表示异步计算的结果.它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果.计算完成后只能使用get方法来获取结果,如有必要,计算完成前可以阻塞此方法.取消则由cancel方法来执行.还提供了其他方法,以确定任务是正常完成还是被取消了.一旦计算完成,就不能再取消计算.如果为了可取消性而使用Future但又不提供可用的结果,则可以声明Future<?>形式类型.并返回nul

Async异步编程入门示例

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace AsyncDemo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Console.WriteLine("异步方法测试开始!&quo

gearman(异步计算)学习

Gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调 用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/C++版本.目前大部分源码都是(Gearmand服务job Server)C++,各个API实现有各种语言的版本.PHP的Client API与Worker API实现为C扩展,在PHP官方网站有此扩展的中英文文档. 2Gearman架构中的三个角色 client:请求的发起者,工作任务的需求方(可以是C.PHP.Java.Perl.Mysql ud

kindeditor官网异步加载示例无效,解决无法通过方法初始化编辑器

官网示例:http://kindeditor.net/ke4/examples/dynamic-load.html 项目中发现一个问题,kindeditor官网是通过 初始化编辑器,但是现在有个需求,通过点击一个按钮使文本域初始化为富文本编辑器,尝试了以下方式 但是点击按钮,完全没有效果. 官网虽然有相应的示例,但是官网上的example根本就跑不起来,not work! 后来发现 异步加载主要的问题是KindEditor.ready无法执行,修改成以下方式即可:

Future和FutureTask实现异步计算

开发Android APP经常会使用AsyncTask框架来异步加载资源或者异步到服务器拉消息,等任务完成后再主动更新结果到UI主线程,AsyncTask框架可以非常方便的获取线程异步执行结果.Java 5之前,Java 并没有提供API用于查询线程是否执行完毕以及如何获取线程执行的结果:Java 5 之后版本提供的并发框架包java.util.concurrent对多线程提供了更多更好的支持,Future接口和FutureTask类是异步执行任务的框架的重要组成部分,为了更清楚的理解,我们还得

Python Web框架Tornado的异步处理代码示例

1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与另一个流行的Python web框架Django相比,tornado不提供操作数据库的ORM接口及严格的MVC开发模式,但可以提供基本的web server功能,故它是轻量级的:它借助non-blocking and event-driven的I/O模型(epoll或kqueue)实现了一套异步网络库,故它是高性能的. Tornado的轻量级+高性能特性使得它特别适用于提供web api的场合,