RocketMQ是如何基于Netty扩展出高性能网络通信架构的
Reactor主线程与长短连接
首先作为Broker而言,它会有一个Reactor主线程(可以先不管它是啥,只要这么一个线程即可),这个线程负载监听一个网络端口,比如监听2888,39150这样的端口。
短连接:建立连接 ->发送请求->接收响应->断开链接,下次发送请求的是还得来一遍。
长连接:建立连接 -> 发送请求 -> 接受响应 ->发送请求 ->接受响应-----知道主动断开为止。
TCP长连接就是:按照TCP协议建立的长连接。
Producer和Broker建立一个长连接
比如Producer要和Broker建立一个长连接,此时Broker上的这个Reactor主线程,会在端口上监听到这个Producer建立连接的请求。那么在Broker里用什么东西和Producer之间建立长连接呢,那就是SocketChannel.Producer里面会有一个SocketChannel,Broker里也会有一个SocketChannel,这两个SocketChannel就代表了他们两建立好的这个长连接。
基于Reactor线程池监听连接中的请求
Producer和Broker通过SocketChannel只是单单建立了长连接,从Producer的SocketChannel发送消息到Broker的SocketChannel想想是不是在Broker中还得有线程来负责这些消息的处理,所以,就引入了Reactor线程池,这个线程池默认3个线程,Reactor主线程建立好的每个连接SocketChannel,都会交给这个Reactor线程池里其中一个线程去监听请求。
image.png
基于Worker线程池完成一系列准备工作
接着Reactor线程池从SocketChannel中读取一个请求,这个请求在正式进行处理之前,必须先要进行一些准备工作和预处理,比如SSL加密验证,编码解码,连接空闲检查,网络连接管理,等这些事情。那么问题就来了,这些事让谁来干呢,此时又得引入一个概念,就是Worker线程池,它默认有8个线程,Reactor线程池中的线程收到的请求会交给Worker线程池中的线程去进行处理,完成上面的SSL加密验证,编码解码等一系列的准备工作。
image.png
基于业务线程池完成请求的处理
上面的Worker线程完成一系列的预处理工作之后,接下来就得开始干之前文章中提到的Broker数据存储的工作了,比如写入CommitLog文件,还有ConsumeQueue文件等这些业务逻辑处理,这个时候,就得继续把经过一系列预处理完的数据交给业务线程池去处理。比如拿发送消息请求来说,就会把这个请求转交给SendMessage线程池,所以在部署集群的时候,我们可以适当的调大一些该线程池的值,来提高吞吐量。
为什么这套网络通信框架会是高性能高并发的
一个线程每秒能处理多少个请求,那肯定是有限的,所以就搞了一个Reactor主线程专门负责和Producer和Consume之类的建立连接,一旦连接建立好之后,大量的长连接就均匀的交给Reactor线程池里的多个线程。每个Reactor线程监听一部分的连接请求,**这里也是个优化点,就是可以使用多线程并发的监听不同连接请求,来提高并发处理能力,提升网络框架的并发能力。接着后续使用Worker线程来对大量的请求进行预处理,当Worker线程池预处理多个请求的时候,Reactor线程还是可以继续监听和接受大量连接请求是否可以到达。而且最终读写磁盘文件之类的操作都是交给业务线程来处理的,当并发执行多个请求的磁盘读写操作时,也不会影响其他线程池的接受请求,请求预处理等。
最终:Reactor主线程在端口上监听Producer建立连接的请求,建立长连接。
Reactor线程池并发的监听多个连接的请求是否到达。
Worker请求并发的对多个请求进行预处理。
业务线程池并发的对多个请求进行磁盘的读写操作。