七的博客

Netty快速入门系列(一)-介绍

网络通信

Netty快速入门系列(一)-介绍

1. 前言

Netty 作为一个 Java 届目前最流行的一个网络通讯框架,可以用来很快速的开发出很高性能的网络通信应用程序。而且 Netty 在业内已经有大量的生产实践,只要符合最佳实际基本不会有太多的问题。

针对这些年使用 Netty 的一些经验,我将总结出 Netty 比较常用的一些知识点以及最佳实践。暂时定位包含这么些内容:

  • 简单介绍下 Netty 的历史、应用场景、优势等。
  • 快速过一个 HelloWorld 例子,为后面的介绍对比做准备。
  • Netty 中比较核心的概念名词、API等。
  • Netty 跟原生的 Java NIO 对比。
  • Netty 跟 Mina 的对比。
  • Netty 中对协议的编解码。
  • Netty 中的粘粘包处理。
  • Netty 中的线程模型讲解、对比。

学习技术最重要的还是学习官方的文档,互联网上的资料可以当做一个参考。文章里有一部分介绍的内容是从 Netty 官网的文档里获取的,这部分内容文档里描述的很清晰,没有必要再次进行重复加工。

2. Netty 是什么

Netty 是一个基于 JDK NIO 的网络通讯框架,本质上还是对于 JDK 的通讯 API 进行封装。 通过 Netty 可以快速的开发一个网络通讯应用程序。

学习一门技术前,先去看下官网 http://netty.io/ 的一些介绍:

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

Netty是一个异步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务器和客户端。

Netty is an NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

Netty 是一个基于 NIO客户端-服务器框架,可以快速轻松地开发网络应用,比如协议服务器和客户端。它可以极大地简化并简化了网络编程,如TCP和UDP套接字服务器。

‘Quick and easy’ doesn’t mean that a resulting application will suffer from a maintainability or a performance issue. Netty has been designed carefully with the experiences earned from the implementation of a lot of protocols such as FTP, SMTP, HTTP, and various binary and text-based legacy protocols. As a result, Netty has succeeded to find a way to achieve ease of development, performance, stability, and flexibility without a compromise.

【快速轻松】并不意味着应用程序将存在可维护性或性能问题。Netty 的设计汲取了众多协议实现的精华,包括FTP、SMTP、HTTP等多种二进制和文本协议。正因如此,Netty成功地在易用性、性能、稳定性和灵活性之间找到了平衡点,不必牺牲任何一方。

3. Netty 的一些特性

3.1 Design 设计

  • Unified API for various transport types - blocking and non-blocking socket. ( 为各种传输类型提供统一的API - 包括阻塞和非阻塞套接字 )
  • Based on a flexible and extensible event model which allows clear separation of concerns. ( 基于灵活可扩展的事件模型,实现关注点分离 )
  • Highly customizable thread model - single thread, one or more thread pools such as SEDA. ( 高度可定制的线程模型 - 单线程,一个或多个线程池,如SEDA )
  • True connectionless datagram socket support (since 3.1). ( 自3.1版本起真正的无连接数据报套接字支持 )

3.2 Ease of use 易用性

  • Well-documented Javadoc, user guide and examples. ( 详细的Javadoc文档、用户指南和示例 )
  • No additional dependencies, JDK 5 (Netty 3.x) or 6 (Netty 4.x) is enough. ( 无额外依赖,仅需JDK 5(Netty 3.x)或 JDK6(Netty 4.x) )

3.3 Performance 性能

  • Better throughput, lower latency. ( 更高的吞吐量,更低的延迟 )
  • Less resource consumption. ( 更少的资源消耗 )
  • Minimized unnecessary memory copy. ( 最小化不必要的内存复制 )

3.4 Security 安全性

  • Complete SSL/TLS and StartTLS support. ( 完整的SSL/TLS和StartTLS支持 )

3.5 Community 社区

  • Release early, release often. ( 快速迭代,持续发布 )
  • The author has been writing similar frameworks since 2003 and he still finds your feed back precious! ( 作者自2003年起持续开发类似框架,重视用户反馈 )

4. 为什么选择 Netty

在企业项目的一些通讯项目中,比较多的开发语言是 C/C++。 其中用 Java 语言写的通讯项目,比较多的还是以原生的 JDK NIO 、Apache Mina 、Netty 为主。

4.1 JDK NIO 存在的问题

Apache Mina 跟 Netty 都是对原生的 JDK NIO 进行封装,因为原生的 JDK NIO 使用起来特别的困难跟复杂。

  • JDK NIO 的空轮询 BUG , 主要会影响 Linux 系统上的 NIO 操作。 在某些情况下导致 Selector 进入死循环,消耗大量 CPU 资源。

  • 使用 JDK NIO 需要了解很多概念名词 , 比如 Channel、Buffer、Selector 等。

  • API 设计并不太友好,将近 20 多年前的 API 不一定符合现代的习惯。

  • 编写程序比较复杂。需要处理很多细节,如缓冲区的分配和释放、通道的注册和取消等。

  • 需要处理多线程编程。线程池,处理线程同步等这些问题,对于新手来说增加了编程的复杂性,不是特别的友好。

  • 缺乏一些高级特性,比如 HTTP、WebSocket 等协议的支持。 如果需要这些特性,需要自己实现,自行实现稍微困难且容易出错。

4.2 MINA 存在的问题

MINA 以前也是一个非常流行的网络通讯框架,但是随着时间的推移,也逐步暴露出来一些问题。

  • Mina 的社区活跃度在最近 10 年比较低,活跃度低意味着生产问题更不容易暴露到互联网上,资料也会更少。
  • Mina 的更新频率很低。
  • 高负载的场景下,Netty 的表现更加优异。
  • Mina 的资料更少,无论是中英文环境,都会比 Netty 更少。

相比之下 , Netty 提供了一个更高层次的抽象,屏蔽了很多底层的细节。这样无论是让新手程序员还是老手程序员,上手的成本都会低很多。

5. Netty 在业内的实践

Netty 已经被广泛应用于各种项目和产品中,无论是商业项目还是开源项目。

商业项目包括国内大中小型公司,海外的就更多。

开源的项目也是特别多,具体的一些列表可以参考 https://netty.io/wiki/related-projects.html ,这里面列举了一些比较出名的基于 Netty 的开源项目,不包括一些商业项目。列举一些比较典型的:

  • Elastic Search 一个分布式的RESTful搜索和分析引擎。

  • Apache Flink 分布式流处理框架。

  • Apache HBase Hadoop数据库 , 是一个分布式、可扩展的大数据存储。

  • gRPC 高性能开源通用RPC框架。

  • Apache Cassandra 一个面向列的分布式数据库。

  • Apache Pulsar 一个开源的分布式发布-订阅消息系统,类似于 Kafka 。

  • Apache Spark 一个快速通用的集群计算框架。

  • Lettuce 用于构建非阻塞响应式应用的可扩展Redis客户端,SpringBoot 高版本默认依赖的 Redis 客户端库。

  • Redisson 在Redis服务器之上提供分布式和可扩展的 Java 数据结构,很方便的一个库。

  • Netty-SocketIO 基于Netty的Socket.IO服务器实现。

  • Vert.x 用于在JVM上构建响应式应用的工具包。

  • Netflix Zuul L7应用网关,提供动态路由、监控、弹性、安全性等功能。

国内一些比较典型的项目:

  • Apache RocketMQ 阿里巴巴开源的分布式消息中间件。
  • Apache Dubbo 阿里巴巴开源的高性能RPC框架。
  • ShenYu 一个京东开源的异步高性能、跨语言、响应式的API网关。
  • Nacos 阿里巴巴开源的动态服务发现、配置管理和服务管理平台。
  • Seata 阿里巴巴开源的分布式事务中间件。
  • Sofa-Bolt 蚂蚁金服开源的基于Netty的网络通信框架。
  • XXL-JOB 分布式任务调度平台。

6. 总结应用场景

主要的应用场景集中在以下几点:

  • 实时通信应用。比如即时通讯系统 (QQ、微信这种)、聊天室、消息推送系统 (各种移动端的 XX 推送服务,极光等等)
  • 游戏客户端服务端通信。这种场景 对性能和并发有很高的要求,需要支持大量的并发连接和实时的数据交互。不过游戏行业普遍采用 C++ 的会多一点,更加稳定。
  • RPC 框架。一些知名的 RPC 框架,比如 Dubbo、gRPC 等都基于 Netty 构建。
  • HTTP 服务器。 尽管像 Tomcat 、Jetty 等容器已经很强大了,但是如果需要高性能以及低延迟,也可以尝试基于 Netty 自定义开发一个 HTTP 服务器 。
  • API 网关。开发类似于 Zuul 这种网关。
  • 物联网应用。物联网应用通常需要支持大量的设备连接 , 并且需要实时地交互数据。Netty 可以满足物联网应用的需求。

参考链接