Gearman 可以在背景幫忙處理繁瑣的工作,例如壓縮影片、處理縮圖、發送認證信…等,這次不會提到太多 Gearman 介紹,如果想瞭解 Gearman 可以參考小鐵兄寫的 Gearman 心得,此篇會筆記如何在 Ubuntu or Debian 安裝 Gearman 搭配 MySQL 服務,當然如果你不是使用 MySQL,也可以另外搭配 Memcached 或 SQLite 都可以
Ubuntu or Debian 安裝 其實安裝方式很簡單,只需要透過 apt-get 指令就可以安裝完成
$ aptitude -y install gearman gearman-job-server libgearman-dev libdrizzle0安裝完成後,在命令列打入
gearmand -V 檢查版本,會發現預設的版本非常的舊,但是沒關係,Ubuntu 可以透過 Package Repository 來安裝到最新版
$ add-apt-repository ppa:gearman-developers/ppa $ aptitude -y update但是在 Debian 7.0 版似乎起不了任何作用,裝起來版本真的很低,爽度不夠,所以最終解法還是要透過 tar 方式安裝,安裝過程一定會遇到一些沒安裝的 develop library,只要把相對應的套件安裝即可
$ aptitude -y install libboost-program-options-dev gperf libcloog-ppl0 libpq-dev libmemcached-dev libevent-dev $ wget https://launchpad.net/libdrizzle/5.1/5.1.4/+download/libdrizzle-5.1.4.tar.gz -O /tmp/libdrizzle-5.1.4.tar.gz $ wget https://launchpad.net/gearmand/1.2/1.1.8/+download/gearmand-1.1.8.tar.gz -O /tmp/gearmand-1.1.8.tar.gz $ cd /tmp && tar xvfz libdrizzle-5.1.4.tar.gz && cd libdrizzle-5.1.4 && ./configure --prefix=/usr && make && make install $ cd /tmp && tar xvfz gearmand-1.1.8.tar.gz && cd gearmand-1.1.8 && ./configure --prefix=/usr && make && make install安裝完成後,直接打
gearmand -h
builtin: libmemcached: --libmemcached-servers arg List of Memcached servers to use. Postgres: --libpq-conninfo arg PostgreSQL connection information string. --libpq-table arg (=queue) Table to use. MySQL: --mysql-host arg (=localhost) MySQL host. --mysql-port arg (=3306) Port of server. (by default 3306) --mysql-user arg MySQL user. --mysql-password arg MySQL user password. --mysql-db arg MySQL database. --mysql-table arg (=gearman_queue) MySQL table name.如果搭配 Mariadb 的話,請安裝
libmariadbclient-dev 才可以將 MySQL 功能編譯進去。從上面結果發現 Gearman 目前支援 libmemcached, Postgres, MySQL 串接方式,底下來一一介紹
搭配 memcached Gearman 0.7 版本以上才支援,設定方式很簡單,開啟 /etc/default/gearman-job-server 找到底下字串
PARAMS="--listen=127.0.0.1"改成
PARAMS="-q libmemcached --libmemcached-servers=localhost"當然要先檢查系統有無啟動 memcached port 11211。重新啟動 gearmand
$ /etc/init.d/gearman-job-server restart
搭配 MySQL 設定前,請先將 Database 建立完成
$ mysql -u root -p -e 'CREATE DATABASE gearman;'最後設定 /etc/default/gearman-job-server
PARAMS="-q mysql --mysql-host=localhost --mysql-user=xxxx --mysql-password=xxxxx--mysql-db=gearman --mysql-table=gearman_queue"重新啟動後,Gearman 會在資料庫建立 gearman_queue 資料表
CREATE TABLE IF NOT EXISTS `gearman_queue` ( `unique_key` varchar(64) DEFAULT NULL, `function_name` varchar(255) DEFAULT NULL, `priority` int(11) DEFAULT NULL, `data` longblob, `when_to_run` int(11) DEFAULT NULL, UNIQUE KEY `unique_key` (`unique_key`,`function_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;嗯嗯,非常好,但是你會發現一個問題,都已經在搞 InnoDB 竟然沒有 primary key,所以這就請系統管理者幫忙建立上去。
測試資料 首先 Gearman 支援任何程式語言 (Shell, Perl, Node.js, PHP, Python, Java ..等),先來介紹使用 PHP command line,請安裝 PHP Gearman API Extension
$ pecl install channel://pecl.php.net/gearman-1.1.0建立
/etc/php5/cli/conf.d/gearman.ini,內容為
[gearman] extension=gearman.so重新啟動 php5 fpm
$ /etc/init.d/php5-fpm restart用指令檢查
$ php -i | grep gearman /etc/php5/cli/conf.d/gearman.ini, gearman gearman support => enabled libgearman version => 1.1.8撰寫 worker.php (copy from
addServer(); // 預設為 localhost $worker->addFunction('sendEmail', 'doSendEmail'); $worker->addFunction('resizeImage', 'doResizeImage'); while($worker->work()) { sleep(1); // 無限迴圈,並讓 CPU 休息一下 } function doSendEmail($job) { $data = unserialize($job->workload()); print_r($data); sleep(3); // 模擬處理時間 echo "Email sending is done really.\n\n"; } function doResizeImage($job) { $data = unserialize($job->workload()); print_r($data); sleep(3); // 模擬處理時間 echo "Image resizing is really done.\n\n"; }Client.php
addServer(); // 預設為 localhost $emailData = array( 'name' => 'web', 'email' => 'member@example.com', ); $imageData = array( 'image' => '/var/www/pub/image/test.png', ); $client->doBackground('sendEmail', serialize($emailData)); echo "Email sending is done.\n"; $client->doBackground('resizeImage', serialize($imageData)); echo "Image resizing is done.\n";到這裡直接先執行 Client 程式,如果安裝的 Gearman 吐出底下訊息:
PHP Warning: GearmanClient::doBackground(): _client_run_tasks(GEARMAN_SERVER_ERROR) QUEUE_ERROR:QUEUE_ERROR -> libgearman/client.cc:1581 in /root/client.php on line 11 表示 Server 沒有產生 unique key,所以造成第二次新增 job 的時候產生衝突,解決方式很解單,在 doBackground,第三個參數加上 unique key
$client->doBackground('sendEmail', serialize($emailData), md5(uniqid(rand(), true)));這樣就可以完整測試了。
See also
- [SQL] 如何從單一資料表取得每個 key 前 n 筆資料
- Debian/Ubuntu 的 update-rc.d 使用教學
- 在 Docker 偵測 MySQL 或 Postgres 是否啟動
- OpenSSH 安全性漏洞 CVE-2016-0777 and CVE-2016-0778
- 在 Debian 7.8 安裝 Gitlab 筆記
- Docker 救了 Debian SSH terminal
- Laravel 50 個小技巧 + Laravel 5.2 新功能
- 優化 Percona XtraDB Cluster for write hotspots
- Debian 7.x Install PHP 5.5 或 5.6 版本
- 解決在 Ubuntu 系統下 Chrome 瀏覽器亂碼