强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

rqlite 完全指南 / 第 5 章:HTTP API 详解

第 5 章:HTTP API 详解

全面掌握 rqlite 的 HTTP API,包括参数绑定、一致性级别、事务和批量操作。


5.1 API 概述

rqlite 提供 RESTful HTTP API,所有数据库操作通过以下端点完成:

端点 方法 说明 一致性要求
/db/query GET, POST SQL 查询(SELECT) 可配置
/db/execute POST SQL 执行(INSERT/UPDATE/DELETE/DDL) 强一致性
/db/request POST 混合请求 按语句配置
/db/backup GET 数据库备份 强一致性
/db/load POST 数据加载/恢复 强一致性
/status GET 节点状态
/nodes GET 集群节点列表
/join POST 加入集群
/remove POST 移除节点
/status/ready GET 健康检查
/status/leader GET Leader 检查

5.2 查询 API (/db/query)

5.2.1 GET 方式查询

# 基本 GET 查询
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users LIMIT 10'

# 多个查询语句
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users' \
    --data-urlencode 'q=SELECT COUNT(*) FROM orders'

# 带一致性级别
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users' \
    --data-urlencode 'level=strong'

# 带超时时间
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users' \
    --data-urlencode 'timeout=10s'

# 美化输出
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users' \
    --data-urlencode 'pretty'

5.2.2 POST 方式查询

# JSON body 方式(适合复杂参数)
curl -XPOST 'localhost:4001/db/query' \
    -H 'Content-Type: application/json' \
    -d '{
        "statements": [
            {"q": "SELECT * FROM users WHERE age > ?", "v": [25]},
            {"q": "SELECT COUNT(*) FROM orders"}
        ],
        "level": "strong",
        "pretty": true
    }'

5.2.3 一致性级别详解

级别 行为 延迟 适用场景
none 任意节点本地读取,不保证一致性 最低 统计数据、缓存查询
weak 尽量从 Leader 读,不确认 Leader 身份 一般业务查询
strong 强制从 Leader 读,并确认 Leader 身份 事务后的读取、关键业务
# 不同一致性级别示例
# none — 可能从 Follower 读到过期数据
curl -G 'localhost:4001/db/query' --data-urlencode 'level=none' --data-urlencode 'q=SELECT COUNT(*) FROM orders'

# strong — 保证读到最新数据
curl -G 'localhost:4001/db/query' --data-urlencode 'level=strong' --data-urlencode 'q=SELECT COUNT(*) FROM orders'

5.2.4 查询参数汇总

参数 说明 默认值
q SQL 查询语句 必填
level 一致性级别 weak
timeout 查询超时 10s
pretty 美化 JSON 输出 false
associative 以对象数组返回结果 false
timings 显示执行时间 false
# associative 模式 — 列名作为 key
curl -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users LIMIT 1' \
    --data-urlencode 'associative'

响应对比:

// 默认模式 (values 数组)
{
    "columns": ["id", "username", "email"],
    "values": [[1, "zhangsan", "zs@example.com"]]
}

// associative 模式 (对象数组)
{
    "columns": ["id", "username", "email"],
    "types": ["integer", "text", "text"],
    "values": [
        {"id": 1, "username": "zhangsan", "email": "zs@example.com"}
    ]
}

5.3 执行 API (/db/execute)

5.3.1 基本执行

# 单条语句
curl -XPOST 'localhost:4001/db/execute' \
    -H 'Content-Type: application/json' \
    -d '[["INSERT INTO users (username, email, age) VALUES (?, ?, ?)", "test", "test@example.com", 20]]'

# 多条语句(同一事务)
curl -XPOST 'localhost:4001/db/execute' \
    -H 'Content-Type: application/json' \
    -d '[
        ["INSERT INTO users (username, email) VALUES (?, ?)", "user1", "u1@example.com"],
        ["INSERT INTO users (username, email) VALUES (?, ?)", "user2", "u2@example.com"],
        ["INSERT INTO orders (user_id, product, quantity, price) VALUES (?, ?, ?, ?)", 1, "商品A", 2, 100.0]
    ]'

5.3.2 JSON body 格式

curl -XPOST 'localhost:4001/db/execute' \
    -H 'Content-Type: application/json' \
    -d '{
        "statements": [
            {"q": "INSERT INTO users (username, email) VALUES (?, ?)", "v": ["user3", "u3@example.com"]},
            {"q": "UPDATE users SET age = ? WHERE username = ?", "v": [25, "user3"]}
        ],
        "timings": true
    }'

5.3.3 参数绑定方式

rqlite 支持两种参数绑定格式:

方式一:位置参数(Positional)

{
    "q": "INSERT INTO users (username, email) VALUES (?, ?)",
    "v": ["zhangsan", "zs@example.com"]
}

方式二:命名参数(Named)

{
    "q": "INSERT INTO users (username, email) VALUES (:name, :email)",
    "v": {"name": "zhangsan", "email": "zs@example.com"}
}

安全警告: 永远使用参数绑定,不要拼接 SQL 字符串!拼接 SQL 会导致注入攻击。

# ❌ 错误 — SQL 注入风险
rxe '[["INSERT INTO users (username) VALUES (\"admin\" OR 1=1 --)\"]]'

# ✅ 正确 — 参数绑定
rxe '[["INSERT INTO users (username) VALUES (?)", "admin"]]'

5.4 混合请求 API (/db/request)

/db/request 允许在同一个请求中混合查询和执行操作:

curl -XPOST 'localhost:4001/db/request' \
    -H 'Content-Type: application/json' \
    -d '{
        "statements": [
            {"q": "INSERT INTO users (username, email) VALUES (?, ?)", "v": ["newuser", "new@example.com"]},
            {"q": "SELECT * FROM users ORDER BY id DESC LIMIT 1"}
        ]
    }'

响应中既有执行结果也有查询结果:

{
    "results": [
        {
            "last_insert_id": 10,
            "rows_affected": 1,
            "time": 0.000234
        },
        {
            "columns": ["id", "username", "email", "age", "created_at"],
            "types": ["integer", "text", "text", "integer", "datetime"],
            "values": [[10, "newuser", "new@example.com", 0, "2026-05-10 12:00:00"]],
            "time": 0.000123
        }
    ]
}

注意: /db/request 中的所有语句在同一事务中执行,确保原子性。


5.5 事务处理

5.5.1 隐式事务

rqlite 默认将单次请求中的多条语句包装在事务中:

# 这三条语句在同一事务中执行
rxe '[
    ["BEGIN"],
    ["INSERT INTO accounts (name, balance) VALUES (?, ?)", "A", 1000],
    ["UPDATE accounts SET balance = balance - 100 WHERE name = ?", "A"],
    ["COMMIT"]
]'

5.5.2 显式事务

# 显式 BEGIN/COMMIT
rxe '[
    ["BEGIN"],
    ["UPDATE accounts SET balance = balance - 200 WHERE name = ?", "A"],
    ["UPDATE accounts SET balance = balance + 200 WHERE name = ?", "B"],
    ["COMMIT"]
]'

重要: rqlite 中 BEGIN/COMMIT 会被转换为 SQLite 本地事务。Raft 日志复制保证操作顺序,但不等同于分布式两阶段提交。

5.5.3 事务回滚

# 如果某条语句失败,整个事务回滚
rxe '[
    ["BEGIN"],
    ["INSERT INTO users (username, email) VALUES (?, ?)", "ok_user", "ok@example.com"],
    ["INSERT INTO users (username, email) VALUES (?, ?)", "duplicate_name", "dup@example.com"],
    ["INSERT INTO users (username, email) VALUES (?, ?)", "duplicate_name", "dup2@example.com"],
    ["COMMIT"]
]'

如果 duplicate_name 违反了唯一约束,整个请求会返回错误,所有操作被回滚。


5.6 备份与恢复 API

5.6.1 备份

# SQLite dump 格式备份
curl -s 'localhost:4001/db/backup' -o backup.sql

# 二进制数据库备份
curl -s 'localhost:4001/db/backup?fmt=binary' -o backup.db

# 加载 dump 文件恢复
curl -XPOST 'localhost:4001/db/load' \
    -H 'Content-Type: text/plain' \
    --data-binary @backup.sql

5.7 错误处理

5.7.1 常见 HTTP 状态码

状态码 说明 常见原因
200 成功
400 请求格式错误 JSON 解析失败、SQL 语法错误
401 未认证 缺少认证信息
403 无权限 认证通过但权限不足
404 不存在 端点不存在或节点不存在
409 冲突 集群状态冲突(非 Leader)
500 内部错误 SQLite 执行错误、Raft 错误
503 服务不可用 集群无 Leader

5.7.2 错误响应格式

{
    "results": [
        {
            "error": "UNIQUE constraint failed: users.username"
        }
    ],
    "time": 0.000234
}
# 检查错误
curl -s -XPOST 'localhost:4001/db/execute' \
    -H 'Content-Type: application/json' \
    -d '[["INSERT INTO users (username, email) VALUES (?, ?)", "zhangsan", "dup@example.com"]]' \
    | python3 -c "
import json, sys
resp = json.load(sys.stdin)
for r in resp.get('results', []):
    if 'error' in r:
        print(f'Error: {r[\"error\"]}')
    else:
        print(f'OK: rows_affected={r[\"rows_affected\"]}')
"

5.8 实用 curl 技巧

5.8.1 美化输出脚本

#!/bin/bash
# rq.sh — rqlite 查询助手
HOST=${RQLITE_HOST:-localhost:4001}

query() {
    curl -s -G "http://$HOST/db/query" \
        --data-urlencode "q=$1" \
        --data-urlencode "pretty" \
        --data-urlencode "level=${2:-weak}" | python3 -m json.tool
}

execute() {
    curl -s -XPOST "http://$HOST/db/execute" \
        -H 'Content-Type: application/json' \
        -d "$1" | python3 -m json.tool
}

# 使用示例
# query "SELECT * FROM users LIMIT 5"
# execute '[["INSERT INTO users (username) VALUES (?)", "test"]]'

5.8.2 超时和重试

# 设置连接超时和最大超时
curl --connect-timeout 5 --max-time 30 \
    -G 'localhost:4001/db/query' \
    --data-urlencode 'q=SELECT * FROM users'

# 自动重试脚本
for i in {1..3}; do
    result=$(curl -s -w "%{http_code}" -G 'localhost:4001/db/query' --data-urlencode 'q=SELECT 1')
    code=${result: -3}
    if [ "$code" = "200" ]; then
        echo "Success"
        break
    fi
    echo "Attempt $i failed ($code), retrying..."
    sleep 1
done

5.9 API 性能对比

API 语句数 平均延迟 吞吐量
单条 Execute 1 ~2ms ~500 ops/s
批量 Execute 10 ~5ms ~2000 ops/s
批量 Execute 100 ~25ms ~4000 ops/s
Query (weak) 1 ~1ms ~1000 ops/s
Query (strong) 1 ~2ms ~500 ops/s
Query (none) 1 ~0.5ms ~2000 ops/s

提示: 批量操作性能显著优于逐条操作。生产环境中应尽量使用批量 API。


5.10 本章小结

要点 内容
查询端点 /db/query,支持 GET 和 POST
执行端点 /db/execute,仅 POST
混合端点 /db/request,同一请求中混合读写
参数绑定 ? 位置参数或 :name 命名参数
一致性 none/weak/strong 三级可选
事务 多条语句默认在同一事务中执行
错误处理 检查响应中的 error 字段

上一章:第 4 章:基础操作 下一章:第 6 章:集群管理