2018年7月

起因

周五在公司加班的时候,调试了一个用户验证短信的一个 Bug,为了尽量做到接口的调用限制,对发送过的手机号设置了一定时长的「黑名单」机制,原理是将发送过的手机号存入缓存中,发送短信的时候获取缓存是否存在,如果存在就说明超频发送了。说实话很简单的一个功能,我却破天荒的调试了半天没搞明白。

后来,老大就坐在旁边,我俩一起调,从生成验证码到发送日志,全给丢到 debug 日志,挂着 tail 命令监听。

然鹅!模拟用户注册居然没有打印验证码日志,只有发送日志!

没记录日志,还始终报验证码错误,真是莫名其妙。

调试

首先,我将视线转移到缓存时间上,发现缓存时间只有 1 分钟,也就是说如果用户填写资料比较慢的话,验证码很可能就过期了!调试嘛,改到 10 分钟先。提交后更新生产环境代码。还是报错!

emmm…难道缓存系统出问题了?还是说 Redis 写不进去了?发送完验证码后,使用 Laravelartisan tinker 打印缓存,居然不是验证码,是手机号!诶,我这儿不是改了吗?(没错,刚开始的时候我勿将手机号存到 values 去了)。代码里加日志,想打印下看下什么情况。可是新加的打印日志死活打印不出来。

不行了,我要冷静下,慢慢的开始分析修改前和修改后的逻辑。

修改前:用户传入手机号->系统生成验证码(这里验证码是手机号)->将发送任务丢到队列->用户收到短信后填写->后端校验。

修改后:用户传入手机号->系统生成验证码(这里新加了日志输出)->将发送任务丢到队列->用户收到短信后填写->后端校验。

而现在的问题是:系统生成的验证码还是手机号,尽管我已经修改了;调试日志不打印!

也就是说。。队列没更新!

解决

分析出队列没更新,我立马就去查了 supervisor 的文档。之前更新队列都只使用了 rereadupdate 命令,只是更新了配置文件,但是队列并没有重新启!而 Laravel 的文档 队列 中提到:

注意一旦 queue:work 命令开始执行,它会一直运行直到它被手动停止或终端被关闭。

supervisor 是不会被关闭的,何况我给了 4 个子进程。而文档中又提到:

记住,队列处理器是一个常驻的进程并且在内存中保存着已经启动的应用状态。因此,它们并不会在启动后注意到你代码的更改。所以,在你的重新部署过程中,请记得 重启你的队列处理器.

也就是说,队列还是保持第一次执行的状态。难怪缓存值修改了没用,日志打印不出来也是这个原因。

重启 supervisor 队列命令:

supervisorctl restart laravel-queue

问题得到解决,真是被自己写的 Bug 蠢哭了。

最近公司分配了一个项目给我,时间相对充裕,所以也就直接用 Laravel 5.6 练手了。参照慕课网实战课程「Laravel 快速开发简书」和 Laravel China 社区出的 「Web 开发实战入门 (Laravel 5.5)」以及 Laravel China 社区翻译的「Laravel 5.6 中文文档」直接开怼。

上线前服务器资源成了一个问题,因为这个项目并没提到正式流程中,所有曲线救国,直接上线在官网的服务器。

配置

  • 阿里云 2 核 4 GB * 3(两台生产使用SLB,一台测试)
  • CentOS 7.4 x86_64
  • Nginx 1.12 + PHP 7.0.9

此次升级共三台服务器,两台生产环境和一台测试环境。

查看 Laravel 5.6 服务器要求 PHP 版本为 PHP >= 7.1.3,因为开发环境装的 7.1.5,所以就直接上 7.1.5 了。

评估影响范围

首先,生产环境还运行着一个官网,不过流量可以忽略不计,所以短暂的宕机是可以接受的,不然我要等到晚上才能升级。

连上服务器,根据需求判断是否需要备份之前的数据。是否安装了其他拓展(Redis、Mencache、Swoole、Yaf 等)有的话需要将 php.ini 文件备份下来。

由于官网 PHP 一直没用过,也没装过什么拓展,所以也就直接覆盖升级了。

升级

注意:是覆盖升级!并非多版本切换。

首先需要找到 PHP 老版本的安装目录。一般路径为 /usr/local/php,现在需要获取当初安装时的配置情况。

使用命令:

$ php -i | grep configure | sed -e "s/Configure Command => //; s/'//g"
 ./configure  --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-gd --with-iconv --with-zlib --enable-xml --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curlwrappers --enable-mbregex --enable-fpm --enable-mbstring --enable-ftp --enable-gd-native-ttf --with-openssl --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --with-pear --with-gettext --enable-session --with-mcrypt --with-curl --with-jpeg-dir=/usr --with-freetype-dir=/usr

若提示 command not found: php 则需要进入到 /usr/local/php/bin/ 使用 ./php 来执行命令。

将以上配置给复制下来,保存好。

然后下载对应升级的 PHP 版本,这里我选择 7.1.5 如果需要其他版本的只需要在下面命令修改对应版本即可。

$ cd ~
$ wget -c http://cn2.php.net/get/php-7.1.5.tar.gz/from/this/mirror -O php-7.1.5.tar.gz
$ tar zxvf php-7.1.5.tar.gz
$ cd php-7.1.5

解压完成,现在开始配置 PHP,这时需要复制上刚刚保存的 ./configure 命令。

$ ./configure  --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-gd --with-iconv --with-zlib --enable-xml --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curlwrappers --enable-mbregex --enable-fpm --enable-mbstring --enable-ftp --enable-gd-native-ttf --with-openssl --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --with-pear --with-gettext --enable-session --with-mcrypt --with-curl --with-jpeg-dir=/usr --with-freetype-dir=/usr
$ make && make install

如果命令有提示 Permission denied 请使用 sudo 来运行命令。

优化

至此,升级已经完成了。但是仍然有优化的地方。

增加或替换 /usr/bin/ 目录下相关 PHP 的命令脚本。

$ cd /usr/local/php
$ cp -f php phpize php-config php /usr/bin/
$ php -v
PHP 7.1.5 (cli) (built: Jun  5 2017 18:00:45) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

重启 PHP-FPM

现在需要将 php-fpm 重启使其生效。命令:

$ killall php-fpm
$ sudo /usr/local/php/sbin/php-fpm