写点什么

程序员容易忽略的问题

用户头像
Janenesome
关注
发布于: 2020 年 05 月 10 日
程序员容易忽略的问题

平时开发中一些容易忽略的细节,在特定场景下可能会引发程序的故障,例如高并发以及大数据量的情境下。



你有遇到过类似问题或是别的场景吗?欢迎在留言区和我们分享。


一、频繁写日志

故障现象:某个服务发布不久后,陆续收到来自这台服务器里多个不同分布式服务的告警,收到系统负载飙升的告警,最后服务器宕机。定位问题,发现磁盘 IO 跟系统负载在短时间内飙升,最后影响到整个服务器里的所有服务。



原因分析:最后 review 代码发现,服务里的日志等级没有调好,每次请求都刷了大量的 debug 日志。开发时留下的测试日志也没有清理干净。该服务的请求量又特别大,日志写得极度频繁,直接把磁盘 IO 打满导致系统负载飙升,最后连锁反应整个服务器都受影响。



经验教训:

  1. 如何输出日志,要根据业务需求和开发测试需求来控制,太多日志等于没有日志。

  2. 日志等级要配置好,不同环境对应不同的等级。

  3. 对第三方的日志组件要摸清楚,避免输出很多不必要的日志。

二、不必要的数据库请求

故障现象:应用发布后,数据库 Load 居高不下,服务持续告警。



原因分析:检查服务日志,发现是某个请求的调用频率非常高,导致频繁执行某个 SQL 语句。追查这个请求,最后发现是在首页被调用了,首页是最频繁被访问的页面,导致数据库也被频繁访问了。



经验教训:

  1. 首页不应该访问数据库,首页需要的数据应该从缓存或者搜索引擎服务器中获取。

  2. 首页最好做成静态化的。这也能利用多级缓存( CDN 、反向代理缓存等等)

三、使用锁时不注意粒度

故障现象:某服务上线后 QPS 一直上不去,请求量大时大量响应超时的告警。



原因分析:在服务的某个请求里使用了锁,而锁的粒度比较大,代码块中竟然有耗时比较长的网络 IO 操作。导致请求量大的时候,成为了性能的瓶颈。



经验教训:

  1. 锁的使用要谨慎。

  2. 能无锁化编程就不要用锁,锁的粒度要控制好,耗时长的代码考虑能不能放到锁的外面。

四、不重视缓存

故障现象:某次上线需要更新缓存里的字段,工程师直接清理缓存,数据库连接池很快被占用完,持续告警,服务直接停止对外提供服务。



原因分析: 部分工程师认为缓存只是改善性能的手段,清理缓存时没有考虑到数据库的可用性,没有考虑逐步失效缓存,而是直接清理了所有缓存,导致数据库压力大增,最后宕机。



经验教训:

  1. 当数据库的设计是在有缓存的前提下进行设计时,缓存就已经是系统中不可或缺的一部分,对待缓存的管理操作就应该提升到和服务器一样的级别。

五、应用启动不同步

故障现象: 某次上线。Web 应用和分布式服务同时上线,过程中 Web 先发布了,而服务还在启动中,导致短时间的 Web 请求失败告警。



原因分析: 在使用了微服务跟分布式后,应用和应用、应用和服务之间的依赖关系没梳理清楚。上线时没有想好兼容的关系,没有意识到要先上线服务才能再上线应用。



经验教训:

  1. 如果是使用自动部署工具,则要配置好上线的先后顺序,不断 curl 试探服务是否已上线完毕,服务上线成功后才能发布应用。

  2. 手动发布应用时,应该考虑兼容性。前置的服务要先发布。

六、大文件读写导致独占磁盘

故障现象: 偶发的,某次上传图片,从原本只需要一两秒,变成了需要几十秒,最后响应超时。



原因分析:检查储存服务器,发现大部分文件只有几百KB。而有几个文件达到了数百兆,非常大,读写这些大文件一次需要几十秒,这段时间,磁盘基本被这个文件操作独占。导致其他的文件操作变慢。



经验教训:

  1. 储存服务器应该根据不同文件类型和用途进行管理。大文件和小文件不能共用储存。

七、没有意识到生产环境的重要性

故障现象: 某段时间,突然收到应用持续十几秒的告警。



原因分析:检查发现,这段时间内数据库的操作超时导致告警。原来是开发直接执行生产环境的 SQL 操作,导致锁表了。



经验教训:

  1. 开发应该敬畏规范,线上生存环境的所有操作,都要遵循规范和谨慎。

  2. 很多开发觉得执行 SQL 操作是小事,有些会直接上去线上服务器执行语句;如果没有线上权限,就悄悄的把语句放到生产环境的应用服务器上执行,神不知鬼不觉。但是如果不小心写错了 SQL ,后果可想而知。

八、不规范的操作

故障现象: 某应用发布后,持续受到数据库的告警。回滚应用后告警消除。



原因分析:发现该应用发布后大量数据库读操作,而这些数据本来应该是走缓存服务器的。检查缓存发现数据的确是有被缓存了。 review 代码发现访问缓存的代码被注释了。原来是工程师为了方便测试注释了代码,可是提交代码和上线时忘了改回来。



经验教训:

  1. 提交代码时应该看一下提交的差异,确认没有提交不该提交的代码。

  2. 加强代码 review ,代码提交时必须经过另一个工程师的 review。

  3. 制定规范并遵守规范,很多团队会不重视规范,导致规范流于形式,根本没有被执行到位。


很多问题会在产品初期难以披露,而问题发生的时候有可能会导致严重的后果。



这就要我们平时编程时就培养好这种意识和好的习惯。



软件设计时也应尽量简单,使问题能在尽量早的环节中就被发现,甚至问题出现时能快速地定位到问题所在。



用户头像

Janenesome

关注

功不唐捐 2018.10.29 加入

程序员

评论

发布
暂无评论
程序员容易忽略的问题