502、504 傻傻分不清楚

很长一段时间,对于网站 502 和 504 错误的原因一直混淆不清,最近备战面试,想到了这么个问题,便搜集了很多的资料来试图理解他们发生的本质原因,下面以 nginx + php-fpm 模型来讲解。

502——Bad Gateway,web 服务器上游网关错误,即 web 服务器和 web 程序之间的通信异常,常见的一种原因有:

  • nginx 同上游的 php-fpm 通信异常,如:php-fpm 未启动,nginx 与 php-fpm 的连接配置错误等导致连接失败。
  • php-fpm 主动与 nginx 断开连接,主要有以下几个原因:
    • php worker 进程达到 php-fpm 配置中的最大进程数量,导致 php-fpm 分配不了资源来处理后续的请求,直接关闭了与 nginx 的连接,后续的请求都返回 502 错误。
      • 短时间内大量的并发,操作了 php 的处理能力。
      • php 有比较耗时的操作,常见的如:网络 IO,数据库查询等,导致 php worker 进程长时间被占用,得不到释放,随着时间的推移,达到了 worker 进程的上限。
    • php-fpm 中的 request_terminate_timeout 的值小于 nginx 配置中的 max_execution_time 值,且单个请求的处理时间超过了 request_terminate_timeout,这时,php-fpm 主动终止此 worker 进程,也即主动中断与 nginx 的连接。

504——Gateway Time-out,网关超时,也即上游服务器(php-fpm)未能在 nginx 指定的时间内返回响应,这时候 nginx 主动断开与上游服务器的连接,返回 504 并输出到客户端。通过调整 fastcgi_connect_timeoutfastcgi_send_timeoutfastcgi_read_timeout 这三个参数可以在一定程度上避免 504 错误。

  1. http://www.dnsdizhi.com/post-187.html
  2. https://segmentfault.com/a/1190000002686153
  3. https://github.com/lisijie/lab/issues/16

王者荣耀的一点感悟

《王者荣耀》无疑是当前这个世界最火的 moba 游戏了,看到一朋友更新了朋友圈:男友送了她一个王者荣耀专用神器——类贴膜式的手柄。常玩王者的朋友看到这样一个东西应该也会有想买的冲动吧,于是我去淘宝上搜索了一下“王者荣耀”关键词,结果罗列了一大串相关产品和服务,如下图:

WechatIMG52

排行第一的是王者代练,我曾经看到过一些报道,讲的是一些专业的王者代练公司和平台。有些敏锐的人已经发现了王者荣耀这个金矿了,他们成立公司,招聘游戏打手接单代练,据说也活的挺好,更为厉害一点的成立了王者代练平台,连接想要快速上王者的菜鸟玩家和业余高手玩家,平台通过佣金抽成获利。

排行第二的手柄也很受欢迎,下图是简易版的手柄:

WechatIMG53

做工简单,成本低廉,关键是售价也低,10 元人民币左右包邮。对于常玩这款游戏的人来说,毫不犹豫地剁手。平台上卖的好的月销量能达到几千几万,但这东西也就是谁先嗅到了先机谁就能赚一票。

作为一位非资深的王者荣耀玩家,这款游戏给我的第一感觉是操作简单,易上手,这也是很多妹子加入进来的原因,妹子的涌入也是诸多男性加入进来的诱因。排位赛的成就设置满足了众多玩家比拼炫耀的心里;微信和 QQ 的好友机制,使得这款游戏的社交场景越来越凸显;一时间,只要有人的地方就有王者,人群中三五人簇拥着,横握手机,眉头紧锁着盯着屏幕,不用想,定是在开黑。在王者中,我们嘲笑那些菜鸟为小学生,遇到连续几场的失利,我们便抱怨“小学生放学了”,这也算得上一种特有的文化现象吧。

从游戏的诸多场景中可以看到人间百态。当我们奋力追赶一个残血的敌人的时候,可能立马就掉入了敌人的圈套,但大部分人就是忍不住去追,那种即将胜利的感觉无时无刻不在簇拥着他继续向前。当我们接近一个目标的时候,我们可能很难冷静下来思考,这或许是我们体内的基因在控制的吧。游戏团战中,最怕的就是己方队友一个一个的往敌人堆里送人头,毫无秩序可言,在这种时刻我们都忍不住骂一句傻逼。现实中,一群散兵游勇面对有秩序有组织的团体时,只能是丢盔卸甲而逃。面对近处队友被绞杀,选择置之事外或者或火速逃跑,如果奋力一搏,或许有能力解救队友,但此时站在自己角度却是躲得远远的,这在现实中到处都可以看到。还有仗着单个高输出的英雄,逍遥自在的到处砍人,该团战的时候他在打野,大家都不动的时候他一一人之力挑战对方整个团,运气好一点的,待对方技能尚未冷却之时,干脆利落地将对方斩落马下,但多数时候上演的却是神风特工队,现实中这样的人偶尔也能遇到。

 

 

 

MYSQL 优化读书笔记

近两天着重研究了 MYSQL 优化的一些细节,为了尽快地补充 MYSQL 相关的知识,看了一些相关的视频教程,也学习到很多的知识。记录如下:

关于 InnoDB 和 MyISAM 引擎的区别

  • 事务支持
    • InnoDB 引擎支持事务(ACID);
    • MyISAM 引擎不支持事务;
  • 存储结构
    • MyISAM 的存储结构与 InnoDB 有很大的不同。MyISAM 中每个表的数据分为三个文件存储,分别是:表名.frm(表结构定义)、表名.myd(表的实际数据)、表名.myi(表索引);
    • InnoDB 所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB。
  • 表锁的差异
    • MyISAM 引擎只支持表级锁,也可称之为读写锁,读数据时不予许写操作,读数据时允许别的读操作,写数据时不允许别的读和写操作;
    • InnoDB 引擎支持行级锁,锁的粒度要小的多,但因为 InnoDB 的锁是和索引结合在一起使用的,所以如果没有用到索引,还是使用表级锁。
  • 索引的差异
    • MyISAM 引擎中索引和数据是分开存放的,通过索引找到数据后需要定位到具体的数据地址去获取数据,这个操作称之为 回行。MyISAM 中的数据都是按照插入的顺序存放的。
    • InnoDB 引擎的主索引和数据是绑定在一起的,我们称其主索引为聚簇索引,因为数据和主索引绑定在一起,而索引是有序的,所以不管插入数据的先后顺序如何,数据都会按照主索引的顺序排列,如果数据非常大,也会影响到索引的查询性能。另外非聚簇索引(也称之为二级索引)上存放一个指向主索引的指针,所以对于二级索引查找来说,需要通过两次索引查找定位数据。InnoDB 默认使用自增的主键作为主索引,如果没有设置主键,则使用唯一索引作为主索引,如果二者都没有设置,则系统默认生成一个隐藏的主键作为主索引,推荐每张表都建一个自增的主键作为主索引。
  • 全文索引
    • MyISAM 支持全文索引;
    • InnoDB 不支持全文索引;

索引的分类及原理

常用的索引有 BTree 索引和 Hash 索引

  • BTree 索引用树这种数据结构来维护索引,一次查询只能用到一个索引,索引遵循最左匹配原则()。
  • Hash 索引使用 Hash 这种数据结构来维护索引结果,数据存放的地址是通过对索引列求 Hash 值得出,所以存放不均匀且无序,这使得 Hash 索引无法进行范围查询、不能用于前缀索引,不能优化排序等。

索引覆盖

索引覆盖是指直接通过索引查找数据而不需要回行。比如:一个表 tmp 中有 id、name 等多个字段,name 字段上有索引,查询语句:select name from tmp where name = ‘张三’; 就会使用到索引覆盖,因为索引本身含有 name 信息,不需要定位到具体的数据地址去取数据。使用到索引覆盖时通过 explain 语句分析可以看到 extra 字段为 using index。

索引使用原则

  • 查询频繁。结合实际业务,给查询频繁的字段加索引。
  • 尽量覆盖常用查询字段。结合实际业务,尽可能多的覆盖常用查询字段,联合索引的先后顺序根据实际业务来设置。
  • 索引字段区分度高。尽量选取区分度高的字段建立索引,或者考虑将区分度高的字段放在联合索引的前面。
  • 索引长度小。索引的长度一般与区分度成反相关性,找到一个平衡点。
  • 冗余索引。如 A 和 B 字段建立联合索引,但 A 和 B 的先后顺序不能确定,可以建立两个顺序相反的相同字段的联合索引。
  • 索引碎片。定期清理碎片,常用优化命令有:optimize table  表名。。

Explain 分析

各字段含义如下:

  • id:编号,为了区分同一个查询语句中多个 select 语句。
  • select_type:
    • simple:不含子查询的简单查询。
    • primary:含子查询及派生查询。
      • subquery:非 from 子查询,如:in、exists
      • derived:from 型查询。
      • union:union 查询。
      • union result:类似 union。
  • table:表名或表别名或 derived。
  • possible_keys:可能用到的索引。
  • key:实际使用的索引。
  • key_len:使用到的索引总长,按照最左前缀匹配原则,计算所有使用到的索引的总长度。
  • type:
    • all:全表扫描,性能最差。
    • index:扫描索引的全部节点,性能比 all 稍好。
    • range:范围查询,用到了索引,较之 index 性能稍好。
    • ref:通过索引快速引用数据。
    • eq_ref:类似 ref,引用一行数据。
    • const,null,system:常量级别,性能最好。
  • rows:估算需要扫描的行数。
  • ref:联表查询的引用关系。
  • extra:
    • using index:用到了索引覆盖,效率高。
    • using where:索引不能完全定位数据,还需结合 where 语句过滤出所需数据。
    • using temporary:使用临时表,性能差,需优化。
    • using filesort:使用表外排序(可能在内存中排序,如果数据太大,则会在硬盘上排序),必须优化了。

 

http://study.163.com/course/courseMain.htm?courseId=1003746011

《TCP/IP》读书笔记(上)

有输入就得有输出,不然辛苦学到知识过不多久都得换回去了。辞职后,一直在思考自己的弱项,为什么找不到满意的工作,仔细想了想,可能还是自己的基础知识过于匮乏了。入行到现在已经接近四年了,而做的事情一直都浮于表面,不了解计算机底层的运行逻辑,网络间通信的细节,甚至有些概念从来没有听过,想想也是挺可怕的,正是由于这样的一些原因,导致在这一行混了这么久仍然底气不足,常常有种怕被揭穿的感觉。

焦虑的心情不适合出去玩耍,最近三天看了三天网络相关的书,一本网上精简版的《TCP/IP详解》,到目前为止,略读了很多自认为不是很实用的细节,着重研读了 TCP 协议相关的细节,自觉以前对网络的理解太过于肤浅,也为了加深自己的理解,防止过快的忘记,记录下自己对 TCP 协议的一些理解。

TCP 位于 TCP/IP 协议的传输层,在它下层的分别是网络层和链路层,在它之上的是应用层。越往底层越偏向物理硬件,下层协议细节对上层透明,这也就使得上层的开发在不知道下层协议细节的情况下也能够正确地开发。不同层的作用及常见协议如下所示:

  1. 链路层:负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网、ADSL、ARP、RARP 等;
  2. 网络层:网络层负责分配地址和传送二进制数据,主要协议是 IP、ICMP、IGMP 等;
  3. 运输层:主要为两台主机上的应用程序提供端到端的通信,主要的协议是 TCP、UDP 等;
  4. 应用层:负责处理特定的应用程序细节,常见的协议有 HTTP、SMTP、SNTP、FTP、SSH、DNS、DHCP 等;

并不是所有的网络设备都具备这四层,比如:常见的路由器只有链路层和网络层这两层,它的作用主要是网络路由转发,如下图所示:

52im_3

连接网络的另一个途径是使用网桥。网桥是在链路层上对网络进行互连,而路由器则是在网络层上对网络进行互连。

MTU(最大传输单元)是一个非常重要的概念,它与通信接口有关,在一条网络路径中,MTU 取这条网络路径所经过的所有设备中的 MTU 最小值。通过路径最大传输单元发现方法可以确定一条路径的 MTU,常见的 MTU 值为 1500。

IP 分片是网络上传输 IP 报文的一种技术手段。IP 协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组。这一过程称为分片(fragmentation)。因为单包大小不能超过 MTU 值,所以对于超过 MTU 的包需要将其进行切片传输。网络层是不可靠的,分片传输的各包中,只要其中一个包在传输的过程中出现了差错或者丢失,需要重新传递整个包,所以应该尽量避免分片,将单个包的大小控制在 MTU 之内。

UDP 的包体较之 TCP 比较简单,下图展示了 UDP 包的结构:

udp.png

TCP 是互联网上使用最多的一个协议,它是一种面向连接的、可靠的、基于字节流传输层通信协议。包体结构如下:

tcp.png

各字段解释如下:

  1. 16 位源端口号和 16 位目标端口号:发送端和接收方的端口号;
  2. 序列号(seq,32 位长):
    • 如果含有同步化旗标(SYN),则此为最初的序列号;第一个数据比特的序列码为本序列号加一。
    • 如果没有同步化旗标(SYN),则此为第一个数据比特的序列码。
  3. 确认号(ack,32位长):期望收到的数据的开始序列号。也即已经收到的数据的字节长度加1;
  4. 报头长度(4位长):单位为字节,数据段开始地址的偏移值,即上图中选项所占的字节数,大小范围 0-60 字节;
  5. 保留—须置0;
  6. 标志符:
    • URG:为 1 表示高优先级数据包,紧急指针字段有效。
    • ACK:为 1 表示确认号字段有效
    • PSH:为 1 表示是带有 PUSH 标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
    • RST:为 1 表示出现严重差错。可能需要重现创建TCP连接。还可以用于拒绝非法的报文段和拒绝连接请求。
    • SYN:为 1 表示这是连接请求或是连接接受请求,用于创建连接和使顺序号同步
    • FIN:为 1 表示发送方没有数据要传输了,要求释放连接。
  7. 窗口(WIN,16 位长):表示从确认号开始,本报文的接受方可以接收的字节数,即接收窗口大小,用于流量控制。接收方有一个缓冲区,应用层从缓冲区内取出数据,缓冲区剩余未填满的大小即为窗体大小;
  8. 校验和(Checksum,16 位长):对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。这是一个强制性的字段;
  9. 紧急指针(16 位长):本报文段中的紧急数据的最后一个字节的序号。
  10. 选项字段:最多 40 字节。每个选项的开始是 1 字节的 kind 字段,说明选项的类型;
    • 0:选项表结束(1 字节)
    • 1:无操作(1 字节)用于选项字段之间的字边界对齐。
    • 2:最大报文段长度(4 字节,Maximum Segment Size,MSS)通常在创建连接而设置 SYN 标志的数据包中指明这个选项,指明本端所能接收的最大长度的报文段。通常将 MSS 设置为(MTU-40)字节,携带 TCP 报文段的 IP 数据报的长度就不会超过 MTU,从而避免本机发生 IP 分片。只能出现在同步报文段中,否则将被忽略。
    • 3:窗口扩大因子(4 字节,wscale),取值 0-14。用来把 TCP 的窗口的值左移的位数。只能出现在同步报文段中,否则将被忽略。这是因为现在的 TCP 接收数据缓冲区(接收窗口)的长度通常大于 65535 字节。
    • 4:sackOK :发送端支持并同意使用 SACK 选项。
    • 5:SACK 实际工作的选项。
    • 8:时间戳(10 字节,TCP Timestamps Option,TSopt)
      • 发送端的时间戳(Timestamp Value field,TSval,4 字节)
      • 时间戳回显应答(Timestamp Echo Reply field,TSecr,4 字节)

 

TCP 是一个面向连接的协议,但它的连接只是一种虚拟连接,是连接两端的状态同步,通过三次握手和四次挥手来建立连接和断开连接。下面是我画的流程图:

status.jpeg

status_change.png

status1.png

通过 tcpdump 命令可以清楚地看到 tcp 数据包的结构细节:

tcpdump.jpg

根据上面的状态变迁图可以看到:主动终止连接的一方在最后会有一个 TIME_WAIT 的状态,TIME_WAIT 状态也称为 2MSL(Maximum Segment Lifetime)等待状态。这个状态持续的时间在 1~4min 之间,取决于操作系统的实现。这种 2MSL 等待的另一个结果是这个 TCP 连接在 2MSL 等待期间,定义这个连接的插口(客户的 IP 地址和端口号,服务器的 IP 地址和端口号)不能再被使用。这个连接只能在 2MSL 结束后才能再被使用。

  1. https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE
  2. http://www.52im.net/topic-tcpipvol1.html
  3. http://coolshell.cn/articles/11564.html

阴雨连绵的日子

南方到了梅雨时节了,大大小小的雨下个不停,阴雨连绵的天气让人感觉压抑、心情灰暗。老天爷就像个饱含心事的少女,哭哭啼啼,但时而心情好转,将太阳还给大地,时而黑云压城,细雨连绵。

不喜欢这种天气的另外一个原因是空气中飘散着一股霉味,衣服袜子由于未干透所散发出来的刺鼻的气味。望着窗外,湿漉漉的、阴沉沉的,唯有小屋的宁静让自己置之度外。回想着那些让人恐惧、日复一日、朝九晚五的日子,有点绝望。有时想:做一个自由职业者也很好啊。但想归想,没有严格的自律能力,自由的代价就是衣不果腹,必须找到高价值、高产出、高回报的职业带代替现有的朝九晚五,这本身就是一种巨大的挑战。但是如果永远不去想、不去做,是不是在朝九晚五的怪圈中,永远也走不出来了?

整理整理继续上路

失业了,这次裸辞心里还是有些许的不安和担忧,毕竟到新公司才不到一周,提出辞职的时候,上司和 HRBP 都很惊讶。每一次的决定我都是考虑再三,当决定的那一刻,基本上就不会再改变主意了。可能在上一家公司养成了自由的习惯,稍有些许的约束就让我感觉浑身难受。打定主意先休息几天,看看书、充充电,制定好读书计划,在没找到下家之前,我的心总是悬在半空中,督促自己快速补充基础知识,以求找到一个满意的工作。

今天一天下来,发现效率挺高的。买了一个 linode 的 vps,将原阿里云上的数据和代码都迁移过来,博客又重新开张了,只是你们都感知不到,这前前后后也花了些许的时间,遇到了很多诡异错误,不过好在都解决了。闲下来的时光也正好可以想象以后的路,我的内心告诉我,职场这条路我走不长,以后一定要找到自己的事业,只有这样,才能摆脱这种朝九晚五的机械般的生活。

武侠世界

每一次看武侠,都会沉醉一段时间,脑海中仗剑江湖的场景久久不能忘怀。

武侠是围绕着狭义二字构建的虚拟世界,多数以真实的历史事件作为基础,增强读者的代入感。武是武侠世界中的一个一元标准,在这个世界中,绝世武功是世人孜孜不倦追求的,以武功为高低为标准,又分化为多个派系,在这个世界,也存在着一种公认的至上武功,围绕着这些至上武功而演绎着不同的爱恨情仇。武功已书籍或者其他载体长久保存,只要得到秘籍,按照秘籍上的方法去勤学苦练,就能在短时间内跨入武林高手的行列,由于这种短时间内的可转移性,对个人的天资并没有过分的要求,只要是个正常人,机缘巧合之下便能跻身武林高手行列,成为受人尊敬和敬仰的人物。这个以现实世界为蓝本的狭义世界,给人一种真实的梦幻感,给无数的失意青少年予以慰藉。

在现实世界里,与“武”对应的应该是“钱”,大部分人一生所追求都离不开一个“钱”字,钱的多少能够决定一个人的人生自由和自由意志。马云的花名是“风清扬”,华山派剑宗宗师,名字中便透露着几分飘逸,洒脱,从某种程度上来说,马云之流就是这个世界的武林高手,他们就如同绝世高手一般地主宰这个世界。只是现实中多是尔虞我诈罢了,与武侠世界中的狭义相比,这个世界多是一个混沌的地方。

就如同金庸的武侠小说,其中处处映射了作者对真实世界的讽刺,隐喻,从这个角度来说,金庸对我们这几代人的影响是巨大的,我们或多或少接受了他老人家的狭义思想。

如果只要在指尖植入一个晶粒大小的电脑芯片,从此无须使用信用卡和钥匙,只要挥一挥手就能购物或者开锁,你想要尝试吗?

看到这个问题,我首先想到的是安全,如果只要在指尖植入一个芯片,就能更为方便地开锁和购物消费,这必然存在巨大的安全隐患。比如说,我手中有一个芯片,我出门时不小心挥了一下手臂,结果门自动开了,而此时的我并没有意识到这个问题,那我的房子就面临了巨大的盗窃风险,又比如,如果挥一挥手便能刷卡消费,那便可能被不法分子利用,逼迫你挥手消费,亦或者将你的手指砍落得到芯片,亦或者设置骗局,让你无意识地挥动手臂从而盗刷你的卡。这一切都是使用这种方式带来的安全隐患。

即便上面列举的这些问题都有相应的解决方案,还有一个很大的问题,我们自己的自制力。消费越便利,我们便会下意识地促成自己更多的消费。对于自制力差的人来说,这种便利性会对他们的财政产生非常大的危害性。

我自认为自己的自制力还算可以,唯一担心的是安全性问题,如果能够解决安全性这个最大的问题,我很愿意尝试这种新科技,我想这也将是未来的科技发展方向。

你在喝酒时最爽的体验是什么,最糟糕的体验又是什么?

酒是一种神奇的东西,它能够让你放松自己的神经,很多在正常状态下说不出口的话,借着酒劲能够非常自然地说出来,酒也是很好的镇静剂。因为酒的这些功效,让我们人类对酒的依赖非常严重。因为遗传的原因,身体内没有解酒的酶,每次一杯酒下肚,脸上开始发烫,如果再继续喝上几杯,全身开始泛红,再几杯,脑子开始晕乎乎,心脏开始剧烈跳动,再多一点,感觉心脏就要跳出来了,全身难受。与喝酒得到的那点释放来说,喝酒的难受状态让我对酒产生了严重的恐惧,厌恶酒桌文化。

你知道如果全身心投入一件十分耗费时间的事业,例如音乐、写作、表演、从商、从政或从医长达二十年之后,你会变成世界范围内这个行业的佼佼者,你愿意尝试吗?如果愿意,你会选择哪个行业?

长时间坚持一件事,要么是强大的兴趣驱动,要么是丰厚的利益驱动,如果都没有,靠意志力驱动,是很难长久坚持下来的。

音乐、表演都算是艺术领域,除了靠长时间的坚持外,天分也是非常重要的,如果没有天分,不管你多么努力,永远不可能达到顶尖水平。写作也算艺术领域,但写作还有一个重要属性是沟通交流,通过写作,可以将自己的思想传达给成千上万的人,忽略艺术创作,仅考虑沟通这个属性,写作是能够通过长时间的训练达到优秀的水平的。从医和其他专业性质的职业一样,都是靠经验的不断累积来提升自己的水平的,与其他职业不同的是医生面对的是活生生的人,作为一个医生,个人道德水平和医术同样重要。对于艺术类的职业,我承认自己并没有天赋,而像医生这样的职业,职业选择的时机要求非常早,毕业院校决定了一个医生能走多远。

除却这些职业,写作是我现在就开始在尝试坚持做的一件事,剩下的从商这件事就比较宽泛了,大部分人从商的初衷都是赚大钱,这是能驱动我选择并坚持的一个重要因素,虽然目前我还在职业发展的道路上,但创业或者经商的念头却一直在我的脑中飘荡。人的自由很大程度上取决于财富,财富自由之前,大部分人的最优选择是找一份朝九晚五的工作,每天过着机械般的生活,这个时候谈自由是一件奢侈的事情。

一旦选择从商,所有的一切都得靠自己拼搏,这是极为考验个人能力、意志力甚至是运气的事情。路都是自己选择的,不管选择哪条路,坚持下去,或多或少都会有所收获。