tp5结合 beanstalkd,supervisor 的使用

最近在用消息队列,并结合网上一些文章,集成出一个精华版:

 

1.安装beanstalk

 

在linux 

yum install -y beanstalkd

运行

nohup beanstalkd &

安装完后启动,若不启动运行phenstalk会报错

 

 

 

2.安装php消息队列包 phenstalk

 

在tp5项目中运行

composer require pda/pheanstalk

 

安装后,记得放行端口 11300

踩坑注意 : 如果使用过了一个 tube名 (这里是order) ,则下个消息队列要使用新的 tube 名字,因为开启了守护进程,建议不要重新用一个管道名写逻辑

class Index
{
    public function index()   //前台下单,类似生产者
    {
        $data = [
            'name' => '消息队列1',
            'good_id' => mt_rand(1000,9999),
        ];
        $pda  = Pheanstalk::create('127.0.0.1');
        //投入到管道中  等待消费者消费  参数分别是  1 数据  2优先级  3设置延迟秒数处理
        $id   = $pda->useTube('order')->put(json_encode($data),0,3);
        dump('生成管道'.$id->getId());
    }

    public function cost()     //创建消费者消费任务数据
    {
        $pda  = Pheanstalk::create('127.0.0.1');
//        获取管道并消费
        $job  = $pda->watch('order')->ignore('default')->reserve();//        获取任务数据
        $data = $job->getData();
        dump($data);
//        处理完任务后就删除掉
        $pda->delete($job);
    }
}

  建议 用网页开两个页面测试,先运行index() 再运行cost()  

 

3.安装supervisor

 

linux中运行

# yum install epel-release
# yum install supervisor

//设置成开机自动启动
# systemctl enable supervisord

 

自定义配置

 

1.在这里我创建了一个命名为supervisor的目录用于存放supervisor和队列的日志文件以及include的配置文件,其目录结构

 

 

 

创建supervisord的日志文件

 

 

 

 

然后找到/etc/supervisord.conf配置文件,修改一些路径

; 将supervisor.sock 的路径换成如下

[unix_http_server]

file=/var/supervisor/run/supervisor.sock   ; (the path to the socket file)

; 将supervisord.log 和 supervisord.pid 的路径换成如下

[supervisord]

logfile=/var/supervisor/log/supervisord.log  ; (main log file;default $CWD/supervisord.log)

pidfile=/var/supervisor/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)

; 将supervisor.sock 的路径换成如下

[supervisorctl]

serverurl=unix:///var/supervisor/run/supervisor.sock ; use a unix:// URL  for a unix socket

; 将最底部的files路径换成如下

[include]

files = /var/supervisor/conf/*.conf

 

 

4.使用supervisor 配置守护进程

 

/var/supervisor/conf目录里创建一个 selectMsg.conf ,内容如下:

[program:selectMsg] ;项目名称 自定义

directory = /www/wwwroot/tp5.1Project ; 项目路径

command = /usr/bin/php think xxxxx ; 这里是tp5 command的 启动命令  (php think 文件名 )

process_name=%(program_name)s_%(process_num)02d

numprocs = 1         ; 开启的进程数量

autostart = true     ; 在 supervisord 启动的时候也自动启动

startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了

autorestart = true   ; 程序异常退出后自动重启

startretries = 3     ; 启动失败自动重试次数,默认是 3

user = root          ; 用哪个用户启动

redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false

stdout_logfile_maxbytes = 50MB  ; stdout 日志文件大小,默认 50MB

stdout_logfile_backups = 20     ; stdout 日志文件备份数

; stdout 日志文件,需要手动创建目录(supervisord 会自动创建日志文件)

stdout_logfile = /var/supervisor/log/select_msg.log ;日志记录的位置

loglevel=info

 

 

 

在log创建上面配置的日志路径:名字由上面的  stdout_logfile 定义

 

同上操作,创建一个守护,守护 beanstalkd

 

创建  beanstalkd.conf

; 使用Pheanstalk队列 需要先运行beanstalkd,所以要把beanstalkd守护

[program:beanstalkds] ;项目名称
directory = /usr/bin ; 程序的启动目录,项目根目录的上一级
command = beanstalkd  ; 启动命令
process_name=%(program_name)s_%(process_num)02d
numprocs = 1         ; 开启的进程数量 该进程只能开一个因为beanstalkd默认端口11300
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数,默认是 3
user = root          ; 用哪个用户启动
redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 50MB  ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20     ; stdout 日志文件备份数
; stdout 日志文件,需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /var/supervisor/log/beanstalkd.log
loglevel=info


;对于单模块而言,不同的业务逻辑为了区分可能会存在多个队列名,这种情况将多个队列名用逗号拼接起来,如下
;command = php think queue:work --queue queueName1,queueName2 --daemon 

 

对应的日志文件

 

 

  重启配置

supervisorctl reload

或

systemctl restart supervisord

查看状态,RUNNING 或 starting 则成功,若是其他状态,则去 /var/supervisor/log/supervisor.log 查看报错
supervisorctl status

 

 注意,每次修改守护的php 类的代码,都要重启supervisor

 

5. 使用tp5 的command 

 

 

 tp5中执行,也可以手动创建,注意 文件夹 application/command  和 方法 configure() execute 必须有

php think make:command Test

 

三处名字必须一样,  此处文件名就是上面 supervisor 配置的  /usr/bin/php think test 

 

守护进程守护之后,只要写生产者 就可以随时被监听 消费了!

最后,记得设置数据库断开重连. database.php 中修改

'break_reconnect' => true,

 

 

使用实例: 监听频繁的数据库操作,生产者 放入到管道 消费者排队消费,防止高并发的db操作 带来数据库压力

 

消费者:

//设置php脚本执行时间
set_time_limit(0);
//设置socket连接超时时间
ini_set('default_socket_timeout', -1);

class addWorkAttend extends Command
{
    protected function configure()
    {
        $this->setName('addWorkAttend');
    }

    protected function execute(Input $input, Output $output)
    {
        $pda  = Pheanstalk::create('127.0.0.1');
//        获取管道并消费
        while (1){
            try {
            $job = $pda->watch('records')->ignore('default')->reserveWithTimeout(60);
                    // 接受成功则 做数据库操作
                    if ($job != false && $job->getData()) {
                        $data = json_decode($job->getData(), true);
                        if ($this->records($data))
                            $pda->delete($job);     // 插入Db操作
                        else
                            $pda->release($job);  // 处理失败
                    }else
                        continue;               // 跳出一次循环
            } catch (\Exception $e) {
                logs('消息队列错误,'.$e->getMessage(),'error');
                die;
            }
        }
    }
View Code

 

生产者:

public function setArrive($d)     // 设置已到校
    {
        // $d 是要插入的数据
        $pda  = Pheanstalk::create('127.0.0.1');
        //投入到管道中  等待消费者消费  参数分别是  1 数据  2优先级  3设置延迟秒数处理
        $pda->useTube('records')->put(json_encode($d),0,3);
        
    }

 

前端操作后执行生产接口就可以了

beanstalk常用方法:https://www.kancloud.cn/vson/php-message-queue/895571

 

posted @ 2021-09-15 21:24  jaychou、  阅读(428)  评论(0)    收藏  举报