当前位置: 首页 > 科技观察

线上系统没有做性能优化,所以会爆炸...

时间:2023-03-21 18:21:43 科技观察

[.com原稿]前几天和一个互联网主题旅游网站的架构师聊性能优化的话题.关于在线调优的一些困惑,希望大家共同探讨。图片来自Pexels。他告诉我,他们公司的系统从未针对性能进行过调整。功能测试完成后上线,上线没有性能问题。为什么需要调整它?它充满信心。无知者无畏;不怕给公司埋地雷,到时候追究责任?到了某个临界点,说爆就爆,到时候就耗尽了。于是我回复他,“我去,如果你们公司运营的是淘宝、京东、12306这样的网站,没有系统性能优化就上线了,你试试看。”今天,我们就开始聊这个话题,希望能和大家一起厘清这些问题:为什么要做性能调优?我们什么时候开始做?有没有性能调优的标准?为什么我们需要做性能调优?调整?在互联网项目的开发中,总是根据新的需求开发新的系统,很多系统的设计是可以绕过的。在系统架构设计中,我们必须遵循一些原则:海恩定律:事故的发生是体量(并发量、数据量、服务量……)积累的结果。在实际操作层面不能替代人自身的素质和责任感。墨菲定律:没有什么事情像看起来那么简单。一切都将花费比你预期更长的时间。可能出错的事情总会出错。如果你担心某事发生,它就更有可能发生。这些原则告诫我们,在互联网公司,对于生产环境中出现的任何怪异现象和问题,都不能轻易忽视,一定要彻查背后的原因。同样,海恩定律也强调,任何严重事故的背后,都是许多小问题的积累,积累到一定程度就会发生质的变化,严重的问题就会浮出水面。然后,我们需要对在线服务的任何症状进行追根溯源,哪怕是一个小问题。这就要求我们要有攻坚克难的能力,对任何现象都要坚持以下原则:为什么会发生?如何处理?如何恢复?如果一个在线产品没有通过性能测试,它就像一颗定时炸弹。你不知道它什么时候会出问题,你也不知道它能承受的极限在哪里。性能测试的目的是验证软件系统是否能够满足用户提出的性能指标,同时发现软件系统中的性能瓶颈,从而对软件进行优化。有些性能问题是随着时间慢慢积累的,一定时间后自然会爆发;更多的性能问题是由于访问量的波动引起的,例如活动增加或公司产品的用户数量增加。当然,也有可能一个产品上线后半死不活,没有大量访问量,所以这个定时炸弹还没有被触发。现在假设你的系统要搞一个促销活动,产品经理或者老板跟你说预计会有几十万,几百万,甚至更多的用户访问量,问系统能不能承受这个活动的压力.如果不知道自己系统的性能,只能战战兢兢的回答老板,说不定就没什么问题。所以,做不做性能调优,这个问题其实很好回答。所有的系统开发出来之后,或多或少都会出现性能问题。我们首先要做的是想办法把问题暴露出来,比如压力测试,模拟可能的运行场景等等,然后通过性能调优来解决。问题。良好的系统性能调优不仅可以提升系统性能,还可以为公司节约资源,实现降本增效。这也是我们进行性能调优最直接的目的。我们什么时候开始介入调音的?解决了为什么要进行性能优化的问题之后,又出现了一个新的问题:如果我们需要对系统做一个全面的性能监控和优化,那么应该从什么时候开始介入性能调优呢?是的,是不是越早介入越好?其实在项目开发的初期,我们不需要过多关注性能优化,那样会让我们对性能优化产生厌倦。不仅不会提升系统性能,还会影响开发进度。甚至适得其反,给系统带来新的问题。我们只需要在代码层面保证有效的编码,同时在架构层面进行设计。具体的架构设计可以参考以下行之有效的规则:①系统架构设计,如何在架构层面减少不必要的处理(网络请求、数据库操作等),例如:使用Cache减少IO次数,使用异步来提高单服务吞吐量,使用无锁数据结构减少响应时间。②网络拓扑优化减少网络请求时间,如何设计拓扑,如何实现分布式?③系统代码层面的代码优化,用什么设计模式起作用?哪些类需要使用单例,哪些需要尽量减少新操作?④如何提高代码层面的运行效率,如何选择合适的数据结构进行数据访问?如何设计合适的算法?⑤任务执行层级的同步和异步操作,哪里用同步,哪里用异步?⑥JVM调优,Heap、Stack、Eden大小如何设置,GC策略如何选择,FullGC的频率如何控制?⑦服务器调优(线程池、等待队列)。⑧数据库优化减少查询修改时间。数据库的选择?数据库引擎的选择?数据库表结构设计?数据库索引、触发器等的设计?是否使用读写分离?内存缓存?如何设计缓存机制?⑩数据通信问题,如何选择通信方式?使用TCP还是UDP,使用长连接还是短连接?蔚来还是生物?Netty、mina还是本机套接字??操作系统选择,用winserver还是linux?还是Unix??硬件配置?是8G内存还是32G,网卡10G还是1G?比如:增加CPU核心数比如32核,升级更好的网卡比如10G,升级更好的硬盘比如SSD,扩展硬盘容量比如2T,扩展后的系统内存比如128G。系统编码完成后,我们就可以对系统进行性能测试了。这时候产品经理一般会提供线上预期数据,我们会在提供的参考平台上进行压力测试,使用性能分析和统计工具统计各项性能指标是否在预期范围内。项目上线成功后,我们还需要根据线上的实际情况,根据日志监控和性能统计日志,观察系统性能问题。一旦发现问题,我们需要分析日志,及时修复问题。在我们进行调优之前,我们必须对性能指标有一定的了解,否则我们的调优就像是空中楼阁,没有任何参考依据,是不可能实现调优的。在了解性能指标之前,我们先了解一下哪些计算机资源会成为系统的性能瓶颈。这些你应该很清楚。系统上线后无非是CPU、内存、磁盘、网络等问题。CPU:一些应用程序需要大量的计算,会长时间不间断地占用CPU资源,导致其他资源无法竞争CPU,响应缓慢,导致系统性能出现问题。例如代码递归导致的死循环、正则表达式导致的回溯、JVM频繁的FULLGC、多线程编程导致的大量上下文切换等,都可能导致CPU资源繁忙。大量线程抢占CPU资源,导致CPU使用率升高:CPU使用率排查:内存:Java程序一般通过JVM来分配和管理内存,主要是利用JVM中的堆内存来存放Java创建的对象。系统堆内存的读写速度很快,所以基本没有读写性能瓶颈。但是,由于内存的成本高于磁盘,因此内存的存储空间相对于磁盘来说非常有限。因此,当内存空间满了,对象无法回收时,就会出现内存溢出、内存泄漏等问题。磁盘I/O:与内存相比,磁盘的存储空间要大得多,但是磁盘I/O读写的速度要比内存慢。目前推出的SSD虽然已经进行了优化,但仍然无法与内存相提并论。读写速度相提并论。网络:网络在系统性能方面也起着至关重要的作用。如果你购买过云服务,那么一定经历过选择网络带宽大小的环节。如果带宽太低,网络很容易成为传输数据量比较大或者并发量比较大的系统的性能瓶颈。Exception:在Java应用程序中,抛出异常需要构建一个异常栈来捕获和处理异常。这个过程消耗了大量的系统性能。如果在高并发下抛出异常,继续异常处理,将对系统的性能造成很大的影响。数据库:大部分系统都使用数据库,数据库操作往往涉及磁盘I/O读写。大量的数据库读写操作会造成磁盘I/O性能瓶颈,进而导致数据库操作延迟。对于有大量数据库读写操作的系统,数据库性能优化是整个系统的核心。锁竞争:在并发编程中,我们经常需要多个线程共享同一个资源进行读写操作。这时候,为了保持数据的原子性(即保证共享资源不被其他线程修改写入),我们就会用到锁。锁的使用可能会引入上下文切换,这会给系统带来性能开销。JDK1.6之后,为了减少锁竞争带来的上下文切换,Java对JVM内部的锁进行了多次优化,例如加入偏向锁、自旋锁、轻量级锁、锁粗化、锁淘汰等待等。如何合理使用锁资源,优化锁资源,需要你了解更多的操作系统知识,Java多线程编程基础,积累项目经验,结合实际场景处理相关问题。了解了以上基本内容后,我们可以得到以下衡量通用系统性能的指标。响应时间响应时间是衡量系统性能的重要指标之一。响应时间越短,性能越好。通常,接口的响应时间在毫秒级。在系统中,我们可以将响应时间从下到上细分为以下几种类型:数据库响应时间:数据库操作所消耗的时间往往是整个请求链中最耗时的。服务器响应时间:服务器包括Nginx分发请求消耗的时间和服务器程序执行消耗的时间。网络响应时间:这是网络硬件在网络传输过程中解析传输的请求和其他操作所花费的时间。客户端响应时间:对于普通的web和app客户端来说,消耗的时间可以忽略不计,但是如果你的客户端嵌入了大量的逻辑处理,那么消耗的时间可能会变得更长,从而成为系统的瓶颈。吞吐量在测试中,我们往往更关注系统接口的TPS(transactionspersecond),因为TPS反映了接口的性能,TPS越大,性能越好。在系统中,我们还可以将吞吐量从下到上分为两种:磁盘吞吐量网络吞吐量我们先来看磁盘吞吐量。磁盘性能有两个关键指标:一个是IOPS(Input/OutputPerSecond),即每秒的输入输出量(或者说读写次数),指的是每秒的I/O请求数系统可以处理单位时间。I/O请求通常是读写数据操作请求,注意的是随机读写性能。适用于频繁随机读写的应用。另一个是数据吞吐量,指的是单位时间内可以成功传输的数据量。对于大量顺序读写的应用,传输大量的连续数据。接下来看网络吞吐量,它是指设备在网络传输过程中不丢帧的情况下可以接受的最大数据速率。网络吞吐量不仅与带宽有关,还与CPU、网卡、防火墙、外部接口和I/O的处理能力密切相关。吞吐量主要由网卡的处理能力、内部程序算法和带宽决定。计算机资源分配使用情况通常用CPU使用率、内存使用率、磁盘I/O、网络I/O来表示资源使用情况。这些参数就像一个木桶。如果其中任何一个板子出现短板,或者任何一个项目分配不合理,对整个系统性能的影响将是毁灭性的。负载承受能力当系统压力升高时,可以观察系统响应时间的上升曲线是否平滑。该指标可以直观地反馈系统所能承受的负载压力极限。例如,当你对系统进行压力测试时,系统的响应时间会随着系统并发数的增加而增加,直到系统无法处理这么多请求并抛出大量错误,它就会达到极限。作者:飞机哥简介:目前在58研发中心担任高级架构师,负责消息中间件的设计和实施以及全链路压测。前阿里巴巴消息中间件高级研发、架构师。擅长Java编程,对主流中间件RocketMQ、Dubbo、ElasticJob、Netty、Sentienl、Mybatis、Mycat等中间件有深入研究。编辑:陶佳龙征稿:如有意投稿或寻求报道,请联系编辑微信:gordonlonglong【原创稿件,合作网站转载请注明原作者和出处为.com】