工作散记 一

这个系列的工作散记,主要用于记录工作中遇到的散碎技术问题。

用于备忘,也用于整理思路,以便后续回来看的时候,能记起当时解决问题的思路。

 

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连接是否正确。

有好几次都是因为数据库连接不正确,导致网页出现空白、一直加载、页面出错等现象。

运维分配账号时,要先自行验证是否能正常连接,再交给开发。

需要注意的是:即便给了正确的账号,开发有时候也会填错,这一环需要在排查问题的时候,确认清楚。遇到好几次都是因为开发填错数据库账号,而网页上报错信息又不显示,导致排查一直以为数据库已经正常连接了。。。

 

posted @ 2017-02-14 15:31  hjqjk  阅读(350)  评论(0编辑  收藏  举报