Netty介绍及应用

 2024-03-01 01:05:13  阅读 0

在JAVA领域的网络通信中,我们会想到应用层的HTTP协议和传输层的TCP协议。 基于HTTP会更简单,因为它解决了一些基于TCP需要解决的问题,比如解包、粘包等。 但其性能较差:半双工、文本传输、重数据包头等,所以我们追求高效的网络通信。 通常选择基于TCP的通信实现。 对于TCP通信,我们可以选择BIO阻塞实现或者NIO非阻塞实现(当然还有AIO)。 对于NIO,我们可以选择JDK自带的API或者NIO框架。 对于NIO框架,我们可以选择Netty、MINA或者(基于JDK API实现)。 这里我们介绍一下Netty。 在此之前,我们先介绍一下相关的基础知识。

基础知识

输入/输出模型

Unix 提供了五种 I/O 模型:阻塞 I/O、非阻塞 I/O、I/O 复用、信号驱动 I/O 和异步 I/O。 JDK没有五个相应的实现。 JDK 1.4 之前的版本是阻塞 I/O。 1.4 引入了NIO包,并提供了将阻塞复用为同一个阻塞,从而可以在单个线程中同时处理多个客户端请求。 1.7引入的NIO2.0提供了更完整的AIO功能。 当然,JDK提供的这些功能都依赖于底层操作系统的实现。

零拷贝

当我们进行I/O操作时,无论是文件I/O还是网络I/O,传统的实现都会涉及到内核空间和用户空间之间的数据传输。 为什么存在内核空间和用户空间? 因为操作系统为了保证自身的安全稳定,做了这样的划分,普通进程无法直接使用内核空间,底层操作依赖于操作系统,所以就有了这种数据复制。 例如一个典型的数据流向(读取硬盘数据并通过网络发送):

netty使用反应堆模式_netty现在使用多么_netty如何在项目中使用

如果我们的应用程序不需要对数据进行操作,那么步骤2和步骤3显然需要优化,所以就有了零拷贝技术。 零复制是一种防止 CPU 将数据从一个存储复制到另一个存储的技术。 具体实现有mmap()、()等。

Netty简介

内蒂

Lee写的一个nio框架(mina也是他的作品,但Netty是后来的)。 方便我们快速开发高性能、高可靠的网络服务器和客户端程序。

Netty并不是那样基于JDK NIO实现的。 它重写了大部分底层实现,如and等,同时也依赖于JDK NIO。 例如,在分配直接内存时,它会调用JDK API。

Netty的API简单,开发门槛低,不像JDK NIO那么复杂。 强大的功能预设了多种编解码功能(多种)。 高性能,成熟稳定(解决了jdk的epoll bug)。 社区活跃,大规模商业应用测试。

Netty核心模块

JDK的结构如左图所示。 由于没有单独的指针来标识读写数据,因此在调用read()或write()方法之前需要调用flip()和clear()方法来在读写之间切换。 如果忘记,将会调用错误的数据。 Netty的结构(右图)进行了重新设计。 有分别用于读取和写入的位置指针。 可以直接调用读写方法,无需进行相关的复位操作。

netty如何在项目中使用_netty现在使用多么_netty使用反应堆模式

netty使用反应堆模式_netty如何在项目中使用_netty现在使用多么

具体实现是根据空间类型进行分类。 堆分配在普通堆空间中,但分配在直接内存中(基于mmap,通过API级别打开),避免了内核空间和用户空间数据的无效拷贝。 直接内存是一个特殊的空间。 它的大小不受Xmx的限制,也不会被GC回收。

它是Netty网络操作的抽象,聚合了一组功能,包括但不限于网络读写、客户端发起连接、主动关闭连接等。 实现:el(tcp传输服务器)、(tcp传输)、(udp传输)

与机制和过滤器类似,这类拦截器实际上是责任链模型的变种,主要是为了方便事件的拦截和用户业务逻辑的定制。 这是我们的业务逻辑实现的地方。 他们的关系如下:

netty如何在项目中使用_netty现在使用多么_netty使用反应堆模式

Netty 附带了一些预设供开发人员使用。 例如r、der等用于处理拆包和粘贴。 序列化和反序列化/等等。 还有一些方法可以实现长连接。

/

从类继承关系来看,它们都与线程池相关。 根据用户启动参数,可同时支持单线程模型、多线程、主从等多种模型。 单线程模型意味着所有I/O操作都在同一个NIO线程上完成。 多线程和单线程最大的区别就是有一组NIO线程来处理I/O操作(一个单独的NIO线程监听服务器监听客户端的tcp链接请求,一个NIO线程池是负责阅读和写作)。 主从使用线程池来处理与客户端的连接。 如果链路上有大量的业务逻辑处理,比如登录、握手、安全认证等,显然一个线程无法处理。

总结与应用

Netty主要负责底层通信,其功能远不止上面介绍的这些。 在Java引入nio或aio之前,底层高性能通信主要由c或c++主导,但现在我们有多种选择。

由于Netty是用于网络通信的,所以涉及到通信的地方可以考虑使用Netty,比如Web服务器、消息中间件、RPC框架等。 京东的RPC框架JSF、阿里巴巴的消息中间件均采用Netty进行底层通信(RPC是主动调用模式,消息中间件是推送模式),还有美团点评的实时监控系统CAT等,由此可见netty在底层是高效的。 沟通仍然需要时间的考验。 这里介绍一下它在RPC框架实现中的使用。

RPC(Call)远程方法调用并不是什么新技术,它只是应用框架的一种解决方案。 它是一个相对纯粹的进程间通信解决方案。 比如京东的SOAP或者REST就是RPC,京东的jsf、阿里巴巴的dubbo、腾讯的tars、grpc也是RPC的实现。 、grpc和tars可以跨语言,所以需要IDL来规范需要传输的对象。 不要太拘泥于概念,只需了解其本质即可。 除了使用一些开源的RPC框架之外,我们如何自己实现RPC呢? 这里介绍一下使用Netty实现的RPC。 黄勇(:/.git)和李业兵(:/ares-.git)都是基于Netty实现的RPC框架,都是供我们学习的demo。 虽然它与生产平台的 RPC 有所不同,但 很小,并且具有所有必需的功能。

框架结构如下:

netty现在使用多么_netty如何在项目中使用_netty使用反应堆模式

底层通信是使用Netty实现的,流程类似。

启动服务器并注册服务

客户端获取服务提供的信息并组装请求参数

序列化请求参数并请求服务器等待响应结果。

服务器获取结果并反序列化

反射调用服务实现

封装结果并将响应序列化给客户端

客户端反序列化获取结果

标签: 线程 操作 通信

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码