Drupal 整合 Gearman实战

By Richard Yu (理查)

@Chegg China

Senior Developer

声明

  • 是分享,不是授课
  • 所说的不一定全对,个人见解
  • Gearman不一定最好,方案众多
  • Gearman很深,不要轻易下结论
  • Gearman也很简单,不妨试试

Gearman

Gearman provides a generic application framework to farm out work to other machines or processes that are better suited to do the work. It allows you to do work in parallel, to load balance processing, and to call functions between languages.

Gearman 工作原理

Gearman 工作原理

  • Client: 客户端,发出任务处理请求
  • Job Server: Job服务器,接收来自客户端的任务处理请求,然后以负载均衡的方式分发给注册的worker.
  • Worker: 工人,处理Job服务器分发过来的任务处理请求

Gearman 工作原理

<?php
// Reverse Client Code
$client = new GearmanClient();
$client->addServer();
print $client->doBackground("reverse", "Hello World!");

Client

Worker

<?php
// Reverse Worker Code
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", function ($job) {
  return strrev($job->workload());
});
while ($worker->work());

并发任务

$client->addTask('lookup_user', 'joe@joe.com', 'lookup_user');
$client->addTask('baconate', 'joe@joe.com', 'baconate');
$client->addTask('get_latest_posts_by', 'joe@joe.com', 'get_latest_posts_by');

$client->runTasks();

Gearman 特点

  • 开源
  • 多语言驱动
  • 灵活,没有任何模式限制
  • 快,基于C/C++
  • 可以很容易嵌入现有系统
  • 无单点故障
  • 不限制消息大小
  • 适合大型网站架构

Gearman 使用场景

  • 格式转化,视频转码
  • 缩略图生成
  • 缓存更新,静态化
  • 发邮件
  • 分布式日志查询
  • 搜索引擎
  • Map/Reduce

使用 Gearman 的注意事项

  • 多Worker进程实现负载均衡
  • Job持久化
  • Worker进程守护
  • 逻辑更改,需要重启Worker

Worker守护进程

  • nohup + &
  • screen
  • Gearman monitor
  • Shell daemon
  • PHP daemon
  • Supervisord

Gearman最简安装

yum install epel-release
yum install gearman

pecl install gearman

配置

vim /etc/sysconfig/gearmand

OPTIONS=" \
-q mysql \
--mysql-host=localhost \
--mysql-user=root \
--mysql-password=root \
--mysql-db=gearman \
--mysql-table=gearman_queue \
--mysql-port=3306 \

"
gearmand -d
/etc/init.d/gearman start

监控

gearadmin --workers
gearadmin --status
gearadmin --show-jobs

(echo status; sleep 0.1) | nc 127.0.0.1 4730

启动

测试

$ gearman -w -f wc -- wc -l

$ gearman -f wc < /etc/passwd
26

$ wc -l < /etc/passwd

Supervisord

Supervisord是用Python实现的一款非常实用的进程管理工具。supervisord会帮你把管理的应用程序转成daemon程序,而且可以方便的通过命令开启、关闭、重启等操作,而且它管理的进程一旦崩溃会自动重启,这样就可以保证程序执行中断后的情况下有自我修复的功能。

Supervisord 简介

安装

## Mac
$ sudo easy_install pip
$ sudo pip install supervisor

## CentOS
$ sudo yum install supervisor
$ echo_supervisord_conf > /etc/supervisord.conf

logfile=/tmp/supervisord.log

[inet_http_server] 
port=127.0.0.1:9001 
username=user 
password=123

[program:zinch_gearman_background_process]
command = /Applications/MAMP/bin/php/php5.3.28/bin/drush -r /Users/zhicheng/Sites/zinch/html gearman-worker background_process
process_name=%(program_name)s_%(process_num)02d
autostart = true
autorestart = true
numprocs = 3
stdout_logfile=/tmp/background_process.log
user = zhicheng
redirect_stderr = true

配置

tail -f /tmp/supervisord.log
2015-05-25 13:49:34,389 INFO RPC interface 'supervisor' initialized
2015-05-25 13:49:34,390 INFO RPC interface 'supervisor' initialized
2015-05-25 13:49:34,390 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2015-05-25 13:49:34,391 INFO supervisord started with pid 89964
2015-05-25 13:49:34,631 INFO spawned: 'zinch_gearman_user_register_02' with pid 1531
2015-05-25 13:49:34,634 INFO spawned: 'zinch_gearman_user_register_01' with pid 1532
2015-05-25 13:49:34,638 INFO spawned: 'zinch_gearman_user_register_00' with pid 1533
2015-05-25 13:49:35,639 INFO success: zinch_gearman_user_register_02 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-05-25 13:49:35,640 INFO success: zinch_gearman_user_register_01 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-05-25 13:49:35,640 INFO success: zinch_gearman_user_register_00 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

Supervisord日志

启动

supervisord -c /etc/supervisord.conf
$ supervisorctl -h

Documented commands (type help <topic>):
========================================
EOF    exit  maintail  quit    restart   start   stop
clear  help  open      reload  shutdown  status  tail

控制

Worker 日志

tail -f /tmp/background_process.log
Gearman version: 1.1.12
function background_process added!
Gearman version: 1.1.12
function background_process added!
Gearman version: 1.1.12
function background_process added!

Supervisord Web 控制台

Gearman的可靠性思考

持久化能解决可靠性问题么???

解决方案

  • 自己维护 job 列表和 job 的状态
  • 即使失败了还可以重新启动
  • 与Worker的持久化并存,互不干涉
CREATE TABLE `background_process_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `callback` varchar(255) DEFAULT NULL,
  `params` longblob,
  `cid` varchar(255) DEFAULT NULL,
  `uid` int(10) unsigned DEFAULT NULL,
  `timestamp` int(10) unsigned DEFAULT NULL,
  `processed` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

数据结构

<?php
function drupal_background_process($callback_params) {
  
  // Record to background_process_log
  // If enabled, Using GearmanClient add job to job server
  // If not enabled, Using original way to process the job

  return true;
}

Add job to job server

<?php

$background_params = array(
    'callback' => 'registration_new_user_profile_makeup',
    'params'   => array($user, $values, request_uri())
      );

drupal_background_process($background_params);
drush gearman-worker background_process

Drush 启动 Worker

Worker 定义

function drush_process_zinch_gearman_worker($workerKey = NULL) {
  $workers = _gearman_workers_info();

  $worker= new GearmanWorker();

  try {

    $worker->addServer(GEARMAN_SERVER_HOST, GEARMAN_SERVER_PORT);
  } catch (Exception $e) {
    drush_die($e->getMessage());
  }

  if (isset($workers[$workerKey])) {
    $worker->addFunction($workerKey, $workers[$workerKey]);
    drush_print(strtr('function !function added!', array('!function' => $workerKey)));
    while ($worker->work());
  }
}
drush gearman-client background_process 1

客户端测试

Gearman 高级话题

  • 集群架构设计
  • Worker工作流设计
  • Worker的划分方法
  • 数据交换格式
  • 持久化方案选型
  • REST方式添加job
  • 并行任务处理
  • 任务优先级的用途和用法
  • Gearman & 云

Thank you!~

Questions?

参考资料

http://blog.csdn.net/jiao_fuyou/article/details/16330195

Drupal集成Gearman实战分享

By Richard Yu

Drupal集成Gearman实战分享

How Drupal integrates Gearman!~

  • 2,902