更新文档
This commit is contained in:
13
.zed/debug.json
Normal file
13
.zed/debug.json
Normal file
@@ -0,0 +1,13 @@
|
||||
// Project-local debug tasks
|
||||
//
|
||||
// For more documentation on how to configure debug tasks,
|
||||
// see: https://zed.dev/docs/debugger
|
||||
[
|
||||
{
|
||||
"label": "dev",
|
||||
"adapter": "Delve",
|
||||
"request": "launch",
|
||||
"program": "./cmd/web/main.go",
|
||||
"mode": "debug",
|
||||
},
|
||||
]
|
||||
26
README.md
26
README.md
@@ -1,8 +1,11 @@
|
||||
## TODO
|
||||
|
||||
此实现目前并不是完全并发安全的:
|
||||
|
||||
- 目前事务等级没有对 cityhash 表的 offset 字段做防丢失,并发操作可能会出问题
|
||||
|
||||
考虑把命令行接口改为 web 接口
|
||||
|
||||
### 统一节点调度
|
||||
|
||||
节点上下线:
|
||||
@@ -24,7 +27,22 @@ util/ 工具类
|
||||
scripts/ shell 脚本
|
||||
```
|
||||
|
||||
---
|
||||
## 使用方式
|
||||
|
||||
此项目在本地运行,其编译产物放在服务器运行
|
||||
|
||||
1. 在项目根目录下运行 `./deploy.ps1`,或直接复制脚本中的命令,编译出执行程序并上传到服务器
|
||||
2. (可选)可以把 `update.sh` 和 `rollback.sh` 也上传到服务器,方便更新和回滚
|
||||
3. (可选)可以在服务器将编译出的 cli 可执行文件链接到 /bin 下以实现全局执行
|
||||
|
||||
cli 有三个命令:
|
||||
- `cli sync` 是同步城市节点
|
||||
- `cli update` 是更新网关配置
|
||||
- `cli clear` 是清空网关配置
|
||||
|
||||
> 三个命令对应于代码中 actions/ 目录下三个同名文件
|
||||
|
||||
## 逻辑梳理
|
||||
|
||||
```
|
||||
|
||||
@@ -33,12 +51,12 @@ scripts/ shell 脚本
|
||||
遍历配置[网关][配置]
|
||||
如果无需更新直接放入新配置
|
||||
如果需要更新,放入城市更新统计
|
||||
|
||||
|
||||
统计[城市][配置]
|
||||
遍历城市
|
||||
取到新节点
|
||||
遍历需要更新的配置:
|
||||
根据配置放入指定槽位[网关][配置]
|
||||
|
||||
|
||||
新配置[网关][配置]
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
$env:GOOS="linux"; $env:GOARCH="amd64"; $env:CGO_ENABLED=0; go build -o dist/zz main.go
|
||||
$env:GOOS="linux"; $env:GOARCH="amd64"; $env:CGO_ENABLED=0; go build -o dist/zz ./cmd/clt/main.go
|
||||
|
||||
scp ./dist/zz wyk@43.226.58.254:~/zz/cli.new
|
||||
scp ./dist/zz wyk@43.226.58.254:~/zz/cli.new
|
||||
|
||||
107
main.go
107
main.go
@@ -1,107 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"jhman/actions"
|
||||
"jhman/clients"
|
||||
"jhman/model"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
slogjournal "github.com/systemd/slog-journal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// 初始化环境
|
||||
slog.Debug("初始化环境变量")
|
||||
ex, err := os.Executable()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
exPath := filepath.Dir(ex)
|
||||
file := filepath.Join(exPath, ".env")
|
||||
println("加载环境变量文件:", file)
|
||||
err = godotenv.Load(file)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Errorf("初始化变量失败:%w", err).Error())
|
||||
}
|
||||
|
||||
// 初始化日志
|
||||
handler, err := slogjournal.NewHandler(&slogjournal.Options{
|
||||
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||
a.Key = strings.ToUpper(a.Key)
|
||||
a.Key = strings.ReplaceAll(a.Key, "-", "_")
|
||||
return a
|
||||
},
|
||||
})
|
||||
slog.SetDefault(slog.New(handler))
|
||||
|
||||
// 初始化数据库和 Redis
|
||||
model.Init()
|
||||
defer model.Close()
|
||||
|
||||
clients.InitRedis()
|
||||
defer clients.CloseRedis()
|
||||
|
||||
// 执行命令
|
||||
if len(os.Args) < 2 {
|
||||
println("缺少命令参数")
|
||||
return
|
||||
}
|
||||
switch os.Args[1] {
|
||||
|
||||
// 同步城市节点
|
||||
case "sync":
|
||||
err := actions.Sync()
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("同步城市节点数据失败:%s", err.Error()))
|
||||
} else {
|
||||
slog.Info("同步城市节点数据成功")
|
||||
}
|
||||
return
|
||||
|
||||
// 更新网关
|
||||
case "update":
|
||||
var args actions.UpdateArgs
|
||||
if len(os.Args) >= 3 {
|
||||
if slices.Contains(os.Args, "--mock") {
|
||||
args.Mock = true
|
||||
}
|
||||
}
|
||||
|
||||
err := actions.Update(args)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("更新节点失败:%s", err.Error()))
|
||||
} else {
|
||||
slog.Info("更新节点成功")
|
||||
}
|
||||
return
|
||||
|
||||
// 清空网关
|
||||
case "clear":
|
||||
err := actions.Clear()
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("清空节点失败:%s", err.Error()))
|
||||
} else {
|
||||
slog.Info("清空节点成功")
|
||||
}
|
||||
return
|
||||
|
||||
// 新增混拨配置(临时)
|
||||
case "gen-mix":
|
||||
err := actions.GenConfig(model.DB)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("生成混拨配置失败:%s", err.Error()))
|
||||
} else {
|
||||
slog.Info("生成混拨配置成功")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
println("请输入正确的命令参数")
|
||||
}
|
||||
57
web/web.go
Normal file
57
web/web.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
defer cancel()
|
||||
|
||||
// 初始化数据库和 Redis
|
||||
// model.Init()
|
||||
// defer model.Close()
|
||||
|
||||
// clients.InitRedis()
|
||||
// defer clients.CloseRedis()
|
||||
|
||||
// 测试
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("Hello, World!"))
|
||||
})
|
||||
|
||||
// 同步节点
|
||||
http.HandleFunc("/sync", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
})
|
||||
|
||||
// 更新节点
|
||||
http.HandleFunc("/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
})
|
||||
|
||||
// 标记上线
|
||||
http.HandleFunc("/up", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
})
|
||||
|
||||
// 标记下线
|
||||
http.HandleFunc("/down", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
})
|
||||
|
||||
// 启动服务
|
||||
server := http.Server{Addr: ":8080"}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
server.Shutdown(ctx)
|
||||
}()
|
||||
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
slog.Error("启动服务失败", "error", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user