Yifans_Z's Blog.

2018.07 工程月度总结

字数统计: 1.6k阅读时长: 24 min
2018/07/30 Share

使用 … 运算符定义变长参数函数

在写一方式时使用了 ... 运算符,但是这个运算符是 PHP 5.6 增加的,线上是 PHP 5.5 导致 500 报错,环境问题暴露。

如果可能出错,就一定会出错。

从 PHP 5.5.x 移植到 PHP 5.6.x

Ubuntu 核心参数

net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000

sysctl -p 显示系统内核参数变化。

其中含义待研究。

/etc/sysctl.conf

net.ipv4.tcp_tw_recycle 改为 0

tcp_tw_recycletcp_timestmaps 同时开启时,会有 risk,来自 NAT 网路的用户访问会有丢包情况从而导致 504。tcp_tw_recycle 默认是不开启的,之前的优化配置开启该选项时时并没有考虑这一点。从 Linux 4.12 开始,该选项已被移除。

正确使用 Redis

在读 Redis 大数组会占用大量的 PHP-FPM 内存,影响查询效率。

在大量(百万级)使用存储 Redis Key 发现慢查询,拖累服务器,是否是此原因待详细查

如何正确使用 Redis、配置 Redis 需要总结。

MySQL 索引选择

某查询中通过 explain 发现 MySQL 选择了一个较慢的索引,发现相同条件下不同的时间会使用不同的索引,引发了慢查询。

需要研究 MySQL 如何进行索引的选择,和如何建立合理的索引。

AWS EC2 服务器类型

定额配置信用积分,影响服务器性能。

Python SELECT 查询事务

Python 的 SELECT 查询默认是事务性的操作,期间无法对表 DDL 进行改变。

SELECT 语句也应该进行 COMMIT

道听途说,待自测详查。

try catch 导致的死循环

外层函数 while(1) 内部 catchcontinue 导致死循环,不能假设处理一定成功。

NGINX Log 中挖掘项目隐藏的问题

  • 通过 log 监控流量、访问行为、发现爬虫
  • 通过 log 分析非 200 状态码,检查项目页面

数据库字段中包含 HTML 元素导致页面错乱

数据库数据有 </div> 等标签,与模板元素连接在一起,导致页面错乱。

要显示的数据要 htmlspecialchars 转码。

爬取检查时发生 Connection to the other side was lost in non-clean

thanks for xq24.

Scrapy 快速的三次 retry 之后 give up,然后接着 url 都出现这个问题。

此时状态:

这时浏览器挂上代理能访问出现问题的 url,但是本地无代理时 IP 无法访问。

查看服务器 Log:

发现有状态码 499 但是,只有访问一次这个 url 会出现俩三个 499 的 response,然后一段时间内,整个站就都不能访问了,没有反应了,Nginx 日志里面也没有记录到任何东西了,说明数据没有到 Nginx 应该是 Tcp 层的网络有问题。

验证:

tcpdump + Wirsshark 分析。

sudo tcpdump tcp -i eth0 -t -s 0 -c 1000 and dst port ! 22 -w ./target.cap

出现了很多的 RST 导致 TCP 连接中断,仔细看,发现里面的 ACK 完全和上一个包的 Seq 对不上,我们客服端的 ACK 的是一个巨大的随机数。导致服务器端返回 RST

因为项目是 HTTP 应用层的,不会影响到 TCP 层,所以 Google 关键字 tcp reset + blogspot.com 看到 reddit 一篇 8 年前的讨论。讲到了 关于中国防火墙。中国 GFW 会有根据 tcp 协议里面的关键字来进行屏蔽。然后会通过 reset 修改来屏蔽整个站几分钟。https 协议的不会。

测试了俩个国外的网站:

http://site.aace.org/conf/blogspot.com
http://www.motogp.com/blogspot.com

加入了 blogspot.com 就无法访问了。

所以问题找到了中国 GFW 会通过 URL 里面的敏感字进行封锁网站,有篇具体分析的文章。线上因为用的 HTTPS 协议所以内容加密了,没有被 block,解决方法:

  • 将测试服务器换成 HTTPS 然后就可以访问了
  • 通过代理访问

NGINX Log 出现大量(10K)HTTP 499 错误

499 CLIENT CLOSED REQUEST

A non-standard status code introduced by nginx for the case when a client closes the connection while nginx is processing the request.

NGINX Log 出现大量(10K)HTTP 499 错误,几乎都是 AJAX POST 请求。经过日志排查,发现这些 499 请求都是来自于 Safari 浏览器,再通过日志查看,这些请求都是正常的用户行为。在本地使用 Safari 浏览器实测时也是会出现这样的问题。基本可以断定是 Safari 浏览器导致。

最终确定为在点击一个 button 时同发送了两请求,分别为 async: false,async: true。

在进行控制变量的测试中,基本确定与 AJAX 同异步请求有关。不建议修改 async 为 false。

在测试的过程中,也发现虽然使用 Safari 请求显示 NGINX 日志中会显示 499,但是数据的记录并没有受到影响。

服务器器运维工具 atop

待整理

完全独立的分支

在使用 Git 进行版本控制的某些场景中我们可能需要在一个项目中建立完全独立的分支,此分支将作为一个独立的版本历史根节点,不与之前任何分支拥有相同的版本祖先。

比如当我们要在一个项目中使用一个分支进行项目文档的管理时,或者当我们想要发布一个软件的开源版本但又不希望将软件的版本历史暴露给外界时,都可以使用以下的方法建立一个独立分支。

通过带有 --orphan 参数的 checkout 命令即可从 start_point 或者 HEAD 创建一个独立分支:

$ git checkout --orphan 新分支名 <start_point>

如果希望创建全新的独立分支,例如用于文档管理,不想出现项目代码,则还需要进行如下删除操作。注意如果有不在索引中的文件,则需要手工删除(包括 .gitignore),删除此分支中的索引及索引中的所有文件

$ git rm -rf .

然后从新建立文件和提交。

通过一个独立分支管理文档?一个思路。

CATALOG
  1. 1. 使用 … 运算符定义变长参数函数
  2. 2. Ubuntu 核心参数
  3. 3. /etc/sysctl.conf
  4. 4. 正确使用 Redis
  5. 5. MySQL 索引选择
  6. 6. AWS EC2 服务器类型
  7. 7. Python SELECT 查询事务
  8. 8. try catch 导致的死循环
  9. 9. NGINX Log 中挖掘项目隐藏的问题
  10. 10. 数据库字段中包含 HTML 元素导致页面错乱
  11. 11. 爬取检查时发生 Connection to the other side was lost in non-clean
  12. 12. NGINX Log 出现大量(10K)HTTP 499 错误
  13. 13. 服务器器运维工具 atop
  14. 14. 完全独立的分支