文章来自微信公众号:techreading 技术阅读Martin Thompson 在巴西圣保罗的InfoQ全球软件开发大会上,分享了在软件开发中,哪些问题容易影响系统的性能。他总结了在工作中比较常见的10个问题以及相应的解决办法
文章来自微信公众号:techreading 技术阅读
Martin Thompson 在巴西圣保罗的InfoQ全球软件开发大会上,分享了在软件开发中,哪些问题容易影响系统的性能。
他总结了在工作中比较常见的10个问题以及相应的解决办法。
10 环境没有升级到最新版
很多人不愿意把软件运行的环境或者系统升级到最新版,因为这些升级很可能会影响到正在运行的软件或服务。如果你的确希望提高系统的性能,不妨先在测试环境中试一试。
同时,应该采取持续集成的工作流程,经常更新代码,写完整的测试,另外试试看是否有一些bug可以通过升级它所依赖的环境就得到解决。
9 重复运行的代码
这个问题还比较常见。代码可以运行,和可以有效率地运行是两回事。一段代码可能被重复调用了很多次,而表面上看起来却没有问题。比如每次需要一个文件就从磁盘读取,用过之后并不缓存起来,导致接下来访问这个文件都很慢。
Thompson提到一个案例。在这个案例中,网页的响应速度非常慢。一般来说是数据库出了问题。但当他仔细检查代码时,却发现在同一个循环中,数据库被调用了7000次。问题不是数据库引起的,而是代码引起的。
这个案例带来的教训就是,永远要弄清楚你的代码正在处理什么问题。重复运行的代码极有可能不会带来明显的bug,但并不意味着它没有问题。
8 数据结构的选择
当你把超过1GB的数据存在一个数据结构里,就需要小心内存的读取速度了。对于一个超过2GB的字典,Java的HashMap比.NET的字典慢10倍以上。当然,在别的情况下,Java可能也比.NET快。
处理特别占有内存的数据时,在选择数据结构上需要仔细斟酌,同时不要太依赖系统自带的数据结构。
7 内存回收慢
这个问题和上个问题有点儿像,它指是自动内存回收导致的问题。
使用自动内存回收的语言或者工具时,一次性分配过多的内存会增加内存回收的时间,导致系统速度变慢。
6 并行问题
并行任务的通信和同步需要系统开销,并且这些通信和同步本身并不一定是并行的。根据阿姆德尔定律(Amdahl Law),如果5%的系统活动需要串行,不论使用多少个处理器,系统最多也只能加速20倍。而通用扩展性定律(USL)则指出,在处理器达到一定数量后,并行系统的通讯开销会导致性能下降。
建立并行系统时,尽量避免引入共享可变的全局数据,因为一旦出了问题,你几乎不可能知道是哪里的代码有问题。推荐使用不共享数据的方式构建并行系统,或者严格控制写入数据的场景。
如果需要给算法加速,应首先考虑单线程的情况,再考虑复杂的并行情况。
5 不理解TCP原理
很多人不理解TCP的原理就开始考虑微服务架构,在某些情况下,遇到ACK延时可能导致每秒只能传输2-5个包。造成这个现象的原因是,TCP中的Nagle和TCP延时确认两种算法有时会造成进程死锁,影响微服务间的通讯。
Thompson推荐通过TCP_NODELAY来禁用Nagle算法,不再限制小包的发送,这样做的话每秒可多处理5-500个请求。
4 通信同步问题
做过网页前端的同学对这个问题应该比较了解。浏览器访问网页时,速度可能会很慢,而再好再贵的服务器也解决不了这个问题,因为用户还是有可能用2G的手机网络来访问你的网站。
但是还是有一些办法可以尽量让网页加载速度快一点。比如优化图片的大小,让不同分辨率的屏幕加载不同大小的图片,优化脚本加载顺序,以及尽量采用异步加载等等。
3 数据编码问题
有些程序员喜欢用JSON,XML,或Base64等编码格式来传送数据,因为这样数据更具有可读性,在debug的时候非常方便。
但是,系统间的交互是不需要可读性的。将二进制的数据转换成文本再转换成二进制不仅消耗CPU,还消耗网络带宽。
其实,你可以用Wireshark来debug服务器通信,或者使用ProtoBuffer,Thrift等工具库来优化通信过程。
2 函数设计问题
在保证代码的易读性的同时,再提高代码的性能可能会比较困难。但你总得做出取舍,或者多花点时间来好好设计。
有很多技巧可以在避免一些常见性能问题的同时,不会过多牺牲代码的可读性。比如,用C++语言写函数参数时,可以考虑使用引用或指针类型,这样可以避免在函数内生成临时的数据结构,而且不用返回数据。对于大部分语言来说,函数返回Iterable就比直接返回Array要好,而且不影响易读性。
1 日志问题
很惊讶吧,No. 1性能问题竟然是日志带来的问题!对于大多数日志系统来说,随着进程数量的增加,记录日志所需要的时间也会线性增加。在进程数量达到8个时,日志记录时间大约为0.15s,非常影响系统的响应速度。所以说,日志是一个比较重要的性能瓶颈,而且常常被人忽视。
为了解决这个问题,我们可以使用异步logger,同时小心设计logger所记录数据的结构,以便进行后续的读取和处理。
另外,logger重复记录同一个错误是非常浪费性能的,我们可以将它设置为只记录第一次错误,然后设置一个计数器来记录错误发生的次数。
语音:Mia
原作者:Abel Avram@InfoQ
声明:本文内容来源自网络,文字、图片等素材版权属于原作者,平台转载素材出于传递更多信息,文章内容仅供参考与学习,切勿作为商业目的使用。如果侵害了您的合法权益,请您及时与我们联系,我们会在第一时间进行处理!我们尊重版权,也致力于保护版权,站搜网感谢您的分享!