Netty HTTPS服务端高并发宕机案例

读李林峰《netty进阶指南》于第18章有感。特此记录一下问题的现象,以及他是如何排障的,以此加深理解

目录标题

  • 事件梳理
  • 排查
  • 事后分析
  • 如何解决
  • 总结

事件梳理

某系统内部两个模块之间采用 HTTPS 通信。

某天:

  1. 客户端某时间吞吐量为0,发送给服务端的消息失败
  2. 服务端OOM

排查

  1. 查看流量,并没有明显的流量变化,排除突发流量高峰导致系统过载。
  2. 客户端存在大量超时以及关闭连接的日志。
  3. 服务端日志发现,后台某个逻辑超时,超过了客户端的超时时间,所以这是客户端超时的原因。
  4. 此时dump内存,发现服务端的NioSocketChannel占用排名第一。这是服务端OOM的原因
  5. 停止压测,发现一切逐渐正常:客户端没有超时连接、服务端内存也正常。

事后分析

客户端与服务端通信架构图。客户端采用 HTTP 连接池的方式与服务端进行 RPC 调用,单个客户端连接池上限为200,客户端部署了30个实例,而服务端只部署了3个实例。
在这里插入图片描述

此问题出现原因是使用了HTTP1通信,高并发时,服务端瞬间涌入大量的HTTPS连接,
同时进行SSL握手,服务端处于高负载所以导致部分连接失败超时。客户端发起的重连、服务端GC受限无法及时关闭超时连接,又进一步加重服务器压力。

如何解决

功能层面:

  1. 服务端可以做流控(比如窗口限流等)、动态扩容、换为Open SSL
  2. 客户端也做流控、把超时时间设长同时加大tomcat线程数、减少并发请求RPC时的线程数量从200减到50(服务端用netty,网络IO不是问题,一旦出现服务端响应慢,说明服务端内部逻辑处理慢,此时再增加连接数量无意义)
    注意:在其他条件不变的情况下,只做“把超时时间设长同时加大tomcat线程数”相当于是:任务执行时间变长了,还加大线程的数量,可能把客户端也搞崩了。

架构层面:
1.客户端也使用Netty,进行多路复用。客户端使用httpclient发起RPC调用,网络IO阻塞时,CPU是空闲的。是典型的BIO模型,升级为NIO模型后:一个线程就可以轮询IO结果,有一个事件发生,就唤醒httpclient调用方。这样就增加了吞吐量。
3. 升级为HTTP2.0
3.客户端考虑异步编程,使用future来发起多个RPC调用,最后汇总结果

注意:使用netty解决了通信层面的异步问题,通信效率和可靠性提高了。
但是和服务的异步调用没有关系。
服务的异步与非异步调用,伪代码如下。远程调用RPC可以用netty,可以用BIO来实现。

	result1 = 远程调用RPC;// 同步阻塞result2	= 远程调用RPC;
和result1 = future(远程调用RPC);// 服务的异步调用result2	= future(远程调用RPC);

总结

导致NioSocketChannel泄漏的可能原因有两个。
(1)代码有缺陷,HTTPS客户端关闭连接之后,服务端没有正确关闭连接。
(2)服务端负载比较重,客户端超时之后的断连和重连速度超过服务端关闭连接速度,导致服务端的NioSocketChannel发生积压。随着积压数的增加,导致占用的内存快速增加,频繁GC使得服务端处理更慢,积压更严重,最终导致OOM异常。

在贴一个NIO的客户端、服务端的模型。不要忘了客户端也可以连接多个服务器,可以用多路复用来增加吞吐量。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/48569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海思arm-hisiv400-linux-gcc 交叉编译rsyslog 记录心得

需要编译rsyslog,参考海思3536平台上rsyslog交叉编译、使用-CSDN博客和rsyslog移植(亲测成功)_rsyslog交叉编译-CSDN博客 首先下载了要用到的一些库的源码,先交叉编译这些库 原来是在centos6上交叉编译的,结果编译时报缺少软件要…

MySQL练习02

题目 步骤 创建数据库 create database mydb8_worker; #创建数据库 use mydb8_worker; #使用数据库 创建表 create table t_worker( department_id int(11) not null comment 部门号, worker_id int(11) primary key not null comment 职工号, worker_date date not …

数据结构 - 栈(精简介绍)

文章目录 普通栈Stack用法Q 最长有效括号 单调栈Q 接雨水 普通栈 栈就是一个先进后出的结构 想象一个容器,往里面一层一层放东西,最早放进去的东西被压在下面(所以放元素也叫压栈),要拿到这个最低层的东西需要先把上面…

【系统架构设计师】十三、软件可靠性(基本概念|软件可靠性建模)

目录 一、基本概念 1.1 定义 1.2 软件可靠性的定量描述 1.3 可靠性测试的意义 1.4 广义的软件可靠性测试和狭义的软件可靠性测试 二、软件可靠性建模 2.1 可靠性模型的组成 2.2 可靠性模型的共同假设 2.3 可靠性模型的重要特性 2.4 可靠性建模方法 往期推荐 历年真…

当Excel处理神器EasyExcel遇上Apache POI:一场关于依赖的趣味‘撞车’冒险

目录 前言 报错 解决思想 解决方案 结尾 前言 🎈🎈🎈"Hey there, 大家好!我是Blue,今天可不是一般的‘代码奇遇记’!我在与EasyExcel这位数据处理界的魔术师共舞时,突然遭遇了前所未…

Unity-URP-SSAO记录

勾选After Opacity Unity-URP管线,本来又一个“bug”, 网上查不到很多关于ssao的资料 以为会不会又是一个极度少人用的东西 而且几乎都是要第三方替代 也完全没有SSAO大概的消耗是多少,完全是黑盒(因为用的人少,研究的人少,优…

解决GoLand添加GOROOT提示The selected directory is not a valid home for Go Sdk的问题

现象 解决 在Go安装路径下找到zversion.go文件,我的在D:\Program Files\Go1.21.1\src\runtime\internal\sys下面 打开文件,添加如下内容: const TheVersion go1.21.1保存后再重新添加GOROOT即可

Python莫兰生死抑制放大进化图

🎯要点 🎯种群离散时间莫兰生死动态图解 | 🎯良好混合种群的固定概率 | 🎯数值求解生成埃尔多斯-雷尼图 | 🎯计算马尔可夫链的转移矩阵概率 | 🎯出生死亡动态和死亡出生动态概率无向随机图和有向随机图&am…

react Jsx基础概念和本质

什么是jsx jsx是JavaScript和XML(HTML)的缩写&#xff0c;表示在js代码中编写HTML模板结构&#xff0c;它是react中编写UI模板的方式 const message this is message function App(){return (<div><h1>this is title</h1>{message}</div>) } jsx优…

Mike she中常出现的error及解决办法

前言&#xff1a; 最近用了下MIKE SHE坡面流模块&#xff0c;感觉一场雨降下来和MIKESHE和MIKE21模块算出来还是有不一样的地方&#xff0c;这个先不聊&#xff0c;聊点直接的&#xff0c;到底一个玩个模块遇到了哪些错误&#xff0c;我们来说说解决方法。 Error1&#xff1a;…

嵌入式人工智能(16-基于树莓派4B的电机控制-步进电机28BYJ-48)

1、步进电机 步进电机是一种旋转电机&#xff0c;通过在特定的步进角度内进行转动来实现精确的定位控制。步进电机通常由电磁线圈和磁轴组成&#xff0c;线圈通过电流激励产生磁场&#xff0c;而磁轴则受到线圈所产生的磁场的作用而转动。 步进电机的运动是离散的&#xff0c;…

el-select选择器修改背景颜色

<!--* FilePath: topSearch.vue* Author: 是十九呐* Date: 2024-07-18 09:46:03* LastEditTime: 2024-07-18 10:42:03 --> <template><div class"topSearch-container"><div class"search-item"><div class"item-name&quo…

野兔在线工具箱系统全新升级改版,基于TP8和yetuadmin后台实现

野兔在线工具箱系统全新升级改版&#xff0c;基于TP8和yetuadmin后台实现 系统名称&#xff1a;野兔在线工具系统 系统语言&#xff1a;支持多语言&#xff0c;大概有20种 系统源码&#xff1a;不加密&#xff0c;开源 系统开发&#xff1a;PHPMySQL (基于thinkphp8&#x…

linux内核中list的基本用法

内核链表 1 list_head 结构 为了使用链表机制&#xff0c;驱动程序需要包含<linux/types.h>头文件&#xff0c;该文件定义了如下结构体实现双向链&#xff1a; struct list_head {struct list_head *next, *prev; };2 链表的初始化 2.1 链表宏定义和初始化 可使用以…

无刷电机数学模型建立之——克拉克变换

前言 MOS管如何驱动无刷电机&#xff0c;请参考如下链接 无刷电机概念与原理 一、FOC流程图 二、FOC的过程是输入需求的电机力矩&#xff0c;最后把需求的电机力矩转换为三相线的电力输出&#xff0c;并且让电机旋转物理上输出需求的力矩的过程&#xff0c;这也称为电机控制三…

钡铼分布式I/O系统边缘计算Modbus,MQTT,OPC UA耦合器BL206

BL206系列耦合器是一个数据采集和控制系统&#xff0c;基于强大的32 位微处理器设计&#xff0c;采用Linux操作系统&#xff0c;支持Modbus&#xff0c;MQTT&#xff0c;OPC UA协议&#xff0c;可以快速接入现场PLC、DCS、PAS、MES、Ignition和SCADA以及ERP系统&#xff0c;同时…

通过vue3 + TypeScript + uniapp + uni-ui 实现下拉刷新和加载更多的功能

效果图: 核心代码: <script lang="ts" setup>import { ref, reactive } from vue;import api from @/request/api.jsimport empty from @/component/empty.vueimport { onLoad,onShow, onPullDownRefresh, onReachBottom } from @dcloudio/uni-applet form …

【Android】Activity的生命周期

Activity的生命周期 1.返回栈 其实Android是使用任务&#xff08;task&#xff09;来管理Activity的&#xff0c;一个任务就是一组存放在栈里的Activity的集合&#xff0c;这个栈也被称作返回栈&#xff08;back stack&#xff09;。栈是一种后进先出的数据结构&#xff0c;在…

AES算法概述

文章目录 一、AES 概述二、AES 加密算法的特点三、秘钥类型四、填充方式五、加密方式 一、AES 概述 二、AES 加密算法的特点 AES加密的数据块长度为128&#xff08;16字节&#xff09;&#xff0c;长度不足需要填充。密码长度可以为16,24,32字节。 三、秘钥类型 AES加密按秘…

【C++高阶】精通AVL树:全面剖析与深度学习

目录 &#x1f680; 前言一&#xff1a; &#x1f525; AVL树的性质二&#xff1a; &#x1f525; AVL树节点的定义三&#xff1a; &#x1f525; AVL树的插入四&#xff1a; &#x1f525; AVL树的平衡调整&#xff08;附动图&#xff09; 五&#xff1a;&#x1f525; AVL树的…