1 设计要点解析
1.1 线程模型
此部分内容主要介绍蚂蚁为什么选择Netty4作为基础网络编程框架,来源于蚂蚁技术团队发布的一篇文章:
文章名称为:蚂蚁通信框架实践;
链接地址为:https://mp.weixin.qq.com/s/JRsbK1Un2av9GKmJ8DK7IQ?
此处引用该文章的内容,主要是想让大家更好的理解SOFA Bolt设计过程中所考虑的关键点,以便大家在实现自己的私有通信协议时,更加全面的考虑问题。
本文对原文作了一些修改,以更详细的说明SOFA Bolt实现过程中一些细节。
蚂蚁的中间件产品,主要是 Java 语言开发,如果通信产品直接用原生的 Java NIO 接口开发,工作量相当庞大。通常我们会选择一些基础网络编程框架,而在基础网络通信框架上,我们也经历了自研、基于Apache Mina实现。最终,由于 Netty 在网络编程领域的出色表现,我们逐步切换到了 Netty 上。
Netty 在 2008 年就发布了3.0.0 版本,到现在已经经历了 10 年多的发展。而且从 4.x 之后的版本,把无锁化的设计理念放在第一位,然后针对内存分配,高效的 Queue队列,高吞吐的超时机制等,做了各种细节优化。同时 Netty 的核心 Committer 与社区非常活跃,如果发现了缺陷能够及时得到修复。所有这些,使得Netty 性能非常的出色和稳定,成为当下 Java 领域最优秀的网络通信组件。
SOFA Bolt采用Netty4作为底层的网络通信组件,并对其进行了优化和扩展。所以,我们先看一下Netty4的线程模型,如下图所示:

本文没有采用原文的Netty4的线程模型图,而是采用自己以前绘制的Netty4线程模型图,突出了一些关键的细节,并根据SOFA Bolt实现,做了一些修改。
Netty4线程模型有几个关键点:
1. Reactor模型;
2. 串行化处理;
3. 业务线程池;
1.1.1 Reactor模型
Netty4采用Reactor模式。
Reactor模式是基于事件驱动的并发处理模型,将业务组织成各种事件驱动的对象。
Reactor模式主要用来处理来自于一个或多个客户端的并发服务请求。
Reactor模式主要是提高系统的吞吐量,在有限的资源下处理更多的事情。

RpcServer基于Netty4的ServerBootstrap实现了SOFA Bolt服务器端,其主要源码如下:
1. public class RpcServer extendsRemotingServer {
2.
3. ……略
4. /** server bootstrap */
5. privateServerBootstrap bootstrap;
6.
7. /** channelFuture */
8. private ChannelFuture channelFuture;
9.
10. /** global switch */
11. private GlobalSwitch globalSwitch = newGlobalSwitch();
12.
13. /** connection event handler */
14. private ConnectionEventHandler connectionEventHandler;
15.
16. /** connection event listener */
17. private ConnectionEventListener connectionEventListener =new ConnectionEventListener();
18.
19. /** user processors of rpc server */
20. private ConcurrentHashMap<String,UserProcessor<?>> userProcessors = new ConcurrentHashMap<String,UserProcessor<?>>(4);
21.
22. /** boss event loop group*/
23. private final EventLoopGroup bossGroup = new NioEventLoopGroup(1, newNamedThreadFactory("Rpc-netty-server-boss"));
24.
25. /** worker event loop group. Reuse I/Oworker threads between rpc servers. */
26. private final static NioEventLoopGroup workerGroup = newNioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2, new NamedThreadFactory("Rpc-netty-server-worker"));
27.
28. /** address parser to get custom args */
29. private RemotingAddressParser addressParser;
30.
31. /** connection manager */
32. private DefaultConnectionManager connectionManager;
33.
34. /** rpc remoting */
35. protected RpcRemoting rpcRemoting;
36.
37. static {
38. workerGroup.setIoRatio(SystemProperties.netty_io_ratio());
39. }
40.
41. /**
42. * Construct a rpc server. <br>
43. */
44. public RpcServer(int port) {
45. super(port);
46. }
47.
48. /**
49. * Construct a rpc server. <br>
50. */
51. public RpcServer(int port, booleanmanageConnection) {
52. this(port);
53. /** server connection managementfeature enabled or not, default value false, means disabled. */
54. if (manageConnection) {
55. this.globalSwitch.turnOn(GlobalSwitch.SERVER_MANAGE_CONNECTION_SWITCH);
56. }
57. }
58.
59. /**
60. * Construct a rpc server. <br>
61. */
62. public RpcServer(int port, booleanmanageConnection, boolean syncStop) {
63. this(port, manageConnection);
64. if (syncStop) {
65. this.globalSwitch.turnOn(GlobalSwitch.SERVER_SYNC_STOP);
66. }
67. }
68.
69. @Override
70. protected void doInit() {
71. if (this.addressParser == null) {
72. this.addressParser = newRpcAddressParser();
73. }
74. initRpcRemoting(null);
75. this.bootstrap = new ServerBootstrap();
76. this.bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
77. .option(ChannelOption.SO_BACKLOG,SystemProperties.tcp_so_backlog())
78. .option(ChannelOption.SO_REUSEADDR,SystemProperties.tcp_so_reuseaddr())
79. .childOption(ChannelOption.TCP_NODELAY,SystemProperties.tcp_nodelay())
80. .childOption(ChannelOption.SO_KEEPALIVE,SystemProperties.tcp_so_keepalive());
81.
82. // set write buffer water mark
83. initWriteBufferWaterMark();
84.
85. boolean pooledBuffer =SystemProperties.netty_buffer_pooled();
86. if (pooledBuffer) {
87. this.bootstrap.option(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT)
88. .childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT);
89. }
90.
91.