netty(一) netty有哪几部分构成
netty
netty是一个支持高并发的非阻塞I/O框架。
Channel
Channel 是 NIO 基本的结构。它代表了一个用于连接到实体如硬件设备、文件、网络套接字或程序组件,能够执行一个或多个不同的 I/O 操作(例如读或写)的开放连接。
现在,把 Channel 想象成一个可以“打开”或“关闭”,“连接”或“断开”和作为传入和传出数据的运输工具。
Callback (回调)
callback (回调)是一个简单的方法,提供给另一种方法作为引用,这样后者就可以在某个合适的时间调用前者。这种技术被广泛使用在各种编程的情况下,最常见的方法之一通知给其他人操作已完成。
Netty 内部使用回调处理事件时。一旦这样的回调被触发,事件可以由接口 ChannelHandler 的实现来处理。如下面的代码,一旦一个新的连接建立了,调用 channelActive(),并将打印一条消息。
Listing 1.2 ChannelHandler triggered by a callback
public class ConnectHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { //1
System.out.println(
"Client " + ctx.channel().remoteAddress() + " connected");
}
}
1.当建立一个新的连接时调用 ChannelActive()
Future
Future 提供了另外一种通知应用操作已经完成的方式。这个对象作为一个异步操作结果的占位符,它将在将来的某个时候完成并提供结果。
JDK 附带接口 java.util.concurrent.Future ,但所提供的实现只允许您手动检查操作是否完成或阻塞了。这是很麻烦的,所以 Netty 提供自己了的实现,ChannelFuture,用于在执行异步操作时使用。
ChannelFuture 提供多个附件方法来允许一个或者多个 ChannelFutureListener 实例。这个回调方法 operationComplete() 会在操作完成时调用。事件监听者能够确认这个操作是否成功或者是错误。如果是后者,我们可以检索到产生的 Throwable。简而言之, ChannelFutureListener 提供的通知机制不需要手动检查操作是否完成的。
每个 Netty 的 outbound I/O 操作都会返回一个 ChannelFuture;这样就不会阻塞。这就是 Netty 所谓的“自底向上的异步和事件驱动”。
下面例子简单的演示了作为 I/O 操作的一部分 ChannelFuture 的返回。当调用 connect() 将会直接是非阻塞的,并且调用在背后完成。由于线程是非阻塞的,所以无需等待操作完成,而可以去干其他事,因此这令资源利用更高效。
Listing 1.3 Callback in action
Channel channel = ...;
//不会阻塞
ChannelFuture future = channel.connect(
new InetSocketAddress("192.168.0.1", 25));
1.异步连接到远程地址
下面代码描述了如何利用 ChannelFutureListener 。首先,连接到远程地址。接着,通过 ChannelFuture 调用 connect() 来 注册一个新ChannelFutureListener。当监听器被通知连接完成,我们检查状态。如果是成功,就写数据到 Channel,否则我们检索 ChannelFuture 中的Throwable。
注意,错误的处理取决于你的项目。当然,特定的错误是需要加以约束 的。例如,在连接失败的情况下你可以尝试连接到另一个。
Listing 1.4 Callback in action
Channel channel = ...;
//不会阻塞
ChannelFuture future = channel.connect( //1
new InetSocketAddress("192.168.0.1", 25));
future.addListener(new ChannelFutureListener() { //2
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //3
ByteBuf buffer = Unpooled.copiedBuffer(
"Hello", Charset.defaultCharset()); //4
ChannelFuture wf = future.channel().writeAndFlush(buffer); //5
// ...
} else {
Throwable cause = future.cause(); //6
cause.printStackTrace();
}
}
});
1.异步连接到远程对等节点。调用立即返回并提供 ChannelFuture。
2.操作完成后通知注册一个 ChannelFutureListener 。
3.当 operationComplete() 调用时检查操作的状态。
4.如果成功就创建一个 ByteBuf 来保存数据。
5.异步发送数据到远程。再次返回ChannelFuture。
6.如果有一个错误则抛出 Throwable,描述错误原因。
Event 和 Handler
Netty 使用不同的事件来通知我们更改的状态或操作的状态。这使我们能够根据发生的事件触发适当的行为。
这些行为可能包括:
- 日志
- 数据转换
- 流控制
- 应用程序逻辑
由于 Netty 是一个网络框架,事件很清晰的跟入站或出站数据流相关。因为一些事件可能触发传入的数据或状态的变化包括:
- 活动或非活动连接
- 数据的读取
- 用户事件
- 错误
出站事件是由于在未来操作将触发一个动作。这些包括:
- 打开或关闭一个连接到远程
- 写或冲刷数据到 socket
每个事件都可以分配给用户实现处理程序类的方法。这说明了事件驱动的范例可直接转换为应用程序构建块。
图1.3显示了一个事件可以由一连串的事件处理器来处理
Figure 1.3 Event Flow
Netty 的 ChannelHandler 是各种处理程序的基本抽象。想象下,每个处理器实例就是一个回调,用于执行对各种事件的响应。
在此基础之上,Netty 也提供了一组丰富的预定义的处理程序,您可以开箱即用。比如,各种协议的编解码器包括 HTTP 和 SSL/TLS。在内部,ChannelHandler 使用事件和 future 本身,创建具有 Netty 特性抽象的消费者。
整合
FUTURE, CALLBACK 和 HANDLER
Netty 的异步编程模型是建立在 future 和 callback 的概念上的。所有这些元素的协同为自己的设计提供了强大的力量。
拦截操作和转换入站或出站数据只需要您提供回调或利用 future 操作返回的。这使得链操作简单、高效,促进编写可重用的、通用的代码。一个 Netty 的设计的主要目标是促进“关注点分离”:你的业务逻辑从网络基础设施应用程序中分离。
SELECTOR, EVENT 和 EVENT LOOP
Netty 通过触发事件从应用程序中抽象出 Selector,从而避免手写调度代码。EventLoop 分配给每个 Channel 来处理所有的事件,包括
- 注册感兴趣的事件
- 调度事件到 ChannelHandler
- 安排进一步行动
该 EventLoop 本身是由只有一个线程驱动,它给一个 Channel 处理所有的 I/O 事件,并且在 EventLoop 的生命周期内不会改变。这个简单而强大的线程模型消除你可能对你的 ChannelHandler 同步的任何关注,这样你就可以专注于提供正确的回调逻辑来执行。该 API 是简单和紧凑。
netty(一) netty有哪几部分构成的更多相关文章
- 【Netty】Netty入门之WebSocket小例子
服务端: 引入Netty依赖 <!-- netty --> <dependency> <groupId>io.netty</groupId> <a ...
- Netty学习——Netty和Protobuf的整合(二)
Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...
- Netty学习——Netty和Protobuf的整合(一)
Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...
- 【netty】Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- 【Netty】Netty核心组件介绍
一.前言 前篇博文体验了Netty的第一个示例,下面接着学习Netty的组件和其设计. 二.核心组件 2.1. Channel.EventLoop和ChannelFuture Netty中的核心组件包 ...
- 【Netty】Netty传输
一.前言 在简单学习了Netty中的组件后,接着学习Netty中数据的传输细节. 二.传输 2.1 传输示例 Netty中的数据传输都是使用的字节类型,下面通过一个实例进行说明,该实例中服务器接受请求 ...
- 【Netty】Netty之ByteBuf
一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...
- 【Netty】Netty之Bootstrapping
一.前言 前面已经学习了Netty的EventLoop以及线程模型,接着学习Netty的Bootstrapping. 二.Bootstrapping 在学习了Netty中的很多组件后,如何将这些组件有 ...
- netty学习--netty源码中的部分util方法
io.netty.buffer.AbstractByteBuf#calculateNewCapacity 申请内存空间 private int calculateNewCapacity(int mi ...
- Netty 之 Netty生产级的心跳和重连机制
https://blog.csdn.net/z69183787/article/details/52625095 最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github ...
随机推荐
- opencv::将两幅图像合并后,在同一个窗口显示;并将合并的图像流保存成视频文件
/** * @file main-opencv.cpp * @date July 2014 * @brief An exemplative main file for the use of ViBe ...
- 【python】numpy中的shape用法
转自 https://blog.csdn.net/u010758410/article/details/71554224# shape函数是numpy.core.fromnumeric中的函数,它的功 ...
- 【python】self & cls
转自 python中self,cls 普通的方法,第一个参数需要是self,它表示一个具体的实例本身. 如果用了staticmethod,那么就可以无视这个self,而将这个方法当成一个普通的函数使用 ...
- kafka集群的错误处理--kafka一个节点挂了,导致消费失败
今天由于kafka集群搭建时的配置不当,由于一台主消费者挂掉(服务器崩了,需要维修),导致了所有新版消费者(新版的offset存储在kafka)都无法拉取消息. 由于是线上问题,所以是绝对不能影响用户 ...
- (整理)在REHL6.5上部署ASP.NET MVC
最近项目要使用Linux服务器(REHL6.5)+MySQL,因此特尝试操作. 1 Linux 安装Jexus 1.1 下载Jexus 因为服务器没有安装Xwindows,Jexus的下载又出现问题, ...
- NoSql图形数据库
NoSQL数据库可以按照它们的数据模型分成4类: 键-值存储库(Key-Value-stores); BigTable实现(BigTable-implementations); 文档库(Documen ...
- java效率取随机不重复数
//效率取随机不重复数 public int[] takeRandom(int num) { Random rd = new Random(); int[] rds = new int[num];// ...
- HTTP的长连接(持久连接)和短连接
HTTP的长连接和短连接 本文总结&分享网络编程中涉及的长连接.短连接概念. 关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持 ...
- Java 学习 注解
转载:https://blog.csdn.net/briblue/article/details/73824058 注解语法 因为平常开发少见,相信有不少的人员会认为注解的地位不高.其实同 class ...
- 安装grid时找不到ASM共享磁盘
1.安装ORACLE数据库集群软件grid时找不到共享磁盘,如下图: 2.网上找过有各种说法,但此处小编的解决方案是:通过重新安装软件:oracleasmlib-2.0.4-1.el6.x86_64. ...