SRE实战:如何低成本推进风险治理?稳定性与架构优化的3个策略
一分钟精华速览
SRE 团队每天面临着不可控的各类风险和重复发生的琐事,故障时疲于奔命忙于救火。作为技术管理者,你一直担心这些琐事会像滚雪球一样,越来越多地、无止尽地消耗你的团队,进而思考如何系统性地枚举、掌控这些风险?怎么能更低成本地推进风险治理?
本文根据多家企业 SRE 实战总结,重点分享稳定性和架构优化的核心策略。实践已经验证,多且散的风险是可以被低成本解决的。
作者介绍
数列科技联合创始人、CTO——陆学慧
TakinTalks 稳定性社区发起人。参编《信息系统稳定性保障能力建设指南 1.0》和《稳定性保障服务商能力要求》。2017 年联合创立数列科技,专注于高可用性领域,为企业提供稳定性解决方案,帮助快速稳定地应对技术挑战。
温馨提醒:本文约 5000 字,预计花费 9 分钟阅读。
「TakinTalks 稳定性社区」公众号后台回复 “交流” 进入读者交流群;回复“0926”获取课件资料;
背景
最近一两年,我和很多公司的 SRE 团队进行了交流,发现大家日常都在面临一些故障处理、应急、琐事等等之类的难题。总的来说,就是团队能力和掌控系统风险之间存在一些差距。
其实,系统和人一样会出现健康问题,这是不可避免的。很简单的比方,我们很难通过一次体检、一次手术,就把身上所有不健康的指标变成正常指标,这是不现实的。从长远来看,我们所有的稳定性和 SRE 工作,其实是在解决系统的整体健康和医疗成本之间的平衡问题。
今天我将主要分享如何系统地解决这些问题,以及稳定性保障和架构优化的核心策略。本次分享将以案例实践为主,我将快速与大家分享我对 SRE 团队所面临的问题和核心策略的理解,也将结合实际案例分析,并深入理解核心策略的具体内容。
一、SRE 团队面临哪些核心问题?
1.1 风险多且散
我个人理解的 SRE 面临的两个最核心的问题,可能和大家在业界常讨论的有些不一样。
SRE 的同学都知道航空界的海恩法则:每一起严重事故的背后,必然有 29 次轻微事故和 300 起未遂先兆以及 1000 起事故隐患。大家听起来觉得都很有道理,但是与很多 SRE 同学交流后发现,实际工作中大家眼睛都盯着故障,故障的发现、故障的应急处理、故障的快恢等等。
那背后的 29 次轻微事故和 300 起未遂先兆以及 1000 起事故隐患,为什么不管呢?因为故障背后的风险太多、太散了。
以一个普通互联网公司为例——
应用多:一般公司应用 200 以上
风险类型多:版本发布、配置变更、局部流量变化、全局流量变化、运行环境变化、架构变化、服务依赖变化、数据库容量、缓存容量等
故障原因散:短中期看故障根因很难总结并以此预防后续故障
所以可以看到故障风险是非常复杂的。比如,一个公司里识别出来的风险数量在 2 万个以上,这些风险发现、解决和管理的成本太高了。而且故障也不是天天发生,发生了应急的成本相对较小,所以目前业界的选择大多数还是以故障应急为主。
1.2 重复发生
对于 SRE 和运维岗位来说,类似的问题重复发生,会占用大量的时间和精力。
以某厂商的订单系统调研数据为例——
客户反馈稳定性问题列表中,重复出现的问题占比 51%
订单异常咨询列表中:
①数据库 SQL 执行超时导致的,1 个月有 182 条
②系统间调用异常未处理导致的,1 个月有 375 条
这其中的琐事特别多,而且会一直重复发生。然而,SRE 同学如果想让这些问题彻底解决,需要涉及多个研发团队。比如,想要彻底解决系统间调用异常处理的问题,就需要协同好几个研发团队,甚至因为一个风险,需要给全公司发邮件要求大家整改,这个执行成本也是非常高的。所以大家大多数会选择把眼下的问题解决掉,至于这个问题在其他应用会不会也存在,SRE 很难考虑,也很难推动。
上述两个痛点都指向同一个问题:公司的稳定性表现和投入在稳定性上的成本是正相关。由于目前风险管理的成本较高,所以大家被迫选择围绕故障来解决问题。但是,从中长期维度来看,比如一年、两年、三年,其实围绕故障去解决问题的成本并不低。
二、稳定性和架构优化有哪些核心策略?
目前我看到绝大多数公司还是围绕故障来开展 SRE 相关工作。那么,在中长期的周期上,如何才能降低整体的成本?这成为一个核心问题。
2.1 三个核心策略
我们实践下来应该在以下三个维度不断深化:采集更丰富的数据、积累更丰富的经验库、从劣化场景不断消化风险。
丰富的数据和经验库大大地降低风险的发现、解决和管理的成本,抓住劣化的场景可以尽早逐步消灭风险,降低故障的发生概率。
2.2 经验库
2.2.1 什么是经验库
先解释一下什么是经验库。经验库是用来积累并产品化经验的模块,它有一个核心的特点——察打一体。以性能容量领域的经验库为例,它需要能够做到发现链路的容量瓶颈在哪个节点,这是察;同时,也能确定瓶颈节点的问题原因是什么,这是打。比如,下单接口性能容量不达标时,经验库可以实时诊断出瓶颈点具体在哪个微服务上,而且可以给出直接原因,如:打印太多日志导致的瓶颈、微服务代码中有较大事务导致并发度上不去等等。
(部分性能相关经验库示例)
2.2.2 经验库繁多但能穷举
经验库需要经过长时间的积累,才能逐步发挥其价值。如图的 SLA 经验库,整个系统中的 SLA 指标非常庞大,有非常丰富的管理维度,也需要从链路到节点的全面覆盖。
(SLA 经验库示例)
维度包括:响应时间类、容灾部署类、发布变更类、故障发现类、请求正确率类、服务耦合类、架构隔离类等。
链路和节点全面覆盖包括:链路、应用服务节点、容器节点、物理机节点、数据库节点、缓存类节点、消息类节点、搜索类节点等。
经验库的数量和种类都如此之多,那它可以穷举吗?答案是肯定的。即使没办法做到 100%,哪怕能做到七八成,就已经能够解决很大部分问题了,可以把风险控制的成本和琐事都降下来。
2.3 数据
2.3.1 采集维度需更丰富
提到运维的常用数据,大家往往想到的是 Metrics、Trace 和 Log。而其实想要做好技术风险管理,还需要更丰富、更多种类的数据,才能降低整体的执行成本。
经验库的特点是察打一体,需要具备诊断原因的能力,所以需要的数据维度会更丰富。比如——
MySQL 中一张表的数量超过 2000 万时,普通的 SQL 也会变慢。而且如果大表出现慢 SQL,则会极大影响到整个库的稳定性,所以大表是一个很危险的现象。判断这样的情况,我们就需要用到每个数据库中每张数据表的数据量这样的数据。
配置类数据,正常来说应该使用配置中心或者参数中心管理,但有很多公司的开发,会将配置类数据放在数据库中管理。而配置数据它需要大量频繁地访问,且不太需要变更,所以它放在数据库里其实不合适。它会让整个链路的 RT 响应时间变长,且变得很不稳定。为了发现这种情况,我们需要用到数据库的表结构数据、数据库的行数、数据库某张表的读写比例等等。比如,一个很简单的判断规则,如果这张数据库里的某张表,它的列数不超过 10 ,行数不超过 5000 ,读写比例大于 1000 (即 1000 次读只有 1 次写),满足这一条件的数据,我们就把它归为配置类数据。把这种数据风险扫描出来后,就能通过技术风险管理的手段将其提前消化掉。
2.3.2 重视前期数据建设的投入
我个人的经验是,数据采集的工作和总体成本是不能忽视的。因为在很多公司里,数据采集和打通的工作难度比较大,前期确实需要投入一些建设成本,比如找到一些业务方配合,才可能逐步把数据建立起来。但是后期这种比较丰富的数据带来的效率提升是特别明显的。
在经验库中我们会记录每次经验匹配对数据的要求,从而帮助我们快速识别出缺少的数据。如下图页面所示,红色的部门就是缺少数据的,我们就可以知道还要再去采集哪些类型的数据过来,以让整个经验库更加完善。
(经验库示例-红色部分为缺少数据)
2.4 劣化场景
2.4.1 系统劣化的 3 个阶段
我们把系统的稳定性分为三个阶段:劣化、技术债、重构。
设想一个稳定性的系统,因为版本的不断更新,响应时间自然会不断劣化。我们有一个统计数据,即一个月的时间,接口响应时间劣化 10%以上的接口数量占比 25%左右。
随着劣化不断累积,就会在系统内部逐步留下技术债。大家都知道系统哪里有明显不稳定的地方,但是改动起来已经需要一定的成本了,且不是想改就能立马改掉的。这种状态就会导致出现故障的可能性大大增加。
技术债的累积,就会导致稍不注意就发生故障,而且修复成本很高,最终演化为被迫重构系统了。
2.4.2 劣化的 4 个主要场景
劣化一般是由于应用的版本变更、数据量的增加逐步导致,一般包括:接口响应时间劣化、业务容量劣化、业务正确率劣化、部署架构劣化等等。
在每次应用发布后,出现劣化现象时,是一个非常好的逐步推动消化技术风险的场景。比如发布后,链路响应时间相较于发布前增加 5%,相较于 1 个月前增加 15%。此时将这样的风险发布出来,推动解决,是一个大家比较容易接受的场景。
三、以上策略落地效果怎么样?
以上是理论层面的分享,那么是否能落地?落地效果如何?接下来我将分享具体客户的应用实践,我们在案例中看看落地数据+经验库和劣化的策略。
3.1 业务背景
这家公司是一家新能源企业,前两年新能源汽车业务迎来爆发式增长,导致系统的稳定性也遇到不小的挑战——故障频发、告警不断。
新能源汽车一般都有一个可以在 APP 上控制车辆的功能,从下图中可以看到,用户每操作 3 次,就会因为各种原因失败 1 次。可以看到系统已经处于高负荷的状态运行,随时可能出现问题——今年春节出行高峰发生了系统崩溃。
今年五一高峰是疫情后的第一个小长假,预计出行人数会爆发式增长。然而系统的稳定性面临了很多挑战。比如,MQTT(一个物联网消息系统)连接数不足、数据库容量不足且无法扩容、内部的消息系统经常堆积、网关经常超时等等。从上图的描述中,可以看到技术债已经很多了。
3.2 实施契机
这家企业早些时候已经安装了数据采集的客户端,并且在系统逐渐劣化的过程中已经识别出了很多风险,比如微服务自消耗超时、缓存响应时间超标、网关耗时过长、消息容量不足以及应用机器内存使用率不足等等。
虽然已经意识到了有这么多风险,但之前一直没有下定决心逐步消除它们,也没有找到一个好的机会。考虑到五一出行的重要性,经过多次商议后,我们最终决定启动部署架构优化的项目。
3.3 落地过程
3.3.1 识别--风险库匹配,提取 5 个风险点
这里有几个 SLA 的概念,给大家简单介绍一下:
微服务自耗时:指一个微服务的总耗时,减去调用其他服务的耗时,即只计算自己服务的消耗。一般要包括服务本地的计算逻辑、对数据库、缓存等访问。实际指标的计算是有点复杂的,需要考虑多线程异步调用的情况、回调的情况等等。这个指标是用来衡量单个微服务的响应时间是否劣化的重要指标。
网关自耗时:网关自身的消耗时间,一般是用网关总耗时减去后端服务的实际耗时,这段时间一般包括接受请求、路由计算、转发请求、接受响应等环节。这个指标是衡量网关自身响应时间是否劣化的重要指标。
这些是从数据、经验库里面识别出来的风险,然后从风险库里面选出来跟这次唯一相关的一些稳定性风险的类型。
上图我们看到微服务自身的劣化情况非常明显,缓存响应时间的劣化尤其严重,已经超过了 500%。网关劣化度不高,但是抖动率有提升。消息的容量目前确实有一些不足的迹象。最后一点就是机器资源浪费比较严重。
3.3.2 评估--判断风险,确定 2 个高优先级
对这些风险进行评估,需要从多方面综合判断风险影响,从而来确定优先级。一般会从六个维度来综合评估 :
风险对全链路的影响总和
风险对核心链路的影响总和
风险对单链路的影响
风险的修复难度
风险发生后恢复难度
风险继续劣化的可能
基于以上维度综合分析后,我们发现优先级较高的风险是缓存响应时间超标、消息容量不足这两项。
3.3.3 方案--察打一体,明确 3 个任务
任务 1:云部署架构调整,切换可用区
缓存响应时间超标的影响是最大的。通过经验库的察打一体的定位能力,我们发现应用和缓存之间的网络延时特别长,达到了 2-3ms,而内部网络延时的标准一般在 0.5ms 以内,这明显是有很大的问题。通过后续详细的分析后,发现半年前购买的机器和各种云资源与之前的可用区不同,但是架构上没有支持多可用区,仍然当做一个集群在使用,导致每次访问都需要跨可用区,导致延时较大。综合评估后,考虑到改造成本,我们决定先切回一个可用区。
任务 2:调整消息存储时间,3 天缩短到 12 小时
消息容量不足直接原因很明确,就是磁盘的容量不足导致的。但是当时扩容遇到一个问题——因为历史原因,有部分应用消息的地址是直接写死的,而且目前已经无人维护,大家不敢修改,所以即使扩容也不一定能够解决这个问题。最后我们分析消息的使用场景,发现消息量最大的 2 个 topic,完全没有保留 3 天的必要,10 分钟后基本消息就无效了。所以最后选择将消息的存储时间调整到 12 小时,相当于容量提升了五六倍。这个容量足够五一业务高峰使用。
任务 3:调整应用的 JVM 参数,充分使用内存
最后,我们还额外解决了一个风险——应用机器的资源浪费。虽然不是必须修复的问题,但我们还是评估了一个方案,建议其调整 JVM 参数,充分利用可用内存。这样做可以充分利用内存资源。
3.3.4 验收--70%资源渡过五一高峰
最终顺利渡过五一高峰,只收到了 3 次告警,没有其他稳定性相关问题或者故障中断等情况发生。
1)用户体验提升:核心功能,因为超时错误原先每天影响 40000+客户,基本消失
2)超时、堆积告警基本消失:早晚高峰平均 28 条消息堆积告警,每次堆积几十万条,基本消失
3)硬件成本降低:RT 降低后,集群容量提升 40%以上,整体硬件缩容了 30%
四、总结与展望
通过上述案例,我们可以回顾之前提到的核心策略,即丰富数据、积累经验库和治理劣化场景。这三个策略在这个案例中得到了应用。
由于篇幅限制,还有一些业务架构和技术架构优化、日常发布中的劣化治理的案例无法一一分享。然而,从这个案例中,大家可以看到数据+经验库的方式,持续积累,可以用很低的成本来解决稳定性风险多而散且重复发生的问题。(全文完)
本文由博客一文多发平台 OpenWrite 发布!
相关文章:

SRE实战:如何低成本推进风险治理?稳定性与架构优化的3个策略
一分钟精华速览 SRE 团队每天面临着不可控的各类风险和重复发生的琐事,故障时疲于奔命忙于救火。作为技术管理者,你一直担心这些琐事会像滚雪球一样,越来越多地、无止尽地消耗你的团队,进而思考如何系统性地枚举、掌控这些风险&a…...

APK大小缩小65%,内存减少70%:如何优化Android App
APK大小缩小65%,内存减少70%:如何优化Android App 我们一直在努力为我们的Android应用程序构建MVP产品。在开发MVP产品后,我们发现需要进行应用程序优化以提高性能。经过分析,我们发现了以下可以改进的应用…...

传统工厂如何搭建蒸汽流量远程无线抄表系统?
一、应用背景 2021年国务院政府工作报告中指出,扎实做好碳达峰、碳中和各项工作,制定2030年前碳排放达峰行动方案,优化产业结构和能源结构,特别是近期煤炭价格上涨导致蒸汽价格大幅上涨,节能减排显得更加重要…...

睿趣科技:抖音店铺怎么取名受欢迎
抖音作为国内最大的短视频平台,其商业价值不容忽视。许多商家和创作者都在抖音上开设了自己的店铺,而一个富有创意和吸引力的店铺名字,往往能带来更多的客流量。那么,如何为抖音店铺取个好名字呢?以下是一些有用的建议。 明确定位…...

面试经典 150 题 22 —(数组 / 字符串)— 28. 找出字符串中第一个匹配项的下标
28. 找出字符串中第一个匹配项的下标 方法一 class Solution { public:int strStr(string haystack, string needle) {if(haystack.find(needle) string::npos){return -1;}return haystack.find(needle);} };方法二 class Solution { public:int strStr(string haystack, s…...
儿童产品亚马逊CPC认证审核不通过的原因解析
一、亚马逊CPC认证审核不通过的原因 CPC认证是亚马逊针对卖家销售儿童用品的一个认证,如果提交CPC证书到亚马逊,亚马逊审核一直不通过,我们可以从几个方面入手来查下什么原因,是资料本身的原因?是否提供的资料合规&…...

项目_数据可视化| 折线图.散点图.随机漫步
安装matplotlib 在正式开始编写程序之前,需要先安装pip、matplotlib模块,苹果系统的安装问题在之前的文章中有相关介绍内容,如果pycharm运行模块报错,可以再次检查是否版本兼容问题。 绘制折线图 调用subplot(&#x…...

Android 项目增加 res配置
main.res.srcDirs "src/main/res_test" build->android->sourceSets...
MySQL数据库的MVCC详解
在MySQL的事务隔离锁机制中,MVCC是一个非常重要的概念,学会MVCC可以更好地理解MySQL如何实现各种隔离级别。 首先,大概地介绍一下mysql的事务隔离级别: 1、读未提交(Read Uncommited):指的是&…...

AI:10-基于TensorFlow的玉米病害识别
玉米是世界上最重要的粮食作物之一,然而,玉米病害对其产量和质量造成了严重威胁。传统的病害识别方法通常依赖于人工观察和经验判断,效率低下且易受主观因素影响。近年来,基于深度学习的图像识别技术在农业领域取得了显著进展,为玉米病害的快速、准确识别提供了新的解决方…...

vue3前端开发系列 - electron开发桌面程序(2023-10月最新版)
文章目录 1. 说明2. 创建项目3. 创建文件夹electron3.1 编写脚本electron.js3.2 编写脚本proload.js 4. 修改package.json4.1 删除type4.2 修改scripts4.3 完整的配置如下 5. 修改App.vue6. 修改vite.config.ts7. 启动8. 打包安装9. 项目公开地址 1. 说明 本次安装使用的环境版…...

前端uniapp生成海报并保存相册
uiapp插件 目录 图片qrcode.vue源码完整版封装源码qrcodeSwiper.vue最后 图片 qrcode.vue源码完整版 <template><view class"qrcode"><div class"qrcode_swiper SourceHanSansSC-Normal"><!-- <cc-scroolCard :dataInfo"dat…...

0基础学习VR全景平台篇 第104篇:720全景后期软件安装
上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 摄影进入数码时代,后期软件继承“暗房工艺”,成为摄影师表达内在情感的必备工具。 首先说明,全景摄影与平面摄影的一个显著的区别是全景图片需…...
CMakeLists编译前拷贝文件或目录
${CMAKE_CURRENT_BINARY_DIR} 编译工程目录 file(COPY python/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python/ FILES_MATCHING PATTERN "*.exe") file(COPY python/Lib DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python/) file(COPY python/Libs DESTINATION $…...

mysql面试题35:MySQL有关权限的表有哪些?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL有关权限的表有哪些? MySQL中与权限相关的表主要包括以下几个: user表:存储MySQL用户的基本信息,包括用户名、密码等。可以使用以下命令…...
ES6:什么是Symbol_
引言 在编程领域,我们经常听到关于"Symbol"的术语,但你知道它到底是什么吗?Symbol是一种基本数据类型,它在JavaScript中被引入,用于表示唯一的标识符。本文将介绍Symbol的概念、用途以及如何在代码中使用它…...

E. Li Hua and Array
Problem - E - Codeforces 思路:观察给定的函数,其实就是求与这个数互质的数的个数,即欧拉函数,我们发现一个数迭代欧拉函数不会很多,那么对于第一个操作来说我们可以直接暴力修改,而对于第二个操作来说&am…...

【项目】在线oj
1. 创建项目 创建maven项目。 引入依赖(mysql connector和servlet): <dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><ar…...

第十章-输入输出系统
Ⅰ.锁 本质是互斥操作 原因:针对公共资源访问时,临界区若不加以互斥限制,可能导致执行过程中突然的中断导致出现异常。 1.互斥过程 设定互斥量M为二值信号量,0/1,P-,V,现有两个进程A、B共同…...

TensorFlow学习:使用官方模型进行图像分类、使用自己的数据对模型进行微调
前言 上一篇文章 TensorFlow案例学习:对服装图像进行分类 中我们跟随官方文档学习了如何进行预处理数据、构建模型、训练模型等。但是对于像我这样的业余玩家来说训练一个模型是非常困难的。所以为什么我们不站在巨人的肩膀上,使用已经训练好了的成熟模…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...