内容简介: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
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python网络编程基础
John Goerzen / 莫迟 等 / 电子工业出版社 / 2007 / 68.00元
《Python网络编程基础》可以作为各层次Python、Web和网络程序的开发人员的参考书,在实际工作中使用书中的技术,效果更佳。一起来看看 《Python网络编程基础》 这本书的介绍吧!