apiserver
简介
GO 编写的 WEB 框架,支持用户管理、角色管理、接口权限管理、OAuth2 登录等功能,此框架基于流行的Gin框架构建。
前端地址:https://github.com/yiran15/ui.git
预览地址:清泉流响
账号: readonly@qqlx.net
密码: 12345678
技术栈
- gin ---> web 框架
- zap ---> 日志
- gorm ---> mysql 数据持久化
- go-redis ---> 缓存
- wire ---> 依赖注入
- casbin ---> 访问控制
- otel ---> 可观测性
- oauth2 ---> OAuth2 登录
API 文档

功能
用户管理: 增删改查

角色管理: 增删改查

接口权限管理: 增删改查

OAuth2 登录
支持 OAuth2 登录,目前支持飞书、keycloak。

可观测性
基于otel的可观测性,包括trace、metrics。
使用 阿里云 otel 构建镜像,自动注入trace、metrics。
配置 trace & metrics 导出
- OTEL_EXPORTER_OTLP_ENDPOINT: otlp 服务地址
- OTEL_EXPORTER_OTLP_PROTOCOL: otlp 服务协议
- OTEL_SERVICE_NAME: 服务名称
- OTEL_METRICS_EXPORTER: metrics 导出方式为
prometheus格式
- OTEL_EXPORTER_PROMETHEUS_PORT: metrics 导出端口
- OTEL_EXPORTER_PROMETHEUS_HOST: metrics 导出主机
cat deploy/docker-compose.yaml
services:
apiserver:
image: api-server
restart: always
container_name: apiserver
environment:
- CONFIG_PATH=/app/config.yaml
- OTEL_EXPORTER_OTLP_ENDPOINT=http://10.10.10.10:30001
- OTEL_EXPORTER_OTLP_PROTOCOL=grpc
- OTEL_SERVICE_NAME=api-server
# - OTEL_METRICS_EXPORTER=prometheus
# - OTEL_EXPORTER_PROMETHEUS_PORT=9464
# - OTEL_EXPORTER_PROMETHEUS_HOST=0.0.0.0
Trace

Metrics

快速开始
配置
所有配置项均支持环境变量配置,环境变量前缀从环境变量SERVICE_NAME获取。
- 例如
SERVICE_NAME=qqlx,则环境变量前缀为QQLX
- 例如
SERVICE_NAME=api-server,则环境变量前缀为API_SERVER
- 如果未设置
SERVICE_NAME,则环境变量前缀默认为API_SERVER。
配置中时间单位为“ns”、“us”(或“µs”)、“ms”、“s”、“m”、“h”。
指定配置文件路径:
- 命令行参数:
-c或--config-path。
- 环境变量:
${SERVICE_NAME}_CONFIG_PATH。
server:
bind: 0.0.0.0:8080
timeZone: "Asia/Shanghai"
log:
level: debug
mysql:
# 开启后会打印 sql 语句
debug: true
username: xxx
password: xxx
host: xxx
port: 3306
database: xxx
maxIdleConns: 10
maxOpenConns: 20
maxLifetime: 30m
redis:
# single sentinel
mode: single
host: 127.0.0.1:6379
password: 123456
# 过期时间 3s 3m 3h
expireTime: 300s
# redis key 前缀
keyPrefix: tutu
db: 0
poolSize: 20
minIdleConns: 10
connMaxLifetime: 30m
jwt:
issuer: tutu
# jwt secret
secret: 123456
# token 过期时间
expireTime: 9999h
oauth2:
# 是否启用 oauth2
enable: true
providers:
feishu:
clientId: xxx
clientSecret: xxx
# scopes: []
authUrl: https://accounts.feishu.cn/open-apis/authen/v1/authorize
tokenUrl: https://open.feishu.cn/open-apis/authen/v2/oauth/token
userInfoUrl: https://open.feishu.cn/open-apis/authen/v1/user_info
# 回调地址, host 为前端地址
redirectUrl: http://10.0.0.10:5173/oauth/login
keycloak:
clientId: xxx
clientSecret: xxx
scopes:
- openid
- email
- profile
- roles
authUrl: https://keycloak.qqlx.net/realms/qqlx/protocol/openid-connect/auth
tokenUrl: https://keycloak.qqlx.net/realms/qqlx/protocol/openid-connect/token
userInfoUrl: https://keycloak.qqlx.net/realms/qqlx/protocol/openid-connect/userinfo
# 回调地址, host 为前端地址
redirectUrl: http://10.0.0.10:5173/oauth/login
部署
# 构建前端资源
git clone -b main https://github.com/yiran15/ui.git
cd ui
# 静态资源会拷贝到 /data/html/apiserver 目录下
make deploy
git clone -b main https://github.com/yiran15/api-server.git
cd api-server/deploy
# 初始化配置文件, 需要修改配置文件中的数据库信息
mv config-example.yaml config.yaml
# 初始化数据库
mysql -h 127.0.0.1 -P 3306 -u root -p my_database < schema.sql
# 启动容器
make start
教程
定位错误日志
接口发送错误时通过 requestId 快速定位日志

root@qqlx:~# docker logs nginx-otel | grep '8611cf16-493b-4e0f-8367-fb9b8647c5a1'
{"@timestamp":"2025-09-27T09:41:23+00:00", "request_id":"8611cf16-493b-4e0f-8367-fb9b8647c5a1","trace_id":"7dee96370cfa5fb64f2c81438e1c98d2","client_ip":"221.219.176.189","method":"GET","uri":"/api/v1/user","args":"page=1&pageSize=10&status=0","status":"403","bytes_sent":90,"request_time":0.001,"upstream_time":"0.001","upstream_host":"172.18.0.2:8080","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"}
root@qqlx:~# docker logs apiserver | grep '8611cf16-493b-4e0f-8367-fb9b8647c5a1'
{"level":"ERROR","time":"2025-09-27T17:41:23+08:00","caller":"middleware/authz.go:32","msg":"user has no roles","request-id":"8611cf16-493b-4e0f-8367-fb9b8647c5a1","userName":"胡云飞","trace_id":"7dee96370cfa5fb64f2c81438e1c98d2","span_id":"fa5abf963a87d297"}
{"level":"ERROR","time":"2025-09-27T17:41:23+08:00","caller":"zap@v1.1.5/zap.go:121","msg":"access forbidden","status":403,"method":"GET","path":"/api/v1/user","query":"page=1&pageSize=10&status=0","ip":"221.219.176.189","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36","latency":0.000438359,"request-id":"8611cf16-493b-4e0f-8367-fb9b8647c5a1","trace_id":"7dee96370cfa5fb64f2c81438e1c98d2","span_id":"fa5abf963a87d297"}
链路信息
