接入外部数据库实战
Hyperdrive 的价值要在真实接入后才能体现。这篇把一个 PostgreSQL 数据库接到 Hyperdrive 上,让 Workers(Cloudflare 的边缘计算函数服务)能直接读写远程数据。整个流程分四步,准备数据库、创建 Hyperdrive 配置、绑定到 Worker、在代码里发查询。
准备 PostgreSQL 数据库
可以用任意公网可达的 Postgres,比如 AWS RDS、Supabase、Neon 或自建实例。无论哪种,要保证三件事
| 准备项 | 要求 |
|---|---|
| 公网可达 | Hyperdrive 节点要从公网连进来,实例不能只在内网 |
| TLS 支持 | 推荐开启 SSL,连接串里带上 sslmode=require |
| 防火墙放行 | 若用 IP 白名单,需放行 Cloudflare 出口 IP 段 |
连接串格式
postgresql://用户名:密码@主机:5432/数据库名?sslmode=require
先在数据库里建一张测试表
CREATE TABLE products (
id serial PRIMARY KEY,
name text NOT NULL,
price integer NOT NULL,
updated_at timestamptz DEFAULT now()
);
INSERT INTO products (name, price) VALUES
('T 恤', 89),
('帽子', 39),
('背包', 199);
创建 Hyperdrive 配置
用 wrangler(Cloudflare 的命令行工具)创建配置。先确认 wrangler 已登录
npx wrangler login
创建 Hyperdrive,name 是后续绑定的标识,connection-string 指向数据库
npx wrangler hyperdrive create demo-hyperdrive \
--connection-string="postgresql://user:pass@db.example.com:5432/shop?sslmode=require"
命令执行后会输出一个 id,形如 c4a3b2e1d5f6a7b8c9d0e1f2a3b4c5d6,记下它。
列出已创建的 Hyperdrive
npx wrangler hyperdrive list
绑定到 Worker
在 Worker 项目的 wrangler.toml 里加上 hyperdrive 绑定
name = "demo-worker"
main = "src/index.ts"
compatibility_date = "2024-09-01"
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "c4a3b2e1d5f6a7b8c9d0e1f2a3b4c5d6"
binding 是代码里访问它的变量名,id 就是上一步拿到的标识。本地开发时还要加一个 localConnectionString 让 wrangler 直连数据库做调试
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "c4a3b2e1d5f6a7b8c9d0e1f2a3b4c5d6"
localConnectionString = "postgresql://user:pass@127.0.0.1:5432/shop"
本地连接串只在你本机生效,不会上传,可以指向本地 Postgres 做开发。
在代码里发查询
Hyperdrive 把自己伪装成 Postgres,返回一个连接字符串,驱动直接连就行。这意味着已有的 pg 代码几乎不用改。先装驱动
npm install pg
npm install -D @types/pg
Worker 代码
import { Client } from "pg";
export interface Env {
HYPERDRIVE: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const client = new Client({ connectionString: env.HYPERDRIVE });
await client.connect();
try {
const result = await client.query("SELECT id, name, price FROM products");
return Response.json({ rows: result.rows });
} finally {
await client.end();
}
},
};
注意 env.HYPERDRIVE 不是连接对象,而是一串连接串。每次请求 new 一个 Client 看起来浪费,但 Hyperdrive 在背后复用连接池,握手开销已经被它吃掉了。
查询缓存控制
默认情况下 Hyperdrive 对只读查询自动缓存 60 秒。可以用 SQL 注释显式开关
// 强制缓存 5 分钟
await client.query({
text: "/* hyperdrive cache max-age=300 */ SELECT id, name, price FROM products",
});
// 跳过缓存,直查数据库
await client.query({
text: "/* hyperdrive cache skip */ SELECT id, name, price FROM products WHERE id = $1",
values: [123],
});
缓存策略怎么选
| 查询类型 | 建议缓存 | 原因 |
|---|---|---|
| 商品列表、配置字典 | max-age=300 | 读多写少,短时不一致可接受 |
| 用户订单状态 | skip | 强实时,缓存会误导用户 |
| 库存查询 | max-age=5 | 近实时,允许极短延迟 |
| 写操作 INSERT 等 | 自动不缓存 | Hyperdrive 识别写语句,永远直连 |
带参数的查询缓存按完整 SQL 字符串匹配,包括参数值。这意味着 id=1 和 id=2 是两条独立缓存项,参数离散度高时缓存命中率会很低,这种场景更适合 skip。
部署与验证
部署 Worker
npx wrangler deploy
部署后访问 Worker URL,第一次请求会触发 Hyperdrive 建立连接池,可能稍慢。第二次起就能看到明显的提速效果。
验证缓存是否生效可以观察响应时间
const start = Date.now();
const result = await client.query("SELECT id, name, price FROM products");
const elapsed = Date.now() - start;
console.log(`查询耗时 ${elapsed}ms`);
第一次几十毫秒是数据库往返,缓存命中后通常降到个位数毫秒。
小结
接入流程的关键是 wrangler 创建 Hyperdrive 配置拿到 id,在 wrangler.toml 里绑定,代码里用 env.HYPERDRIVE 当连接串丢给 pg 驱动。查询缓存用 SQL 注释控制,按业务对实时性的要求选 max-age 或 skip。整体下来,远程 Postgres 在 Worker 里用起来和本地几乎没差别。