文档章节

Netty3服务端流程简介

加大装益达
 加大装益达
发布于 2017/03/20 13:32
字数 923
阅读 11
收藏 0

原文链接

在学习Dubbo的时候需要学习Netty的流程等,在此做一个简单的入门学习。Dubbo中使用的是Netty3,所以这里说的都是Netty3。

Netty3可以看成是对Reactor的实现,所以先简单看下Reactor模式。

Reactor模式

Reactor模式是基于事件驱动的,有以下几种角色存在:

  • Handle,句柄,用来表示打开的文件,打开的连接等,Java NIO中使用Channel来表示。
  • Synchronous Event Demultiplexer,阻塞的等待发生在句柄上的一个或多个事件,就是监听事件的到来。Java NIO中使用Selector来表示。
  • EventHandler接口,来处理不同的请求事件。
  • Concrete Event Handler,EventHandler实现。
  • Initiation Dispatcher(Reactor),用来管理EventHandler;有事件到来时分发事件到EventHandler上去处理。

Netty中的Reactor模式

Netty中使用了两层Reactor,Main Reactor用于处理连接请求,Sub Reactor用于处理请求连接之后的读写请求。

Netty中各类释义

Channel

Reactor模式中使用Handle来表示打开的连接,也就是事件源,在java nio中使用Channel来抽象事件源,Netty中的Channel是自己的抽象。

ChannelEvent

在Netty中使用ChannelEvent来抽象在事件源中可以产生的各种事件。

ChannelHandler

作用就是Reactor模式中的EventHandler,用来处理事件请求。有两个子接口:

  • ChannelDownstreamHandler,处理从Netty内部流向Socket的事件。
  • ChannelUpstreamHandler,处理从Socket进入Netty内部的事件。

ChannelPipeline

每个Channel都会有一个ChannelPipeline,用来管理ChannelHandler。ChannelPipeline内部有一个ChannelHandler的双向链表,以Upstream为正方向,Downstream为负方向。

NioSelector

对应的是Reactor模式中的Synchronous Event Demultiplexer,Java NIO使用Selector,每个Channel都会把自己注册到Selector上,Selector就可以监听Channel中发生的事件。当有事件发生的时候,会生成ChannelEvent实例,该事件会被发送到Channel对应的ChannelPipeline中,然后交给ChannelHandler处理。

NioSelector有两个实现:

  • Boss,是Main Reactor,用来处理新连接加入的事件。
  • Worker,是Sub Reactor,用来处理各个连接的读写事件。

ChannelSink

ChannelSink可以看成Handler最后的一个处于末尾的万能handler,只有DownStream包含ChannelSink。

服务端例子

public class NettyServerTest {

    private final int port;

    public NettyServerTest(int port){
        this.port = port;
    }

    public void startServer(){
        ChannelFactory channelFactory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool());
        ServerBootstrap serverBootstrap = new ServerBootstrap(channelFactory);

        serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(new ServerHandlerTest());
            }
        });

        serverBootstrap.bind(new InetSocketAddress(port));
    }

    public static void main(String[] args) {
        new NettyServerTest(8888).startServer();
    }
}
public class ServerHandlerTest extends SimpleChannelUpstreamHandler {
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        ChannelBuffer channelBuffer = (ChannelBuffer)e.getMessage();
        String msg = channelBuffer.toString(Charset.defaultCharset());
        if(msg != null && !"".equals(msg)){
            System.out.println("服务端接收到消息:" + msg);
            ChannelBuffer sendMsg = ChannelBuffers.dynamicBuffer();
            sendMsg.writeBytes("我是服务器,已经接到消息".getBytes());
            e.getChannel().write(sendMsg);
        }else {
            e.getChannel().write("我是服务器,收到了空消息");
        }
        e.getChannel().close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        e.getCause();
        e.getChannel().close();
    }
}

ChannelFactory主要是用来产生Channel实例和ChannelSink实例。

ChannelPipelineFactory主要是用于具体传输数据的处理,是我们自己实现具体内容,一般我们是往里面添加Handler实现。

大概的流程是:

  • 首先使用Boss和Worker两个线程池来初始化一个ChannelFactory。
  • 使用ChannelFactory来初始化一个ServerBootstrap实例。
  • 为ServerBootstrap设置pipelineFactory,这里用来添加各种处理用的Handler。
  • 使用Bind方法绑定并监听。

Handler处理顺序

Handler跟Servlet中的Filter类似,在Netty中,Handler存在于Pipeline中,是一个链状的。

在Netty中存在两种ChannelHandler,一种是ChannelDownstreamHandler,另外一种是ChannelUpstreamHandler,从Socket流向Netty内部的数据经过ChannelUpstreamHandler处理,而从Netty内部流向Socket的数据由ChannelDownstreamHandler处理。

有关具体的分析和源码分析,等到dubbo分析完成之后,再做。

© 著作权归作者所有

加大装益达
粉丝 31
博文 83
码字总数 138659
作品 0
浦东
高级程序员
私信 提问
[Java] Netty Websocket Server Javascript Client

WebSocket协议的出现无疑是 HTML5 中最令人兴奋的功能特性之一,它能够很好地替代Comet技术以及Flash的XmlSocket来实现基于HTTP协议的双向通信。目前主流的浏览器,如Chrome、Firefox、IE10、...

长平狐
2012/11/19
851
1
netty3 UDP 组播问题

用netty3实现组播的服务器端代码,只能在linux上使用(win下无法接受组播)netty3有别于JAVA原始UDP组播实现方式 使用netty3实现组播同时还用绑定一个组播的本地端口(同组播端口一样的本地端...

蓝色火焰
2015/08/03
651
1
dubbo通信消息解析过程分析(1)

由于rpc底层涉及网络编程接口,线程模型,网络数据结构,服务协议,细到字节的处理。牵涉内容较多,今天就先从一个点说起。 说说,dubbo通过netty框架做传输层,从接到数据字节流到把字节转换...

wannshan
2018/01/19
307
0
netty4.0 研究 ing ... ...

之前做过一个基于netty3.X版本的server,性能测试很不错,现在netty4.0已经出beta2版本beta3的快照也出来了,相信不久就会发布,先尝鲜,总结了一些东西: #The shutdown process of a typic...

石头哥哥
2013/03/11
2.4K
0
netty4 如何建立心跳机制

@石头哥哥 你好,想跟你请教个问题: 关于netty4如何建立心跳机制,我目前的实现是这样的: 服务端增加对空闲时间处理pipeline.addLast("ping", new IdleStateHandler(60, 15, 13,TimeUnit.S...

预兆师
2014/03/06
29.8K
11

没有更多内容

加载失败,请刷新页面

加载更多

用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
2
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
12
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
13
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
6
0
Django的ChoiceField和MultipleChoiceField错误提示,选择一个有效的选项

在表单验证时提示错误:选择一个有效的选项 例如有这样一个表单: class ProductForm(Form): category = fields.MultipleChoiceField( widget=widgets.SelectMultiple(), ...

编程老陆
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部