工作散记 一
这个系列的工作散记,主要用于记录工作中遇到的散碎技术问题。
用于备忘,也用于整理思路,以便后续回来看的时候,能记起当时解决问题的思路。
1、服务器返回500错误,以及Ajax跨域问题
问题截图:
(1)、
遇到 5xx 系列的错误,是服务器的问题,或是服务配置错误,或是一些相关的错误。
第一步,要先看各种错误日志,最首先的是nginx的错误日志。
果然,在nginx错误日志中找到了原因:
2017/02/14 11:07:05 [error] 18783#0: *8275 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught exception 'yii\base\ErrorException' with message 'session_write_close(): open(/var/lib/php/session/sess_316h15gg4kqjkjj3bdfj4ktfq3, O_RDWR) failed: Permission denied (13)' in /home/wwwroot/mobile/vendor/yiisoft/yii2/web/Session.php:186
解决方法:
查知php-fpm是用nobody用户运行的,将 /var/lib/php/session/ 的属主属组改为nobody
# chown nobody.nobody /var/lib/php/session/ # chmod 775 /var/lib/php/session/
(2)、
这问题之前没遇到过,只能谷歌了。
No 'Access-Control-Allow-Origin' header is present on the requested resource.
将这问题直接谷歌,立马就有答案了。
这是Ajax跨域的问题。因为浏览器跨域策略起作用,阻止了跨域的请求。
详细的原因:http://www.jb51.net/article/85447.htm
解决方法:http://www.cnblogs.com/xiezn/p/5651093.html
原因和解决方法,网上都写得很清楚了,这里就不多说了。
2、搭建https的api,并通过api上传图片,上传返回成功,访问图片却报404错误。
问题描述:
原api(三级域名)是http协议的,后来买了通配型的SSL证书,因证书不支持三级域名,只能重新搭建二级域名的https的api,并做对应的地址映射(凡是通过 http://rpc.api.xxx.com 访问的,现在都可以通过 https://appapi.xxx.com/api/webroot 访问)。
开发反馈,通过https协议的api上传图片,提示上传成功了,但访问该图片却报404错误。
而通过原http协议的api域名上传图片,图片上传成功,图片也正常显示。
问题分析:
没有报错,说明已经上传成功。但访问显示404,说明上传的路径可能错了。
跟开发沟通,知道了图片上传的过程:
(1)上传到/tmp目录上,以phpxxxx命名
(2)获取api域名的DocumentRoot(根目录)
(3)将临时文件移到DocumentRoot下的uploads目录下,并改名为xxxxxxx.jpg
解决思路:
叫开发帮忙,分别通过 http://rpc.api.xxx.com 和 https://appapi.xxx.com/api/webroot 来上传图片,并把对应的上传信息(DocumentRoot,文件名,路径,临时文件名等)打印出来,做相互比较。
比较得知:
http协议的api域名 的 DocumentRoot为:/home/www/chw_v3/web/api/webroot/
https协议的api域名 的 DocumentRoot为:/home/www/chw_v3/web/
问题找到了!
问题解决:
http://rpc.api.xxx.com的配置文件中:
location ~ \.php/?.*$ { root /home/www/chw_v3/web/api/webroot; ... }
https://appapi.xxx.com/api/webroot 的配置文件中:
#原网站:rpc.api.xxx.com location ~ /api/webroot/(.*)\.php$ { root /home/www/chw_v3/web/; ... }
由于nginx配置上的问题,导致了抓取的根目录不同,进而上传的路径也不同,所以导致访问404。
又因为某些原因,不能修改nginx里的这些配置,只能叫开发在上传程序中手动补上缺的路径,这方法不是很妥当,还得继续想更为灵活妥当的解决方法。
3、QQ上发送链接,链接缩略图显示403,点击链接能正常在浏览器上打开
问题描述:
接到同事反馈,公司主站的某些网页链接,在最新版QQ上缩略图显示403。
解决思路:
(1)第一反应是安全联盟的问题,因公司主站购买了安全联盟的产品。
去问他们客服,原来我们购买的安全联盟版本是只支持主域名的名片展示,不支持主域名的长链接的名片展示。
那么,排除安全联盟。
(2)因主站挂了网宿cdn,怀疑是cdn的问题导致QQ抓取主站网页出现异常。
问网宿技术客服,得知他们并没有做任何额外的操作。在本地hosts绑定主域名和源ip,绕过cdn,发现问题还存在。
(3)只能尽量从服务器上找原因了。
新建一个网页,发到QQ上,一样显示403错误,排除QQ抓取缓存和cdn的问题。
查找nginx日志,该链接的记录都是200,没有403错误。
头疼啊,不是安全联盟的问题,又不是cdn的问题,nginx日志里边也没有相关的记录,到底是什么原因呢?
。。。
忽然想起,把链接发到QQ上,QQ去抓取链接网页的信息,不属于正常的UA访问。而我之前把UA为空的访问给禁掉了。会不会是这个问题?
将UA为空的限制打开,新建一个网页(加上参数,跳过缓存),发到QQ上,显示正常。
划重点:
要谨慎禁止UA为空的情况。
逐一排除各方因素,即便最后觉得不可能的原因,也很可能就是它引起的。
4、网站频繁报504错误
问题描述:
事发前一天,经运营同事反馈,有一段时间(大概一个小时)频繁报504错误。
我着手排查,无意发现数据库所在的磁盘已经100%了(缺乏报警机制),binlog 一直没有清理。
清理binlog:
my.cnf 上有 expire_logs_days = 14 ,估计是没重启服务所以一直没生效。
查过得知 expire_logs_days 能在线修改,能立即生效,修改:mysql > set global expire_logs_days = 14;
手动清理14天前的binlog ,mysql > PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTERVAL 14 DAY);
清理binlog 后,故障恢复正常,我当时以为就是这个问题,就没有继续查下去了。
过了一天,504错误频繁出现,甚至导致网站打不开,影响甚大。
问题排查:
(1)负载过高(平常都是5以下,现在是20)
top命令查负载和占CPU最多的进程,发现mysqld进程占CPU资源过高。
(2)mysql > show full processlist; 查MySQL并发线程数,不到50,不是MySQL连接数被挤满了。
mysql 慢查询日志,记录的也不多,不是慢查询过多的问题。
(3)由于这服务器上只有 mysql 和 php-fpm 两个服务,所以剩下的排查对象是php-fpm
查php-fpm的慢查询日志,发现以下记录频繁出现:
flock() 函数用于锁定或释放文件。说明php-fpm在频繁锁定文件避免被其他进程占用,很有可能是文件句柄数设置过小了,不够用,导致文件频繁被锁。
ulimit -n ,查得系统设置为 1024,太小了,得设置大点。
立刻生效: # ulimit -n 102400 永久生效: #vim /etc/security/limits.conf #加入以下两行代码 * soft nofile 102400 * hard nofile 102400
调整ulimit 大小后,负载逐渐降下来了,网站恢复正常。
划重点:
(1)必须做好监控,如果有监控告警,服务器磁盘用满的问题,就能第一时间知道并处理了。
(2)各种日志,永远是解决问题的好帮手,要熟悉日志记录。
5、windows 上启动 http 服务,总提示端口被占用
问题描述:
同事安装XAMPP,在自己的办公电脑上部署LAMP服务,启动apache的时候,老提示80端口已经被占用。
他通过netstat 查找,发现确实有占用80端口的进程,只能看到pid不能看到进程名。
netstat -ano|findstr "80"
想通过任务管理器查看进程名,发现根本没有这个pid。(任务管理器不会显示所有pid的,别太相信任务管理器就能看到全部)
重启电脑也不行,依然被占用80端口。
解决思路:
(1)通过pid,查进程名(关键点: 要找到进程名)
tasklist | findstr “<PID号>”
或者找安全管家,一般都会有网络工具,能看到pid对应的具体进程名。
(2)kill 掉该进程
taskkill /PID PID号 -F # -F 表示强制kill掉
可能需要管理员权限:右键CMD程序,以管理员身份运行
(3)重启仍然不行,说明那个进程被设为了自启动。
如果是进程,去启动项里删除自启动。
如果是服务,去服务管理那里修改启动方式(不要自动启动)
解决:
最后查出来的原因是,他之前安装了apm serv ,有个服务被设为了自启动。
6、LNMP架构下网站排查问题的思路
(1)、先检查静态文件是否能正常访问。可创建一个测试的test.html,看是否能正常访问。
(2)、再检查php-fpm是否配置正确。创建一个测试php文件。
<?php echo 'this is a test' ?>
(3)、接着检查mysql连接是否正确。
有好几次都是因为数据库连接不正确,导致网页出现空白、一直加载、页面出错等现象。
运维分配账号时,要先自行验证是否能正常连接,再交给开发。
需要注意的是:即便给了正确的账号,开发有时候也会填错,这一环需要在排查问题的时候,确认清楚。遇到好几次都是因为开发填错数据库账号,而网页上报错信息又不显示,导致排查一直以为数据库已经正常连接了。。。