我40岁了, 还在写javascript
很多小伙伴想转后端、做全栈,但是不知道后端都有什么。
其实你可以把这 20 个关键词给到 AI,提示词:
我的项目需要限流、熔断、降级、重试、超时、隔离(舱壁)、背压、流量整形、预热、健康检查、优雅关闭、幂等、缓存、抖动、回退、死信队列、分片、滚动更新、负载均衡、信号量。
今天你会学到这些关键词
| 关键词 | 一句话解释 |
|---|---|
| 限流 | 限制单位时间请求数,防冲垮 |
| 熔断 | 下游连续失败就断开请求,防雪崩 |
| 降级 | 依赖失败时返回兜底数据,保核心 |
| 重试 | 临时故障自动重试,配合退避 |
| 超时 | 请求超过时限就放弃,不占资源 |
| 隔离(舱壁) | 业务独立资源池,互不影响 |
| 背压 | 下游慢了上游就减速,防缓冲区爆 |
| 流量整形 | 平滑突发流量,匀速处理 |
| 预热 | 启动时模拟请求,提前初始化 |
| 健康检查 | /health 接口,告诉负载均衡我还活着 |
| 优雅关闭 | 收到停服信号后处理完老请求再退 |
| 幂等 | 同一请求多次执行效果一样 |
| 缓存 | 暂存高频数据,减少重复计算 |
| 抖动(Jitter) | 重试加随机延迟,避免惊群 |
| 回退(Fallback) | 首选失败自动切备选方案 |
| 死信队列(DLQ) | 多次失败的消息进专用队列等人查 |
| 分片(Shard) | 数据拆到多个库,用余数分配 |
| 滚动更新 | 逐个换实例,不停机升级 |
| 负载均衡 | 请求分散到多台服务器 |
| 信号量/并发控制 | 限制同时执行的任务数 |
每个关键词都配有:一句话作用 + 最简 Bun 代码 + JS 库或实际工具示例。看完就能用。
1. 限流
作用:限制单位时间内的请求数量,防止系统被突发流量冲垮。
(常用算法"令牌桶":水桶按固定速率加令牌,每个请求消耗一个令牌,没令牌就拒绝。)
ts
let tokens = 10
let last = Date.now()
Bun.serve({
fetch() {
const now = Date.now()
tokens = Math.min(10, tokens + (now - last) / 100)
last = now
if (tokens < 1) {
return new Response("Too Many", { status: 429 })
}
tokens--
return new Response("OK")
}
})
JS 库:express-rate-limit
ts
import rateLimit from 'express-rate-limit'
const limiter = rateLimit({ windowMs: 60 * 1000, max: 10 })
2. 熔断
作用:下游服务连续失败时自动"断开"请求,避免故障扩散。
(状态机:closed 正常 → 失败次数多变成 open 拒绝请求 → 过一会儿变成 half-open 试探性放行一个,成功就 closed。)
ts
let failures = 0
let state = "closed"
async function call(fn) {
if (state === "open") throw new Error("熔断中")
try {
return await fn()
} catch (e) {
failures++
if (failures >= 5) {
state = "open"
setTimeout(() => { state = "closed" }, 10000)
}
throw e
}
}
JS 库:opossum
ts
import CircuitBreaker from 'opossum'
const breaker = new CircuitBreaker(asyncFn, { failureThreshold: 5 })
3. 降级
作用:核心依赖失败时返回兜底结果,保证主流程不中断。
ts
async function get() {
try {
return await fetch("/core").then(r => r.json())
} catch {
return { fallback: true, data: "缓存数据" }
}
}
JS 库:opossum fallback
ts
const breaker = new CircuitBreaker(riskyFn)
breaker.fallback(() => ({ fallback: true }))
4. 重试
作用:临时故障自动重试,配合"指数退避"避免加重负担。
(指数退避:第一次重试等 100ms,第二次等 200ms,第三次等 400ms... 翻倍增长,避免拥堵。)
ts
async function retry(fn, n = 3) {
for (let i = 0; i < n; i++) {
try {
return await fn()
} catch (e) {
if (i === n - 1) throw e
await Bun.sleep(100 * Math.pow(2, i))
}
}
}
JS 库:p-retry
ts
import pRetry from 'p-retry'
await pRetry(asyncFn, { retries: 3 })
5. 超时
作用:请求超过限定时间就放弃,避免资源长期占用。
ts
async function timeout(promise, ms) {
const ctrl = new AbortController()
const timer = setTimeout(() => ctrl.abort(), ms)
try {
return await promise
} finally {
clearTimeout(timer)
}
}
JS 库:p-timeout
ts
import pTimeout from 'p-timeout'
await pTimeout(slowPromise, { milliseconds: 3000 })
6. 隔离(舱壁)
作用:不同业务用独立资源池,一个故障不会耗尽全局资源。
(舱壁是造船术语:船底隔成多个密封舱,一个进水不会沉船。)
ts
class Bulkhead {
running = 0
max = 5
queue = []
async exec(task) {
if (this.running >= this.max) {
await new Promise(r => this.queue.push(r))
}
this.running++
try {
return await task()
} finally {
this.running--
if (this.queue.length) this.queue.shift()()
}
}
}
JS 库:p-limit
ts
import pLimit from 'p-limit'
const limit = pLimit(5)
const result = await limit(() => asyncTask())
7. 背压
作用:下游处理不过来时,上游主动减慢发送速率,防止缓冲区爆掉。
(背压原指流体力学中下游压力太大导致上游流速变慢。)
ts
let paused = false
async function producer() {
if (paused) {
await Bun.sleep(100)
return producer()
}
const ok = socket.send(data)
if (!ok) {
paused = true
await once(socket, "drain")
paused = false
}
}
JS 库:stream.pipeline(内置)
ts
import { pipeline } from 'stream'
pipeline(source, dest, (err) => { /* 背压自动处理 */ })
8. 流量整形
作用:平滑突发流量,使请求均匀进入系统。
(常用"漏桶"算法:水(请求)先倒进桶里,桶底以固定速率漏水,突发流量不会一次性冲垮后端。)
ts
let queue = []
let working = false
async function add(task) {
queue.push(task)
if (!working) process()
}
async function process() {
working = true
while (queue.length) {
await queue.shift()()
await Bun.sleep(1000)
}
working = false
}
JS 库:bottleneck
ts
import Bottleneck from 'bottleneck'
const limiter = new Bottleneck({ minTime: 1000 })
limiter.schedule(() => myTask())
9. 预热
作用:启动时先模拟请求,让连接池、JIT(即时编译器)完成初始化,避免冷启动后高流量击垮服务。
(JIT 是 JavaScript 引擎的优化机制,代码跑几遍后才会被编译成高效机器码。)
ts
async function warmup() {
for (let i = 0; i < 5; i++) {
await fetch("http://localhost/health")
}
console.log("预热完成")
}
warmup().then(() => {
Bun.serve({ fetch: realHandler })
})
JS 库:无专用库,启动时调用即可
ts
await Promise.all([warmupDb(), warmupCache()])
10. 健康检查
作用 :提供 /health 接口,供负载均衡检测服务是否存活。
ts
Bun.serve({
fetch(req) {
const url = new URL(req.url)
if (url.pathname === "/health") {
return new Response("OK")
}
// 正常业务...
}
})
JS 库:@godaddy/terminus
ts
import { createTerminus } from '@godaddy/terminus'
createTerminus(server, { healthChecks: { '/health': () => Promise.resolve() } })
11. 优雅关闭
作用:收到终止信号后,处理完已有请求再退出,实现零停机重启。
ts
const server = Bun.serve({ fetch: handler })
process.on("SIGTERM", async () => {
server.stop({ hard: false })
await gracefulShutdown()
process.exit(0)
})
JS 库:http-graceful-shutdown
ts
import gracefulShutdown from 'http-graceful-shutdown'
gracefulShutdown(server, { finally: () => process.exit(0) })
12. 幂等
作用:同一个请求执行多次,效果与一次相同。
(比如用"幂等键"去重,第二次请求直接返回"已处理"。)
ts
const processed = new Set()
app.post("/pay", async (req) => {
const id = req.headers["idempotency-key"]
if (processed.has(id)) {
return new Response("Already done")
}
processed.add(id)
await doPayment()
return new Response("OK")
})
JS 库:@node-idempotency/express
ts
import idempotent from '@node-idempotency/express'
app.post('/pay', idempotent(), handler)
13. 缓存
作用:高频数据暂存,减少重复计算。
ts
const cache = new Map()
async function get(key) {
if (cache.has(key)) return cache.get(key)
const value = await fetchDB(key)
cache.set(key, value)
setTimeout(() => cache.delete(key), 60000)
return value
}
JS 库:lru-cache
ts
import LRU from 'lru-cache'
const cache = new LRU({ max: 500, ttl: 60000 })
cache.set(key, value)
14. 抖动(Jitter)
作用:重试时增加随机延迟,防止"惊群"。
(惊群:大量失败请求同时重试,瞬间把后端打爆。加随机延迟让它们错开时间重试,避免互相踩踏。)
ts
for (let i = 0; i < 3; i++) {
try {
return await fn()
} catch {
const delay = 100 * Math.pow(2, i) + Math.random() * 100
await Bun.sleep(delay)
}
}
JS 库:p-retry 自带 jitter
ts
import pRetry from 'p-retry'
await pRetry(asyncFn, { retries: 3, jitter: true })
15. 回退(Fallback)
作用:首选方案失败时,自动切换到备选方案。
ts
async function fetchData() {
try {
return await redis.get("key")
} catch {
try {
return await db.get("key")
} catch {
return "default"
}
}
}
JS 库:safe-wrap
ts
import safe from 'safe-wrap'
const fallbackFn = safe(riskyFn, { fallback: () => 'default' })
16. 死信队列(DLQ)
作用:多次处理失败的消息放入专用队列,等人排查。
ts
async function handle(msg) {
try {
await process(msg)
} catch (e) {
if (msg.retryCount >= 3) {
await dlq.send(msg)
} else {
await retryQueue.send(msg)
}
}
}
JS 库:BullMQ
ts
import { Queue } from 'bullmq'
const queue = new Queue('failed')
await queue.add('dead', msg)
17. 分片(Shard)
作用:把数据拆分到多个数据库里,每个库存一部分,避免单库压力过大。
(用"余数"分配:用户 id 除以数据库总数,余数是几就去第几个库。)
ts
// 假设有 3 个数据库
const databases = ['db0', 'db1', 'db2']
// 根据用户 id 的余数决定去哪个库
function getShard(userId) {
const index = userId % databases.length // % 是求余数,比如 5 ÷ 3 余 2
return databases[index]
}
console.log(getShard(0)) // 0 ÷ 3 余 0 → db0
console.log(getShard(1)) // 1 ÷ 3 余 1 → db1
console.log(getShard(2)) // 2 ÷ 3 余 2 → db2
console.log(getShard(3)) // 3 ÷ 3 余 0 → db0
JS 库:hashring(一致性哈希)
ts
import HashRing from 'hashring'
const ring = new HashRing(['db0', 'db1', 'db2'])
const node = ring.get(userId.toString())
18. 滚动更新
作用:一次只升级一台服务器,不中断服务。
这是运维层策略,不写代码。用 Kubernetes 配置即可:
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 允许额外多起一台新机器
maxUnavailable: 0 # 升级期间不允许有机器不可用
实际工具:Kubernetes、Docker Swarm
19. 负载均衡
作用:把请求分散到多台服务器上,避免单点过载。
(常用"轮询":按顺序轮流分配,第一个请求给 A,第二个给 B,第三个给 C,第四个再给 A。)
ts
// 概念 demo:轮询
let current = 0
const servers = ['192.168.1.1', '192.168.1.2', '192.168.1.3']
function getServer() {
const server = servers[current]
current = (current + 1) % servers.length
return server
}
实际工具:Nginx(最常用)
nginx
upstream backend {
server 192.168.1.1;
server 192.168.1.2;
server 192.168.1.3;
}
server {
location / {
proxy_pass http://backend;
}
}
20. 信号量 / 并发控制
作用:限制同时执行的异步任务数量。
(信号量是一个计数器,初始为最大并发数,每执行一个任务减一,完成加一,达到零时后续任务排队等待。)
ts
let running = 0
const max = 3
async function sem(task) {
if (running >= max) {
await new Promise(r => setTimeout(r, 10))
}
running++
try {
return await task()
} finally {
running--
}
}
JS 库:p-limit
ts
import pLimit from 'p-limit'
const limit = pLimit(3)
const result = await limit(() => asyncTask())
关注我, 关注Bunjs