有关Gearman的用途,这里不再赘述,详见三五互联技术博文。
文章链接:http://ptc.35.com/?p=654
这里只介绍一个Gearman的三个角色以及它们之间的关系。Job Server、Client、Worker,Job Server负责接收Client请求/发送的任务,然后分发给合适的Worker完成,若需要返回,则返回值给Client。
数据流向:
Client---->Job Server---->Worker---->Job Server----->Client
Client、Worker并不知道对方的存在。
这三者都可以有多个,并且分布在不同的机器上,通常情况下,Client出现在业务应用中,负责请求/发送任务;而Worker是一个独立进程,除此之外,Worker还提供任务的实现,是具体任务实现的执行者。因此Client请求/发送的任务,应指明任务实现的唯一标识。在后面的例子,可以看到这一点。
部署:
1、下载gearman服务端(示例所用版本为1.1.4),这里指的是Job Server,有三个语言版本。分别是C、Perl、Java。Worker、Client有很多语言的实现,包括C、Perl、Python、Java等,可自行参考http://gearman.org/download,下载需要的版本。
本文所用的Job Server是C版,Worker、Client是gearman-java,注意不是
java-
gearman-service。gearman-java所属公司提供了gearman的Job Server、Worker、Client的Java版实现。
2、解压、编译、安装
tar xzf gearmand-X.Y.tar.gzcd gearmand-X.Y./configuremakemake install
configure过程,可能会出现一些错误:
(1)could not find toolset name.... 需要安装gcc-c++,yum install gcc-c++
(2) cannot find Boost headers version >= 1.39.0 需要安装boost-devel-1.41.0,yum install boost-devel-1.41.0
3、启动gearman
gearmand -d
4、打开4730端口
注:gearmand有很多参数,可以使用 gearman -h查看。如配置端口号、日志文件路径。初始时,若不指定日志文件路径,可能会报错,除非在报错信息指定的路径下建立日志文件后,再启动gearman。
Java测试例子:
EchoClient.java
package
com
.
laudandjolynn
.
test
.
gearman
;
import
java.io.IOException
;
import
java.util.concurrent.Future
;
import
org.gearman.client.GearmanClientImpl
;
import
org.gearman.client.GearmanJob
;
import
org.gearman.client.GearmanJobImpl
;
import
org.gearman.client.GearmanJobResult
;
import
org.gearman.common.Constants
;
import
org.gearman.common.GearmanJobServerConnection
;
import
org.gearman.common.GearmanNIOJobServerConnection
;
import
org.gearman.util.ByteUtils
;
/**
* @author: Laud
* @date: 2013-2-1 下午5:12:35
*/
public
class
EchoClient
{
private
final
GearmanClientImpl
client
;
public
EchoClient
(
String
host
,
int
port
)
throws
IOException
{
GearmanJobServerConnection
connection
=
new
GearmanNIOJobServerConnection
(
host
,
port
);
client
=
new
GearmanClientImpl
();
client
.
addJobServer
(
connection
);
}
public
String
echo
(
String
input
)
throws
IOException
{
byte
[]
data
=
ByteUtils
.
toUTF8Bytes
(
input
);
byte
[]
respBytes
=
client
.
echo
(
data
);
return
ByteUtils
.
fromUTF8Bytes
(
respBytes
);
}
public
String
hello
()
throws
IOException
{
String
uniqueId
=
null
;
GearmanJob
job
=
GearmanJobImpl
.
createJob
(
EchoWorker
.
class
.
getCanonicalName
(),
null
,
uniqueId
);
Future
<
GearmanJobResult
>
f
=
client
.
submit
(
job
);
GearmanJobResult
jr
=
null
;
try
{
jr
=
f
.
get
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
// NOPMD
}
return
new
String
(
jr
.
getResults
());
}
public
void
shutdown
()
throws
IllegalStateException
{
if
(
client
==
null
)
{
throw
new
IllegalStateException
(
"No client to shutdown"
);
}
client
.
shutdown
();
}
public
static
void
main
(
String
[]
args
)
{
String
host
=
"192.168.1.123"
;
int
port
=
Constants
.
GEARMAN_DEFAULT_TCP_PORT
;
try
{
EchoClient
ec
=
new
EchoClient
(
host
,
port
);
// String value = ec.echo("hello!");
// System.out.println(value); // NOPMD
System
.
out
.
println
(
ec
.
hello
());
ec
.
shutdown
();
}
catch
(
IOException
ioe
)
{
ioe
.
printStackTrace
();
// NOPMD
}
}
}
EchoWorker.java
package
com
.
laudandjolynn
.
test
.
gearman
;
import
org.gearman.client.GearmanJobResult
;
import
org.gearman.client.GearmanJobResultImpl
;
import
org.gearman.common.Constants
;
import
org.gearman.common.GearmanNIOJobServerConnection
;
import
org.gearman.worker.AbstractGearmanFunction
;
import
org.gearman.worker.GearmanWorker
;
import
org.gearman.worker.GearmanWorkerImpl
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* @author: Laud
* @date: 2013-2-1 下午5:23:03
*/
public
class
EchoWorker
extends
AbstractGearmanFunction
{
private
final
static
Logger
log
=
LoggerFactory
.
getLogger
(
EchoWorker
.
class
);
public
static
void
main
(
String
[]
args
)
{
GearmanWorker
worker
=
new
GearmanWorkerImpl
();
GearmanNIOJobServerConnection
conn
=
new
GearmanNIOJobServerConnection
(
"192.168.1.123"
,
Constants
.
GEARMAN_DEFAULT_TCP_PORT
);
worker
.
addServer
(
conn
);
worker
.
registerFunction
(
EchoWorker
.
class
);
log
.
debug
(
"启动服务..."
);
worker
.
work
();
}
@Override
public
GearmanJobResult
executeFunction
()
{
log
.
debug
(
"调用了worker方法!"
);
GearmanJobResult
jr
=
new
GearmanJobResultImpl
(
"哈哈"
.
getBytes
());
return
jr
;
}
}