实际项目中遇到的502 Bad Getway

不同于404、503、504这些明确错误,502错误感觉真心是最难查的,原因五花八门。

最初始的502,就是nginx与程序通讯问题,这种一般是nginx配置问题。只在刚开始环境搭建的情况下会出现,或者是如php-fpm这种程序停止运行。但是更多的却是日常运行过程中出现的匪夷所思的502。

其他的502错误基本上就是,程序抛出一些Nginx无法理解的错误就是502,原因各种各样

下面说说我遇到的一些502:

1、正式环境登录成功后,偶然性502,这个问题查了很久。最终发现是因为设置cookie的方法不小心被多次调用,后面实验证明set-cookie超过十几个在我们公司的运行环境就会报502,所以一次性set-cookie千万注意数量,和处理好循环调用

2、公司测试环境,PHP 运行 curl,请求一个https地址直接502。这个功能原先是好的,突然后面变成502。cli命令行模式运行同样代码功能正常,查了很久没找到原因,后面重启php-fpm就好了。这个502错误,目前仍未想通是为什么。

谈谈我对502问题查找的一些心得。因为502错误基本上在web端是看不到啥有用的信息的,纯靠猜,所以,我们可以先用cli命令行模式去看下,程序是不是有啥坑。这种方法能发现大部分502问题,当然像上面set-cookie这种数量过多问题无法发现。


为什么mysql的varchar字符长度会被经常性的设置成255

很多时候我们设置varchar(255)都习以为常了,甚至我还遇到过有人以为varchar不能设置超过255的人。其实varchar没有明确最大长度,然后有人说那65535字节(bytes)不是吗?

但是事实上如果你用的 utf8 编码的话按理最大可以设置到 varchar(21845),但是其实一般都会说你超出。其实MySQL要求一个行定义长度不能超过 65535 bytes(所有字符串类型字段包括其字段名称占用空间都计算在内, text、blob等大字段类型除外)。

如下图我先设置了个21842成功了,后面加个长度为3的varchar都会报错,所有如果一个表有很多varchar字段的时候,不应该把varchar设置的特别大,会影响后面的字段

言归正传那为什么我们会经常性设置成varchar(255)呢?

首先我们要知道一个概念:InnoDB存储引擎的表索引的前缀长度最长是767字节(bytes)(PS:mysql5.6及之前版本)

你如果需要建索引,就不能超过 767 bytes;utf8编码时 255*3=765bytes ,恰恰是能建索引情况下的最大值。

如果像lavavel5.3往后 使用的是utf8mb4编码,默认字符长度则应该是 767除以4向下取整,也就是191。

总结:varchar(255) 不是最优的字符长度,最优还是应该根据实际需要的来。但是这是一个保证你能少出错的一个很好的默认值

转至本人CSDN博客


数据表设计注意事项

数据库建一张表简单,但是建的表会不会给后面的自己留坑呢?我们这里聊聊创建数据库表的注意事项(以mysql为例)

  1. 库、表字符编码选择

      mysql数据库默认编码是:字段继承表,表继承库。如果你建库时未选择编码,然后默认就是latin1,然后你每建一张表、或建需要存中文的字段,就需要重新选编码格式,是不是很坑。那么我们选字段该选什么编码呢,在中国也就逃不过GBK、UTF8了,大部分情况我建议UTF8,其实有些人会说GBK中文占字节少,可以减少IO。但是我感觉小公司,访问量小不在乎这边IO,都抗的住。大公司大部分都国际化,得为支持多种语言做准备,最关键的是,有用户输入的数据,UTF8支持更好,谁也不知道用户会输入什么。

  2. 数据引擎选择MyISAM还是InnoDB或其他

      MyISAM写的时候直接锁锁表了,会阻塞其他人读和写,而读的时候还会阻塞其他人的写,所以只适合那种后台更新且操作人数少、切更新少的项目,不然它的查询速度也没法发挥。

      InnoDB删修都是行级锁,适用于大部门场景,但是索引查询效率低一点,不支持全文索引(据说新版本支持,暂未使用新版本),但是支持事务,需要用到事务的逻辑引擎则不能选MyISAM。

  3. 表字段的默认值如何选才合理

    表字段默认值最好不要有NULL,会出现以下两点问题:

    查询问题:

      查询是否为空时,int型必须写成 WHERE A=0 OR A IS NULL;字符串型:必须写成 WHERE A=”” OR A IS NULL,是不是感觉很麻烦。但是最麻烦的还是更新。

    更新问题:

      比如执行 UPDATE 表名 SET A=A+1时,你会发现值为NULL的依旧还是NULL,并没有跟想象中的那样变成1。这就很尴尬了,已经是程序BUG了。你必须 UPDATE 表名 SET A=IF(A IS NULL,1,A+1)

  4. 不要忘了建索引

      索引能大大提升查询效率,可以缩小查询数据范围。很多时候我们只关心WHERE条件中用到的字段加索引,但是没考虑到Order By排序也需要用到索引,我们可以用explain去查看索引是否被用到,和查询扫描条数。