司契权限系统是一个基于 C++ 和 bRPC 开发的高性能、中心化权限控制服务。它采用 RBAC(基于角色的访问控制)模型,为微服务架构中的其他应用(如 QQ 机器人、青鸾系统等)提供统一的权限校验能力。
- 高性能 RPC:基于百度 bRPC 框架,支持高并发低延迟调用。
- 安全鉴权:基于 Token 的管理员登录与会话管理,杜绝身份伪造。
- 本地缓存:权限数据本地缓存,提升权限检查性能,减少数据库访问压力。
- 审计日志:自动记录所有管理操作,追踪到具体操作人,保障系统安全。
- 持久化存储:使用 MySQL 存储权限数据。
- 多语言接入:提供 Node Agent (Sidecar) 模式,通过 HTTP 接口支持 Python/Java/Go 等多语言无缝接入,零 SDK 依赖。
- RPC 框架: Apache bRPC
- 序列化: Protocol Buffers 3
- 数据库: MySQL (使用 MySQL Connector/C++)
- 构建工具: CMake 3.10+
siqi_auth/ # 项目根目录
├── conf/ # 配置文件目录
│ ├── agent.conf # Agent 配置文件 (连接本地 Slave)
│ └── server.conf # 服务端配置文件 (连接远程 Master)
├── include/ # 头文件目录
│ ├── admin_service_impl.h # 管理服务接口实现类定义
│ ├── auth_agent.h # Agent 业务逻辑实现类定义
│ ├── auth_service_impl.h # 鉴权服务接口实现类定义
│ ├── auth.pb.h # [自动生成] Protobuf 生成的 C++ 头文件
│ ├── local_cache.h # 本地缓存实现,提升权限检查性能
│ └── permission_dao.h # 数据访问层(DAO)接口定义,负责数据库交互
├── proto/ # RPC 接口定义目录
│ └── auth.proto # Protobuf 文件,定义服务接口与消息结构
├── scripts/ # 辅助脚本目录
│ ├── init.sql # 初始化数据库脚本
│ ├── deploy_db.sh # 一键部署 Master 数据库 (Docker)
│ ├── start_server.sh # 启动管理服务端
│ └── master_snapshot.sql # [生成] 主从同步数据快照
├── src/ # 源代码目录
│ ├── admin_service_impl.cpp # 管理服务具体逻辑实现
│ ├── admin_tool.cpp # CLI 管理工具
│ ├── auth_service_impl.cpp # 鉴权服务具体逻辑实现
│ ├── auth_agent.cpp # Agent 主入口,负责初始化本地数据库连接
│ ├── auth_agent_impl.cpp # Agent 逻辑,直连本地 Slave 进行查询
│ ├── auth.pb.cc # [自动生成] Protobuf 生成的 C++ 源文件
│ ├── client_example.cpp # 客户端 SDK 调用示例代码
│ ├── permission_dao.cpp # 数据库操作具体实现(CRUD)
│ └── server_main.cpp # 服务端主入口,负责初始化与启动 bRPC 服务
├── test/ # 测试目录
│ └── perf_test.cpp # 性能测试工具,多线程压测 AuthService
├── third_party/ # 第三方依赖 Bazel 构建规则
│ ├── BUILD # 包声明文件
│ ├── protobuf.BUILD # Protobuf 构建规则(含 protoc 编译器)
│ ├── leveldb.BUILD # LevelDB 构建规则
│ ├── zlib.BUILD # Zlib 构建规则
│ ├── openssl.BUILD # OpenSSL 构建规则(链接系统库)
│ └── mysqlcppconn.BUILD # MySQL Connector/C++ 构建规则(链接系统库)
├── BUILD.bazel # Bazel 构建脚本,定义项目目标与依赖关系
├── WORKSPACE # Bazel 工作空间配置,声明外部依赖(bRPC, Protobuf 等)
├── .bazelrc # Bazel 构建选项配置
├── .bazelversion # 指定 Bazel 版本 (6.4.0)
├── CMakeLists.txt # CMake 构建脚本,定义依赖与编译规则
└── README.md # 项目说明文档
为解决高并发下的网络延迟问题,本项目采用了 Agent + 本地数据库副本 (Local DB Replica) 的架构模式。
graph TD
%% 服务端部分
subgraph "中心端 (Cloud/Server)"
MasterDB["MySQL Master"]
AdminServer["Auth Server (Manager)"]
AdminTool["CLI Admin Tool"]
AdminTool -->|RPC| AdminServer
AdminServer -->|Write/Read| MasterDB
end
%% 业务节点部分
subgraph "业务节点 (Client Agent 1)"
Agent1["Auth Agent"]
SlaveDB1["MySQL Slave"]
App1["业务 App (QQ Bot)"]
App1 -->|HTTP/RPC| Agent1
Agent1 -->|Localhost ~1ms| SlaveDB1
end
subgraph "业务节点 (Client Agent 2)"
Agent2["Auth Agent"]
SlaveDB2["MySQL Slave (Docker)"]
App2["业务 App (Course API)"]
App2 -->|HTTP/RPC| Agent2
Agent2 -->|Localhost ~1ms| SlaveDB2
end
%% 同步链路
MasterDB -->|Binlog Sync| SlaveDB1
MasterDB -->|Binlog Sync| SlaveDB2
- 极速鉴权:业务查权限就像查本机文件一样快 (延迟 < 1ms),完全消除网络 RTT。
- 高可用:即使中心端网络中断或 Master 宕机,Agent 依然可以依靠本地数据正常工作。
- 读写分离:鉴权流量全部由各节点的 Slave 承担,中心 Master 只负责管理操作的写入。
确保系统安装了必要的构建工具和依赖库:
# 基础构建工具
sudo apt install -y git g++ cmake make pkg-config
# 依赖库
sudo apt install -y libssl-dev libgflags-dev libprotobuf-dev protobuf-compiler libleveldb-dev libprotoc-dev
# MySQL Connector/C++
sudo apt install -y libmysqlcppconn-devbRPC 安装(参考brpc的安装与使用介绍以及channel的封装):
git clone https://github.com/apache/brpc.git
cd brpc/
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr .. && cmake --build . -j4
make && sudo make installcmake -B build
make -C build/ -j`nproc`构建完成后,build/ 目录下将生成以下可执行文件:
auth_server: 权限系统服务端 (连接 Master)auth_agent: 节点级 Sidecar 代理 (连接 Local Slave)admin_tool: 命令行管理工具perf_test: 性能压测工具
Bazel 构建系统会自动从网络下载并编译大部分依赖(bRPC、Protobuf、gflags、LevelDB、Zlib),仅需安装少量系统级依赖:
# 基础构建工具
sudo apt install -y git g++ make
# Bazel 依赖的系统库(OpenSSL、MySQL Connector/C++ 通过系统安装提供)
sudo apt install -y libssl-dev libmysqlcppconn-dev# 通过 Bazelisk(会自动读取 .bazelversion 文件选择版本)
# 注意:v1.19.0 存在 HTTP 下载挂起的已知 Bug,请使用 v1.22.1 或更新版本
export https_proxy=http://127.0.0.1:7890 # 设置代理(如果需要)
sudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/download/v1.22.1/bazelisk-linux-amd64
sudo chmod +x /usr/local/bin/bazel
bazel --version # 首次运行会自动下载 Bazel 6.4.0
### 编译构建
```bash
# 编译所有目标(推荐)
bazel build //...
# 或单独编译指定目标
bazel build //:auth_server
bazel build //:test_client
bazel build //:admin_tool
bazel build //:auth_agent
bazel build //:perf_test构建完成后,可执行文件位于 bazel-bin/ 目录下:
bazel-bin/auth_server: 权限系统服务端 (连接 Master)bazel-bin/auth_agent: 节点级 Sidecar 代理 (连接 Local Slave)bazel-bin/admin_tool: 命令行管理工具bazel-bin/test_client: 客户端示例bazel-bin/perf_test: 性能压测工具
目标:部署 MySQL Master 和 Auth Server。
本方案基于 docker-compose.master.yml,会同时启动:
mysql-master:MySQL 主库,宿主机端口8002auth-server:权限服务端,宿主机端口8001
其中:
- MySQL 数据会持久化到 Docker 命名卷
mysql_master_data - 初始化建库建表脚本来自
scripts/init.sql - 主从复制账号
repl/slave123会在首次初始化时通过deploy/master_repl.sql自动创建 auth-server容器会通过 Docker 内部服务名mysql-master:3306连接数据库
-
准备环境: 确保宿主机已安装 Docker 与 Docker Compose 插件:
docker --version docker compose version
如果未安装,可在 Ubuntu 上执行:
sudo apt update sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable --now docker -
进入项目目录:
cd /path/to/siqi_auth -
确认宿主机端口未冲突:
docker-compose.master.yml会占用宿主机8001和8002,如果当前机器已经运行了docker-compose.slave.yml,需要先停止旧服务:docker compose -f docker-compose.slave.yml stop docker compose -f docker-compose.slave.yml down
也可以先检查端口占用:
sudo ss -lntp | grep -E '8001|8002'
-
启动 Master 与 Auth Server: 直接构建并后台启动:
docker compose -f docker-compose.master.yml up -d --build
-
如需代理拉取依赖,可透传代理环境变量:
docker-compose.master.yml已透传HTTP_PROXY、HTTPS_PROXY、http_proxy、https_proxy,可按需这样构建:HTTP_PROXY="http://172.17.0.1:7897" \ HTTPS_PROXY="http://172.17.0.1:7897" \ http_proxy="http://172.17.0.1:7897" \ https_proxy="http://172.17.0.1:7897" \ docker compose -f docker-compose.master.yml up -d --build
请将地址替换为宿主机代理软件实际 IP 和端口。
-
检查容器状态:
docker compose -f docker-compose.master.yml ps
预期应看到:
siqi_mysql_master处于healthy或runningsiqi_auth_server处于running
-
查看启动日志:
docker logs -f siqi_mysql_master docker logs -f siqi_auth_server
auth_server正常启动时,日志中应包含监听8001的信息。 -
验证 MySQL Master 是否可用:
mysql -h127.0.0.1 -P8002 -uroot -proot123 -e "SHOW DATABASES;"此时 Master 对外暴露
8002端口(替代默认的3306)。业务账号为siqi_dev/siqi123。 -
验证复制账号是否已创建:
mysql -h127.0.0.1 -P8002 -urepl -pslave123 -e "SHOW MASTER STATUS\G"如果可以正常返回 binlog 信息,说明从库同步使用的账号
repl/slave123已创建成功。 -
验证 Auth Server 是否可用:
curl http://127.0.0.1:8001/
如果返回 bRPC 默认页面,说明
auth_server已成功启动并对外监听8001。 -
导出主库快照给业务节点使用: 在中心端导出包含同步坐标的快照:
docker exec siqi_mysql_master mysqldump -uroot -proot123 \ --databases siqi_auth \ --master-data=1 \ --single-transaction > slave_init.sql
将生成的
slave_init.sql发送到所有业务节点,用于初始化从库。 -
查看主库数据卷位置(可选): 当前 Compose 使用的是 Docker 命名卷,不是宿主机目录直挂载。可用以下命令查看真实宿主机路径:
docker volume ls | grep mysql_master_data docker volume inspect <卷名>
其中
Mountpoint即为宿主机上的实际存储路径。 -
常用管理命令:
# 停止服务 docker compose -f docker-compose.master.yml stop # 重启服务 docker compose -f docker-compose.master.yml restart # 停止并删除容器(保留数据卷) docker compose -f docker-compose.master.yml down # 停止并删除容器和数据卷(危险) docker compose -f docker-compose.master.yml down -v
注意:
deploy/master_repl.sql只会在 MySQL 数据卷首次初始化时自动执行一次。如果此前已经创建过mysql_master_data数据卷,后续重新up不会重复自动建复制账号;此时可手动执行:docker exec -i siqi_mysql_master mysql -uroot -proot123 < deploy/master_repl.sql如果中心端还需要暴露到公网,可在宿主机进一步配合 Nginx、反向代理或
autossh做穿透。
-
启动 MySQL Master (Docker): 使用内置脚本启动并自动配置 Replication 账号:
sudo ./scripts/deploy_db.sh
此时 Master 会对外暴露 8002 端口(替代默认的 3306)。账号:
siqi_dev/siqi123,同步账号:repl/slave123。 -
准备同步数据: 在中心端导出当前数据快照(包含同步坐标):
sudo docker exec siqi_mysql_prod mysqldump -uroot -proot123 \ --databases siqi_auth \ --master-data=1 \ --single-transaction > slave_init.sql
将生成的
slave_init.sql发送到所有业务节点。 -
启动管理服务:
./scripts/start_server.sh
Auth Server 将监听 8001 端口,并连接到 127.0.0.1:8002 的 Master 数据库。
目标:在业务机器上部署 MySQL Slave 和 Auth Agent。
- 进入siqi_auth目录,运行以下命令导出快照
mysqldump -h <MASTER_IP> -P 8002 -uroot -proot123 \
--databases siqi_auth \
--master-data=1 \
--single-transaction > slave_init.sql- 在siqi_auth目录下运行以下命令进行构建 (通过 SERVER_ID 环境变量指定这台机器的唯一节点 ID,多台部署切勿重复)
SERVER_ID=2 docker compose -f docker-compose.slave.yml up -d --build
# 如果是在国内服务器或校园网环境,如果在拉取github仓库时出现网络问题,请使用类似代理的构建方式
# HTTP_PROXY 和 HTTPS_PROXY 替换为你宿主机代理软件的 IP 及端口
# 代理软件记得开局域网连接
SERVER_ID=2 docker compose -f docker-compose.slave.yml build \
--build-arg HTTP_PROXY="http://172.17.0.1:7897" \
--build-arg HTTPS_PROXY="http://172.17.0.1:7897"
# 构建完成后再启动
SERVER_ID=2 docker compose -f docker-compose.slave.yml up -d注意:
SERVER_ID环境变量必须为每台业务节点指定一个唯一的整数值(如 2, 3, 4...),以避免 MySQL 主从复制中的server_id冲突。 另外,新版docker使用的不再是docker-compose命令,而是docker compose(空格分隔),请根据实际环境调整命令。 如果报permission denied,请检查当前用户是否有权限访问 Docker Socket,或尝试使用sudo运行命令。
- 配置slave同步master 等待slave初始化后,配置主从同步
# 进入 Slave 容器
docker exec -it siqi_mysql_slave mysql -uroot -proot123在控制台中执行
STOP SLAVE;
-- 配置主库连接(替换 <MASTER_IP> 为实际 IP)
CHANGE MASTER TO
MASTER_HOST='<MASTER_IP>',
MASTER_PORT=8002,
MASTER_USER='repl',
MASTER_PASSWORD='slave123',
GET_MASTER_PUBLIC_KEY=1;
START SLAVE;
-- 检查同步状态
SHOW SLAVE STATUS\G- 验证部署 检查容器状态
docker compose -f docker-compose.slave.yml ps测试agent服务
# 测试 Agent 是否响应
curl http://localhost:8001/health
``
5. 管理命令
```bash
# 停止服务
docker compose -f docker-compose.slave.yml stop
# 停止并删除数据卷(谨慎使用!)
docker compose -f docker-compose.slave.yml down -v
# 重启服务
docker compose -f docker-compose.slave.yml restart
# 查看同步延迟
docker exec -it siqi_mysql_slave mysql -uroot -proot123 -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master提示:如果您的宿主机/容器已经存在旧版的数据库,并非首次安装,请跳过新建流程,直接查阅 进阶:在已有实例上重建/对齐主从库
-
启动 Slave 数据库: 将
slave_init.sql放入当前目录,运行:# 注意修改 server-id (每个节点必须唯一,如 2, 3, 4...) # 映射端口到宿主机 3306 docker run -d --name auth_slave_db \ --restart always \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=slave_root_123 \ -v $(pwd)/slave_init.sql:/docker-entrypoint-initdb.d/init.sql \ mysql:8.0 \ --server-id=2 \ --log-bin=mysql-bin --binlog-format=ROW
-
直连 Master 同步数据: 由于中心端已开放 8002 端口,不再需要建立 SSH 隧道,直接进入 Slave 容器配置:
docker exec -it auth_slave_db mysql -uroot -pslave_root_123STOP SLAVE; -- <Master_IP> 替换为中心服务器的公网 IP,端口为 8002 CHANGE MASTER TO MASTER_HOST='<Master_IP>', MASTER_PORT=8002, MASTER_USER='repl', MASTER_PASSWORD='slave123', GET_MASTER_PUBLIC_KEY=1; START SLAVE; SHOW SLAVE STATUS\G -- 检查 Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes
-
启动 Agent: 修改
conf/agent.conf连接本地数据库(127.0.0.1:3306),然后启动:./build/auth_agent --flagfile=conf/agent.conf
- 安装 MySQL Server,修改
/etc/mysql/mysql.conf.d/mysqld.cnf设置server-id = 2并重启。 - 导入快照:
sudo mysql < slave_init.sql。 - 配置 Master(同上,Host 填
127.0.0.1即可)。 - 创建 Agent 专用账号:
CREATE USER 'agent_user'@'127.0.0.1' IDENTIFIED BY 'agent123'; GRANT SELECT ON siqi_auth.* TO 'agent_user'@'127.0.0.1';
- 启动 Agent。
如果您已经在运行(Docker 或 本地物理机)节点,因为网络切换或故障导致同步完全断裂并需要推翻重置,请按照以下方案实现热覆盖(无需删除容器或重装 MySQL):
第一步:从主库拉取带有坐标的最新单库快照
这里使用 --databases siqi_auth 而非 --all-databases,是为了避免主库的系统表覆盖掉本机的用户密码权限和免密配置。这样您原先的 root 密码和 sudo mysql 都不会被篡改。
# 从中心主库(8002 端口)抽取出业务库及其位点
mysqldump -h <Master_IP> -P 8002 -uroot -proot123 --databases siqi_auth --master-data=1 > db_rescue.sql第二步:进入需要抢救的从库进行覆盖
- 如果是 Docker 从库:
先拷贝文件进去:
docker cp db_rescue.sql auth_slave_db:/tmp/db_rescue.sql再切入终端:docker exec -it auth_slave_db mysql -uroot -p<原来的密码> - 如果是 本地宿主机从库:
直接进控制台:
sudo mysql或mysql -uroot -p
第三步:执行清洗、源导入和重新对齐 在控制台中依次粘贴:
-- 彻底扼杀旧的从库链路
STOP SLAVE;
RESET SLAVE ALL;
-- 强制覆盖本地数据库表结构与数据
SOURCE /路径到/db_rescue.sql;
-- 可选:若担心本地 server_id 与主库冲突,强制指定本机 id
SET GLOBAL server_id = 999;
-- 重新搭建到新的 8002 桥梁
CHANGE MASTER TO MASTER_HOST='<Master_IP>', MASTER_PORT=8002,
MASTER_USER='repl', MASTER_PASSWORD='slave123', GET_MASTER_PUBLIC_KEY=1;
-- 启动并验货
START SLAVE;
SHOW SLAVE STATUS\G-
检查 Agent 状态:
curl -X POST "http://127.0.0.1:8881/AuthService/Check" -H "Content-Type: application/json" -d '{"app_code":"test", "user_id":"1", "perm_key":"test"}' -v
Response Header 应包含
X-Strategy: Local-DB-Slave -
性能压测:
./build/perf_test --server=127.0.0.1:8881 --threads=20 --duration=30
预期性能: QPS > 20k, Latency < 1ms
启动输出示例:
I0212 20:47:43.613006 20766 0 /home/justin/siqi_auth/src/auth_service_impl.cpp:15 AuthServiceImpl] 数据库连接成功
I0212 20:47:43.629907 20766 0 /home/justin/brpc/src/brpc/server.cpp:1232 StartInternal] Server[AuthServiceImpl+AdminServiceImpl] is serving on port=8001.
I0212 20:47:43.630029 20766 0 /home/justin/brpc/src/brpc/server.cpp:1235 StartInternal] Check out http://justin-Inspiron:8001 in web browser.
I0212 20:47:43.630126 20766 0 /home/justin/siqi_auth/src/server_main.cpp:36 main] 司契权限系统启动成功,监听端口: 8001
I0212 20:47:43.630136 20766 0 /home/justin/siqi_auth/src/server_main.cpp:37 main] 其他系统可以通过 brpc://localhost:8001 调用
本项目推荐采用 Node Agent (节点级 Sidecar) + Local DB Replica 模式接入。
- 极致性能:Agent 直接查询本地从库,没有网络 I/O,延迟稳定在 <1ms。
- 高可用:Master 宕机不影响现有权限查询;Agent 宕机只需重启。
- 解耦:业务代码无需连接远程中心,不用处理复杂的 RPC 重试和熔断。
见上文架构图
在每台业务服务器上运行一个 Agent 守护进程。建议使用配置文件启动:
# 推荐:使用配置文件启动
./build/auth_agent --flagfile=conf/agent.conf
# 验证 Agent 是否正常工作
# POST 方法 (通用)
curl -X POST "http://127.0.0.1:8881/AuthService/Check" -H "Content-Type: application/json" -d '{"app_code":"test", "user_id":"1", "perm_key":"test"}'
# GET 方法 (仅agent可用,对server不可用)
curl "http://127.0.0.1:8881/AuthService/Check?app_code=test&user_id=1&perm_key=test" -w "\n"
# 加上 -w "\n" 是为了在输出后换行,因为默认情况下输出没有换行,可能会和后续命令行提示符混在一起。Python:
import requests
# 直接访问本机 Agent
resp = requests.post("http://127.0.0.1:8881/AuthService/Check", json={
"app_code": "qq_bot",
"user_id": "10086",
"perm_key": "member:kick"
})
if resp.json().get("allowed"):
print("允许操作")Curl (测试):
# 模拟一次请求
curl -X POST "http://127.0.0.1:8881/AuthService/Check" \
-H "Content-Type: application/json" \
-d '{"app_code":"qq_bot", "user_id":"123456", "perm_key":"member:kick"}'Agent 接口返回标准的 JSON 对象:
成功允许 (Allowed):
{
"allowed": true
}拒绝访问 (Denied):
// 情况1:用户没有该权限,但系统能给出建议角色
{
"reason": "用户没有该权限",
"current_roles": "member",
"suggest_roles": "admin"
}
// 情况2:用户不存在或未分配任何角色
{
"reason": "用户不存在或未分配任何角色",
"current_roles": "无",
"suggest_roles": "admin"
}
// 情况3:应用不存在
{
"reason": "应用不存在"
}
// 情况4:权限不存在
{
"reason": "权限不存在"
}
// 情况5:参数不完整
{
"reason": "参数不完整 (Agent)"
}注意:根据 Protobuf 3 序列化规范,当
allowed字段值为false(默认值)时,该字段如果不显示,即代表拒绝。
Header 辅助信息:
Agent 会在响应 Header 中添加 X-Strategy 字段:
X-Strategy: Local-DB-Slave- 标识本次请求是由本地从库直接响应的。
本项目提供了两种管理方式:
基于 Vue 3 开发的现代化可视化管理界面,支持应用、权限、角色、用户的全生命周期管理以及审计日志查询。 详见前端项目:siqi_admin_web
使用 admin_tool 进行命令行管理操作。这些操作会直接写 Master 库,然后自动同步给所有 Agent。
# 1. 管理员登录 (获取 Token)
# 默认连接 Master (localhost:8001)
./build/admin_tool --op=login --user=admin --password=admin123
# 2. 创建一个新权限 (立即同步给所有 Slave)
./build/admin_tool --op=create_perm --perm=drive:upload --name="上传文件" --desc="允许上传"
# 3. 授权给用户
./build/admin_tool --op=grant_perm --user=10086 --perm=drive:upload所有写操作都会通过 Binlog 在毫秒级时间内同步到各个业务节点的 Slave 数据库中。
运行测试客户端以验证服务是否正常工作:
./build/test_client客户端会尝试连接本地服务器并进行一次模拟的权限检查。
服务接口定义在 proto/auth.proto 中:
CheckRequest: 包含app_code(应用标识),user_id(用户ID),perm_key(权限标识)。CheckResponse: 返回allowed(布尔值) 表示是否拥有权限。
当接口文件发生变更时,请重新生成对应的 C++ 代码:
protoc --proto_path=proto --experimental_allow_proto3_optional --cpp_out=src proto/auth.proto && mv src/auth.pb.h include/已完成:多语言接入方案(Agent 模式)
| 功能 | 当前状态 | 计划中 |
|---|---|---|
| 配置管理 | ✅ 支持 gflags (命令行/文件) | 动态配置中心 (Etcd) |
| 接入方式 | ✅ Node Agent (HTTP/Local DB) | SDK (直连 Slave) |
| 高可用 | ✅ 读写分离,本地容灾 | Master 故障自动选举 (MHA) |
| 多级缓存 | ✅ MySQL Page Cache | Redis (如果 QPS > 100k) |