当前位置: 移动技术网 > IT编程>软件设计>架构 > netty框架概述

netty框架概述

2019年06月21日  | 移动技术网IT编程  | 我要评论
概述 最近在学习netty的相关知识,也在看netty的源码,光看不练假把式,所以也正好利用自己学习的机会写几篇netty的分析文章,主要还是一些源码解析的文章,一方面有输出会促使自己在看源码,学习原理的过程中更系统,更深入,同时也能加强记忆,巩固对知识的理解。 关于netty的简介和应用我就不做介 ...

概述

最近在学习netty的相关知识,也在看netty的源码,光看不练假把式,所以也正好利用自己学习的机会写几篇netty的分析文章,主要还是一些源码解析的文章,一方面有输出会促使自己在看源码,学习原理的过程中更系统,更深入,同时也能加强记忆,巩固对知识的理解。

关于netty的简介和应用我就不做介绍了,在网络上都能搜索到相关的资料。

netty是一个性能非常优秀的网络框架,采用reactor模式,使用非常高效的基于事件驱动的io线程模型,即经典的多路复用的io模式。关于io线程模型其实又是一个很大的话题,涉及到操作系统的底层原理,后面有时间我也打算深入学习一下这方面的知识,并写一些相关的分析文章。

我的整体思路是这样的:首先,以netty提供给用户的常用的接口为切入点,一步步地深入netty内核进行分析,因为netty的模块众多,而且某一个层级往往有很多种平级的模块,这些不同的模块一般代表了不同的实现机制或不同的功能,如根据多路复用系统调用的不同就分为epolleventloop,nioeventloop,kqueueeventloop等;根据不同的应用层协议把编解码器分为不同种类,如http,smtp, http2, xml等等。所以,我们只需要分析其中的一套,其他类型的在实际用到时在深入了解,这样既能整体上掌握框架,也能深入实现的细节。

 

netty应用示例

之前对spark-core的源码进行过一些讲解,分析了spark-core中的大部分模块,但是其中有一个很重要的模块却没有分析,那就是spark的rpc模块,spark的rpc模块是基于netty实现的,也是对netty的一个很典型的应用,所以这里我还是以spark中的rpc模块为示例,切入netty的源码分析。

 1 // 初始化netty服务端
 2   private void init(string hosttobind, int porttobind) {
 3 
 4     // io模式,有两种选项nio, epoll
 5     iomode iomode = iomode.valueof(conf.iomode());
 6     // 创建bossgroup和workergroup,即主线程组合子线程组
 7     eventloopgroup bossgroup =
 8       nettyutils.createeventloop(iomode, conf.serverthreads(), conf.getmodulename() + "-server");
 9     eventloopgroup workergroup = bossgroup;
10 
11     // 缓冲分配器,分为堆内存和直接内存
12     pooledbytebufallocator allocator = nettyutils.createpooledbytebufallocator(
13       conf.preferdirectbufs(), true /* allowcache */, conf.serverthreads());
14 
15     // 创建一个netty服务端引导对象,并设置相关参数
16     bootstrap = new serverbootstrap()
17       .group(bossgroup, workergroup)
18       .channel(nettyutils.getserverchannelclass(iomode))
19       .option(channeloption.allocator, allocator)
20       .childoption(channeloption.allocator, allocator);
21 
22     // 内存使用的度量对象
23     this.metrics = new nettymemorymetrics(
24       allocator, conf.getmodulename() + "-server", conf);
25 
26     // 排队的连接数
27     if (conf.backlog() > 0) {
28       bootstrap.option(channeloption.so_backlog, conf.backlog());
29     }
30 
31     // socket接收缓冲区大小
32     if (conf.receivebuf() > 0) {
33       bootstrap.childoption(channeloption.so_rcvbuf, conf.receivebuf());
34     }
35 
36     // socket发送缓冲区大小
37     if (conf.sendbuf() > 0) {
38       bootstrap.childoption(channeloption.so_sndbuf, conf.sendbuf());
39     }
40 
41     // 子channel处理器
42     bootstrap.childhandler(new channelinitializer<socketchannel>() {
43       @override
44       protected void initchannel(socketchannel ch) {
45         rpchandler rpchandler = apprpchandler;
46         for (transportserverbootstrap bootstrap : bootstraps) {
47           rpchandler = bootstrap.dobootstrap(ch, rpchandler);
48         }
49         context.initializepipeline(ch, rpchandler);
50       }
51     });
52 
53     inetsocketaddress address = hosttobind == null ?
54         new inetsocketaddress(porttobind): new inetsocketaddress(hosttobind, porttobind);
55     // 绑定到ip地址和端口
56     channelfuture = bootstrap.bind(address);
57     // 同步等待绑定成功
58     channelfuture.syncuninterruptibly();
59 
60     port = ((inetsocketaddress) channelfuture.channel().localaddress()).getport();
61     logger.debug("shuffle server started on port: {}", port);
62   }

netty使用一个引导对象serverbootstrap来引导服务端的启动,最后的bootstrap.bind(address)实际出发了一系列的初始化机制。

总结

本节,我主要是开了一个头,以spark中rpc服务端的初始化为例子切入netty的源码。

 

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网