From 2d39a135f26409e13e068845d4069267e8c03dbd Mon Sep 17 00:00:00 2001 From: JustSong Date: Thu, 18 May 2023 12:48:20 +0800 Subject: [PATCH] feat: now slave server can sync options with master server (close #88) --- README.md | 27 +++++++++++++++++++-------- main.go | 7 +++++++ model/option.go | 13 +++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2f980f5a..77496019 100644 --- a/README.md +++ b/README.md @@ -55,19 +55,20 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用 + [x] 自定义渠道:例如使用自行搭建的 OpenAI 代理 2. 支持通过**负载均衡**的方式访问多个渠道。 3. 支持 **stream 模式**,可以通过流式传输实现打字机效果。 -4. 支持**令牌管理**,设置令牌的过期时间和使用次数。 -5. 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。 -6. 支持**通道管理**,批量创建通道。 -7. 支持发布公告,设置充值链接,设置新用户初始额度。 -8. 支持丰富的**自定义**设置, +4. 支持**多机部署**,[详见此处](#多机部署)。 +5. 支持**令牌管理**,设置令牌的过期时间和使用次数。 +6. 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。 +7. 支持**通道管理**,批量创建通道。 +8. 支持发布公告,设置充值链接,设置新用户初始额度。 +9. 支持丰富的**自定义**设置, 1. 支持自定义系统名称,logo 以及页脚。 2. 支持自定义首页和关于页面,可以选择使用 HTML & Markdown 代码进行自定义,或者使用一个单独的网页通过 iframe 嵌入。 -9. 支持通过系统访问令牌访问管理 API。 -10. 支持用户管理,支持**多种用户登录注册方式**: +10. 支持通过系统访问令牌访问管理 API。 +11. 支持用户管理,支持**多种用户登录注册方式**: + 邮箱登录注册以及通过邮箱进行密码重置。 + [GitHub 开放授权](https://github.com/settings/applications/new)。 + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。 -11. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。 +12. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。 ## 部署 ### 基于 Docker 进行部署 @@ -133,6 +134,14 @@ sudo service nginx restart 更加详细的部署教程[参见此处](https://iamazing.cn/page/how-to-deploy-a-website)。 +### 多机部署 +1. 所有服务器 `SESSION_SECRET` 设置一样的值。 +2. 必须设置 `SQL_DSN`,使用 MySQL 数据库而非 SQLite,请执行配置主备数据库同步。 +3. 所有从服务器必须设置 `SYNC_FREQUENCY`,以定期从数据库同步配置。 +4. 从服务器可以选择设置 `FRONTEND_BASE_URL`,以重定向页面请求到主服务器。‘ + +环境变量的具体使用方法详见[此处](#环境变量)。 + ## 配置 系统本身开箱即用。 @@ -159,6 +168,8 @@ sudo service nginx restart + 例子:`SQL_DSN=root:123456@tcp(localhost:3306)/one-api` 4. `FRONTEND_BASE_URL`:设置之后将使用指定的前端地址,而非后端地址。 + 例子:`FRONTEND_BASE_URL=https://openai.justsong.cn` +5. `SYNC_FREQUENCY`:设置之后将定期与数据库同步配置,单位为秒,未设置则不进行同步。 + + 例子:`SYNC_FREQUENCY=60` ### 命令行参数 1. `--port `: 指定服务器监听的端口号,默认为 `3000`。 diff --git a/main.go b/main.go index 0a04ca6c..c8656c7a 100644 --- a/main.go +++ b/main.go @@ -47,6 +47,13 @@ func main() { // Initialize options model.InitOptionMap() + if os.Getenv("SYNC_FREQUENCY") != "" { + frequency, err := strconv.Atoi(os.Getenv("SYNC_FREQUENCY")) + if err != nil { + common.FatalLog(err) + } + go model.SyncOptions(frequency) + } // Initialize HTTP server server := gin.Default() diff --git a/model/option.go b/model/option.go index 0a29910d..5f7ad36c 100644 --- a/model/option.go +++ b/model/option.go @@ -4,6 +4,7 @@ import ( "one-api/common" "strconv" "strings" + "time" ) type Option struct { @@ -59,6 +60,10 @@ func InitOptionMap() { common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() common.OptionMap["TopUpLink"] = common.TopUpLink common.OptionMapRWMutex.Unlock() + loadOptionsFromDatabase() +} + +func loadOptionsFromDatabase() { options, _ := AllOption() for _, option := range options { err := updateOptionMap(option.Key, option.Value) @@ -68,6 +73,14 @@ func InitOptionMap() { } } +func SyncOptions(frequency int) { + for { + time.Sleep(time.Duration(frequency) * time.Second) + common.SysLog("Syncing options from database") + loadOptionsFromDatabase() + } +} + func UpdateOption(key string, value string) error { // Save to database first option := Option{