坑爹,线上同步近 3w 个用户导致链路阻塞引入发的线上问题,你经历过吗?

news2025/7/9 16:58:17

分享一个印象深刻的线上问题,希望能够给 xdm 带来一点思考

一个稀松平常的工作日,正准备下班的时候,不巧,突发线上紧急问题,心中一万个不情愿,可还是要硬着头皮去定位问题

简单的表象为微服务之间 gRPC通信的通道默认是用了默认值,并没有按照实际业务去设置通道接受和发送的字节大小

用过 golang grpc 通信的 xdm 就知道,grpc 通道默认的发送和接收的消息大小为 4M,由于传送的数据包大于了 4M,导致通道阻塞,一直报错 rpc 错误,

 rpc error: code = ResourceExhausted desc = grpc: received message larger than max (6394324 vs. 4194304)
复制代码

于是便有了一个定位并想办法解决或者规避问题的慢慢长夜

简述基本介绍通信流程

整个业务架构比较复杂,我们简单的提出出问题的服务链路来进行阐述

服务 A - 专门和第三方对接

有一个服务 A 是专门找第三方同步源读取第三方系统的用户组织结构,并转换成咱们平台自己的数据结构,将数据发送给 服务 B

服务 B - 专门处理用户相关数据

服务 B 专门处理关于用户组织结构数据的,处理完毕之后落盘,并将数据给到服务 C

服务 C - 主要做数据转发

服务 C 主要是做数据的通道,会将数据转发给到节点中的应用 D,因为 应用 D 和 服务 A 和 服务 B 没有办法直接通信

应用 D,处理处理实际的流量即管控

应用 D 接收或者去找 服务 C 拉取数据后做相应的业务,做基本的流量管控和用户认证等

其中上述两者之间都是通过 gRPC 的方式通信

问题 1 - rpc 通道发送和接收消息设置过小

万万没想到的是,在做第三方组织结构同步的时候,居然是服务 A 从第三方同步源中获取所有的用户组织结构(包括所有的组,所有的用户),不管总量多少,一口气全部弄过来,然后再一口气全部推给 服务 B

可这一次线上问题,正是因为这么 low 的做法和处理方式,导致超出了 gRPC 的默认消息大小 4M,显现就是服务 A 将数据发送给到服务 B 的时候,发送没有问题,但是服务 B 接收的时候出了问题,日志中疯狂打印上述的 rpc 错误

 rpc error: code = ResourceExhausted desc = grpc: received message larger than max (6394324 vs. 4194304)
复制代码

当然,这个时候不允许我们停下来去思考如何优化的事项,必须第一时间解决或者规避问题

立刻评估,将涉及到的服务,gRPC 的 send 和 receive 的地方全部统一修改为 32 M(1024102432) ,这个问题暂时得以规避

可以查看到 grpc 源码中的说明

MaxRecvMsgSize 接受消息 在 grpc 中默认大小为 4M−−(1024∗1024∗4)=2224M --(1024*1024*4)= 2^{22} 4M−−(1024∗1024∗4)=222

MaxSendMsgSize 发送消息在 grpc 中默认是MaxInt32=1<<31−1也就是4M∗29−1即2048M=2GMaxInt32 = 1<<31 - 1 也就是 4M * 2^9 -1 即 2048 M = 2GMaxInt32=1<<31−1也就是4M∗29−1即2048M=2G

则在 grpc.NewServer 的时候,将上述的 option 加上去就可以了,例如这样

// 例如设置接收消息大小为 math.MaxInt32
var opts []grpc.ServerOption
opts = append(opts, grpc.MaxRecvMsgSize(math.MaxInt32))
newSvr := grpc.NewServer(opts...)
// grpc RegisterxxxxServer()
复制代码

问题 2 - 组织结构同步的层级太小,不支持 16 层

本以为问题就这么规避了,然而还是太年轻

当服务 A 将数据全部打包发送到服务 B 的时候,才发现,原来问题才刚刚开始,由于数据量比之前测试过的数据量大了好几倍,导致各种问题接二连三的出来,这也体现了整个平台的健壮性太差

当前遇到的问题是服务 B 处理的组织结构层数,最大只能有 8 层,超过 8 层的数据就直接不要了😂😂😂,看到这里,what??? 之前是谁设计的😢😢😢

迅速阅读源码,查看相关联的逻辑,调整关联代码,火速将支持的 8 层,调整为 16 层组织结构,还好代码不是太复杂,否则这么大半夜的,真的不敢大动,毕竟这个时候已经不是一个人了,只是半个人😅😅😅

此处的组织结构好在不是传递的一棵树,如果是一棵树的话,大概率是要栈空间超限的,我们知道栈空间一般 2M,超过就要溢出了

好在是传递的是一个用户的 list,元素是关于用户的绝对路径,例如 /a/b/c/小花

问题 3 - 同步近 3 w 个用户居然花了近 8 分钟,近 3w 用户放到一个消息里

处理完问题 2 之后,尝试同步一次组织结构,发现近 3 w 的用户,居然同步花费了 8 分钟左右,其中 服务A 到服务B耗时近 2 分钟,然后服务 B 就处理了4 分钟,其余时间花费在别的服务处理

这个时候,就看到页面上一直在转圈,如果是用户看到一幕,那可能直接就是退货的节奏了🤣🤣

不过好在是同步成功了,暂时先把同步的按钮先关了吧,毕竟数据都过来了,接下来的事情都是可以调整的

其实看到这里,一个消息放近 3 w 个用户,只能说这一块根本没有设计,需求是赶鸭子上架赶出来的吧?对于这一块的优化放到下一篇来分享

问题 4 - 操作界面一直转圈,前端处理数据极慢

然而,当上一个问题还没有完全解决的时候,发现又爆出另外一个问题,看来年轻的不仅仅是一点点大,这个时候甲方爸爸要开始喊 细狗你行不行啊

打开平台,查看用户相关页面,卡的一匹,足以和上世纪打开网页的程度比慢了,简直没眼看,。处理 3 w 数据耗时 20 分钟,才看到正常的页面

原来处理方式是这样的:

前端找后台查询这个租户所有的用户,然后前端再进行树形展示,看到这里是不是蒙圈了???

哪有这么去实现功能的?基本的懒加载不会吗?暂时后端提供相应的接口, 前端 调整逻辑得以规避

懒加载, 是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据,而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用

然后,大部人的回答是,我也不知道会有那么多数据呀🤣🤣🤣,诶,还是吃亏在太年轻,不够专业,甚至还有人提议,这个页面暂时让客户不要点😥😥

问题 5 - 大数据日志上报,由于数据量猛增,导致日志通道阻塞

真是福无双至,祸不单行啊

由于大数据日志上报模块也需要通过 grpc 根用户数据更新时间来一次性查询用户,同样的问题,这一条链路也卡的要死,显示由于请求超时,因为 rpc 超时时间代码中默认就设置了 10 s , 后面将时间改大了之后得以规避,最终由于大数据模块处理数据慢,花费了 2 个小时才把近 3w 的数据搞定

心中想,这也是大数据??😪😪,感觉这个产品要完蛋了

问题 6 - 系统本身仅支持 1 w 用户,前线默默的揽了一个 5w 用户的客户

处理到这里,天也渐渐蒙蒙亮了,从性能测试的小伙伴报告中了解到,之前做的性能测试最多就支持 1 个租户下有 1w 个用户,然而,销售吹牛皮招揽了远远大于这个数的客户,且还不告知研发内部

其实销售也没想到,怎么我们的平台这么弱鸡?逐步丧失信心。。

实际上出现的问题远远不止上述几个,接下来便是无尽的优化和思考,希望暴露的问题能给 xdm 带来一些提醒和思考

无论之前架构如何,对于第三方组织结构同步的时候,咱们需要考虑这些问题

  • 产品的基本数据指标要同步给前线等相关方,避免自己人坑自己人,火急火燎的,很难有效的解决好问题
  • 从第三方获取组织结构的时候,基本的分页要有,不仅仅是分页从第三方同步源获取,还要分页的给出去
  • 对于服务 A 将数据给到服务 B 的时候,先分页给组,再分页给用户
  • 对于 rpc 中消息大小设计,需要在设计之初根据业务考虑到可能的消息情况,去设置一个合理的数值
  • 对于同步数据的时候,需要分步骤,分状态来进行处理,需要实现断点续传,需要能够应对各种异常场景
  • 对于前端从后台获取用户树的时候,务必记得使用懒加载(简单来说就是可以先获取最外层的组,当点击到某个组的时候,再去查询这个组下面的用户信息和子组信息,而不是一口气将整个租户的组织结构加载出来🤣🤣,这也太心大了)

自然,实际落地的时候还需要考虑很多,我们需要更多的往前看一步,不给别人留坑,也不给自己挖坑

自然我们需要提升自己的能力,提升自己的思维,不断向大佬看齐,可能低级问题我们都会犯,但要有进步,要有变化,做需求,做设计,需要考虑更加全面,否则你永远不知道你带来的影响有多大

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

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

相关文章

打造高安全数字基础设施:中国电子云服务关键行业的宣言

11月18日&#xff0c;主题为“至信铸云守正创新”的2022中国电子云峰会在北京举行。中国电子云在会上发布了其服务关键行业的价值主张、分布式云战略&#xff0c;实测了仓海CeaStor分布式存储的性能。中国电子党组书记、董事长曾毅&#xff0c;中国工程院院士沈昌祥&#xff0c…

制作电子签名

每天一个PS/PR小技巧&#xff08;原理实践&#xff09; 每天一个PS/PR小技巧&#xff08;原理实践&#xff09;_Dezeming的博客-CSDN博客PS是由Adobe Systems开发和发行的图像处理软件。本文的特色在于快速上手和制作一些生活中会常用的功能&#xff0c;并且解释这些功能的具体…

DJYGUI系列文章四:GK文本显示

目录 1 GK文本显示概述 1.1 ansi系 1.2 unicode系 1.3 DJYGUI文本显示 2 字符集说明 3 字符集API说明 3.1 ModuleInstall_Charset&#xff1a;字符编码模块初始化 ​​​​​​​3.2Charset_NlsInstallCharset&#xff1a;安装字符编码 ​​​​​​​3.3 Charset_NlsG…

1527_AURIX_TriCore内核架构开篇与架构概述

全部学习汇总&#xff1a; GreyZhang/g_tricore_architecture: some learning note about tricore architecture. (github.com) 看文档的时候&#xff0c;引用了内核架构的内容。这方面我没有看过&#xff0c;除了ARM也没有什么内核算是较为认真的看过。纵然是ARM&#xff0c;看…

锐捷MSTP实验配置

目录 Vlan基础配置 多生成树配置 查看生成树信息 MSTP其它特性配置 边缘端口 生成树保护特性 生成树时间特性 Vlan基础配置 SW1、SW2配置Vlan vlan range 10,20,40 int g0/0 switchport mode trunk switchport trunk allowed vlan add 10,2…

图卷积神经网络 | Python实现基于GCN-GRU图卷积门控循环单元网络模型

图卷积神经网络 | Python实现基于GCN-GRU图卷积门控循环单元网络模型 目录 图卷积神经网络 | Python实现基于GCN-GRU图卷积门控循环单元网络模型效果分析基本描述模型结构程序实现参考资料效果分析 基本描述 GCN-GRU 模型是用于动态网络数据中动态不确定意见预测的端到端可训练…

Linux多线程编程

文章目录1、线程基本知识2、线程控制3、线程同步与互斥<1>线程互斥<2>线程同步条件变量生产者消费者模型POSIX信号量读者写者问题<3>线程池<4>单例模式1、线程基本知识 线程概念 线程是在进程内部运行的一个执行分支(执行流)&#xff0c;属于进程的一部…

Vue2.0开发之——Vue基础用法-条件渲染指令(23)

一 概述 条件渲染指令—v-if和v-showv-elsev-else-if 二 条件渲染指令—v-if和v-show 2.1 条件渲染指令 条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个&#xff0c;分别是&#xff1a; v-ifv-show 2.2 示例 布局代码 <div id"a…

【考研复试】计算机专业考研复试英语常见问题五(兴趣爱好/实践经历篇)

相关链接&#xff1a; 【考研复试】计算机专业考研复试英语常见问题一&#xff08;家庭/家乡/学校篇&#xff09;【考研复试】计算机专业考研复试英语常见问题二&#xff08;研究方向/前沿技术/本科毕设篇&#xff09;【考研复试】计算机专业考研复试英语常见问题三&#xff0…

Redhat(10)-防火墙-文件管理-JINJA2模板-Cron-文件权限-NTP-autofs

1.防火墙 2.文件管理 3.JINJA2模板 4.Cron作业 5.文件权限 6.NTP 7.autofs 1.防火墙 网络过滤子系统-netfilter&#xff1a;修正、丢弃数据包。 firewalld是什么&#xff1f; 就是处理网卡来的数据包。 1.源地址被分配给特定区域&#xff0c;应用该区域的规则。 2.网卡…

PyQt5 QLineEdit

PyQt5 QLineEditQLineEdit常用方法及属性QLineEdit 实例1QLineEdit 实例2QLineEdit 实例3QLineEdit 综合示例QLineEdit常用方法及属性 QLineEdit 实例1 import sys from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import *class MyLineEditWindo…

【VTK+有限元后处理】实时剖切视图

目的 实现后处理结果云图的平面剖切视图。 方法 通过使用vtkPlaneWidget控件交互&#xff0c;得到剖切平面&#xff0c;通过vtkClipDataSet完成对vtkUnstructuredGrid有限元结果数据的剖切操作。渲染管线如下图所示[1]^{[1]}[1]。 代码实现 首先&#xff0c;我们先写一个创…

【软考软件评测师】第二十八章 计算机网络(网络设备网络地址)

【软考软件评测师】第二十八章 计算机网络&#xff08;网络设备网络地址&#xff09; 第二十八章 计算机网络&#xff08;网络设备网络地址&#xff09;【软考软件评测师】第二十八章 计算机网络&#xff08;网络设备网络地址&#xff09;第一部分 知识点集锦1.IPv4地址1&#…

Maya 贴图链接检测重链打包插件tjh_lost_textures_finder 1.3.2 更新发布

经常遇到maya工程文件贴图丢失或是路径链接更改的问题&#xff0c;对于贴图师和渲染师来说&#xff0c;海量的贴图重连 贴图和查找丢失贴图都是繁重耗时的工作。自从tjh_lost_textures_finder插件诞生以来&#xff0c;就一直再做此项工作的优化工作。 V1.3.2最新版更新内容&am…

Python爬虫:scrapy从项目创建到部署可视化定时任务运行

目录前言第一节 基本功能1、使用 pyenv创建虚拟环境2、创建 scrapy项目3、创建爬虫第二节 部署爬虫4、启动 scrapyd5、使用 scrapyd-client 部署爬虫项目6、使用 spider-admin-pro管理爬虫第三节 部署优化7、使用 Gunicorn管理应用8、使用 supervisor管理进程9、使用 Nginx转发…

简单shell批量文件转换gbk转为utf8编码

前言 matlab打包成exe时发现中文乱码&#xff0c;查找发现是gbk编码问题,找半天没找到合适的批量转换编码工具&#xff0c;就搞了个简单的shell来实现 准备工作 windows上有安装git bash命令行的话可以直接跑sh脚本,没有的话下一个很快。linux可以直接运行 代码 #!/bin/sh…

Answering the SDIs Step by Step

title: Notes of System Design No.01 —Answering the SDIs Step by Step description: Answering the SDIs Step by Step ’ date: 2022-05-04 14:52:06 tags: 系统设计 categories: 系统设计 In this Article , I will give a introduction to the guildline of answerin…

实验33:RFID门禁卡实验

OK&#xff0c;本实验分为两个部分 一、读卡 二、显示不同的卡的信息&#xff0c;同时继电器动作 01 硬件电路设计 读卡ID&#xff0c;两张卡&#xff0c;白卡和蓝卡&#xff0c;用txt文件名称体现 lib里面是库文件 把它放在自己的Arduino相应的文件家里&#xff0c;最好是…

MySQL数据库 -- 内置函数

今天来一起学习MySQL数据库的内置函数。 目录 日期函数 current_date current_time current_timestamp date_add date_sub datediff 实例演示 创建一张表&#xff0c;记录生日 创建一个留言表 字符串函数 charset concat length replace substring ucase…

第02章 变量

变量介绍 定义 定义&#xff1a;变量是程序的基本组成单位&#xff0c;变&#xff08;变化&#xff09;量&#xff08;值&#xff09; 变量有三个基本要素&#xff1a;数据类型 变量名称 值 变量相当于内存中的一个数据存储空间的表示&#xff0c;可以把变量看作是一个房间…