Overview1.下载安装gearman2.安装perl扩展包3.运行测试perl脚本 Overview Bastion4这个项目经过我们实验验证和安全考虑，决定舍弃kafka而转用gearman这个消息队列框架，具体分析将在后续文章中给出，这里只记录gearman相关的安装。 1.下载安装gearman 最新版的gearman是gearmand-1.1.12。我们执行下面几步，先将其下载到本地主文件夹，并解压缩。 sudo apt-get update wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz tar zxvf gearmand-1.1.12.tar.gz cd gearmand-1.1.12/ 进入gearmand-1.1.12文件夹后，如果直接运行 ./configure 就会报缺少如下几个依赖包错误： configure: error: could not find boost configure: error: Could not find a version of the library configure: error: could not find gperf configure: error: Unable to find libevent configure: error: Unable to find libuuid 所以，我们先将这些依赖都安装好： sudo apt-get install libboost-dev sudo apt-get install libboost-all-dev sudo apt-get install gperf sudo apt-get install libevent-dev sudo apt-get install uuid-dev 安装好之后，如果没有错误，仍在gearmand-1.1.12文件夹下运行下面两条命令，编译时间比较长： sudo make sudo make install 这个过程中如果出现了错误，就运行下面的命令清除一下之前编译产生的可执行文件以及object文件(即扩展名为o的文件)： sudo make clean 继续重新安装编译： ./configure sudo make sudo make install 没有错误的话，就安装gearman的job server： sudo apt-get install gearman-job-server 安装好以后，运行一下gearman: gearman 会提示错误： gearman: error while loading shared libraries: libgearman.so.8: cannot open shared object file: No such file or directory 这表示找不到libgearman.so.8所在的目录。这时我们打开/etc/ld.so.conf文件： sudo vim /etc/ld.so.conf 添加一句话: include /usr/local/lib 保存退出，并执行下面这句： sudo /sbin/ldconfig 这样就不会出错了。 启动一下job server： gearmand -d 报错如下： gearmand: Could not open log file "/usr/local/var/log/gearmand.log", from "/home/young/gearmand-1.1.12", switching to stderr. (No such file or directory) 我们这样解决：在/usr/local/下面新建var子目录，进去，新建log子目录，再进去，新建文件gearmand.log。这样就没有问题了。 用sudo权限运行下面的命令： sudo gearmand -d -L 127.0.0.1 -p 4730 -d表示daemon，在后台运行； -L表示监听的ip，默认是localhost； -p表示监听的端口号port，默认是4730。 这样gearman在ubuntu14.04上面就安装成功了。 2.安装perl扩展包 perl端需要3个扩展包： Gearman::Server Gearman::Client Gearman::Worker 可以用之前Chris的博客BioPerl（一）：安装BioPerl中介绍的方法，先安装好CPAN。 之后，用sudo权限打开CPAN： sudo cpan 然后依次安装3个扩展包： install Gearman::Server install Gearman::Client install Gearman::Worker 都安装后之后，可以重启一下机器。 启动之后，用如下命令观察4730端口，查看gearman的job server是否已经启动(gearmand -d这条命令是否生效)： sudo lsof -i:4730 如果不加sudo是看不到的，所以linux命令建议都要加上sudo。 可以看到： COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 576 gearman 9u IPv4 12861 0t0 TCP *:4730 (LISTEN) gearmand 576 gearman 10u IPv6 12862 0t0 TCP *:4730 (LISTEN) 服务器端可能会只显示 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 576 gearman 9u IPv4 12861 0t0 TCP *:4730 (LISTEN) 可见这个server是开机启动的。 3.运行测试perl脚本 client.pl将消息发送到server，相当于生产者； worker.pl来处理这些消息，并把结果返回给client.pl， 相当于消费者。我们观察输出即可。 client.pl代码如下： #!/usr/bin/perl use strict; use warnings; use Gearman::Client; use Storable; use Storable qw(freeze); use Storable qw(thaw); use IO::All; # fork this process my $pid = fork(); if ($pid == 0) { # do this in the child print "start new client \n"; my $client = Gearman::Client->new; print "finish new client \n"; print "start job_servers \n"; $client->job_servers('127.0.0.1',4730); print "finish job_servers \n"; # 设置异步任务 print "start new_task_set \n"; my $tasks = $client->new_task_set; print "finish new_task_set \n"; print "start add_task \n"; #handle database my @rows=('hello','byebye'); $tasks->add_task( # 开始任务,多个参数 showMessage => freeze(\@rows), # 注册回调函数 { on_complete => \&complete }, ); print "finish add_task \n"; print "start wait \n"; # 等待任务结束 $tasks->wait; print "finish wait \n"; exit; } print "The background task will be finished shortly.\n"; sub complete{ my $ret = ${ $_[0] }; #io("complete.txt")->print($ret); print $ret, "\n"; } worker.pl代码如下： #!/usr/bin/perl use strict; use warnings; use Gearman::Worker; use Storable qw(thaw); use Storable qw(freeze); print "start new worker \n"; my $worker = Gearman::Worker->new; print "finish new worker \n"; print "start job_servers \n"; $worker->job_servers('127.0.0.1',4730); print "finish job_servers \n"; # Worker 注册可以使用的功能 print "start register_function \n"; $worker->register_function( showMessage => \&showMessage ); print "finish register_function \n"; # 等待连接的任务 print "start work \n"; $worker->work while 1; print "finish work \n"; sub showMessage{ my @row=@{ thaw($_[0]->arg) }; my $job = \@row; print "\n"; print "$row[0] \n"; print "$row[1] \n"; print "start sleep \n"; my $date = &getTime(); print $date->{date}," ",$date->{hour},":",$date->{minute},":",$date->{second}; print "\n"; sleep(10); print "finish sleep \n"; $date = &getTime(); print $date->{date}," ",$date->{hour},":",$date->{minute},":",$date->{second}; print "\n"; my $ret = "hello world"; return $ret; } sub getTime { my $time = shift || time(); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time); $year += 1900; $mon ++; $min = '0'.$min if length($min) < 2; $sec = '0'.$sec if length($sec) < 2; $mon = '0'.$mon if length($mon) < 2; $mday = '0'.$mday if length($mday) < 2; $hour = '0'.$hour if length($hour) < 2; my $weekday = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$wday]; return { 'second' => $sec, 'minute' => $min, 'hour' => $hour, 'day' => $mday, 'month' => $mon, 'year' => $year, 'weekNo' => $wday, 'wday' => $weekday, 'yday' => $yday, 'date' => "$year-$mon-$mday" }; } 我们先运行worker.pl sudo perl worker.pl 再查看4730端口： sudo lsof -i:4730 发现多了两个占用： COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 576 gearman 9u IPv4 12861 0t0 TCP *:4730 (LISTEN) gearmand 576 gearman 10u IPv6 12862 0t0 TCP *:4730 (LISTEN) gearmand 576 gearman 33u IPv4 191760 0t0 TCP localhost:4730->localhost:37151 (ESTABLISHED) perl 4508 root 3u IPv4 192605 0t0 TCP localhost:37151->localhost:4730 (ESTABLISHED) 再运行多个client.pl sudo perl client.pl 每启动一个client.pl就会多两个端口占用。 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 576 gearman 9u IPv4 12861 0t0 TCP *:4730 (LISTEN) gearmand 576 gearman 10u IPv6 12862 0t0 TCP *:4730 (LISTEN) gearmand 576 gearman 33u IPv4 191760 0t0 TCP localhost:4730->localhost:37151 (ESTABLISHED) gearmand 576 gearman 34u IPv4 215493 0t0 TCP localhost:4730->localhost:37189 (ESTABLISHED) perl 4508 root 3u IPv4 192605 0t0 TCP localhost:37151->localhost:4730 (ESTABLISHED) perl 4709 root 3u IPv4 214688 0t0 TCP localhost:37189->localhost:4730 (ESTABLISHED) 每运行一次worker.pl表示启动一个新的消费者。如果只启动一个消费者，而启动多个生产者，就可以很好地观察到“排队”效果了：一定是一个任务执行完成之后才会开始处理另一个任务。 这样gearman和perl扩展包的安装使用就结束了。 这篇文章主要参考了如下几篇文章： Gearman Job Server Gearman 使用 Gearman 实现分布式处理 Gearman 安装使用 以及 问题处理 Ubuntu下Gearman安装搭建