SOFA BOLT源码解析之设计要点-线程模型

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.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任性之闲来无事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值