ARTICLE · 1113458
Tomcat9源码剖析(三):性能优化的底层逻辑
Tomcat9源码剖析(三):性能优化的底层逻辑
Tomcat9源码剖析(三):性能优化的底层逻辑
很多人说Tomcat快,但很少有人说得清它到底快在哪。其实它赢就赢在把“不该做的事”几乎全省了。
少做:连接空闲时不扫全表查超时,事件处理完就不重复解析。
换个做法:不创建对象、不重复拷贝,不让两个线程抢同一个socket。
分离IO等待与计算,靠select和processSocket分开,把内存和上下文切换的代价从“连接数”降到“活跃数”。
消灭高频路径上的对象分配。方法名和URI直接用字节切片,头部字段延迟转换,Poller和Processor用完放回池子复用。这直接拉高了吞吐量上限,压测时看GC次数最直观。
减少系统调用和内存拷贝。静态文件走sendfile零拷贝,响应头和响应体批量写出去。Poller和Acceptor之间靠CAS操作,一次判断要不要唤醒、要不要阻塞。
消除锁竞争。每个连接的状态只在当前线程手里改,Poller派发前先摘掉就绪位,保证同一时刻只有一个线程碰这个socket。
避免无效工作。比如Acceptor分三档sleep,暂停时间短就紧循环,长才睡10ms,绝不空转烧CPU。
不过这些优化都在互相牵制。合并写可能增加延迟,对象池有状态残留风险,所有权转移一旦出错就会有两个线程同时碰一个socket。
真要调优,得先找准瓶颈。网上那些把pollerThreadCount调到CPU核数的教程,在9.0.122上根本没用——这方法已经是空的了。
原文Tomcat 9 源码剖析(三):性能优化的底层实现逻辑
河南,51分钟前,