聊聊jetty的线程模型

Acceptor

监听

每个acceptor绑定一个ServerSocketChannel通道

  1. ServerConnector由其管理容器启动start
  2. 打开连接:打开ServerSocketChannel通道,并配置accept通道(_acceptChannel)为阻塞模式,绑定地址端口
  3. 构建org.eclipse.jetty.server.AbstractConnector.Acceptor并提交至线程池执行启动,如果通道已打开,阻塞在accept接受客户端请求,等待数据,线程池中异步执行
  4. 如果存在多个Acceptors则配置accept通道(_acceptChannel=ServerSocketChannel)为非阻塞模式
  5. 选择器管理器提交org.eclipse.jetty.io.ManagedSelector.Acceptor(绑定SocketChannel、attachment为null)至队列并唤醒选择器通知选择器存在更新选择器更新
  • 选择器生产者自旋阻塞在java.nio.channels.Selector#select()等待唤醒并处理更新
  • 处理选择器更新,回调选择器更新实例的org.eclipse.jetty.io.ManagedSelector.Acceptor#update方法,将SelectableChannel(accept通道(_acceptChannel=ServerSocketChannel))注册至选择器Selector

数据到达服务端

客户端数据到达服务端,阻塞唤醒

  1. 服务端接收到数据唤醒accept阻塞
  2. 配置SocketChannel通道为非阻塞模式
  3. 选择器管理器提交org.eclipse.jetty.io.ManagedSelector.Accept(绑定SocketChannel、attachment为null)至队列并唤醒选择器通知选择器存在更新选择器更新
  4. 选择器生产者自旋阻塞在java.nio.channels.Selector#select()等待唤醒并处理更新
  5. 处理选择器更新,回调选择器更新实例的org.eclipse.jetty.io.ManagedSelector.Accept#update方法,将SelectableChannel(与客户端建立的数据通道SocketChannel)注册至选择器Selector

jetty线程模型

1

总结

Acceptor可以理解为NIO的:java.nio.channels.ServerSocketChannel
Selector可以理解为NIO的:java.nio.channels.Selector

优点

架构设计的优点很明显,并发扩展能力很强大,可以支持多个Connector的垂直向扩展,由于使用了多路复用IO,每个Selector可以监听多个Channel,进一步提升了框架的并发能力

缺点

线程模型较为单调,对于多个Connector其实可以理解为多个租户,如果对多个租户做到线程池的资源隔离的话个人感觉效果会更好。不过其实也还好,算是鸡蛋里挑骨头了,毕竟多Connector的场景以及多租户的场景可以通过水平方向的扩展+DNS路由来弥补