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安装搭建