Netty的服务器实现浅析

如果你现在还在写着操作socket的代码,也许不能说你落伍,但至少也不能说你做的工作很超前。因为现在有很多的网络通信框架已经把底层的东东封装的很完善,今天要说的Netty也算是一款不错的产品了。
突然半路进来看Netty其实是最近看HornetQ的缘故,HornetQ的底层传输的实现就是借助了Netty。按照官方的解释,Netty是一个异步的事件驱动的网络应用框架,它使得我们关于客户端服务器协议的开发变得更加的方便,维护更容易,扩展性更好。它极大的简化了我们的网络编程。更为难得的是Netty顺便打包了一堆很好的例子,对于快速入门的人来说能够很短的时间内就对其有了感官上的认识。我们就从一个例子开始吧。

package org.jboss.netty.example.discard;

import java.net.InetSocketAddress;
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.oio.OioServerSocketChannelFactory;

public class DiscardServer {

public static void main(String[] args) throws Exception {
// Configure the server.
ServerBootstrap bootstrap = new ServerBootstrap(
new OioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));

// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new DiscardServerHandler());
}
});

// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(8080));
}
}

上面的程序主要是用来启动了一个服务器端的服务,这个服务会监听本机的8080端口,也就是说你可以通过客户端来访问8080端口了。 ServerBootstrap 类作为一个工具类,用来启动服务器程序。这段程序主要就是做了三件事:

[list]
[*]设置ChannelFactory,也就是要设置服务器通信的方式,例子就是借助socket的通信,当然你也可以设置成基于nio形式或者数据报形式的。

[*]设置PipelineFactory,其实是为了设置一组Handler,这组Handler会对这个通信的过程进行处理,比如说解码,然后业务处理,然后编码数据。

[*]bootstrap.bind(new InetSocketAddress(8080)); 就是来启动服务。很多猫腻就是出现在这。
[/list]

介绍完上面的例子,我们来说Netty代码中几个关键类型的类。
[b]
Channel[/b] Channel是Netty中数据流转的通道,它对底层的数据传输比如socket等进行了封装,我们可以借助于Channel来完成数据的读写,通道的打开和关闭等操作。Channel可以分为服务器的Channel和于客户端进行通信的Channel。

[b]
ChannelEvent[/b] 定义了一系列的事件类型,比如说Conenct,Receive,Write的等等。这符合Command模式,肯定会有某个地方来对这些命令做不同的处理

[b]ChannelHandler[/b]可以看成是Interceptor,也就是说ChannelHandler会针对发生在Channel中的一些事件进行特定的动作处理。ChannelHandler可以分成ChannelUpstreamHandler和ChannelDownstreamHandler两种 ,顾名思义,就是说这两种handler会对不同流向的事件发挥作用。

[b]ChannelPipeline [/b] Netty是基于事件驱动的,归根结底就是通过ChannelPipeline来控制事件流。我们通过在ChannelPipeline上注册一系列ChannelHandler来处理事件。ChannelPipeline内部维护了一个ChannelHandlerContext的集合,每个ChannelHandlerContext都会维护前后是那个ChannelHandlerContext,类似一个双向的链表。上面说到ChannelHandler分为Up和Down两个方向,那么如何理解Up和Down?其实,Up就是说流入的事件,Down就是流出的事件。对于客户端,读到客户端程序写入的数据就是流入,而返回数据也就是将数据写回到客户端就属于流出的事件。发生流入的事件时,只有属于ChannelUpstreamHandler才有资格处理。而对于流出的时间,则ChannelDownstreamHandler才有资格处理。对于一个ChannelPipeline上注册的多个Handler,他们注册的顺序决定了他们处理的顺序。那么对于流出的事件来说,所有的handler都处理完毕之后,需要有一个类真正的服务将数据写回到客户端,这个类就是下面所说的ChannelSink.

[b]ChannelSink[/b]channelPipline完成所有的DownHandler后通过 ChannelSink来进行底层通信的处理。

[b]XIOWorker[/b] 负责与底层通信,如数据的写入输出。X根据协议的不同而不同。


下面说一下Netty中服务器端的工作原理,本图引自边城客栈[url]http://www.kafka0102.com[/url],如果图的作者对于本文中的引用有意见可以给我留言,我会删除此图。


[img]http://dl.iteye.com/upload/attachment/356278/78043cc6-98af-393c-bcea-12a0ffb5656b.png[/img]

如图所示,服务器端通过mainReactor来处理客户端的连接请求(ChannelSink的Boss内部类充当的就是mainReactor的角色),每建立一个连接后,就会从连接池中获取或者新建一个subReactor(XIOWorker,X根据协议的不同而不同)来专门处理与某个客户端的通信工作。

类图:

[img]http://dl.iteye.com/upload/attachment/356280/a6d441e3-d60d-383c-9518-950ba662e93a.png[/img]

不知不觉已经十二点多了,就此打住了。欢迎朋友们多多交流。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值