您的位置 首页 java

java开发Netty重连实现及Netty原理浅析

引言

Netty 是一个高性能 事件驱动的异步的非堵塞的IO(NIO)框架,用于建立TCP等底层的连接,基于Netty可以建立高性能的Http服务器。支持HTTP、 WebSocket 、Protobuf、 Binary TCP |和UDP,Netty已经被很多高性能项目作为其Socket底层基础,如HornetQ Infinispan Vert.x

Play Framework Finangle和 Cassandra。其竞争对手是:Apache MINA和 Grizzly。

Netty Client有两种情况下需要重连:

Netty Client启动的时候需要重连

在程序运行中连接断掉需要重连。

对于第一种情况,Netty的作者在stackoverflow上给出了解决方案,

对于第二种情况,Netty的例子 uptime 中实现了一种解决方案。

Java /io/netty/example/uptime/UptimeClientHandler.java

而Thomas在他的文章中提供了这两种方式的实现的例子。

实现 channel FutureListener 用来启动时监测是否连接成功,不成功的话重试:

public class Client

{

private EventLoopGroup loop = new NioEventLoopGroup();

public static void main( String[] args )

{

new Client().run();

}

public Bootstrap createBootstrap(Bootstrap bootstrap, EventLoopGroup eventLoop) {

if (bootstrap != null) {

final MyInboundHandler handler = new MyInboundHandler(this);

bootstrap.group(eventLoop);

bootstrap.channel(NioSocketChannel.class);

bootstrap.option(ChannelOption.SO_KEEPALIVE, true);

bootstrap.handler(new ChannelInitializer<SocketChannel>() {

@ Override

protected void initChannel(SocketChannel socketChannel) throws Exception {

socketChannel.pipeline().addLast(handler);

}

});

bootstrap.remoteAddress(“localhost”, 8888);

bootstrap.connect().addListener(new ConnectionListener(this));

}

return bootstrap;

}

public void run() {

createBootstrap(new Bootstrap(), loop);

}

}

ConnectionListener 负责重连:

public class ConnectionListener implements ChannelFutureListener {

private Client client;

public ConnectionListener(Client client) {

this.client = client;

}

@Override

public void operationComplete(ChannelFuture channelFuture) throws Exception {

if (!channelFuture.isSuccess()) {

System.out.println(“Reconnect”);

final EventLoop loop = channelFuture.channel().eventLoop();

loop.schedule(new Runnable() {

@Override

public void run() {

client.createBootstrap(new Bootstrap(), loop);

}

}, 1L, TimeUnit.SECONDS);

}

}

}

同样在ChannelHandler监测连接是否断掉,断掉的话也要重连:

public class MyInboundHandler extends SimpleChannelInboundHandler {

private Client client;

public MyInboundHandler(Client client) {

this.client = client;

}

@Override

public void channelInactive(ChannelHandlerContext ctx) throws Exception {

final EventLoop eventLoop = ctx.channel().eventLoop();

eventLoop.schedule(new Runnable() {

@Override

public void run() {

client.createBootstrap(new Bootstrap(), eventLoop);

}

}, 1L, TimeUnit.SECONDS);

super.channelInactive(ctx);

}

}

参考文档

close d-in-netty

java /io/netty/example/uptime/UptimeClientHandler.java

ctx.close vs ctx.channel().close

ctx.write vs ctx.channel().write

堵塞与非堵塞原理

传统硬件的堵塞,从内存中读取数据,然后写到磁盘,而CPU一直等到磁盘写完成,磁盘的写操作是慢的,这段时间CPU被堵塞不能发挥效率。

使用非堵塞的 DMA :CPU只是发出写操作这样的指令,做一些初始化工作,DMA具体执行,从内存中读取数据,然后写到磁盘,当完成写后发出一个中断事件给CPU。这段时间CPU是空闲的,可以做别的事情。这个原理称为Zero.copy 零拷贝

Netty底层基于上述Java NIO的零拷贝原理实现:

比较

  • Tomcat是一个Web服务器,它是采取一个请求一个 线程 ,当有1000客户端时,会耗费很多内存。通常一个线程将花费 256kb到1mb的stack空间。
  • Node.js是一个线程服务于所有请求,在错误处理上有限制
  • Netty是一个线程服务于很多请求,如下图,当从Java NIO获得一个Selector事件,将激活通道Channel。

演示

Netty的使用代码如下:

Channel channel = …

ChannelFuture cf = channel.write(data);

cf.addListener(

new ChannelFutureListener() {

@Override

public void operationComplete(ChannelFuture future) throws Exception {

if(!future.isSuccess() {

future.cause().printStacktrace();

}

}

});

cf.sync();

总结

以 上就是我对 java开发Netty重连实现及Netty原理浅析 问题及其优化总结,分享给大家,觉得收获的话可以点个关注收藏转发一波喔,谢谢大佬们支持!

最后,每一位读到这里的网友,感谢你们能耐心地看完。希望在成为一名更优秀的Java程序员的道路上,我们可以一起学习、一起进步!都能赢取白富美,走向架构师的人生巅峰!

进阶地址:

想了解学习Java方面的技术内容以及Java技术视频的内容可加群:722040762 验证码:头条(06 必过)欢迎大家的加入哟!

文章来源:智云一二三科技

文章标题:java开发Netty重连实现及Netty原理浅析

文章地址:https://www.zhihuclub.com/200935.shtml

关于作者: 智云科技

热门文章

网站地图