内容简介:netty其实针对nio做了封装,其实最核心的就是BOOS线程和WORK线程。有人了解netty3 有人了解netty4,其实这2个差别并不大。其实netty就是高性能的事件驱动型的NIO框架。源码:https://github.com/limingios/netFuture/tree/master/源码/『互联网架构』软件架构-io与nio线程模型reactor模型(上)(53)/nio
netty其实针对nio做了封装,其实最核心的就是BOOS线程和WORK线程。有人了解netty3 有人了解netty4,其实这2个差别并不大。其实netty就是高性能的事件驱动型的NIO框架。
源码:https://github.com/limingios/netFuture/tree/master/源码/『互联网架构』软件架构-io与nio线程模型reactor模型(上)(53)/nio
(一)netty架构
这次要说netty3,目前dubbo,google,facebook的RPC框架都是基于netty3实现的。目前netty已经到5了。
- 主要分为五個部分
1.Core是核心层,netty最以为傲的东西,Extensible Event Model可扩展的基于拦截器链式实现的。
2.Universal Communication API 统一的通信API,主要是对NIO,BIO统一的封装
3.Zero-Copy-Capable Rich Byte Buffer 0拷贝的
4.Transport Services 传输层服务
5.Protocol Support 应用层协议支持 -
模块组件
1.bootstrap Netty服务端及客户端启动类
2.buffer 缓冲相关,对NIO Buffer做了一些优化、封装
3.channel 处理客户端与服务端之间的连接通道
4.container 连接其他容器的代码,例如Spring
5.handler 实现协议编解码等附加功能
6.logging 日志
7.util工具类
-
netty中的主从线程模型
>使用EventLoop来处理连接上的读写事件,而一个连接上的所有请求都保证在一个EventLoop中被处理,一个EventLoop中只有一个Thread,所以也就实现了一个连接上的所有事件只会在一个线程中被执行。一个EventLoopGroup包含多个EventLoop,可以把一个EventLoop当做是Reactor线程模型中的一个线程。
举个例子吧:在Netty的里面有一个Boss,他开了一家公司(开启一个服务端口)对外提供业务服务,它手下有一群做事情的workers。Boss一直对外宣传自己公司提供的业务,并且接受(accept)有需要的客户(client),当一位客户找到Boss说需要他公司提供的业务,Boss便会为这位客户安排一个worker,这个worker全程为这位客户服务(read/write)。如果公司业务繁忙,一个worker可能会为多个客户进行服务。这就是Netty里面Boss和worker之间的关系。
Server.java
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* netty服务端
* @author idig8.com
*/
public class Server {
public static void main(String[] args) {
// 服务类
ServerBootstrap bootstrap = new ServerBootstrap();
// boss线程,主要监听端口和获取worker线程及分配socketChannel给worker线程
ExecutorService boss = Executors.newCachedThreadPool();
// worker线程负责数据读写
ExecutorService worker = Executors.newCachedThreadPool();
// 设置niosocket工厂
bootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker));
// 设置管道的工厂
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
// 管道过滤器
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("myServerMessageHandler", new MyServerMessageHandler());
return pipeline;
}
});
// 服务类绑定端口
bootstrap.bind(new InetSocketAddress(7777));
System.out.println("服务端启动...");
}
}
处理的handler
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
* 消息处理类
* @author idig8.com
*/
public class MyServerMessageHandler extends SimpleChannelHandler {
/**
* 接收消息
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("messageReceived");
String s = (String) e.getMessage();
System.out.println("服务端收到数据:"+s);
//回写数据给客户端
ctx.getChannel().write("hello...");
super.messageReceived(ctx, e);
}
/**
* 异常处理
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.out.println("exceptionCaught");
super.exceptionCaught(ctx, e);
}
/**
* 获取新连接事件
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelConnected");
super.channelConnected(ctx, e);
}
/**
* 关闭通道的时候触发 (必须是链接已经建立)
*/
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelDisconnected");
super.channelDisconnected(ctx, e);
}
/**
* 通道关闭的时候触发
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelClosed");
super.channelClosed(ctx, e);
}
}
-
处理流程
1.标记nio selector唤醒状态(wakeUp状态位,true有请求,false没有请求)
2.Selector(注册)
3.处理任务队列
4.处理自己的业务(客户端的读写请求等)
- dubbo底层
-
netty启动一个服务所经过的流程
1.设置boss线程 和 worker线程,boss安排,worker干活,让他们入厂,准备由boss安排worker干活。
2.设置启动类参数,最重要的就是设置channel。
3.创建server对应的channel,创建各大组件,包括ChannelConfig,ChannelId,ChannelPipeline,ChannelHandler,Unsafe。
4.初始化server对应的channel,设置一些attr,option,以及设置子channel的attr,option,给server的channel添加新channel接入器,并出发addHandler,register等事件。
5.调用到jdk底层做端口绑定,并触发active事件,active触发的时候,真正做服务端口绑定。
PS:Netty是 Java 程序员进阶的必备神奇。随着网站规模的不断扩大,系统并发访问量也越来越高,传统基于 Tomcat 等 Web 容器的垂直架构已经无法满足需求,需要拆分应用进行服务化,以提高开发和维护效率。从组网情况看,垂直的架构拆分之后,系统采用分布式部署,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。
>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
>>原文链接地址:上一篇:已是最新文章
以上所述就是小编给大家介绍的《『互联网架构』软件架构-netty线程模型源码(55)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Redis单线程架构
- 『互联网架构』软件架构-tomcat之线程源码熟悉通信方式(上)(21)
- Redis 破障之路(三):Redis 单线程架构
- 『互联网架构』软件架构-io与nio线程模型reactor模型(上)(53)
- 『互联网架构』软件架构-io与nio线程模型reactor模型(下)(54)
- 阿里java架构师面试128题含答案:分布式架构+Dubbo+多线程+Redis
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Data Structures and Algorithms
Alfred V. Aho、Jeffrey D. Ullman、John E. Hopcroft / Addison Wesley / 1983-1-11 / USD 74.20
The authors' treatment of data structures in Data Structures and Algorithms is unified by an informal notion of "abstract data types," allowing readers to compare different implementations of the same......一起来看看 《Data Structures and Algorithms》 这本书的介绍吧!