惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
量子位
SecWiki News
SecWiki News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Palo Alto Networks Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
爱范儿
爱范儿
S
Secure Thoughts
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
D
Docker
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
F
Fortinet All Blogs
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
Y
Y Combinator Blog
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
Recent Commits to openclaw:main
Recent Commits to openclaw:main
G
GRAHAM CLULEY
Recorded Future
Recorded Future
罗磊的独立博客
Forbes - Security
Forbes - Security
Security Latest
Security Latest
NISL@THU
NISL@THU
T
The Exploit Database - CXSecurity.com
Hugging Face - Blog
Hugging Face - Blog
T
Tenable Blog
C
Cybersecurity and Infrastructure Security Agency CISA
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Apple Machine Learning Research
Apple Machine Learning Research
K
Kaspersky official blog
月光博客
月光博客
小众软件
小众软件
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic

人人都是产品经理

为什么你的产品找不到差异化?90%的失败都卡在第一步上(下) – 人人都是产品经理, 3年从30万到1300万用户、获2200万美元融资,这个AI教育产品用“抽卡”破解了获客难题 – 人人都是产品经理, 园区招商系统怎么做才能真正帮到去化?我加了这一个功能,推广链接转发400次阅读过万 – 人人都是产品经理, AI大事件:OpenAI发完网络安全模型又搞药物研发,小鹏汽车要抓”DeepSeek时刻” – 人人都是产品经理, 电商不是卖货,是一场更残酷的产品经理实战 – 人人都是产品经理, 没想到,活动营销又回来了! – 人人都是产品经理, 为何All-in海外KOC:一场关于AI时代窗口期的豪赌 – 人人都是产品经理, 重新理解企业的内部协作 – 人人都是产品经理, 苹果的 AI 战略到底是什么? – 人人都是产品经理, 医疗智能体·第2讲——合规护城河:等保、PIPL与HIPAA的架构实战 – 人人都是产品经理, 向量知识库五步法:从“答非所问”到“精准回复” – 人人都是产品经理, 鸿蒙PC三方库构建总指挥HPKBUILD(sha)库为例 – 人人都是产品经理, 何时该用LLM?AI产品经理的LLM设计指南 – 人人都是产品经理, 医疗信息领域的需求方、决策方、准入方以及关注点(二) – 人人都是产品经理, 即梦涨价:一场被误读的「傲慢」 – 人人都是产品经理, 面试AI PM必答题:Hermes和OpenClaw的区别,如何讲清楚业务价值 – 人人都是产品经理, AI的下一张船票:世界模型——AI产品经理必须理解的技术拐点 – 人人都是产品经理, 小红书做GEO,怎么让AI信你?记住这 3 个重要信息 – 人人都是产品经理, 5 家印度 AI 初创公司,看看印度 AI 再做什么 – 人人都是产品经理, AI项目跨团队协作:产品技术业务如何不打架 – 人人都是产品经理, Agentic Workflow(智能体工作流):让AI从”答案生成器”变成”数字员工” – 人人都是产品经理, lycium_plusplus 项目全景解读:OpenHarmony 三方库构建的“大管家” – 人人都是产品经理, 从爆单救火到前置履约:两套预采策略,把生鲜大促履约效率拉满 – 人人都是产品经理, 什么时候该补货?我用一轮数据做了一个决定 – 人人都是产品经理, 从“机械兜底”到“动态分流”:AI客服重复进线治理的4大底层逻辑 – 人人都是产品经理, 抖音拼效率,红书拼洞察 – 人人都是产品经理, 全民狂欢与退潮——为什么龙虾这波热潮冷却得如此之快? – 人人都是产品经理, Stripe押注!MPP重塑全球支付 – 人人都是产品经理, 小红书GEO:AI引用你的内容,不是因为你对,而是因为你看起来可信 – 人人都是产品经理, 前百度副总裁押注办公Agent,日韩付费爆发,Manus迎来强劲对手 – 人人都是产品经理, 企事业单位数字化的业务供需本质 – 人人都是产品经理, 医疗智能体·第1讲——医疗信息化重构:从“辅助软件”到“自主智能体”的范式转移 – 人人都是产品经理, 粉丝量就是空气!!! – 人人都是产品经理, 用户说“薯片碎了”,机器回“要买吗?”:意图识别的翻车与破局 – 人人都是产品经理, RAG召回准确率从75到90 我做对了这三件事 – 人人都是产品经理, AI大事件:Anthropic改收费、OpenAI发安全版、手术机器人纳入医保、阿里发布”秒悟” – 人人都是产品经理, Chrome 推出 Skills 新功能,Agent 重塑上网方式 – 人人都是产品经理, GitHub前创始人拿了a16z的1700万美元,做Agent时代的Git – 人人都是产品经理 拷贝或克隆其他 Flutter OH 项目到本地后无法运行 – 人人都是产品经理, 优惠券设计:优惠券创建 – 人人都是产品经理, 不用死磕文档!AI 助手 1 小时搞定飞书 CLI 安装 + 配置 + 知识库 – 人人都是产品经理, 用小龙虾做竞品分析报告:从2天到20分钟,我是怎么做到的 – 人人都是产品经理 用小龙虾做市场分析报告:搞懂这3个公式,市场规模不再靠猜 – 人人都是产品经理, 你早就在做 Harness 工程,只是不知道它叫这个名字 – 人人都是产品经理, Think Long就够?你可能想多了! – 人人都是产品经理, 货代SRM实战:供应商准入怎么做,才能让资源池不是通讯录而是可交付网络? – 人人都是产品经理, 如何做好用户调研?详解基本技巧 – 人人都是产品经理, 木鸟、途家、美团对打,平台春天行动开“卷” – 人人都是产品经理, 入职才发现公司不靠谱?小红书从业者求职避坑指南 – 人人都是产品经理, 美国 AI 三巨头联手封堵,中国 AI 突围之路在何方 – 人人都是产品经理, 小红书,放在需求对面的镜子 – 人人都是产品经理, AI 会带来大规模失业吗? – 人人都是产品经理, 从出单到补货前,我第一次犹豫:该不该放大? – 人人都是产品经理, Flutter 三方库鸿蒙化适配:5 种高效检查方式,快速判断是否需要适配 – 人人都是产品经理, 从做产品进阶拿结果:医美机构产品经理转岗科室运营经理 – 人人都是产品经理, 阿里HappyHorse,一场关于“Token经济”的阳谋 – 人人都是产品经理, To B AI:客户留存落地的观察与思考 – 人人都是产品经理, AI产品的“生命线”——数据采集、标注、清洗的产品化设计 – 人人都是产品经理, 谈谈AI Agent(二):当“孩子”能自己“体验世界”时,你该学什么? – 人人都是产品经理, UI/UX设计师的3层能力进阶,前两层让你活下来,第三层…才是真正的分水岭 – 人人都是产品经理, 2分钟 → 30秒,效率提升75%:B端产品经理如何用「规则枷锁」驯服AI幻觉? – 人人都是产品经理, 还没来得及学OpenClaw,来了个更猛的:Hermes Agent – 人人都是产品经理, AI日报:宇树机器人跑出10m/s刷新世界纪录 – 人人都是产品经理, 一文说透基金互金如何用情绪价值引导用户决策做转化 – 人人都是产品经理, 当浏览器开始替你”看”网页:AI 浏览器正在亲手拆掉它脚下的那张网 – 人人都是产品经理, 0代码,一天时间我Vibe Coding了个网站 – 人人都是产品经理, Hermes 和 OpenClaw 之争,Agent 的能力应该“装上去”还是“长出来”? – 人人都是产品经理 视频生成的“桌子”,字节Seedance 2掀完,阿里快乐马掀 – 人人都是产品经理, 从听不懂到完全信任:我的 Codex 深度产品体验 – 人人都是产品经理, 当虚拟偶像有了北京户口,与真人偶像还有什么区别? – 人人都是产品经理, 会说,远远比会做更重要 —— 对 SBTI 爆火现象的五层观察 – 人人都是产品经理, AI产品经理必看:当“搭环境”比“选模型”更重要,你的认知还在2024年吗? – 人人都是产品经理, 2026年AI产品商业化核心逻辑:从功能demo到规模化营收的3个必破卡点 – 人人都是产品经理, 京东围绕供应链,卷起裤腿下场的那些事儿 – 人人都是产品经理, SBTI一夜刷屏:它赢在了“太会说人话” – 人人都是产品经理, 折扣零售的真相:不是便宜,而是价值感! – 人人都是产品经理, 和甲方吵了一架,最后加钱做了——我学到的ToB产品经理生存法则 – 人人都是产品经理, 和几位小红书操盘手聊了8小时,干货全在这 – 人人都是产品经理, 智谱GLM-5.1登场,开源模型首超Opus4.6!!! – 人人都是产品经理 Anthropic收入凭什么反超OpenAI,终于有人把这事说清楚了 – 人人都是产品经理, 史上最有故事感的技术报告——Claude最强模型Mythos 7个极其精彩的细节 – 人人都是产品经理, 模型不是壁垒,Harness 也不是 – 人人都是产品经理, 抖音本地生活业务思考21 – 人人都是产品经理, Superpowers:145k Star的AI编码框架,到底是什么来头? Superpowers:145k Star的AI编码框架,到底是什么来头? – 人人都是产品经理, OpenAI 的路走错了,Anthropic Harness 解法启示:模型需要实践专科生 – 人人都是产品经理, 画原型图的前一步:设计站点地图 – 人人都是产品经理, 给 DeepSeek 的最后一封催更信 – 人人都是产品经理, 手把手教你用 Claude Code 搭建 AI 营销团队:5 个 Agent、12 项技能,独立完成研究、写作、设计全流程 – 人人都是产品经理, 你以为大模型在学语言?不,它在重新发明语言学 – 人人都是产品经理 所谓Skill,不过是AI时代的工业垃圾 – 人人都是产品经理, 聊一聊内容传播的几个方法 – 人人都是产品经理, 当平台开始吃掉生态:从 OpenClaw 被封杀,读懂 Anthropic 的这盘棋 – 人人都是产品经理, 你装了 10 个 AI 插件,Obsidian 还是一个文件夹 – 人人都是产品经理 关于AI智能体架构演进的系统性思考:从单体试水到多体协同的重构 – 人人都是产品经理, 当“人”变成Skill,我们又该何去何从? – 人人都是产品经理 Mythos 事件:前沿 AI 治理的意外实验 – 人人都是产品经理, 货代CRM:信用与风险管理怎么做,才能把坏账风险拦在放货之前? – 人人都是产品经理, 从HR收集自拍照到员工自助录入——我见证了园区人脸识别从”不可用”到”真好用”的全过程 – 人人都是产品经理 千问闯关AI混沌期:阿里画靶,吴嘉张弓,马云射箭? – 人人都是产品经理,
架构视角的性能优化,该怎么做?
一个数据人的自留地 · 2023-04-07 · via 人人都是产品经理

性能是一个很笼统的词,我们需要一个完整的方法,对于性能问题进行鉴别、分析、解决。本文作者探讨的就是如何在复杂的系统下进行优化的方法论,让硬件投入划得来,让系统保障可靠的同时无比丝滑。一起来看一下吧。

前言

首先我们的系统通常是非常复杂的。无论你的系统是一个单体应用;还是做了n多解耦、分层、拆分的工作,单元逻辑足够简单的分布式应用;但是对于一个功能视角来看,仍然非常复杂,反而分布式环境下问题要比单体应用还要复杂一个量级。

本文要说的就是:如何在复杂的系统下进行优化,让我们的硬件投入划得来,让我们的系统保障可靠的同时无比的丝滑。

性能是一个很笼统的词儿,很多时候直接性能优化三板斧,只是误打误撞的在解决问题,我们需要一个完整的方法,对于性能问题进行鉴别、分析、从而解决。本文要探讨的就是这部分“方法论”,让性能优化的ROI最大化。

一、什么叫性能好?

要分析性能问题,首先我们得有一个鉴别标准,比如:tps承载量、qps承载量、延时、平均响应时间、每秒IO数量(IOPS)、负载、饱和度等等,甚至有些公司内会有一些内部约定的指标,不同的场景下可能直接使用的指标是不同的(这样做是合理的,更简单且直接的描述性能),但是如果要把性能优化的理论吃透,更从容的解决未知问题,需要找到性能描述最本质的东西。

个人认为,对于不同场景进行分类,描述我们系统最恰当的最原始的指标就是吞吐量(对于容量做考量)和响应时间(对于时间做考量),我们要优化的就是这两点。

tps、qps、IOPS这些一定程度上就是在侧面描述吞吐,而平均响应时间、延时同样是吞吐量的重要影响部分,对于大部分场景,我们追求的往往是吞吐量。而某些场景会最大化追求延时降级,而非吞吐量。

看到这里可能会好奇,吞吐和响应时间不是有对应关系吗,为啥是两个指标?

由于单位资源的限定,即时相同的功能,减少响应时间就是在增大吞吐,而某些情况多牺牲部分资源消耗减少响应时间却又减少了吞吐(比如极多步并发处理),围绕微批处理思路增大延时却又增大了吞吐(比如trigger buffer),具体场景具体分析哈,总之要么高吞吐、要么低延迟,更多的时候是在取折中。

架构视角的性能优化

话题拉回来,我们要知道什么是性能好,才能评判系统,才能进行优化,才能具体执行。总体来说:

以吞吐、延时为基准。

  1. 性能问题的优化是自上而下的,首先确定系统整体的性能目标及评判标准;然后整体评判
  2. 其次性能问题一定是可拆分的,若干的劣化共同导致了“差”;
  3. 优化的每个子环节应该有自身的目标,而不是对于整体目标的简单拆分。根据子目标进行分布评判,有的追求低延时、有的追求高吞吐、有的要兼顾。
  4. 子目标以对整体赋能为标准,避免局部最优解

如何鉴别和判断:我们拿到吞吐量、响应时间的数据之后,有N多的呈现方式。比如说平均值、标准方法、百分位数、中位数。

对于性能问题来讲平均值参考意义不大,只能大致呈现系统水准,仅在系统整体性能差的情况下有帮助,而大多时候的性能分析,通常更关注极端百分位或者异常值,因为这些bad case往往代表了性能的潜在风险及劣化趋势。

二、如何优化

知道好坏,接下来谈如何优化。要谈优化,首先避免犯错,即使不懂成体系的优化理论,常见的坑肯定是熟知的,比如说慢SQL、for-each call、大量重复运算、各种手工暴力解法。这里不过多赘述了,大家对这些常见的性能坑一定很熟悉。

1. 性能优化的思路

我们的应用程序执行是分若干层级的,从应用程序(内部又可以分为业务程序、中间件程序、库函数),到系统库,再到系统调用、最后到内核、再到硬件。

就优化角度而言,越靠近工作执行的地方性能优化带来的收益就越大,直白点就是越靠近我们业务逻辑的优化,越有效。按理说越底层的东西应该对系统产生的影响越大,那为什么这么说呢?

架构视角的性能优化

就影响程度而言,越靠近工作执行的地方,所能对系统产生的影响就越大。比如优化10条sql的底层存储,”10条sql”-> “1条sql” -> “无同步sql”差异。就实现角度和专业角度而言,越靠近具体工作执行的地方,实现较蠢的可能性越高。

而这些可以汇总为:对于系统而言会有“技术选型”、“不合理使用问题”等问题,就经验和概率来讲,99%的问题是因为这部分,如果把所有的性能问题进行汇总,然后看具体分布图,不难发现,几乎都分布在上层(应用层)。说几个问题大家感受一下,慢sql(应用层)、mysql检索复杂度过高需要优化(中间件)、磁盘IO操作不合理(系统调用)、磁盘太慢(硬件层)等问题发生的概率和分布。

总体来说,果断承认“99%的问题是因为我一时犯蠢或者不太聪明”,才能开始逐渐正视性能问题和启动性能优化工作。所以整体的性能优化,应该是自顶而下的,由我及外的。

2.“慢”在哪里?

性能问题要求一定是可观测的、可量化的,但是我们的系统不一定是可观测的,或者无法具体量化。这就导致面临性能低下时,就跟面对一个黑盒盲区一样,只知道差,却束手无策。

这时就需要对于我们的系统进行剖析,系统必定由n多部分构成(比如各种子服务,各种function,各种中间件)除系统构成外,我们更应该知道系统工作时的构成(每条链路的运行视图 — 实时运行状态),然后分析哪些地方出了问题。

首先,对于我们的系统进行层层剖析:

架构视角的性能优化

尤其是对于做工程的或者做业务的,我们的整体架构大多是分布式或者微服务架构,如果进行层级、调用链路的拆分通常是如上图所示。

我们要做的就是对于系统有一个更加全面的认知,最起码要回答如下问题,可以不用非常细节,至少要知道一个概貌:

  • 部署环境&硬件设施是什么样子
  • 由哪些服务构成
  • 用了哪些中间件(&版本 &适配器 &本地优化 &调参)
  • 怎么用的中间件(比如redis做缓存,怎么用的,链路如何)
  • IO链路是什么样子(&对应的协议 &网络处理模型 &放大倍数)
  • 调用链路是同步还是异步&有没有做批处理
  • 怎么用的中间件
  • 每个server功能是什么样子

在有了整体的概貌之后,就可以对系统进行一定的剖析了,看每一步或者关键步骤是否是支持我们观测的,并且观测手段是可以自动化监控,还是巡检机制,还是case by case。再然后就能可以根据目标对于这些步骤或者说环节进行量化分析。(最好自动化哈)至此大概率就知道我们的系统具体慢在了哪里。

三、对影响因素有个大体的感知

先说响应时间,首先我们要对速度有一个基础的概念,数据没那么绝对,但是差不多就是这个数量级先硬件相关:

  • 一个CPU周期:0.3ns
  • L1、L2、L3缓存访问:0.9ns、2.8ns、12.9ns
  • 内存访问:120ns
  • 固态硬盘:150us
  • 机械硬盘:1ms
  • 一次同机房调用:1ms
  • 一次跨城网络传输:30ms
  • 一次跨专线地域传输:100 – 200ms

再包装下看日常的操作耗时:

  • 一条sql call(索引合理,数据量正常):1-2ms
  • 一次RPC调用:1-10ms
  • 一次redis操作(无大key、热key):1-2ms
  • 一次kafka send(带buffer):1ms以内
  • 一次http请求:5ms

对于CPU的消耗程度,如果把CPU看作是稳定的(相对有点粗暴哈),消耗程度通常可以用CPU占用时间来表述(onCPU、offCPU)。比如完成一次md5需要多少时钟、执行磁盘IO需要多少时钟、一次网络IO需要多少时钟等等。

而这个东西具体的表象其实就是cpu使用率,我们不难可以看到各个进程、各个现成的占用程度,如果再挂一下火焰图不难看出哪些操作对CPU消耗更高及对应占比。

架构视角的性能优化

各个响应时间和CPU消耗程度是对吞吐和响应时间最本质的影响,要进行性能优化就是对于CPU占用和响应时间(处理延时)进行优化,各种方法减少CPU动作、减少延时等待,应用层的优化就是奔着这些目的去的。

1. 优化延时

应用层面 关于延时我们该如何进行优化呢?整体来看的话:减少操作、减少等待。说几个常见的策略:

  • 能否减少操作,可以对于一次请求、一次任务的执行步骤进行梳理,分一下类,核心工作是哪些,哪些工作是可以从核心链路摘除的。
  • 能否有复杂度更低的动作,比如检索算法是否可以优化、序列化算法是否可以优化、是否有更高效的数据结构和算法。
  • 能否打时间差,前置处理或后置处理,比如初始化动作前置(不光是对象初始化,业务动作也行,可以提前计算、提前开户等),后置比如异步化处理,发奖券之类的
  • 能否缓存&复用,请求处理的结果、中间过程、或者socket链接是否可以直接复用,各种池化技术。
  • 能否并行,多步并行处理,减少整体耗时,衡量下并行带来的收益,是否比实现并行的代价高。
  • 能否非阻塞并发处理,减少等待,避免大量的等待操作,业务处理的劣根性大多源于此。
  • 能否提前失败,对于易失败请求,提前进行失败性检查,避免正常资源的占用,引起其他请求等待。
  • 能否继续优化中间件操作,是否有更高效的中间件选型,操作上是否有更多的优化空间。
  • 能否无”锁“化处理,锁是导致等待的核心因素之一,但这里是泛指可能让我们线程发生阻塞的情况,尽可能的减少同步链路中的等待机制可以让我们的响应时间更容易得到保证。

以余额支付系统交互信息流程举个例子(省了很多步骤,粗略描述):

架构视角的性能优化

尝试优化一下

架构视角的性能优化

系统层面(假设包含虚拟机),只是举几个例子

垃圾回收中断是否影响过大,poll还是epoll、水平触发还是边缘触发,fsync还是flush,线程的CPU亲和,hardware 是否有特异性优化,SSD还是机械硬盘,设配新旧程度

2. 优化吞吐

接下来看下吞吐的相关优化,吞吐量指的是现有系统在单位时间内能够处理的请求或者任务数量。而对于吞吐的优化通常有两点:

  • 单位资源内能够具备更大的吞吐量,提高系统资源利用率。
  • 保证吞吐量没有瓶颈,一定程度上,可以无限横向扩展。

先看第一个问题,如何让单位资源内承载更多的吞吐。

影响吞吐的因素有很多,比如前面刚刚提到的响应时间,关于响应时间和吞吐量的关系前面已经描述过了,大部分场景下适当的减少延时对于吞吐的影响是线性增长的,如何降低响应时间参照前一段的方案(大部分是正向的),唯一需要注意的是,在有限的资源下,过度的优化是会带来吞吐下降的,要做的是尽可能在不带来CPU增长的情况降低响应时间。

常用的技巧技巧批处理,比如多次IO是否可以进行合并,批处理一下,减少多次链接开销,这样对整体吞吐带来的威力是很大的。对同步批处理,一定程度上也算是对于响应时间的调整,对于整体平均响应时间是在下降的,但是对于头部请求响应时间是被劣化的。

但通常的使用往往是异步化处理 + 批处理,IO 缓冲区、buffer triger、insert buffer、kafka send buffer 都是这个思路。带来的吞吐和响应时间提升通常是炸裂的。

接下来看第二个问题,解决吞吐瓶颈。

当完成单位资源的吞吐优化之后,按理说有诉求就水平扩容即可,但是实时并非如此,经常会出现一个“热点”成为系统的吞吐瓶颈,尤其是在OLTP系统中,热点会以各种各样的方式出现,但是通常都和状态强相关,比如说全局库存、热点用户、热点机器等等。

如果要优化,这里就不得不提CAP理论了,在数据多节点分布的情况下,为了保障一致性,系统整体的可用性必然会受到影响,可用性下降,最大的表现其实就是有效吞吐的下降。突破瓶颈,持续放大吞吐,那就适当的牺牲一下数据的一致性吧。

架构视角的性能优化

要做的是把热点数据进行割裂,然后牺牲一致性,也就是把“热点”进行sharding,让热点也能进行进行水平扩容,然后在这些短暂的不一致之上打补丁,尽快达成最终一致。

四、负载对于性能的影响

1. 劣化现象

除了我们代码的实现、系统的构成会对系统有一定的影响,濒临负载极限的时候不管是吞吐量、响应时间都会受到一定程度的影响。

对吞吐而言,在机器资源一定的情况下,并不是随负载一直线性变化的,到达一定的临界值后如果持续增加负载,吞吐通常会由线性增长进入缓慢增长的,如果再持续的增加负载,会出现一定的劣化现象(比之前的吞吐量还会降低),这在JVM等虚拟机之上运行的应用,或者在池化排队机制的加持下愈发严重和明显。

架构视角的性能优化

对响应时间而言,在机器资源一定的情况下,也不会随始终保持耗时不变,同样在到达负载临界值时,会发成程度不一的劣化现象,有的响应时间增长迅速,有的则呈慢速下降。

架构视角的性能优化

2. 劣化的原因

这是为什么呢,因为在负载到达一定阈值时会触发程度不一的系统资源抢占问题,比如大量的排队等待处理,此时上下文切换会更加的频繁,并且对于某些JVM等虚拟机之上的运行的应用还会带来一定程度上的内存清理(分配和回收)及维护代价进而导致竞争更加激烈,也就导致了性能被进一步劣化。

这也是为什么很多中间件会限制最大链接数、最大线程数、最大排序序列的原因,而对于我们业务应用程序而言也是一样的,在进行池化处理排队机制时一定要明确合适拒绝。

并且我们应该对于我们的的服务加以保护,以此保证负载不会出现这种劣化现象,比如说限流、限并发,比如说tomcat把参数调整的合理一些,让负载,比如说CPU最大不超过60%、70%。

3. 这里有个大坑 – 百分之90的问题是因为这个

除了到达负载临界值时会出现这个问题,在“骤发的流量”面前这个问题也非常的凸显,因为大量的初始化工作(链接建立、线程池扩容、client初始化等等),因为卡顿问题或者延迟变高等问题导致排队激化,同时机器负载也会骤然上升,导致负载临界问题或者时临界值提前到来。日常看监控,突发流量时的尖刺,90%的原因都是这个。

这一点一定要额外注意,大流量前充分预热、保持缓存热度、高性能场景放弃懒加载,极端情况下适当扩大活跃线程数、链接保活都是十分重要的。

架构视角的性能优化

4. 日常的负载要保持多少

日常应用的负载通常由服务器资源的瓶颈负载所决定,CPU争抢会劣化,内存争抢发生换页情况更糟糕。那我们日常的负载到底应该在多少合适,这里以CPU负载为例来进行推导:

通常经验值是60%或者70%,在对稳定性要求极高的场景可能会控制的更低一些,这个值是怎么得来的?

架构视角的性能优化

首先CPU负载超过90%就会有概率发生劣化现象,CPU并非你想象的那么稳定性能方面会有抖动的;

其次即使隔离部署,操作系统之上运行了不止你一个应用程序的进程,可能会有一些重操作的client,比如log拉取,如果log还在客户端做了grep、awk等处理那可能影响更重,这部分的buffer要留出来;

其次我们的进程的CPU消耗并不是线性不变的,仔细看看监控会发现忽高忽低,这部分buffer要留出来;

我们很难保证下游不发生抖动,如果下游抖动发生了一定程度的抖动,但还未超时,一定概率会导致主调server发生排队,进而可能发生雪崩效应,放大问题,这时候产生的劣化波动也是要能承受的,同样的也需要一定的buffer。

同样的,我们也很难保证主调方不会发生合理程度内的激增现象,骤然的CPU波动也是合理的,这部分buffer要留出来。

干掉这些buffer,通常经验值是60%上下浮动,如果单请求消耗资源极多并且可用性要求极高那可能多留点buffer,否则就少点,然后对应的平稳时对应CPU负载所能承载的负载就是我们应该设定的日常负载,再由此推出限流值、动态扩缩标准等等。

5. 热门问题 – 语言的差异到底有多大

语言是个有趣的问题,也是一个争论已久的问题,这里进行简单的讨论哈,通常我们的变成语言会分为编译型语言和解释型语言,还有些语言既有解释器,又有编译器,不用纠结概念,就从解释执行和编译执行的角度看问题即可。

编译型比如说C/C++,编译过的代码总体来说是高性能的,因为在CPU执行执行时不需要额外的一层映射,并且机器代码总是原始代码映射的很紧密,当然啦,很大程度取决于编译器的编译优化。

解释型如说Java(纯解释执行的话,抛开JIT不谈),需要额外的一层解释工作,会增加不少的开销,通常不会被期待有很强大的性能。

对于解释器和编译器共存的语言Java(带上JIT了),性能好坏主要看JIT的优化力度,想观测的话可以打开JIT日志,看下你的代码到底哪些进行最彻底的优化(JIT 优化层级是4),然后看哪些操作会导致退优化的发生,JIT的决策器也非常的关键。但是这种体系下,性能分析会相对费劲一些,JIT的优化策略(决策、编译)很难说对所有开发者都是白盒的,并且在真正执行的时候,和我们代码的映射已经几乎匹配不上了(还好Java的性能分析工具集够全)。

架构视角的性能优化

除此之外,语言的垃圾回收机制虽然带来的很多开发的便捷性,但是对于性能要求极高的场景,垃圾回收会带来额外的影响,比如说程序的停顿,内存中对象的扫描、索引、复制工作。

五、性能优化的时机和判断

1. 性能优化的时机

什么时机进行性能优化,常见的有“系统创建时”、“发生改变时”、“问题暴露时”、“摆烂-重新写”,这个业界并没有一个标准的答案,个人的处理思路是:在系统创建时满足近1年半左右的性能诉求就足够了,剩下的交给将来。

系统设计的初期肯定会进行系统的定位分析及对应的边界划分,此时系统应该具备哪些功能、应该被哪些场景所使用就已经确定了,我们要做的就是对这部分内容进行预判,这应该是属于架构设计很核心的一部分,并且在设计的过程中,如果预判有50%以上场景会发生性能要求的突变,那么我们就应该给系统留足扩展性。

架构设计思路中有种思想叫做“演进式架构”,这里推崇的就是这个观点。

但需要额外注意的是,我们可以不做过多的性能优化设计,但是要做足性能优化分析的设计,正如文章最开始所提到的,我们要保证系统是可观测、可量化的。

上面讲的是设计侧的优化问题,在系统发生变更时,如果通过分析工具和监测工具发现有性能劣化的现象,是一定要进行优化动作的,放任性能问题不管一定会阻碍我们系统的进程,技术债早晚堆成山。

2. 减少局部最优解

局部最优解是一个数学求解的最优化问题,我们设计实现的摸索,也可以粗暴的看作是一个最优的求解问题,那么理论上也是会存在局部最优解问题的。

实践过程也确实如此,相信大家都经历过大规模的重构。因为性能优化方案选择绝对不止一条路,再有拆分到子方案岔路就变的更多了,在选择的过程中很容易发生局部最优解问题。

架构视角的性能优化

就整体方案选择而言

在进行系统设计的时候,因为当前的系统设计整体方案不合理,在一个相对偏差的方向上进行了极致的优化,导致性能看起是得到了解决,并且段时间内没有问题,但是在后期的发展过程中很容易导致性能优化停止不前。所以进行性能问题设计的时候,应该更多的比较各个方案的差异性,以及可发展性。多去探索未知的未知,才能让我们的方案更加合理。

就方案拆分而言

架构设计应该是一个“一锅出”的过程,一定要有一个上层指导,不要求每个子模块要用何种方案,但是一定要有明确的上层指导目标,这样在选择时就避免方向上的偏差,不至于每个子模块都是自己域内最合理的方案,但拼凑在一起确发现压根解决不了问题。

3. 性能分析工具

首先基础架构一定提供了足够全的分析工具,所在的公司也肯定有人在搞定针对基础架构的探测分析及业务系统分析的基础支持,找到对应的人,然后问他们。

要是进行学习或者文档检索,提供一点关键词,火焰图、探针、优化分析、诊断工具、perf、profiling、Trace、netstat、iostat、vmstat、jstack、top、slabtop、ps。

这种资料应该一搜一大片……

六、写在最后

整体算是一点自己对于性能问题分析及设计优化相关的方法论总结,文章里面并没有涉及过多的细节方案,核心原因是想“以渔”。另外市面上大多的直接方案,导致小朋友们习惯性的三板斧,个人觉着这种导向性不算良好,应该更清楚为什么这么做,才能更好的解决问题吧。

除此之外,本文的内容实在是有点扯,建议通过一些系统实践来反观我所描述的这些方法和观点,个人经历过的觉着收益匪浅的系统:支付相关-比如paycore、交易收单、推荐相关、广告相关-比如DSP、营销活动系统。

作者:邹志全

来源:https://mp.weixin.qq.com/s/513BSGZoTWzeVAp6KDTHsA

本文由 @一个数据人的自留地 授权发布于人人都是产品经理,未经作者许可,禁止转载

题图来自 Unsplash,基于 CC0 协议

该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务。