QPS达到峰值时应该如何处理?
真正让系统崩掉的往往不是“平均 QPS”,而是某个时刻突然冲上来的峰值:活动开始、热点新闻、推送、榜单刷新……一波流量把缓存打穿、把数据库打爆,然后你就开始接电话了。 这篇文章不追求“架构百科全书”,更像一份“峰值来了我该先做什么”的清单:从入口限流、缓存策略、降级熔断,到扩容和监控,把常见的解法和思路捋一遍。 架构层面优化1. 负载均衡负载均衡器(如 Nginx、HAProxy 或云服务提供商的负载均衡)可以将用户请求分发到多台服务器上。 硬件负载均衡:使用专用设备对流量进行分发。 软件负载均衡:如 Nginx 配置反向代理,将请求均匀分配到后端应用服务器。 示例:Nginx 配置 12345678910111213141516upstream myapp { server app1.example.com; server app2.example.com; server app3.example.com;}server { listen 80; server_name www.example.com; ...
CSS 中的 flex:1 到底代表什么?
flex: 1 应该算是 Flexbox 里最常见、也最“用着用着就忘了它到底干了啥”的写法之一。你会在各种地方见到它: 三栏布局想让中间自适应 一排按钮想均分宽度 页面里左边固定、右边填满 它看起来像“把剩余空间全吃掉”,但背后其实是三个属性的组合。 123.item { flex: 1;} 下面我们把它拆开看。 flex 属性的简写flex 是一个简写属性,它同时设置三个属性值: flex-grow flex-shrink flex-basis 当我们写下 flex: 1; 时,浏览器实际上将其解析为: 123456flex: 1 1 0%;// 对应属性为flex-grow: 1;flex-shrink: 1;flex-basis: 0%; flex-grow: 1 flex-grow 定义了元素在父容器中如何分配剩余空间。设置为 1 意味着该元素可以等比例扩展,填充容器中剩余的可用空间。 flex-shrink: 1 flex-shrink 定义了元素在父容器空间不足时如何缩小。设置为 1 表示该元素可以以与其他元素相同比例收缩。...
如何判断一个对象是否为空
“对象是不是空的?”这题在业务里经常出现:判断表单有没有填、判断接口返回有没有字段、判断缓存里有没有值…… 大多数情况下,你只需要判断 对象自身有没有可枚举属性,Object.keys(obj).length === 0 就够了。 但偶尔你会遇到更拧巴的需求:对象自己确实没属性,可它的原型链上被人挂了东西(比如某些库/框架做了扩展),这时你想问的其实是“这个对象是不是干净的”。下面我把这两类需求分开讲。 什么叫”空对象”?首先需要明确”空对象”的定义。一般来说,我们有两种判断标准: 仅判断对象自身(own properties)是否为空例如,使用 Object.keys(obj).length === 0 或 for...in 循环(注意,for...in 还会枚举原型链上可枚举的属性)。 判断对象及其原型链上是否没有额外自定义的属性或方法这里的”自定义”通常指开发者额外添加的属性或方法,而不是来自 Object.prototype 上的默认方法。 由于所有对象默认都会继承 Object.prototype 上的一些属性(例如 toString、hasOwn...
用CSS实现翻牌效果
翻牌/卡片翻转这种效果在活动页、卡片信息展示里挺常见:默认只露一面,hover(或点击)后翻过来展示另一面。 这类交互用 CSS 就能做得很顺:3D 透视 + 旋转 + 背面不可见,剩下的就是调动画曲线和细节。 实现原理翻转效果的核心思路如下: 透视(perspective): 在容器上设置透视距离,使得子元素具有 3D 效果。 保留3D空间(transform-style: preserve-3d): 让子元素在 3D 空间中进行旋转。 背面不可见(backface-visibility): 隐藏翻转后不可见的面。 触发翻转: 通过 hover 状态或点击事件,让包含两个面(正面和背面)的容器进行 180° 翻转。 代码示例下面是一个完整的示例代码,展示如何用 HTML 和 CSS 实现翻转效果: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071...
script 标签上有哪些属性?分别干啥用?
<script> 这个标签看起来特别朴素:不就是引个 JS 吗? 但只要你稍微做过一点性能优化、或者线上被 CDN 劫持/脚本顺序坑过一次,你就会发现:script 的属性不是装饰品,是“加载与执行规则说明书”。 下面按“最常用 → 容易踩坑 → 安全相关”的顺序,把属性都捋一遍。 先来一个最常见的 script1<script src="https://cdn.example.com/app.js"></script> 默认行为是: 浏览器解析到它会开始下载脚本 下载完会立刻执行 执行期间会阻塞 HTML 解析(你可以理解成:主线程被叫去“先把这段 JS 跑完”) 所以很多属性,本质都是在解决两个问题: 别卡页面(性能) 别出事(安全/一致性) 一、决定“下哪里”:srcsrc指定外部脚本地址。 1<script src="/assets/app.js"></script> 注意点: 没有 src 就是内联脚本:<script>...
为何CDN请求资源不受跨域限制?
很多人第一次学同源策略会困惑:不是说跨域不行吗?那我为啥能从 CDN 引一个 https://cdn.xxx.com/react.min.js,也能加载跨域图片、样式? 这里的关键点是:同源策略限制的是“读/拿到数据”,不是限制你“发起请求/加载资源”。很多标签天生就允许跨域加载资源,但你想在 JS 里去读它、操作它、拿到响应体,就会触发同源策略和 CORS 这一套限制。 什么是同源策略?**同源策略(Same-Origin Policy)**是浏览器的一项重要安全机制,用于限制来自不同源的文档或脚本之间的交互。具体而言,只有当两个URL的协议、域名和端口号都相同时,才被视为同源。此策略旨在防止恶意网站读取用户敏感数据或执行未经授权的操作。 例如,假设有两个URL: http://example.com/page1.html http://example.com/page2.html 这两个URL被视为同源,因为它们的协议(http)、域名(example.com)和端口号(默认80)都相同。 然而,以下情况则被视为跨域: 不同协议:http://e...
如何将px转换为rem —— CSS单位转换详解
在前端开发中,我们常常面临响应式布局、字体适配和流式设计的挑战。传统的 px 单位虽然直观,但在多终端设备上使用时往往缺乏灵活性。为了解决这个问题,我们引入了 rem 单位,它基于根元素字体大小,能实现更灵活的布局;同时,我们也会结合 vw 单位来打造真正的流式设计,确保页面在不同屏幕下都能保持理想比例。 下面会先把 px -> rem 的换算讲清楚,再补两种常见工程化落地方式(Sass 函数 / PostCSS 插件),最后聊聊 vw 在流式布局里怎么用。 先说我自己的经验:别纠结“哪种单位最先进”,关键看你想解决什么问题——是做一套能跟着根字号整体缩放的设计(rem),还是希望尺寸跟视口宽度直接绑定(vw)。很多项目最后都是混用:字体/间距用 rem,容器宽度/大块区域用 vw。 理解 px、rem 与 vw 单位px – 像素 绝对单位:px 表示像素,是屏幕上最小的显示单位,通常不受用户设置字体大小的影响。 局限性:使用 px 时,页面在不同设备和用户缩放设置下可能显示不协调。 rem – 根 em 相对单位:rem 是相对于根元...
循环渲染中为何不建议用 index 做 key?
key 这个东西,你可能一开始只是为了消掉 React 的 warning 才加上去的。 但它其实会直接影响“列表更新时组件怎么复用”。用对了,你的输入框不会串行、展开态不会乱跳;用错了(尤其是用 index),有些 bug 会特别诡异:看起来像状态乱了,但其实是组件被 React 复用错了。 key 的作用1. 唯一标识每个列表项当你通过循环渲染一个列表时,每个列表项都需要一个独一无二的标识符,这就是 key 的作用。通过 key,框架能够准确地识别出每个元素,确定它们在数据更新时的变化。 例如,在 React 中,key 用于帮助虚拟 DOM 快速判断哪些元素发生了改变、哪些需要重新渲染或移除,从而提高页面更新的性能。 2. 保持组件状态使用正确的 key,可以确保在列表项发生增删或重新排序时,各个组件的内部状态能够正确地保留和复用。例如,如果你有一个表单组件列表,使用唯一的 key 能保证当用户在一个输入框中输入内容后,列表重新排序时,输入框中的数据不会错误地传递到其他组件上。 为什么不推荐使用 index 作为 key?1. 列表项顺序不稳定当列表项的顺序发生变化时...
同一链接如何PC、手机展示两套应用
在实际项目中,为了兼容多终端体验,我们常常希望通过同一个链接来为不同设备提供不同版本的页面。例如,在 PC 端展示完整的 Web 应用,而在手机端展示轻量化、优化的 H5 应用。如何实现这一目标? 我习惯先问一句:你想要的是“同一套应用做响应式”,还是“PC 和 H5 完全两套应用/两套路由”?前者成本更低,后者隔离更彻底,但工程复杂度也更高。 下面按常见落地方式拆开说: 服务端用户代理检测重定向 客户端响应式加载或动态模块切换 服务端检测用户代理原理通过服务器检测 HTTP 请求头中的 User-Agent,根据设备类型选择性地返回不同版本的页面。这样,同一个 URL 在 PC 和手机访问时,会由服务器根据检测结果决定返回哪个 HTML 模板。 示例(Node.js + Express)下面是一个简单的示例,通过 Express 中间件检测 User-Agent 并重定向到不同页面。 123456789101112131415161718const express = require('express');const app = exp...
如何减少项目中的if-else结构
先澄清一句:if-else 不是不能写,很多时候它反而最直观。 真正让人崩溃的是那种“套娃式”的判断:一个函数里几十个分支、嵌套三四层,改一个条件要担心连锁反应,测试也不好补。 下面这些方法的目标不是“消灭 if-else”,而是把复杂度压下去:让分支更扁平、让扩展更便宜、让代码读起来不费劲。 为什么要减少 if-else? 降低代码复杂度:过多的 if-else 分支会使代码阅读困难,增加理解成本。 提高可维护性:业务逻辑变化时,嵌套过深的判断难以定位和修改。 增强扩展性:模块化和面向对象的设计模式能够更轻松地扩展和复用代码。 便于测试:分支逻辑过多时,编写全面的测试用例变得繁琐,容易遗漏边界情况。 常见解决方案1. 使用策略模式策略模式将一系列算法封装为独立的策略对象,并通过上下文类动态选择执行。这样可以将 if-else 判断分散到不同的策略中。 示例代码: 1234567891011121314151617181920// 定义策略函数const strategies = { add: (a, b) => a + b, subtract: (a,...
