laiyuquan

博客

异常监控--发送邮件--消息队列

在工作中,有一个经常发生的场景:线上出现了异常,导致应用程序不能正常的使用!

通常程序员的做法是:通过线上的日志查看(往往是项目的日志,一般程序框架都有日志记录),

找到报错的程序,然后进行针对性修复。

这样的做法弊端很多:

  1. 不是每一个程序员都有线上服务器的权限(即使有:每次需要打开服务器效率也太慢);
  2. 日志文件往往很大,不太容易找到对应的项目程序的报错位置(花费的时间会很长);
  3. 排查问题是滞后的,往往是通过客户的反馈(客户体验性差);

思考:能不能每次程序报错的时候,能及时的通知(短信、邮件、模板消息…)到相关人员呢?

解决:本篇文章通过异常监控,发送邮件提醒,将邮件服务应用到消息队列加快程序性能,解决该问题。


文章先单独理解:异常监控、邮件服务、消息队列,然后用该案例串联三个内容!

异常监控

首先了解一下:laravel采用Monolog日志:

《异常监控--发送邮件--消息队列》

往往线上配置的错误级别:error 或者warning

laravel框架线上异常实时监控:

《异常监控--发送邮件--消息队列》

框架给我们做好相应的封装, PHP实现用户自定义异常、错误抛出方法 : 查看手册

《异常监控--发送邮件--消息队列》

 

邮件提醒服务

laravel已经给我集成了 基于SwiftMail的邮件类库,我们直接调用服务:

首先注册自己的邮箱服务(163、QQ…),然后再.env文件中,填入配置

  • MAIL_DRIVER=smtp
  • MAIL_HOST=yourhost
  • MAIL_PORT=youport
  • MAIL_FROM_ADDRESS=发送邮箱的地址
  • MAIL_FROM_NAME=发送人的姓名
  • MAIL_USERNAME=邮箱的账号
  • MAIL_PASSWORD=邮箱的密码(用服务邮箱的授权码,不是你真正的邮箱密码)

发送邮件的代码:

《异常监控--发送邮件--消息队列》

laravel发送邮件,就ok了,(简单的配置,几行代码,轻松搞定)

 

消息队列

队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求和响应的时间;

往往是应用在批量处理邮件,批量发送短信。

redis的准备工作:

.env 文件配置(我们采用redis 作为消息队列服务)

QUEUE_DRIVER=redis

config/database.php 配置:(备注:laravel使用redis 需要引入preids的包)

'redis' => [
    'client' => 'predis',
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],
],

创建任务队列:

php artisan make:job SendMail

《异常监控--发送邮件--消息队列》

将邮件类的代码 写到handle 方法里面;

 

分发队列:

再具体使用到代码的位置,进行队列分发(简单理解就是:触发队列执行)

dispatch(new SendEmail($user))
    ->delay(now()->addMinutes(1)); #表示延迟分发1分钟

 

运行队列进程:

php artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3

参数说明:

--daemon

一般守护进程需要增加此参数,可以节省 CPU 使用;

--quiet

不输出任何内容

--queue=default

执行默认的队列名称;

--delay=3

一个任务失败后,延迟多长时间后再重试,单位是秒;建议不要太短;

--sleep=3

去进程跑Redis 任务的时候,发现没有任务,休息多长时间,单位是秒;

--tries=3

失败任务最多重试次数

 

安装和配置 Supervisor

Supervisor 是 Linux 系统中常用的进程守护程序。如果队列进程 queue:work 意外关闭,它会自动重启启动队列进程。在应用redis的消息队列也是必备,否则队列非常不稳定;

ubuntu系统安装Supervisor:

sudo apt-get install supervisor

 

配置 Supervisor

Supervisor 配置文件通常存放在 /etc/supervisor/conf.d 目录下,我们创建一个开启并监视 queue:work 进程的 laravel-worker.conf 文件:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/vagrant/Code/zhihuicopy/artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=8
redirect_stderr=true
stdout_logfile=/home/vagrant/Code/zhihuicopy/supervisor.log

command 即我们执行的命令,stdout_logfile:输出的日志文件;

启动 Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

消息队列所有的配置就OK了,执行一下我们刚才配置的代码,看一下redis的运行情况:

zadd  一个 key为:queues:default:delayed

《异常监控--发送邮件--消息队列》

《异常监控--发送邮件--消息队列》

 

进程监控:

《异常监控--发送邮件--消息队列》

 

lpop “queues:default”  到  queues:default:reserved zset 中,

“ZADD” “queues:default:reserved”  “1523019249”  XXX  ,去执行队列任务;

“ZREM” “queues:default:reserved” XXX,执行完毕后,删除任务;

《异常监控--发送邮件--消息队列》

一个完整的在redis脚本 就OK了;

从redis的运行情况理解:队列大致原理 就是 先 push到redis,持续监控,lpop 任务执行,最后从redis删除信息;


最后的案例总结:

基本上前面三个异常监控、发送邮件、redis消息队列 都清楚以后,这个案例就很清晰了;

具体的代码就不贴了,说明一下思路吧:

在异常监控handle 的方法 => 触发 分发消息队列 => 发送邮件 执行队列任务!

over!

 

下面几篇章会介绍: 日志监控神奇–Sentry服务!

点赞

发表评论