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

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

第 5 章:HTTP API 详解

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


5.1 API 概述

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

端点方法说明一致性要求
/db/queryGET, POSTSQL 查询(SELECT)可配置
/db/executePOSTSQL 执行(INSERT/UPDATE/DELETE/DDL)强一致性
/db/requestPOST混合请求按语句配置
/db/backupGET数据库备份强一致性
/db/loadPOST数据加载/恢复强一致性
/statusGET节点状态
/nodesGET集群节点列表
/joinPOST加入集群
/removePOST移除节点
/status/readyGET健康检查
/status/leaderGETLeader 检查

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 查询参数汇总

参数说明默认值
qSQL 查询语句必填
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语句数平均延迟吞吐量
单条 Execute1~2ms~500 ops/s
批量 Execute10~5ms~2000 ops/s
批量 Execute100~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 章:集群管理