近期大量业务激增的微服务性能优化总结-4.增加对同步微服务的HTTP请求等待队列的监控核心业务接口遇到的性能瓶颈不是一个单一的问题,而是几个问题的组合:我们解决了一个之后发到网上,然后发现还有另一个性能瓶颈。这也是由于我经验不足,导致我没能一下子定位解决;而我对整个后台团队有着顽固的自尊心,不想通过大量的横向扩张来熬过压力的巅峰,导致连续几个晚上在线出现分歧度的问题肯定会对我们的业务增长产生影响。这也是我不成熟,不得不反思的地方。本系列文章主要记录我们的后台微服务系统针对本次业务增长的一般技术优化,业务流程和缓存的优化只适用于我们的业务,这里不再赘述。本系列将分为以下几个部分:改进客户端负载均衡算法开发日志输出异常栈过滤插件改进x86云环境异步日志等待策略增加同步微服务HTTP请求等待队列的监控并部署在云端。注意实例网络流量达到上限导致请求响应变慢对系统关键业务增加必要的侵入式监控增加对同步微服务HTTP请求等待队列的监控微服务,基于spring-webmvc的同步微服务做没有很好地处理客户端的请求超时配置。当客户端请求超时时,客户端会直接返回超时异常,但是调用的服务端任务在基于spring-webmvc的同步微服务中不会被取消,但是基于spring-webflux的异步微服务会被取消。目前,在同步环境下,没有很好的方法来取消已经超时的任务。我们基于spring-webmvc的同步微服务,HTTP容器使用Undertow。在spring-boot环境下,我们可以配置处理HTTP请求的线程池大小:server:undertow:#下面的配置会影响buffers,buffer会用于连接到server的IO操作#如果每次都需要ByteBuffer应用中,堆内存的ByteBuffer需要经过JVM内存分配过程(TLAB->heap),直接内存需要经过系统调用,效率很低。#所以一般都会引入内存池。在这种情况下,它是“BufferPool”。#目前UnderTow中只有一个`DefaultByteBufferPool`,其他实现暂时无用。#这个DefaultByteBufferPool相对于netty的ByteBufArena来说非常简单,类似于JVMTLAB的机制#对于bufferSize,最好和你系统的TCPSocketBuffer配置一样#`/proc/sys/net/ipv4/tcp_rmem`(forread)#`/proc/sys/net/ipv4/tcp_wmem`(forwriting)#当内存大于128MB时,bufferSize为16KB减去20字节,用于协议头buffer-size:16364#是否分配directmemory(NIO直接分配的堆外内存),这里开启,所以java启动参数需要配置directmemory大小,减少不必要的GC#当内存大于128MB时,默认为使用directmemorydirectBuffers:truethreads:#设置IO线程数,主要执行非阻塞任务,它们会负责多个连接,默认设置是每个CPU核心1个读线程和1个写线程io:4#阻塞任务线程池,当执行类似servlet请求阻塞IO操作时,undertow会从这个线程池中获取线程#其值设置取决于系统线程执行任务的阻塞系数,默认值为IO线程数*8worker:128后面的线程池是jboss的线程池:org.jboss.threads.EnhancedQueueExecutor,spring-boot目前无法通过配置修改这个线程池的队列大小,默认的队列大小是Integer.MAX我们需要监控这个线程池的队列大小,并针对这个指标做一些操作:当任务数不断增加时,说明此时请求处理跟不上传入的请求,需要报警。当累积到一定数量时,需要暂时将实例从注册中心移除并扩容。队列消费完后,重新上线。如果一定时间后仍未消费完毕,则会重启实例。添加同步微服务HTTP请求等待队列监控好在org.jboss.threads.EnhancedQueueExecutor本身通过JMX暴露了HTTPservlet请求的线程池的各种指标:在我们的项目中,我们使用两种监控:prometheus+grafana微服务指标监控,主要用于告警,快速定位问题根源。JFR监控,主要用于详细定位单例问题。对于HTTP请求等待队列监控,我们应该通过prometheus接口暴露给grafana,收集指标,完善响应操作。暴露prometheus接口指标的代码是:@Log4j2@Configuration(proxyBeanMethods=false)//需要在引入prometheus时加载,actuator暴露prometheus端口@ConditionalOnEnabledMetricsExport("prometheus")publicclassUndertowXNIOConfiguration{@AutowiredprivateObjectProvider
