核心知识
- 高性能RPC框架的3个要素:IO模型、数据协议(http、protobuf、thrift)、线程模型
- EventLoop好比一个线程,1个EventLoop可以服务多个Channel(轮询找是否有请求),1个Channel只有一个EventLoop
可以创建多 个 EventLoop 来优化资源利用,也就是EventLoopGroup
- EventLoopGroup 负责分配 EventLoop 到新创建的 Channel,里面包含多个EventLoop
- EventLoopGroup -> 多个 EventLoop , EventLoop -> 维护一个 Selector -》轮询多个channel
- Selector 学习资料:http://ifeve.com/selectors/
- 源码分析默认线程池数量 (2×核数)
sector工作模式
EventLoop和EventLoopGroup
EventLoop -> 维护一个 Selector
()
观看源码可以得到一个结论:别看了,看不懂的 = =,看代码+百度半天也没搞懂这两个的作用与区别
知道EventLoop -> 维护一个 Selector
(),然后这个sector轮询多个channel,维护多个连接就行了。别的源码跟优化有关
当没有指定线程数的时候,netty如何建立线程数。
观察源码可以看到当为0返回第一个,默认线程池数量 :cpu核数✖2
NioEventLoopGroup()源码
启动引导类servebootstap
之前的例子里两个线程组相一个接待连接,一个处理。相当于一个主从reactor模型。
我们也可以改变参数实现别的线程模型
单线程
channel
设置io类型,现在都是nio
https://www.cnblogs.com/ZhuChangwu/p/11204057.html
设置子通道因为一个接收,一个处理么,另一个负责处理的也需要设置下,进行初始化操作,加handler等一系列操作
option
option: 作用于每个新建立的channel,设置TCP连接中的一些参数,如下(tcp知识详加网络基础tcp部分)
这块应用与连接数多需要优化的情况,可以不重点讲
- ChannelOption.SO_BACKLOG: 存放已完成三次握手的请求的等待队列的最大长度;
- Linux服务器TCP连接底层知识:
- syn queue:半连接队列,洪水攻击,tcp_max_syn_backlog
- accept queue:全连接队列, net.core.somaxconn
- 系统默认的somaxconn参数要足够大 ,如果backlog比somaxconn大,则会优先用后者 ,可以通过改变backlog来改变前者 https://g ithub.com/netty/netty/blob/4.1/common/src/main/java/io/netty/util/NetUtil.java#L250
- ChannelOption.TCP_NODELAY: 为了解决Nagle的算法问题,默认是false, 要求高实时性,有 数据时马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数,就设置为 false,会累积一定大小后再发送
知识拓展: https://baike.baidu.com/item/Nagle%E7%AE%97%E6%B3%95/5645172 https://w
ww.2cto.com/article/201309/241096.html
childHandler
childOption
作用于被accept之后的连接
绑定端口与等待
//绑定端口,同步等待成功
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
//等待服务端监听端口关闭
channelFuture.channel().closeFuture().sync();
客户端启动引导类Bootstrap
remoteAddress: 服务端地址
handler:和服务端通信的处理器
// 略
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
})
// 略
//连接到服务端,connect是异步连接,在调用同步等待sync,等待连接成功
ChannelFuture channelFuture = bootstrap.connect().sync();
//阻塞直到客户端通道关闭
channelFuture.channel().closeFuture().sync();
注意
客户端为handler,服务端为childhandler