在 Java 界,Netty 无疑是开发网络应用的拿手菜。你不需要太多关注复杂的 Nio 模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能。

和 Golang 的网络模块相比,Netty 还是太过臃肿。不过 Java 类框架就是这样,属于那种离了 IDE 就无法存活的编码语言。

最新的 Netty 版本将模块分的非常细,如果不清楚每个模块都有什么内容,直接使用 netty-all 即可。

单纯从使用方面来说,Netty 是非常简单的,掌握 ByteBuf、Channel、Pipeline、Event 模型等,就可以进行开发了。你会发现面试 Netty 相关知识,没得聊。但 Netty 与其他开发模式很大不同,最主要的就是其异步化。异步化造成的后果就是编程模型的不同,同时有调试上的困难,对编码的要求比较高。

在 Java 界,netty 无疑是开发网络应用的拿手菜。你不需要太多关注复杂的 nio 模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能。

和 golang 的网络模块相比,netty 还是太过臃肿。不过 Java 类框架就是这样,属于那种离了 IDE 就无法存活的编码语言。

最新的 netty 版本将模块分的非常细,如果不清楚每个模块都有什么内容,直接使用netty-all即可。

单纯从使用方面来说,netty 是非常简单的,掌握 ByteBuf、Channel、Pipeline、Event 模型等,就可以进行开发了。你会发现面试 netty 相关知识,没得聊。但 Netty 与其他开发模式很大不同,最主要的就是其异步化。异步化造成的后果就是编程模型的不同,同时有调试上的困难,对编码的要求比较高,因为 bug 的代价与业务代码的 bug 代价不可同日而语。

但从项目来说,麻雀虽小五脏俱全,从业务层到服务网关,以及各种技术保障,包括监控和配置,都是需要考虑的因素。netty 本身占比很小。

本文将说明使用 netty 开发,都关注哪些通用的内容,然后附上单机支持 100w 连接的 linux 配置。本文并不关注 netty 的基础知识。

协议开发

网络开发中最重要的就是其通讯格式,协议。我们常见的 protobuf、json、avro、mqtt 等,都属于此列。协议有语法、语义、时序三个要素。

我见过很多中间件应用,采用的是 redis 协议,而后端落地的却是 mysql;也见过更多的采用 mysql 协议实现的各种自定义存储系统,比如 proxy 端的分库分表中间件、tidb 等。

我们常用的 redis,使用的是文本协议;mysql 等实现的是二进制协议。放在 netty 中也是一样,实现一套 codec 即可(继承 Decoder 或 Encoder 系列)。netty 默认实现了 dns、haproxy、http、http2、memcache、mqtt、redis、smtp、socks、stomp、xml 等协议,可以说是很全了,直接拿来用很爽。

一个可能的产品结构会是这样的,对外提供一致的外观,核心存储却不同:文本协议在调试起来是比较直观和容易的,但安全性欠佳;而二进制协议就需要依赖日志、wireshark 等其他方式进行分析,增加了开发难度。传说中的粘包拆包,就在这里处理。而造成粘包的原因,主要是由于缓冲区的介入,所以需要约定双方的传输概要等信息,netty 在一定程度上解决了这个问题。

每一个想要开发网络应用的同学,心里都埋了一颗重新设计协议的梦想种子。但协议的设计可以说是非常困难了,要深耕相应业务,还要考虑其扩展性。如没有特别的必要,建议使用现有的协议。

连接管理功能

做 Netty 开发,连接管理功能是非常重要的。通信质量、系统状态,以及一些黑科技功能,都是依赖连接管理功能。无论是作为服务端还是客户端,netty 在创建连接之后,都会得到一个叫做Channel的对象。我们所要做的,就是对它的管理,我习惯给它起名叫做ConnectionManager

管理类会通过缓存一些内存对象,用来统计运行中的数据。比如面向连接的功能:包发送、接收数量;包发送、接收速率;错误计数;连接重连次数;调用延迟;连接状态等。这会频繁用到 Java 中concurrent 包的相关类,往往也是 bug 集中地。

但我们还需要更多,管理类会给予每个连接更多的功能。比如,连接创建后,想要预热一些功能,那这些状态就可以参与路由的决策。通常情况下,将用户或其他元信息也 attach 到连接上,能够多维度的根据条件筛选一些连接,进行批量操作,比如灰度、过载保护等,是一个非常重要的功能。

管理后台可以看到每个连接的信息,筛选到一个或多个连接后,能够开启对这些连接的流量录制、信息监控、断点调试,你能体验到掌控一切的感觉。

管理功能还能够看到系统的整个运行状态,及时调整负载均衡策略;同时对扩容、缩容提供数据依据。

心跳检测

应用协议层的心跳是必须的,它和 tcp keepalive 是完全不同的概念。

应用层协议层的心跳检测的是连接双方的存活性,兼而连接质量,而keepalive检测的是连接本身的存活性。而且后者的超时时间默认过长,完全不能适应现代的网络环境。心跳就是靠轮训,无论是服务端,还是客户端比如GCM等。保活机制会在不同的应用场景进行动态的切换,比如程序唤起和在后台,轮训的策略是不一样的。

Netty 内置通过增加IdleStateHandler产生IDLE事件进行便捷的心跳控制。你要处理的,就是心跳超时的逻辑,比如延迟重连。但它的轮训时间是固定的,无法动态修改,高级功能需要自己定制。

在一些客户端比如 Android,频繁心跳的唤起会浪费大量的网络和电量,它的心跳策略会更加复杂一些。

边界

优雅退出机制

Java 的优雅停机通常通过注册 JDK ShutdownHook 来实现。

Runtime.getRuntime().addShutdownHook();

一般通过kill -15进行 Java 进程的关闭,以便在进程死亡之前进行一些清理工作。

注意:kill -9 会立马杀死进程,不给遗言的机会,比较危险。

虽然 netty 做了很多优雅退出的工作,通过EventLoopGroupshutdownGracefully方法对 nio 进行了一些状态设置,但在很多情况下,这还不够多。它只负责单机环境的优雅关闭。

流量可能还会通过外层的路由持续进入,造成无效请求。我的通常做法是首先在外层路由进行一次本地实例的摘除,把流量截断,然后再进行 netty 本身的优雅关闭。这种设计非常简单,即使没有重试机制也会运行的很好,前提是在路由层需要提前暴露相关接口。

异常处理功能

netty 由于其异步化的开发方式,以及其事件机制,在异常处理方面就显得异常重要。为了保证连接的高可靠性,许多异常需要静悄悄的忽略,或者在用户态没有感知。

netty 的异常会通过 pipeline 进行传播,所以在任何一层进行处理都是可行的,但编程习惯上,习惯性抛到最外层集中处理。

为了最大限度的区别异常信息,通常会定义大量的异常类,不同的错误会抛出不同的异常。发生异常后,可以根据不同的类型选择断线重连(比如一些二进制协议的编解码紊乱问题),或者调度到其他节点。

功能限制

指令模式

网络应用就该干网络应用的事,任何通讯都是昂贵的。在《Linux 之《荒岛余生》(五)网络篇》中,我们谈到百万连接的服务器,广播一个 1kb 消息,就需要 1000M 的带宽,所以并不是什么都可以放在网络应用里的。

一个大型网络应用的合理的思路就是值发送相关指令。客户端在收到指令以后,通过其他方式,比如 http,进行大型文件到获取。很多 IM 的设计思路就是如此。

指令模式还会让通讯系统的扩展性和稳定性得到保证。增加指令可以是配置式的,立即生效,服务端不需要编码重启。

稳定性保证

网络应用的流量一般都是非常大的,并不适合全量日志的开启。应用应该只关注主要事件的日志,关注异常情况下的处理流程,日志要打印有度。

网络应用也不适合调用其他缓慢的 api,或者任何阻塞 I/O 的接口。一些实时的事件,也不应该通过调用接口吐出数据,可以走高速 mq 等其他异步通道。

缓存可能是网络应用里用的最多的组件。jvm 内缓存可以存储一些单机的统计数据,redis 等存储一些全局性的统计和中间态数据。网络应用中会大量使用 redis、kv、高吞吐的 mq,用来快速响应用户请求。总之,尽量保持通讯层的清爽,你会省去很多忧虑。

单机支持 100 万连接的 Linux 配置

单机支持 100 万连接是可行的,但带宽问题会成为显著的瓶颈。启用压缩的二进制协议会节省部分带宽,但开发难度增加。

和《LWP 进程资源耗尽,Resource temporarily unavailable》中提到的 ES 配置一样,优化都有类似的思路。这份配置,可以节省你几天的时间,请收下!

操作系统优化

更改进程最大文件句柄数

ulimit -n 1048576

修改单个进程可分配的最大文件数

echo 2097152 > /proc/sys/fs/nr_open

修改/etc/security/limits.conf 文件

*   soft nofile  1048576*   hard nofile 1048576*   soft nproc unlimitedroot soft nproc unlimited

记得清理掉/etc/security/limits.d/*下的配置

网络优化

打开/etc/sysctl.conf,添加配置然后执行,使用sysctl生效

#单个进程可分配的最大文件数fs.nr_open=2097152#系统最大文件句柄数fs.file-max = 1048576#backlog 设置net.core.somaxconn=32768net.ipv4.tcp_max_syn_backlog=16384net.core.netdev_max_backlog=16384#可用知名端口范围配置net.ipv4.ip_local_port_range='1000 65535'#TCP Socket 读写 Buffer 设置net.core.rmem_default=262144net.core.wmem_default=262144net.core.rmem_max=16777216net.core.wmem_max=16777216net.core.optmem_max=16777216net.ipv4.tcp_rmem='1024 4096 16777216'net.ipv4.tcp_wmem='1024 4096 16777216'#TCP 连接追踪设置net.nf_conntrack_max=1000000net.netfilter.nf_conntrack_max=1000000net.netfilter.nf_conntrack_tcp_timeout_time_wait=30#TIME-WAIT Socket 最大数量、回收与重用设置net.ipv4.tcp_max_tw_buckets=1048576# FIN-WAIT-2 Socket 超时设置net.ipv4.tcp_fin_timeout = 15

总结

netty 的开发工作并不集中在 netty 本身,更多体现在保证服务的高可靠性和稳定性上。同时有大量的工作集中在监控和调试,减少 bug 修复的成本。

深入了解 netty 是在系统遇到疑难问题时能够深入挖掘进行排查,或者对苛刻的性能进行提升。但对于广大应用开发者来说,netty 的上手成本小,死挖底层并不会产生太多收益。


作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和 Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信 xjjdog0,欢迎添加好友,​进一步交流。​


本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。

阅读全文: http://gitbook.cn/gitchat/activity/5db2984276f64d1ab527e9cb

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App , GitChat 专享技术内容哦。

使用Netty,我们到底在开发些什么? 1相关推荐

  1. 使用Netty,我们到底在开发些什么?

    在java界,netty无疑是开发网络应用的拿手菜.你不需要太多关注复杂的nio模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能. 和golang的网络模块相比,netty还是太 ...

  2. python中mod是什么意思_【python中,mod_python到底做了些什么呢?】mod python 教程

    python 编程小白 ,不会用doctest 请大神指教怎么用!! >>> >>> def is_between(v, lower, higher): ...   ...

  3. 【zhailu】国外产品经理到底在做些什么?【转载内容】

    产品经理在国内可以算是比较新兴的行业.起步晚.环境不同,自然有所需.有所缺. 一开始接触,就感觉,这是要把product从无到有培育起来,--这个product的PM似乎与project的PM雷同只是 ...

  4. 软件在安装时,到底做了些什么?

    软件在安装时,到底做了些什么? 大家每天都在用电脑,可能也经常在自己的电脑上安装软件.就算自己没安装过,至少也看到人家安装过软件.在这里,我不是想教你怎么安装软件,而是想向你展示,软件在安装的过程中, ...

  5. 「01」机器学习,到底在学些什么?

    这是参加原力计划单独投稿的,是我专栏文章的part 2​​​​​​​ 2. 机器学习,到底在学些什么? 2.1 什么是学习? 根据定义,学习是从有限的例子中,找出问题和答案之间规律的一个过程,而所找出 ...

  6. 数据库软件架构,到底要设计些什么?

    数据库软件架构,到底要设计些什么? 原创作者: 58沈剑 来自公众号:架构师之路 一.基本概念 概念一:单库 概念二:分片 分片解决"数据量太大"这一问题,也就是通常说的" ...

  7. 计算机网络到底讲了些什么

    小智:大鹏哥,我最近看了下计算机网络,把书上的内容都过了一遍,可是感觉还是串不起来,不知道计算机网络到底讲了些什么内容,也不知道重点在哪里,你能不能给我梳理梳理呀! 计算机为什么要联网 大鹏:行,那咱 ...

  8. 冰河最新出版的《深入理解高并发编程:核心原理与案例实战》到底讲了些啥?(视频为证)

    大家好,我是冰河~~ 最近有很多小伙伴问我:<深入理解高并发编程:核心原理与案例实战>这本书有没有目录.我:安排!这不,我连夜录制了这本书的整体内容,希望能够为小伙伴们带来实质性的帮助,直 ...

  9. 【说透中台】03 | 中台定义:当我们谈中台时到底在谈些什么?

    前面两讲,我带你从时间维度重新走了一遍中台的发展历程,又在空间维度为你介绍了目前市面上出现过的各类中台. 估计你现在一定被这么多种类的中台搞的有点晕头转向了,这些中台都称的上是中台么?感觉和之前一直在 ...

最新文章

  1. Python经典面试题100道(附PDF下载地址)
  2. springboot使用HttpSessionListener监听器统计在线用户数
  3. 论文浅尝 | GMNN: Graph Markov Neural Networks
  4. 安装 PyTorch C++ API libtorch 及一个最小例子
  5. Windows系统端口转发
  6. Coursera 机器学习笔记(五)
  7. rspec 测试页面元素_如何使用RSpec对Go应用进行黑盒测试
  8. pbl和sbl_PBL与SBL联合教学模式在妇产科教学中的应用研究
  9. asio::io_service被废弃的问题
  10. window8.1中用户的管理员权限的提升方法
  11. winform point数组带数值_excel 根据条件标注最大数值最小数值
  12. Atitit.prototype-base class-based  基于“类” vs 基于“原型”
  13. SpringMVC中Model,ModelAndView,ModelMap的区别
  14. android fastboot 最新版,用adb、fastboot拯救你的安卓手机
  15. IATF16949:2016汽车质量管理体系认证办理流程
  16. 读书-思考力|《金字塔原理》
  17. 冬吃萝卜有讲究 名中医解疑惑
  18. 从 PC 卸载 Office
  19. 长春光机所计算机待遇,有谁知道长春光机所的工资待遇怎么样?硕士一年的收入大概是多少?...
  20. 2017年世界科技11大进展

热门文章

  1. 如何打印csdn的博客,支持谷歌、火狐浏览器
  2. css圆角边框、文字、盒子阴影
  3. Oracle 9i 10g编程艺术-深入数据库体系结构——第6章:锁
  4. 机器学习可解释性(一)
  5. WordPress图片防盗链的几种方法
  6. [数据挖掘之scikit-learn] sklean.svm 分类器实例详解
  7. 人工智能技术:如何应对未来的挑战和机遇
  8. 解开紫光展锐8.37%员工股权代持的疑团
  9. python高级数据分析师_python分析各大城市对数据分析师的招聘情况
  10. centos有阵列机器安装软件方法