微服务网关:Hono 作为轻量级 API Gateway
路由转发、认证、限流、日志
在微服务架构中,API 网关(API Gateway) 是系统的统一入口,负责请求路由、身份验证、限流、监控等横切关注点。传统网关如 Nginx、Kong、Traefik 功能强大但配置复杂,而 Hono 凭借其轻量、高性能、TypeScript 友好和边缘兼容性,成为构建轻量级 API 网关的理想选择。
本文将展示如何使用 Hono 实现一个功能完整的微服务网关,支持:
- 动态路由转发(Reverse Proxy)
- 身份认证(JWT / API Key)
- 请求限流(Rate Limiting)
- 请求日志与监控
- 错误处理与熔断
一、为什么选择 Hono 作为 API 网关?
| 特性 | 优势 |
|---|---|
| 极低延迟 | 路由匹配 < 0.1ms,适合高频请求 |
| 轻量 (~2KB) | 无依赖,内存占用小 |
| TypeScript 原生支持 | 类型安全,开发体验佳 |
| 边缘兼容 | 可部署在 Cloudflare Workers、Deno、Bun |
| 中间件生态 | 支持 JWT、CORS、压缩、限流等 |
| 可编程性强 | 使用 JS/TS 编写网关逻辑,灵活可控 |
适用场景:中小型微服务、Serverless 架构、边缘网关、内部服务网格入口。
二、架构设计
+------------------+
| Client |
+--------+---------+
|
v
+--------+---------+ +------------------+
| Hono Gateway | --> | Service A |
| (API Gateway) | | http://svc-a:3001 |
+--------+---------+ +------------------+
|
+-------------> | Service B |
| http://svc-b:3002 |
+------------------+
|
+-------------> | Auth Service |
| http://auth:3000 |
+------------------+- 所有请求先经过 Hono 网关;
- 网关负责认证、路由、限流、日志;
- 合法请求被转发到对应微服务。
三、核心功能实现
1. 初始化项目
bash
npm create hono@latest my-gateway
cd my-gateway
npm install @hono/jwt @hono/ratelimit @hono/zod-validator2. 路由转发(Reverse Proxy)
ts
// middleware/proxy.ts
import { Hono } from 'hono'
export const createProxy = (target: string) => {
return async (c, next) => {
const path = c.req.path // 如 /api/users/*
const url = new URL(c.req.url)
const proxyUrl = `${target}${path}${url.search}`
const req = new Request(proxyUrl, {
method: c.req.method,
headers: c.req.headers,
body: c.req.method !== 'GET' && c.req.method !== 'HEAD' ? c.req.raw.body : null
})
// 移除 Host 头,避免目标服务拒绝
req.headers.delete('host')
try {
const res = await fetch(req)
return res
} catch (error) {
return c.json({ error: 'Service unreachable' }, 502)
}
}
}3. 服务路由配置
ts
// config/services.ts
export const SERVICES = {
'users': { target: 'http://localhost:3001', prefix: '/api/users' },
'orders': { target: 'http://localhost:3002', prefix: '/api/orders' },
'products': { target: 'http://localhost:3003', prefix: '/api/products' }
}4. 认证中间件(JWT / API Key)
ts
// middleware/auth.ts
import { bearerAuth } from '@hono/bearer-auth'
import { jwt } from '@hono/jwt'
const API_KEYS = new Set(['sk-live-12345', 'sk-test-67890'])
export const authMiddleware = (c, next) => {
const auth = c.req.header('Authorization')
// 方式1:API Key
if (auth?.startsWith('Bearer sk-')) {
const token = auth.split(' ')[1]
if (API_KEYS.has(token)) {
return next()
}
}
// 方式2:JWT
if (auth?.startsWith('Bearer ey')) {
const jwtMiddleware = jwt({
secret: 'your-super-secret-jwt-key'
})
return jwtMiddleware(c, next)
}
return c.json({ error: 'Unauthorized' }, 401)
}5. 限流中间件
ts
// middleware/ratelimit.ts
import { Ratelimit } from '@hono/ratelimit'
import { kv } from '@hono/kv-storage' // 可替换为 Redis、D1 等
export const rateLimit = Ratelimit({
limit: 100, // 每分钟最多 100 次
duration: '1 min',
async store(key) {
// 使用 KV 存储计数
const client = kv()
return {
async increment() {
const value = (await client.get<number>(key)) || 0
await client.set(key, value + 1, { expirationTtl: 60 })
return { current: value + 1, limit: 100 }
}
}
},
key: (c) => c.req.header('x-forwarded-for') || c.req.ip // 按 IP 限流
})6. 日志中间件
ts
// middleware/logger.ts
export const logger = async (c, next) => {
const start = Date.now()
const method = c.req.method
const path = c.req.path
const ip = c.req.header('x-forwarded-for') || c.req.ip
await next()
const status = c.res.status
const ms = Date.now() - start
console.log(`[${new Date().toISOString()}] ${method} ${path} ${status} ${ms}ms ${ip}`)
// 可选:发送到日志服务(如 Logflare、Datadog)
// await fetch('https://logs.example.com', { method: 'POST', body: JSON.stringify(log) })
}四、主网关应用
ts
// app.ts
import { Hono } from 'hono'
import { SERVICES } from './config/services'
import { createProxy } from './middleware/proxy'
import { authMiddleware } from './middleware/auth'
import { rateLimit } from './middleware/ratelimit'
import { logger } from './middleware/logger'
const app = new Hono()
// 全局中间件
app.use('*', logger)
app.use('/api/*', rateLimit)
app.use('/api/*', authMiddleware)
// 动态路由转发
Object.entries(SERVICES).forEach(([name, config]) => {
app.on(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], `${config.prefix}/*`, createProxy(config.target))
})
// 健康检查
app.get('/health', (c) => c.json({ status: 'ok', timestamp: Date.now() }))
// 404 处理
app.notFound((c) => c.json({ error: 'Not Found' }, 404))
// 错误处理
app.onError((err, c) => {
console.error(err)
return c.json({ error: 'Internal Server Error' }, 500)
})
export default app五、部署选项
| 平台 | 优势 |
|---|---|
| Cloudflare Workers | 全球边缘,低延迟 |
| Bun | 高性能,适合自托管 |
| Deno | 安全、无依赖 |
| Node.js + PM2 | 传统服务器部署 |
| Docker | 容器化,K8s 集成 |
Dockerfile 示例
Dockerfile
FROM oven/bun:1.1
WORKDIR /app
COPY . .
RUN bun install
EXPOSE 3000
CMD ["bun", "app.ts"]六、高级功能(可选)
1. 熔断与降级
ts
import { CircuitBreaker } from 'some-circuit-breaker-lib'
const cb = new CircuitBreaker({ threshold: 5, timeout: 30 })
app.use('/api/users/*', async (c, next) => {
try {
await cb.call(() => next())
} catch (err) {
return c.json({ error: 'Service temporarily unavailable' }, 503)
}
})2. 请求改写(Rewrite)
ts
app.post('/api/legacy/order', async (c) => {
const body = await c.req.json()
const newBody = { order: body } // 适配新格式
const req = new Request('http://orders/create', {
method: 'POST',
body: JSON.stringify(newBody)
})
return fetch(req)
})3. 响应缓存
ts
app.get('/api/products', async (c) => {
const cache = await caches.default
const key = c.req.url
const cached = await cache.match(key)
if (cached) return cached
const res = await fetch('http://products:3003/list')
const response = res.clone()
c.executionCtx.waitUntil(cache.put(key, response))
return res
})七、性能优化建议
启用 Gzip 压缩
tsimport { compress } from '@hono/compress' app.use('*', compress())使用连接池(Node.js 环境)
避免阻塞操作
监控 CPU/内存使用
八、总结
| 功能 | Hono 实现方式 |
|---|---|
| 路由转发 | fetch() + 自定义 proxy 中间件 |
| 认证 | @hono/jwt, bearerAuth, 自定义 key 验证 |
| 限流 | @hono/ratelimit + KV/Redis |
| 日志 | 自定义 logger 中间件 |
| 监控 | 集成 Prometheus / Datadog |
| 熔断 | 第三方库或自定义逻辑 |
Hono 不只是一个 Web 框架,它是一个可编程的边缘网关平台。
通过几行 TypeScript 代码,你就能构建一个轻量、高性能、可扩展的 API 网关,完美适配微服务、Serverless 和边缘计算架构。
立即尝试将 Hono 引入你的架构,打造下一代智能网关!