20 个后端"黑话"Bunjs代码演示(限流、熔断、降级、舱壁…)一看就会

我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

相关推荐
天蓝色的鱼鱼5 小时前
10 分钟用 Bun + Hono + SQLite 跑通一个全栈 API
bun
JieE2121 天前
Bun + TypeScript:下一代 JavaScript 全栈开发的正确打开方式
typescript·全栈·bun
不好听6131 天前
Bun vs Node.js:谁才是 TypeScript 的"亲爹"?
typescript·node.js·bun
拾年2751 天前
Bun:重新定义 JavaScript 运行时 - 为什么它可能是 Node.js 的终结者?
javascript·typescript·bun
mONESY1 天前
Bun+TS零配置极速实现大模型API请求
typescript·bun
孟陬20 天前
从 Claude Code 187 种说“正在处理”的方式看一流公司的用户体验
前端·claude·bun
mCell23 天前
从云相册的缩略图说起:Bun.Image 让我告别 sharp
javascript·图片资源·bun
带娃的IT创业者23 天前
Rewrite Bun in Rust:一次前端工具链的底层重构实践入门指南
前端·重构·rust·bun·运行时·前端工具链
子兮曰1 个月前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun