天气:阴-小雨
今天学习内容:
一、剖析netty源码,看看netty是如何设计ChannelPipeline/ChannelHandler和ChannelHandlerContext的
1.每当ServerSocket创建新的链接就会创造一个Socket
2.每个新建的Socket就会分配一个全新的ChannelPipeline,并创建tail节点和head节点
3.每个ChannelPipeline内部都含有多个ChannelHandlerContext
4.他们一起主城了双向链表,这些context用于包装我们调用addLast方法是添加的handler
5.进出站的context链表其实只有一条,通过inbound,outbound标识进行区分,通过遍历获取
二、ChannelPipeline如何调度handler的
1.入站的时候,会调用fire标识的方法,通知后续的handler进行处理
2.出站是从内部向外部写,是从tail开始的,入站是从head开始的,虽然head也实现了outbound接口,但是不从head开始执行出站任务
3.节点之间的传递通过AbstractChannelHandlerContext类内部的fire系列方法,找到当前节点的下一个节点不断循环传播,是一个过滤器形式完成对handler的调度
三、netty心跳服务
1.netty通过心跳检测对方是否有效,提供了IdleStateHandle,ReadTimeoutHandler,WriteTimeoutHandler三个handler。
四、netty核心组件EventLoop
执行当前NioEventLoop的run方法时,这是整个EventLoop的核心,是一个死循环,通过不同的状态去做出反应,最后死循环确认是否关闭,否则不会break,关闭时执行cleanup操作,并更改状态
五、任务加入异步线程池
1.添加线程池
A。在handler中添加线程池
优点是更加自由,但是可能响应达不到标准,轮不到该业务
//在handler中添加一个业务线程池,可以将任务提交到该线程池
static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
//将任务提交到group线程池中
//在channelRead方法中
group.submit(new Callable<Object>(){
@Override
public Object call() throws Exception{
//业务流程
}
});
B。在context中添加线程池
都交由业务线程池处理,不够自由
//在server中创建一个线程池
static final EventExecutorGroup group = new DefaultEventExecitprGroup(2);
//然后在main方法中add的时候不是直接添加handle,改为指定向group添加
p.addLast(group,new EchoServerHandler());
六、RPC
RPC是远程调用,两个或者多个应用分布在不同服务器上,他们之间的调用都像是本地调用一样,程序员无需额外地为这个交互作用而编程