[实践OK]CentOS的Gearman安装与使用无错版,包含PHP的gearmand扩展,包括安装Gearmand及其PHP扩展,及简单task/worker,相当不容易。

jackxiang 2014-12-18 15:22 | |
背景:用PHP做一些简单的上传是没有任何的问题,但是要做断点上传好像也是没有大问题,但要是并发的切片加断点上传可能就会有问题了哟。
第一个问题是合并问题:如果一上传就合并,PHP老半天不返回是一个方面(是PHP超时还是Nginx超时?),这样势必会造成客户端因没返回,没法再启动新的上传进程,如果用php的追加写文件内存太大还会退出的可能,用上gearmand后出现异步同时写,可能加快了传输效率的同时IO可能会比较密集(假如同一时间并发上传的人多的情况。)。
第二个问题是先后问题:如果并发时出现了传一半时最后一片先上传上来了怎么办?如果直接追加进文件是会不按顺序出错的,如果放在那儿不管,那啥时候管,这也是一个问题。
第三个问题是锁的问题:并发时如果同时两片到了,像PHP这种如何去结合锁的功能呢?据我所知有memcache的add函数是原子操作,可以利用,那就设计到锁多久,是不是又回到第一个问题,返回时间得浪费多长时间呢。
基于上面三点,看来PHP做这活不是太靠谱,于是引出了gearman这个模型,相当于异步处理,再集合PHP的memcache锁(memcache放内存,可能得用ttserver才行,协议一样的。),PHP上传逻辑处理,Nginx上传插件,才有可能做一个较为靠谱且稳定的分片,断点加多进程(多线程)上传服务搭建。

一、从源码安装gearmand遇到的各种外部代码版本及yum版本太低的导致各种编译不过的问题,历程相当的麻烦,特别是boost和这个libevent默认的yum install非常低,都给编译了,把rpm所强制删除了,最后才成功,再就是g++编译版本,得export后才能编译,否则一堆问题,都在下面有描写。
出现第一个问题及处理办法:
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
将队列存放在sqlite3或postgresql。这货是用的sqlite存队列啊:
yum search sqlite
yum install sqlite.x86_64 sqlite-devel.x86_64
还是不行,参考:
安装:https://jackxiang.com/post/7709/ 后,
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。


出现第二个问题及处理办法:
./libgearman-1.0/gearman.h:53:23: error: cinttypes: No such file or directory
命令:
yum install gcc44 gcc44-c++ libstdc++44-devel -y
然后在环境变量里加入:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc
export CXX=/usr/bin/g++44
保存退出后执行:
source /etc/profile
删除gearmand-0.34文件夹重新进行编译.
重新进行编译后执行make这步......

看来还得重新export一次新的编译器,因为昨天的关了终端,今天的又没了:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc  //这行有问题~
export CXX=/usr/bin/g++44
g++ -o testmemcached testmemcached.cpp -lmemcached
为何还是不行?
echo $CC
/usr/bin/gcc  //没变,这儿有问题,再重新设置一次,查到上面这个or有问题:export CC=/usr/bin/gcc44。
# echo $CXX
/usr/bin/g++44 //变了

重新设置,好了:
export CC=/usr/bin/gcc44
/usr/bin/gcc44

在后面有详细的说明,可以不source直接设置环境变量,因为编译后也不一定要这个版本的gcc的。



出现第三个问题的处理办法:
ibgearman-server/plugins/queue/mysql/queue.cc:430: error: 'mysql_error' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc: In function 'gearmand_error_t _mysql_queue_replay(gearman_server_st*, void*, gearmand_error_t (*)(gearman_server_st*, void*, const char*, size_t, const char*, size_t, const void*, size_t, gearman_job_priority_t, int64_t), void*)':
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'MYSQL_RES' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'result' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:447: error: 'MYSQL_ROW' was not declared in this scope

[root@test gearmand-1.1.12]# ./configure --help|grep mysql
  --with-mysql=[ARG]      use MySQL client library [default=yes], optionally
                          specify path to mysql_config
              Full path to mysql_config program

看样子是想用mysql做队列queue的:


加上还是报错,去了得了,不用mysql做队列,有sqlite足够了,
--without-mysql就好了,来自:
https://bugs.launchpad.net/gearmand/+bug/1327038 说的:


出现第四个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::m_default_line_length'
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::run()':
/usr/local/include/boost/program_options/detail/parsers.hpp:107: undefined reference to `boost::program_options::detail::cmdline::get_canonical_option_prefix()'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)':
/usr/local/include/boost/program_options/detail/parsers.hpp:77: undefined reference to `boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)'
collect2: ld returned 1 exit status
make[1]: *** [bin/gearadmin] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'


[root@test gearmand-1.1.12]# ./configure --help|grep boost
  --with-boost[=ARG]      use Boost library from a standard location
  --with-boost-libdir=LIB_DIR
                          Force given directory for boost libraries. Note that
                          fails and you know exactly where your boost
  --with-boost-program-options[=special-lib]
                          use the program options library from boost - it is
                          --with-boost-program-options=boost_program_options-gcc-mt-1_33_1

指定boost的库:
从这儿得知在这儿呢:  http://jackxiang.com/post/7706/
系统默认会将include拷贝到/usr/local/include/boost/中
将lib拷贝到/usr/local/lib下
yum install boost-devel  [实践失败]
回头了解下boost的结构,rpm包是啥样的,如下所示,版本号1.33,有可能是因为lddconfig里默认配置指向这个旧版本了,如下:
vi /etc/ld.so.conf


[root@test ~]# rpm -ql boost-1.33.1-16.el5_9
/usr/lib64/*.so.*  //各种so文件
/usr/lib/*.so.*     //各种so文件
rpm -ql boost-devel-1.33.1-16.el5_9
/usr/include/boost  里面是各种分类目录,里面是hpp头文件
algorithm/
archive/
assign/
bind/
compatibility
config/
devel包里还有静态a文件及动态so文件:
/usr/lib/libboost_test_exec_monitor.a
/usr/lib/libboost_test_exec_monitor.so

如下实践试试:
cd /home/xiangdong/software/boost_1_57_0
./bootstrap.sh --prefix=/usr/local/boost-1.57
vi tools/build/v2/user-config.jam
文件尾部增加(没找到,直接./b2 ./b2 install 即可!):
using mpi  
./b2
./b2 install


Boost headers version >= 1.39.0
[root@localdomain gearmand-1.1.12]# yum search boost
[root@localdomain gearmand-1.1.12]# yum install boost.x86_64
[root@localdomain gearmand-1.1.12]# yum install yum install boost-devel.x86_64
旧的yum源,直接干死,用源码装个试试:



出现第五个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/libgearman-server/gearmand_con.cc:677: undefined reference to `event_initialized'
collect2: ld returned 1 exit status
libevent版本太老了,更新新的版本:
安装最新版本的libevent,并执行以下操作:(备份老版本的/usr/lib64/libevent.so)
ln -s /usr/lib64/libevent-2.0.so.5 /usr/lib64/libevent.so
删除老旧的libevent的rpm包后,安装最新的方法实践如下:
[root@test software]# cp  /usr/lib64/libevent.so /usr/lib64/libevent.so.bak.old
[root@test libevent-2.0.21-stable]# tar -zxvf libevent-2.0.21-stable.tar.gz
[root@test libevent-2.0.21-stable]# cd libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr/local/libevent-2.0.21-stable


ls -al /usr/lib | grep libevent
rpm -qa|grep libevent
libevent-1.4.13-1
libevent-devel-1.4.13-1
libevent-devel-1.4.13-1
libevent-1.4.13-1

rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]# rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]#

卸载后看还有没:
[root@test libevent-2.0.21-stable]# ls -al /usr/lib | grep libevent  
lrwxrwxrwx   1 root root       31 Dec 30 17:17 libevent-1.1a.so.1 -> /usr/lib/libevent-1.1a.so.1.0.2
-rw-r--r--   1 root root    31596 Jan  7  2007 libevent-1.1a.so.1.0.2

rm -Rf  /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1 //删除干净
[root@test libevent-2.0.21-stable]# rm -Rf  /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1
[root@test libevent-2.0.21-stable]#

cd /home/xiangdong/software/libevent-2.0.21-stable  //最新安装包
./configure --prefix=/usr   //libevent会安装到 /usr/lib 或 /usr/local/lib 下
#./configure --prefix=/usr/local/libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr && make && make install
测试libevent是否安装成功:ls -al /usr/lib | grep libevent(或 ls -al /usr/local/lib | grep libevent)
ls -al /usr/lib | grep libevent
lrwxrwxrwx   1 root root       21 Dec 31 09:44 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x   1 root root  1065819 Dec 31 09:44 libevent-2.0.so.5.1.9
-rw-r--r--   1 root root  1678970 Dec 31 09:44 libevent.a
lrwxrwxrwx   1 root root       26 Dec 31 09:44 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9

如果libevent的安装目录为/usr/local/lib下,则还需要建立 libevent-1.4.so.2 到 /usr/lib 的软连接,这样其他程序运行时才能找到libevent库:ln -s /usr/local/lib/libevent-1.4.so.2  /usr/lib/libevent-1.4.so.2

ls /usr/lib/libevent-2.0.so.5
/usr/lib/libevent-2.0.so.5

干掉旧的libevent的残留的动态so文件:
ls -al /usr/lib64 | grep libevent
lrwxrwxrwx   1 root root       19 Dec 31 09:40 libevent-1.4.so.2 -> libevent.so.bak.old
-rwxr-xr-x   1 root root   104296 Dec 31 09:22 libevent.so.bak.old
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib64/libevent-1.4.so.2
参考来自:http://blog.sina.com.cn/s/blog_4b93170a0100mbm9.html

编译成功结果如下:


启动gearmand的方法:
[root@test gearmand-1.1.12]# whereis gearmand
gearmand: /usr/local/sbin/gearmand
[root@test ~]# mkdir -p /usr/local/gearman/log

ls /usr/local/sqlite3/bin/
sqlite3

*特别提醒,(mysql性能上可能在做队列上并不比sqlite强到哪儿去)
使用sqlite更加简单方便 :
/usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
很遗憾,我到现在也没能编译出对MySQL的持久化

[root@test ~]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
/usr/local/sbin/gearmand: Error while initializing the queue : libsqlite3

原来是sqlite的位置不对,修改路径后就OK了:

启动成功:
[root@test sqlite3]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite3/bin/gearman --libsqlite3-table gearman_queue -d
[root@test sqlite3]#
端口存在了,说明是真的启动成功了:
[root@test sqlite3]# netstat -atlunp|grep 4830
tcp        0      0 0.0.0.0:4830                0.0.0.0:*                   LISTEN      17820/gearmand      
tcp        0      0 :::4830                     :::*                        LISTEN      17820/gearmand  

也就是说gearmand启动时候自己建立一个sqlite的表,如下:
[root@test sqlite3]# cat /usr/local/sqlite3/bin/gearman
SQLite format 3@  ''blegearman_queuegearman_queueCREATE TABLE gearman_queue ( unique_key TEXT, function_name TEXT, priority INTEGER, data BLOB, when_to_run INTEGER, PRIMARY KEY (unique_key, function_name))9M'indexsqlite_autoindex_gearman_queue_1gearman_queue

经过一陈折腾,说明这个gearmand对boost库的要求高,对libevent的版本也要求高,不是能经过yum install能解决得了的,得自己安装后指定,再就是对编译器的版本也是有要求的,也就是说相对来说其安装比较苛刻一些,如Lamp架构相比较的话,难度要高一些。
——————————————————————————————————————————————————————————————
总之,一大堆问题,这货居然还这么流行听说Gearman最初用于LiveJournal的图片resize功能,由于图片resize需要消耗大量计算资 源,因此需要调度到后端多台服务器执行,完成任务之后返回前端再呈现到界面。,看来广大分发系统还真得靠它啊,其它各种小问题不断,参考:
http://www.111cn.net/sys/CentOS/65334.htm

二、PHP的gearmand扩展编译及遇到问题解决实践如下:
PHP的gearmand折腾扩展,这块试了好几个版本的扩展要么configure不过去,要么是lib里却啥,但最后还是以当前最新的版本gearman-1.1.2.tgz给解决了:

./configure --with-php-config=/usr/local/php/bin/php-config
出现如下所示的配置错误:
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable gearman support... yes, shared
found in /usr/local
checking for gearman_create in -lgearman... no
configure: error: wrong libgearman version or lib not found

问题一:
gearman的PHP扩展时出现configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.警告信息。
警告信息说明需要安装 re2c
执行下面命令安装:
wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
2014-12-31 11:01:59 (999 KB/s) - `re2c-0.13.5.tar.gz' saved [782725/782725]
tar -zxvf re2c-0.13.5.tar.gz
cd re2c-0.13.5
./configure && make && make install //安装成功,警告得到了解决,第二个依旧存在。
它的意思是好像没有找到lib,不对是找到了没有找到里面的某个叫gearman_create的函数,这个就奇怪了,找下:
[root@test /]# find . -name "*gearman*.so*"
./usr/local/lib/libgearman.so.8.0.0
./usr/local/lib/libgearman.so
./usr/local/lib/libgearman.so.8

[root@test /]# vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/lib
/lib64
/usr/lib                                                                                                                                                                                            
/usr/lib64
/usr/local/lib
/usr/local/lib
有这个位置的啊。
[root@test /]# ldconfig  //重新lib的位置载入。

[root@test gearman-0.4.0]# phpize
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
[root@test gearman-0.4.0]# ./configure --with-php-config=/usr/local/php/bin/php-config

问题依旧,去官网看一下呗,http://gearman.org/download/:
文字摘录:PHP
There are two PHP client/worker libraries, one which is a pure PHP extension and one which wraps the libgearman C library.
Gearman Extension
A PHP extension that wraps the libgearman C library.
Gearman PHP Extension (1.0.2) (Source)
官方的PHP扩展高V1.0.2,我这个是gearman-0.4.0太旧了,好像还有更高的gearman-1.1.2.tgz,http://pecl.php.net/package/gearman,放上官网这个上去重新试下了:
tar -zxvf gearman-1.0.2.tgz
cd gearman-1.0.2
[root@test gearman-1.0.2]# phpize
./configure --with-php-config=/usr/local/php/bin/php-config   //这个没有问题
[root@test gearman-1.0.2]# make && make install
/home/xiangdong/software/gearman-1.0.2/php_gearman.c: In function ‘zm_startup_gearman’:
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: ‘GEARMAN_MAGIC_TEXT’ undeclared (first use in this function)
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: (Each undeclared identifier is reported only once
还是差啥么子玩意,换个更新的看下,gearman-1.1.2.tgz 实践OK了,如下:
Libraries have been installed in:
   /home/xiangdong/software/gearman-1.1.2/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

[root@test gearman-1.1.2]# make install
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
真在的:
ls  /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
在php.ini里加上这个扩展就成了。Successful....EOF


[root@test gearman-1.1.2]# php -v
PHP 5.3.10 (cli) (built: Feb  3 2012 14:04:56)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

[root@test gearman-1.1.2]# vi /usr/local/php/etc/php.ini
extension = "gearman.so"  

[root@test gearman-1.1.2]# php -m|grep gearman
gearman



三、代码编写task的分发及client的及简单代码实践OK及其情况实践Ok:
cd /usr/local/gearman/
[root@test gearman]# mkdir codesTest
[root@test gearman]# cd codesTest/
[root@test codesTest]# vi myworker.php


以守护进程方式启动worker:
# nohup php myworker.php >/dev/null 2>&1 &
[root@test codesTest]# nohup php myworker.php >/dev/null 2>&1 &
[1] 31238

一个发送任务处理请求的client:
vi  myclient.php
[root@test codesTest]# vi  myclient.php


运行myclient.php:
[root@test codesTest]# php myclient.php "Jose"
hello, Jose
H:test.local:2

一个发出并行处理任务请求的例子tasksclient:
[root@test codesTest]# vi  tasksclient.php


运行tasksclient:
[root@test codesTest]# php tasksclient.php
Completed task:: id :2 , handled result:hello, John
Completed task:: id :1 , handled result:hello, Jose

查看worker及队列情况:
(echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]#  (echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
34 192.168.109.8 - : sayhello logMsg
35 192.168.109.8 - :
.
查看当前队列情况(显示格式FUNCTION\tTOTAL\tRUNNING\tAVAILABLE_WORKERS):
(echo "status"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "status"; sleep 0.1) | nc 192.168.109.8 4830
sayhello        0       0       1
logMsg  0       0       1
.

监控php的守护进程(没实践), 可以开多个,并同时监控:
关于Worker守护进程的启动和监控
上面例子中直接启动worker脚本作为守护进程,无法监控到worker进程是否存活.
使用Unix进程监控supervisord则可轻松解决这个问题.
将如下配置添加到supervisord的配置中,即可实现由supervisord来启动和监控myworker.
编辑配置文件 vi /etc/supervisord.conf
[program:myworker]
command=/usr/local/php5415/bin/php myworker.php
process_name=%(program_name)s_%(process_num)02d
;修改numprocs即可同时开启多个worker进程
numprocs=1
directory=/usr/local/gearman/codesTest
autostart=true
autorestart=true
user=gearmand
stopsignal=KILL
Posted in Daemon / Worker, Gearman.
Tagged gearman.

监控这块看:
http://jingyan.baidu.com/article/375c8e198d1b1425f2a2290c.html

上面这块的PHP扩展代码及实践来自:
http://www.51itstudy.com/30114.html
http://codego.net/384693/

_________下面是摘录别的文章不一定自己配置时可完全过得过,得按自己环境作配置安装,只是用作参考!_______
Gearman的目的在于用PHP扩展分发,于是PHP扩展如何安装:
tar zxvf gearman-1.1.1.tgz
cd gearman-1.1.1
/opt/local/php/bin/phpize
./configure --with-php-config=/opt/local/php/bin/php-config --with-gearman
make
make install
编辑 php.ini
vi php.ini
增加
extension = "gearman.so"
重启php

启动gearmand 服务
gearmand -L 10.6.0.6 -p 4730  -u root -l /var/log/gearmand.log -d
其他参数请  gearmand --help

摘自:http://jicki.blog.51cto.com/1323993/1177487

通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用WebService的方式来处理此类集成问题,但不管采用何种风格的WebService,如RPC风格,或者REST风格,其本身都有一定的复杂性。相比之下,Gearman也能实现类似的作用,而且更简单易用。

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

Client:请求的发起者,可以是C,PHP,Perl,MySQL UDF等等。
Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Work。
Worker:请求的处理者,可以是C,PHP,Perl等等。

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

甚至我们通过增加更多的Worker,可以很方便的实现应用程序的分布式负载均衡架构。

下面看看如何安装运行一个例子,条件所限,我们把Client,Job,Worker三个角色运行在一台服务器上:

安装libevent:
wget http://www.monkey.org/~provos/libevent-1.4.12-stable.tar.gz
tar zxvf libevent-1.4.12-stable.tar.gz
cd libevent-1.4.12-stable/
./configure --prefix=/usr
make && make install
/sbin/ldconfig
cd ../



安装Gearman server and library:

wget http://launchpad.net/gearmand/trunk/0.9/+download/gearmand-0.9.tar.gz
tar zxvf gearmand-0.9.tar.gz
cd gearmand-0.9
./configure
make
make install
/sbin/ldconfig
cd ../


安装Gearman PHP extension:

wget http://pecl.php.net/get/gearman-0.5.0.tgz
tar zxvf gearman-0.5.0.tgz
cd gearman-0.5.0
/usr/local/webserver/php/bin/phpize
./configure --with-php-config=/usr/local/webserver/php/bin/php-config --with-gearman
make
make install
cd ../

编辑php.ini配置文件加载相应模块并使之生效:

extension = "gearman.so"

启动Job:

gearmand -d

如果当前用户是root的话,则需要这样操作:

gearmand -d -u root

缺省会使用4730端口,下面会用到。

注意:如果找不到gearmand命令的路径,别忘了用whereis gearmand确认。



我们可以用 ps 指令來查看启动是否成功:

ps aux |grep gearman
编写Worker:

worker.php文件内容如下:

<?php
$worker= new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('reverse', 'my_reverse_function');

while ($worker->work());

function my_reverse_function($job)
{
    return strrev($job->workload());
}
?>

设置后台运行work:

#php /var/www/html/worker.php &

编写Client:

client.php文件内容如下:

<?php
$client= new GearmanClient();
$client->addServer('127.0.0.1', 4730);
echo $client->do('reverse', 'Hello World!'), "n";
?>

运行client:

#php /var/www/html/client.php

输出:!dlroW olleH



首先, PHP Gearman Extension 提供了一个名为GearmanClient 的类别,它可以让程序安排工作给 Job Server 。

而 addServer 方法表示要通知的是哪些 Job Server ,也就是说如果有多台 Job Server 的话,就可以透过 addServer 新增。

然后我们将要呼叫哪个 Worker 以及该 Worker 所需要的数据,利用 GearmanClient 的doBackground 方法传送过去。 doBackground 方法顾名思义就是在背景执行, Client 在丢出需求后就可以继续处理其他的程序。

=============

$client->doBackground('sendEmail', serialize($emailData));
echo "Email sending is done.n";

============

doBackground 方法的第一个参数是告诉 Job Server 要执行哪个功能,而这个功能则是由 Worker 提供的;要注意是,这个参数只是识别用的,并不是真正的函式名称。而第二个参数是要传给 Worker 的数据,它必须是个字符串;因此如果要传送的是数组的话,我们就要用 PHP 的 serialize 函式来对这些资料做串行化。

出于方便的考虑,Worker,Client使用的都是PHP,但这并不影响演示,实际应用中,你完全可以通过Gearman集成不同语言实现的Worker,Client。或许此时你还想了解前面提到的负载均衡功能:很简单,只要增加多个Worker即可,你可以按照worker.php的样子多写几个类似的文件,并设置不同的返回值用以识别演示效果。然后依次启动这几个Worker文件,并多次使用client.php去请求,你就会发现Job会把Client请求转发给不同的Worker。

以守护进程启动
gearmand -L 192.168.0.1 -p 4730 -u root -d

命令行工具

如果你觉得安装PHP之类的东西太麻烦的话,你也可以仅仅通过命令行工具来体验Gearman的功能:

启动Worker:gearman -w -f wc -- wc -l &
运行Client:gearman -f wc < /etc/passwd

具体可以参考官方文档。
摘自:http://www.codesky.net/article/201107/174139.html
安装时会出现一个小问题:
configure出现以下错误 checking for gperf... no configure: error: could not find gperf. 解决办法: #yum search gperf #yum install gperf.x86_64.
gperf.x86_64 : A perfect hash function generator.

Gearman 安装使用 以及 问题处理  
http://deapge.blog.163.com/blog/static/1113114792013929380253


gearman.h:53:23: error: cinttypes: No such file or directory
tr1/cinttypes: No such file or directory
错误代码:
make[1]: Entering directory `/usr/local/src/gearmand-0.38'
  CXX    libgearman/libgearman_libgearman_la-actions.lo
In file included from ./libgearman/common.h:44,
                 from libgearman/actions.cc:39:
./libgearman-1.0/gearman.h:53:27: error: tr1/cinttypes: No such file or directory
make[1]: *** [libgearman/libgearman_libgearman_la-actions.lo] Error 1
make[1]: Leaving directory `/usr/local/src/gearmand-0.38'
解决:[root@localdomain gearmand-0.38]# yum install gcc44 gcc44-c++
来自google快照:https://webcache.googleusercontent.com/search?q=cache:GhqVv51gppAJ:www.livingelsewhere.net/2012/08/22/gearman-instal/+&cd=1&hl=zh-CN&ct=clnk&gl=cn
google来自:http://www.livingelsewhere.net/2012/08/22/gearman-instal/

解决./libgearman-1.0/gearman.h:53:23: error: cinttypes: No such file or directory 实践OK如下:
后补来自:http://blog.slogra.com/post-234.html
如果出现configure: error: Unable to find libevent,则输入命令:
yum -y install libevent libevent-devel
然后重新configure.
没有问题后再执行
make
这步出现./libgearman-1.0/gearman.h:53:27: error: tr1/cinttypes: No such file or directory错误,可以推断是gcc编译器的问题,执行命令:
yum install gcc44 gcc44-c++ libstdc++44-devel -y
然后在环境变量里加入:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc
export CXX=/usr/bin/g++44

看来还得重新export一次新的编译器,因为昨天的关了终端,今天的又没了:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc  //这行有问题~
export CXX=/usr/bin/g++44
g++ -o testmemcached testmemcached.cpp -lmemcached
为何还是不行?
echo $CC
/usr/bin/gcc  //没变,这儿有问题,再重新设置一次,查到上面这个or有问题:export CC=/usr/bin/gcc44。
# echo $CXX
/usr/bin/g++44 //变了

重新设置,好了:
export CC=/usr/bin/gcc44
/usr/bin/gcc44

保存退出后执行:
source /etc/profile
删除gearmand-0.34文件夹重新进行编译.
重新进行编译后执行make这步,如图
点击查看原图
没有报错的话才能继续执行
make install
如果没有报错的话,那么恭喜你可以继续安装gearman了.

看下yum后新的gcc在不在,在的:
yum install gcc44 gcc44-c++ libstdc++44-devel -y

Total download size: 4.1 M
Downloading Packages:
libstdc++44-devel-4.4.7-1.el5.i386.rpm      | 4.1 MB     00:00    
Transaction Test Succeeded
Running Transaction
  Installing     : libstdc++44-devel        1/1
Installed:
  libstdc++44-devel.i386 0:4.4.7-1.el5        
Complete!

方法二:
http://www.cnblogs.com/cenalulu/archive/2013/04/03/2998140.html
关键信息:error: tr1/cinttypes: No such file or directory

报错原因:libmemcached需要 gcc 4.2 以上版本才可编译,而centos 5.4 的gcc版本只有4.1 ,详见:https://bugs.launchpad.net/libmemcached/+bug/1076181

解决方法:安装gcc44的扩展包,详见:http://gearman.info/build/centos5-8.html

解决步骤引用如下:

wget http://mirrors.ustc.edu.cn/fedora/epel/5/i386/epel-release-5-4.noarch.rpm
rpm -ivh epel-release-5-4.noarch.rpm
yum -y -q install boost141-devel
ln -s /usr/include/boost141/boost/ /usr/include/boost
export LDFLAGS="-L/usr/lib64/boost141"
export LD_LIBRARY_PATH=/usr/lib64/boost141:$LD_LIBRARY_PATH
yum -y -q install e2fsprogs-devel e2fsprogs
yum -y -q install gcc44 gcc44-c++
export CC="gcc44"
export CXX="g++44"

所有操作完成后,重新执行:

./configure --enable-memaslap && make && make install

安装完成!!

实践如下问题:
[root@test software]# rpm -ivh epel-release-5-4.noarch.rpm
rpm: error while loading shared libraries: libbeecrypt.so.6: cannot open shared object file: No such file or directory


http://pecl.php.net/package/gearman
http://sourceforge.net/projects/boost/?source=pdlp
提示没有安装boost libraries,那么安装之。
下载地址:http://sourceforge.net/projects/boost/?source=pdlp
关于boost的了解,可以到官网:
http://www.boost.org/doc/libs/1_55_0/more/getting_started/index.html
http://www.boost.org/doc/libs/1_55_0/more/getting_started/windows.html

Boost库的安装步骤参照:(漫长的编译过程……)
Linux下安装gearman的方法:
https://jackxiang.com/post/7706/
————————————————————————————————————————
http://www.cnblogs.com/longcpp/archive/2012/06/06/2538251.html
还有http://m.blog.csdn.net/blog/yan420523/9096871(……晕晕呼呼)
http://www.cnblogs.com/cocowool/archive/2011/08/18/2144142.html
接着重新执行上面的./configure
又出现错误了:

http://www.cnblogs.com/youlechang123/archive/2013/10/22/3382425.html
用apt-get install gperf安装了gperf,重新执行./configure,执行一段时间,又出错了:
=====================================================================
重点参考:http://blog.chinaunix.net/uid-27177626-id-4325909.html

参照http://blog.slogra.com/post-234.html解决
用apt-get install libevent libevent-devel安装缺少的依赖,但是又出错了:ubuntu E: Unable to locate package libevent
更新源:apt-get apdate  apt-get upgrade
还是无法安装libevent,只有去官网下载,用源码安装方式安装:http://libevent.org/
下载之后,./configure make make install
重新执行./configure,执行一段时间,又出错:

用apt-get install libuuid无法安装,因此,只有去官网下载:
http://sourceforge.net/projects/libuuid/
用源码安装方式安装。
然后,再次重新执行gearman目录下的./configure。呼呼~~~~~,终于不再出错了,这次顺利执行完毕。

Boost DownLoad:
http://jaist.dl.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.zip

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/7693/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2015-2-16 10:18
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]