Overview
Bastion4
这个项目经过我们实验验证和安全考虑,决定舍弃kafka
而转用gearman
这个消息队列框架,具体分析将在后续文章中给出,这里只记录gearman
相关的安装。
1.下载安装gearman
最新版的gearman
是gearmand-1.1.12
。我们执行下面几步,先将其下载到本地主文件夹,并解压缩。
1 2 3 4 | 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
文件夹后,如果直接运行
1 | . /configure |
就会报缺少如下几个依赖包错误:
1 2 3 4 5 | 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 |
所以,我们先将这些依赖都安装好:
1 2 3 4 5 | 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
文件夹下运行下面两条命令,编译时间比较长:
1 2 | sudo make sudo make install |
这个过程中如果出现了错误,就运行下面的命令清除一下之前编译产生的可执行文件以及object
文件(即扩展名为o
的文件):
1 | sudo make clean |
继续重新安装编译:
1 2 3 | . /configure sudo make sudo make install |
没有错误的话,就安装gearman
的job server
:
1 | sudo apt-get install gearman-job-server |
安装好以后,运行一下gearman
:
1 | gearman |
会提示错误:
1 | 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
文件:
1 | sudo vim /etc/ld .so.conf |
添加一句话:
1 | include /usr/local/lib |
保存退出,并执行下面这句:
1 | sudo /sbin/ldconfig |
这样就不会出错了。
启动一下job server
:
1 | gearmand -d |
报错如下:
1 | 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
权限运行下面的命令:
1 | 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
个扩展包:
1 2 3 | Gearman::Server Gearman::Client Gearman::Worker |
可以用之前Chris
的博客BioPerl(一):安装BioPerl中介绍的方法,先安装好CPAN
。
之后,用sudo
权限打开CPAN
:
1 | sudo cpan |
然后依次安装3
个扩展包:
1 2 3 | install Gearman::Server install Gearman::Client install Gearman::Worker |
都安装后之后,可以重启一下机器。
启动之后,用如下命令观察4730
端口,查看gearman
的job server
是否已经启动(gearmand -d
这条命令是否生效):
1 | sudo lsof -i:4730 |
如果不加
sudo
是看不到的,所以linux
命令建议都要加上sudo
。
可以看到:
1 2 3 | 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) |
服务器端可能会只显示
1 2 | 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
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #!/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
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #!/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
1 | sudo perl worker.pl |
再查看4730
端口:
1 | sudo lsof -i:4730 |
发现多了两个占用:
1 2 3 4 5 | 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
1 | sudo perl client.pl |
每启动一个client.pl
就会多两个端口占用。
1 2 3 4 5 6 7 | 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安装搭建