高并发Java岗(中间件、网关、RPC)必问。看你懂不懂Netty为啥存在。
一连接一线程:1万连接=1万线程×约1MB栈=10GB。上下文切换主导开销。
NIO Selector:一个线程通过内核多路复用(Linux epoll)盯N个socket。非阻塞。
Netty reactor:boss EventLoop接受连接,worker EventLoop组处理IO。每个EventLoop单线程串行处理它的channel——handler内无需加锁。
EventLoop保证:一个channel始终由同一个EventLoop处理,channel状态线程私有。
阻塞操作(DB、文件IO)必须下EventLoop——用EventExecutorGroup或业务线程池卸载,否则把那个EventLoop的所有channel都卡住。
一连接一线程是2000年代服务器贵的原因——1万连接×1MB栈=光线程栈10GB,OS调度被上下文切换拖垮。NIO的Selector让一个线程通过epoll/kqueue盯多个socket。Netty在其上建reactor:boss EventLoop负责accept()、worker EventLoop池每个接一批channel处理IO。每个EventLoop单线程——某channel的所有事件在同一个线程串行跑,handler里不用锁。也是footgun:handler里任何阻塞调用(同步JDBC、磁盘IO、Thread.sleep)会把那个EventLoop上所有channel都停住。规则:handler保持非阻塞;阻塞的丢给专门EventExecutorGroup。Netty就是单JVM能扛几万活连接的原因;用对能扩到thread-per-request扩不到的规模。
channel handler里绝不做JDBC。见过炸生产太多次了。
EventLoop数默认2×CPU核——对CPU轻的IO活合适。
即答侠把Netty跟具体故障模式绑(EventLoop被阻、反压)——答起来像从事故里学的。
Loom让"每请求一线程"没有内存成本,缩小了Netty一项用途。但Netty的非阻塞pipeline和反压模型在协议处理和超高连接数上仍然领先。
事件穿过的有序ChannelHandler链——像中间件链。入站和出站事件反向流动。