不管是对HTTP接口、Thrift接口或者Web Service接口进行压测,发起测试的机器都要尽量靠近被压测的应用服务器,这样才能获得更准确的压测结果(有效减小网络传输开销带来的干扰)git
排除非业务因素影响:压测前先确认硬件(CPU、内存、IO、网络等)、被压测接口用到的中间件(Tomcat、Nginx、Redis、RabbitMQ等)的配置信息和健康情况。若是存在硬件故障或者中间件故障,则须要先排除掉github
肯定压测目标,好比是压测tps、内存消耗量仍是其余如要能支持多少并发用户,达到多少tpsapache
肯定一个压测基准,好比压测某个HTTP API接口的tps时,能够先压测心跳检测接口(业务逻辑最少),好比压测获得5000tps,那么就能够判定其余业务逻辑更复杂的HTTP API接口的极限tps不可能超过5000tps,不管你怎么优化(这里的优化特指业务性能优化,若是中间件优化了,则须要从新肯定压测基准)后端
压测前最好用ping、traceroute查看下网络连通情况tomcat
通常先对单台服务器作压测,单台服务器压测达到指望的压测指标后再扩展到集群环境对多台服务器作压测性能优化
压测服务器尽量和线上服务器一致或者相似,确认发起测试的服务器自己不存在性能瓶颈(好比还没开始压测,发起测试的机器CPU就已经100%、测试机器在建立多一些线程的时候CPU增加很快)服务器
尽量复制或者模拟真实流量来作压测。好比在压测HTTP API接口时,若是后端作了Cache,通常第一次请求会Cache Miss,但后续请求都会Cache Hit,因此重复请求同一个url来压测可能会获得错误的“乐观结果”。推荐用tcpcopy来复制线上真实流量(tcpcopy)网络
压测时先用少许并发用户、少许总请求数,而后逐渐增大并发用户数、总请求数。同时查看系统业务日志、系统负载状况(top)、系统资源消耗变化状况(vmstat)、GC状况和出错率等session
压测时间尽量越长越好,以便观察系统在一段较长时间内的稳定性(之前遇到过系统固定跑一天就崩溃的状况)多线程
压测HTTP接口时,须要确认Nginx是否开启gzip压缩(若是响应数据包挺大时开启gzip压缩与否对结果影响挺大)、KeepAlive开启状态、HTTP Cache开启状态等
压测时获取到的应用内部运行信息越详细越好,好比Tomcat链接池、Thrift客户端链接池、Thfift服务端链接池的运行状态,一个请求各环节的执行时间(日志埋点)
压测前须要想清楚整个系统从前到后的拓扑结构图,能够在纸上画下来
若是应用自己每次请求都会调用第三方服务接口,那么先对第三方服务接口作压测,先确认第三方服务接口不存在性能问题
检查硬件和中间件配置信息和运行健康情况,好比Tomcat最大链接数设置是否合理、Nginx配置是否合理等,确保它们不会影响压测结果
肯定压测目标,好比“压测某HTTP接口的极限,要求1000并发用户下单台tomcat能达到5000tps”
部署应用到压测服务器,准备好发起测试的服务器(若是能和压测服务器同样最好,不能同样至少也要作到在同一个局域网内),而后用ping、traceroute查看下网络连通情况
肯定压测基准,好比获取心跳检测请求的极限tps
构造尽量接近真实用户访问状况的测试数据,好比用tcpcopy复制线上真实流量
逐渐增大并发量和总请求数,观察系统层面的各项 指标和应用运行情况,采用的工具通常是ab、jmeter、loadrunner等
有时候可能须要长时间让系统高负载运行,好比观察系统长时间处于高负载状况下是否会出现GC故障
不要迷信“推荐配置”,须要根据实际状况调整配置。好比如今咱们Thrift服务的selector线程数推荐值为2,worker线程数推荐值为10,然而对平均执行时间10ms左右的Thrift接口作压测时发现大量请求被阻塞,而当调整selector线程数为20、worker线程数为100后发现阻塞状况显著减轻
压测时一切判断必须基于真实测量数据,不能想固然。好比认为某个环节的逻辑不多,而后武断地认为性能瓶颈确定不会出在那个环节,而后就忽略测量这个环节的耗时
可能不止一个环节存在性能瓶颈,好比某个请求会流经A => B => C => D四个环节,通过测量发现当前性能瓶颈存在于B环节(好比80%的时间都消耗在B环节),而后通过努力终于把环节B的耗时降下来了,也许你会发现吞吐量和平均响应时间仍是上不去而且再测量后发现如今性能瓶颈又变成C了。缘由是:实际上B和C两个环节都存在性能问题,只不过未对B环节调优以前,大部分请求流量都堵塞在B环节,致使到达C环节的请求流量压力很是小,因此C环节的性能问题也就凸显不出来了;而当排除B环节的性能问题后,C环节单位时间内接收到的流量剧增,天然而然C环节的性能问题就暴露出来了。也正所以,对于复杂的业务流程,压力测试很难作到一蹴而就,须要逐一排查突破
尽量自动化获取各个环节的性能数据。若是能经过一个集成的监控系统直观地观察到各个环节的耗时,那么对于诊断整个系统的性能瓶颈将很是有帮助(当你尝试过手动插入执行时间记录日志并收集分析后就能切身体会这点了)。同时监控系统也将为提高系统稳定性和可用性提供一大保障
即便你依赖的一个服务号称能达到tps多少多少,号称性能有多快多快,也有必要先弄清楚它的压测场景(用多少数据测的、并发用户多少、总请求多少、测试请求数据是什么样的、可否复现)。确认没问题后还要再检查本身的压测设置有没有问题,好比一个高性能HTTP接口也可能由于你的网络环境或者HTTP客户端链接池大小设置不当、超时时间设置不当等缘由而测不出你预期的性能
高并发场景若是使用log4j(假如采用默认配置)打印大量日志,会对系统吞吐量形成巨大影响,由于默认log4j写日志是同步写,多线程并发写日志时会等待一个同步锁,以下:
/* * org.apache.log4j.Category.callAppenders */ public void callAppenders(LoggingEvent event) { int writes = 0; for(Category c = this; c != null; c=c.parent) { // Protected against simultaneous call to addAppender, removeAppender,... synchronized(c) { if(c.aai != null) { writes += c.aai.appendLoopOnAppenders(event); } if(!c.additive) { break; } } } if(writes == 0) { repository.emitNoAppenderWarning(this); } }
推荐使用logback替换log4j,或者采用异步写日志并调大log buffer size