一次奇怪的事故:机器网络连接打满,导致服务不可用

业务背景

发生事故的业务系统是一个toB业务,业务是服务很多中小企业进行某项公共信息指标查询。系统特点:业务处理相对简单,但是流量大,且对请求响应要求较高:

业务请求峰值qps达50w,平时流量达20w左右。
请求响应时间需控制在50ms内。

系统整体架构如下:
在这里插入图片描述

为了方便下文描述,我简化一下业务处理逻辑:根据请求的内容,从数据库中查询对应的结果,然后返回,为了支撑大并发,把数据库中的数据全部缓存到了redis中,简单来说就是查询redis,返回结果。

业务系统的实现技术也比较常规,采用springboot+redis来完成。为了保证系统的高可用性,我们在系统的入口处添加了限流处理,正常单机可以处理1w并发,为了防止系统过载,限流阈值设置8000qps,超过8000的流量会进行降级处理:返回一个默认值。

在这里插入图片描述

整个业务服务集群70台机器,可以轻松抗住50w并发

系统自上线后的半年多的时间内,都比较稳定。不过就在前几天出了一个奇怪的问题。

事故描述

业务系统的前端的slb告警:新建网络连接过多

但是同一时刻后端服务的负载却是正常的,过了几秒后,
slb告警:与某几个后端服务实例健康检查失败

随后该后端服务实例,从slb上被摘除,实例上流量跌零

看到这一连串的告警,瞬间觉得很懵逼:发生什么事了?这个时候,查看监控,业务请求的qps并没有出现异常流量,请求的qps在45w左右,远没有超过系统容量。

查看日志发现:后端服务和redis之间的网络在刚刚出现了一点抖动,但是很快就恢复了正常了。

为什么后端服务与redis之间瞬间的网络抖动,会触发这么一连串的问题呢?更何况现在后端服务已经恢复了正常?

既然现在后端服务是正常的,那么就对这几个实例进行重启,实例重启后,实例重新注册到了slb上,流量正常进入,一切又恢复了正常。

事故起因

虽然线上问题解决了,但是我们心中的疑问并没有解决。

冷静过后,开发同学对刚刚的问题进行了复盘:为什么后端服务与redis之间短时间的网络抖动,会导致slb上连接被占满呢?看着两者好像没有什么关系

通过观察事故发生事件段内的监控和日志:
网络抖动期间,服务器实例创建了大量的网络连接,新建网络连接超过10000多个,平常只有几百个。

结合日志和监控,系统出现问题的大致流程如下:

后端服务与redis之间网络抖动,使服务实例与redis进行了连接重试,导致在那段时间内,该服务实例对请求的处理变慢

但slb到该实例的请求转发还是正常,因为后端服务请求处理的比较慢,所以slb需要和后端服务建立新的网络连接来进行新的请求的发送,新建连接发送的请求,被处理的速度依旧很慢,所以需要不断的建立新的连接,很快导致该实例所在的机器的网络连接被占满。

机器网络连接被占满后,slb再将请求转发到该机器上时,网络连接的建立就会被阻塞,直至超时,而超时后,slb又会进行重试,导致出现的大量链接建立行为,也就出现了slb连接创建过多的告警,这个时候slb与该实例的健康检查请求也会出现问题,导致该实例从slb上被摘除。

问题分析

问题的原因虽然找到了,但是这里还有几个问题需要继续讨论一下:

后端服务的限流配置是:该服务实例1s最大可以处理8000个请求,而网络连接被打满时,最多可以建立8000个链接,难道限流没有生效吗?

通过查看日志发现,事故时间段内,并没有达到限流的条件,也没有进行限流相关的处理。

看到这里就有点想不明白了,为什么创建了8000个链接,却没有触发限流呢?

其实这里要了解一个springboot中tomcat中关于网络连接相关的配置了,下面是本项目中关于tomcat的配置:

server:tomcat:accept-count: 1000max-connections: 8000

tomcat网络连接管理模型如下:

在这里插入图片描述

maxConnections:

服务程序可以在一定时间内接收并处理的连接数目如图1中queue-2,超过这个数,会根据acceptCount 这个值继续建立连接存放在queue-1中,但是该连接不会被处理,只有当queue-2中的连接数小于maxConnections值,queue-1中的连接才会进入queue-2中,该连接才有可能被执行。queue-2中的连接状态如图2标注所示。当同时请求数大于maxConnections+acceptCount 时,新的请求将会被拒绝连接。

acceptCount

超过maxConnections这个值的连接数将根据acceptCount这个值继续建立连接,如图1 queue-1,当queue-2的连接数小于maxConnections, queue-1的连接进入queue-2.

maxThreads:

服务程序可以同时处理的线程数如图1 ThreadPool,可以理解为通过设定 maxConnections=10 ,同时可以建立10个连接,maxThreads=3,则这10个连接中同时只有3个连接被处理,其余7个连接都在queue-2中等待被处理,等这3个连接处理完之后,其余的7个连接中的3个才可以被处理。如果处理完的3个连接关闭后,queue-1中就可以有3个连接进入queue-2。

总结来说:当客户端发送请求时,完成三次握手建立连接后,先进入queue1中,然后在转移到queue2中,然后在被ThreaPool中的线程处理。

我们系统中 maxConnections参数值 是8000,也就是进入系统的最大并发也就是8000,当系统请求处理比较慢时,系统中进行8000qps的限流,其实是不起作用的。

当服务业务处理变慢时,也就是ThreadPool从queue2中取出请求速度变慢了,那么queue2就会变满,进而queue1也会变满,此时,当再有请求过来时,就会等待,直到queue1空出一个位置,或者请求连接建立超时。

解决方案

到这里,我们明白了为什么机器实例的链接会被打满,以及系统服务的限流降级策无法生效了。

解决方案就比较简单了:
首先出现上述一连串问题的根本原因是:实例机器网络连接被占满。
所以解决方案的出发点就是:避免实例机器网络连接被占满,因此需要把maxConnections 和
我们将 acceptCount设置大一些

同时给业务系统添加请求处理响应时间的限流和降级策略。

这样可以保证流量都能进到系统中,而不至于连接建立失败,只是超过系统可承载的部分被限流出去了。

调整后的系统架构图如下:

在这里插入图片描述

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

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

相关文章

前端学习第七天-css常用样式设置

达标要求 掌握元素的显示与隐藏 熟练应用溢出的文字隐藏 熟练掌握版心和布局流程 1. 元素的显示与隐藏 在CSS中有三个显示和隐藏的单词比较常见,我们要区分开,他们分别是 display visibility 和 overflow。 他们的主要目的是让一个元素在页面中消失…

Springboot接口参数校验

在设计接口时我们通常需要对接口中的非法参数做校验,以降低在程序运行时因为一些非法参数而导致程序发生异常的风险,例如登录的时候需要校验用户名密码是否为空,创建用户的时候需要校验邮件、手机号码格式是否准确。如果在代码中对接口参数一…

【Git教程】(三)提交详解 —— add、commit、status、stach命令的说明,提交散列值与历史,多次提交及忽略 ~

Git教程 提交详解 1️⃣ 访问权限与时间戳2️⃣ add命令与 commit 命令3️⃣ 提交散列值4️⃣ 提交历史5️⃣ 一种特别的提交查看方法6️⃣ 同一项目的多部不同历史6.1 部分输出:-n6.2 格式化输出:--format、--oneline6.3 统计修改信息:--st…

Linux内存地址空间

目录 一、虚拟地址空间 1.虚拟地址空间的定义 2.虚拟地址空间的布局 二、内存壁垒 1.内存壁垒的定义​编辑 2.段错误 三、内存映射的建立与解除 (1)mmap (2)munmap (3)堆内存的分配和释放 1.sbrk …

浅析能耗监测系统在大型数据中心的应用

彭姝麟 Acrelpsl 1总体设计 大型数据中心能耗监测系统包含硬件和软件两大部分,其硬件组成主要包括监控服务器、主机设备、网络设备、环境参数传感器、通风模块等,总体采集逻辑采用三级监控体系。一级为主机设备,作为系统的应用层&#xff0c…

【JSON2WEB】06 JSON2WEB前端框架搭建

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 前端技术路线太多了,知识点更多&…

【Maven】Maven 基础教程(一):基础介绍、开发环境配置

《Maven 基础教程》系列,包含以下 3 篇文章: Maven 基础教程(一):基础介绍、开发环境配置Maven 基础教程(二):Maven 的使用Maven 基础教程(三):b…

探索数据宇宙:深入解析大数据分析与管理技术

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…

Linux技巧|centos7|重新认识和学习egrep和grep命令

前言: 相信提高文本检索工具,大家脑海里肯定有很多工具会自动跳出来,比如,grep,egrep,sed,cat,more,less,cut,awk,vim,vi…

排序算法--堆排序

堆排序的时间复杂度是O(N*logN),优于选择排序O(N^2) 一、堆 1.堆的概念:堆一般指的是二叉堆,顾名思义,二叉堆是完全二叉树或者近似完全二 2.堆的性质:①完全二叉树 ②每…

【QT+QGIS跨平台编译】之六十二:【QGIS_CORE跨平台编译】—【错误处理:未定义类型QgsPolymorphicRelation】

文章目录 一、未定义类型QgsPolymorphicRelation二、解决办法一、未定义类型QgsPolymorphicRelation 报错信息: 错误原因为,使用了未定义类型 QgsPolymorphicRelation 二、解决办法 QgsRelation.h文件中 ①注释第36行: //class QgsPolymorphicRelation;②注释第414行: …

智能家居控制系统(51单片机)

smart_home_control_system 51单片机课设,智能家居控制系统 使用及转载请标明出处(最好点个赞及star哈哈) Github地址,带有PPT及流程图 Gitee码云地址,带有PPT及流程图 ​ 以STC89C52为主控芯片,以矩阵键…

Linux Shell脚本练习(一)

一、 Linux下执行Shell脚本的方式: 1、用shell程序执行脚本: a、根据你的shell脚本的类型,选择shell程序,常用的有sh,bash,tcsh等 b、程序的第一行#!/bin/bash里面指明了shell类型的,比如#!/…

【监督学习之支持向量机(SVM)】

曾梦想执剑走天涯,我是程序猿【AK】 目录 简述概要知识图谱基本原理支持向量线性SVM与非线性SVM优化问题软间隔与正则化SVM的应用实现 简述概要 了解监督学习-支持向量机(SVM) 知识图谱 支持向量机(Support Vector Machine&…

WPF的DataGrid自动生成中文列头

直接将一个对象集合绑定到DataGrid上面,设置自动生成列AutoGenerateColumns"True",DataGrid会自动根据对象类的属性生成对应的列 示例类对象: public class DataModel{public int Id { get; set; }public string Name { get; set;…

网站添加pwa操作和配置manifest.json后,没有效果排查问题

pwa技术官网:https://web.dev/learn/pwa 应用清单manifest.json文件字段说明:https://web.dev/articles/add-manifest?hlzh-cn Web App Manifest:Web App Manifest | MDN 当网站添加了manifest.json文件后,也引入到html中了&a…

构建大语言模型的四个主要阶段

大规模语言模型的发展历程虽然只有短短不到五年的时间,但是发展速度相当惊人,国内外有超过百种大模型相继发布。中国人民大学赵鑫教授团队在文献按照时间线给出 2019 年至 2023 年比较有影响力并且模型参数量超过 100 亿的大规模语言模型。大规模语言模型…

66-ES6:var,let,const,函数的声明方式,函数参数,剩余函数,延展操作符,严格模式

1.JavaScript语言的执行流程 编译阶段:构建执行函数;执行阶段:代码依次执行 2.代码块:{ } 3.变量声明方式var 有声明提升,允许重复声明,声明函数级作用域 访问:声明后访问都是正常的&…

集成2.5G/5G/10G高速率网络变压器的RJ45网口连接器产品特点介绍

Hqst华轩盛(石门盈盛)电子导读:集成2.5G/5G/10G高速率网络变压器的RJ45网口连接器产品特点介绍: 第一、 高速率:支持高达2.5Gbps、5Gbps和10Gbps的传输速率,能够满足高带宽的网络应用需求。 第二、 集成2.5G/5G/10G高速率网…

【C++庖丁解牛】类与对象

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.面向过程和面向对象…