Skip to content

Commit

Permalink
feat: 添加定时任务进程
Browse files Browse the repository at this point in the history
  • Loading branch information
axetroy committed May 28, 2020
1 parent 22e1c42 commit b55a8d6
Show file tree
Hide file tree
Showing 22 changed files with 1,206 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RESOURCE_HTTP_DOMAIN=http://localhost:9003
######################## 公共配置 ########################
# 通用
MACHINE_ID="0" # 机器 ID, 在集群中,每个ID都应该不同,用于产出不同的 ID
GO_MOD="production" # 处于开发模式(development)/生产模式(production), 默认 development
GO_MOD="development" # 处于开发模式(development)/生产模式(production), 默认 development
SIGNATURE_KEY="signature key" # 数据签名的密钥, 该配置不可泄漏
UPLOAD_DIR=upload # 图片上传储存的目录
UPLOAD_FILE_MAX_SIZE=10485760 # 文件上传的最大大小,这里是 1024 * 1024 * 10 = 10M
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
timeout-minutes: 10
strategy:
matrix:
target: ['admin', 'user', 'resource', 'message_queue']
target: ['admin', 'user', 'resource', 'message_queue', 'scheduled']
kind: ['build']
go: ['^1.14.2']
os: [ubuntu-latest, macOS-latest, windows-latest]
Expand Down Expand Up @@ -157,4 +157,7 @@ jobs:
./bin/message_queue_server_darwin_amd64.tar.gz
./bin/message_queue_server_linux_amd64.tar.gz
./bin/message_queue_server_windows_amd64.tar.gz
./bin/scheduled_server_darwin_amd64.tar.gz
./bin/scheduled_queue_server_linux_amd64.tar.gz
./bin/scheduled_queue_server_windows_amd64.tar.gz
draft: false
6 changes: 6 additions & 0 deletions .s4
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ UPLOAD ./bin/admin_server_linux_amd64.tar.gz ./admin-api/
UPLOAD ./bin/user_server_linux_amd64.tar.gz ./user-api/
UPLOAD ./bin/resource_server_linux_amd64.tar.gz ./resource-api/
UPLOAD ./bin/message_queue_server_linux_amd64.tar.gz ./message-queue/
UPLOAD ./bin/scheduled_server_linux_amd64.tar.gz ./message-queue/

CD /home/zingy/go-server/admin-api
RUN tar -xzf admin_server_linux_amd64.tar.gz
Expand All @@ -27,4 +28,9 @@ RUN tar -xzf message_queue_server_linux_amd64.tar.gz
TRY docker-compose down
TRY docker-compose up -d

CD /home/zingy/go-server/scheduled
RUN tar -xzf scheduled_server_linux_amd64.tar.gz
TRY docker-compose down
TRY docker-compose up -d

RUN echo "------ Deploy Done! ------"
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ build:
bash ./scripts/build.sh user
bash ./scripts/build.sh resource
bash ./scripts/build.sh message_queue
bash ./scripts/build.sh scheduled
echo "Build Success!"

clean:
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

然后获取[构建好的可执行文件](https://github.com/axetroy/go-server/releases), 找到对应的平台,并且下载。或者自行构建。

你需要使用 4 个文件
你需要使用 5 个文件

1. message_queue_server

Expand All @@ -77,6 +77,10 @@

> 监听管理员相关的接口服务
5。scheduled

> 定时任务
然后复制 [.env](.env) 到可执行文件目录下,运行可执行文件即可。例如 `./user_server start`

快速下载可执行文件
Expand Down Expand Up @@ -111,6 +115,7 @@ $ go run ./cmd/message_queue/main.go # 启动消息队列
$ go run ./cmd/user/main.go # 运行用户端的接口服务
$ go run ./cmd/admin/main.go # 运行管理员端的接口服务
$ go run ./cmd/resource/main.go # 运行资源类的接口服务
$ go run ./cmd/scheduled/main.go # 运行定时任务
```

可以通过 [.env](.env) 文件进行配置
Expand Down
125 changes: 125 additions & 0 deletions cmd/scheduled/job/split_login_log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package job

import (
"fmt"
"github.com/axetroy/go-server/internal/model"
"github.com/axetroy/go-server/internal/service/database"
"github.com/jinzhu/gorm"
"time"
)

func generateNewLoginTableName(date time.Time) string {
year := fmt.Sprintf("%d", date.Year())
month := fmt.Sprintf("%d", date.Month())
if len(month) == 1 {
month = "0" + month
}

loginLog := model.LoginLog{}

tableName := loginLog.TableName() + "_" + year + month

return tableName
}

// 迁移数据
func moveLoginLog(startAt time.Time, endAt time.Time) (bool, error) {
var (
tx = database.Db.Begin()
err error
eol = true // 这个时间段的数据是否已经迁移完,当 eol == true 时,则迁移下一个时间段
)

defer func() {
if err != nil {
_ = tx.Rollback().Error
} else {
_ = tx.Commit().Error
}
}()

newTableName := generateNewLoginTableName(startAt)

if err = ensureLoginLogTableExist(newTableName, tx); err != nil {
return true, err
}

logs := make([]model.LoginLog, 0)

limit := 100 // 一次迁移一百条数据

// 查找在这个时间段的数据,移动到新表中
// 最早的数据排到前面
if err = tx.Model(model.LoginLog{}).Where("created_at >= ?", startAt).Where("created_at <= ?", endAt).Limit(limit).Order("created_at ASC").Find(&logs).Error; err != nil {
return true, err
}

for _, loginLog := range logs {
dataID := loginLog.Id
if err = tx.Table(newTableName).Create(&loginLog).Error; err != nil {
return true, err
} else {
// 更新表信息 - 还原 ID/创建时间/更新时间 信息
if err = tx.Table(newTableName).Where("id = ?", loginLog.Id).UpdateColumn("id", dataID).UpdateColumn("created_at", loginLog.CreatedAt).UpdateColumn("updated_at", loginLog.UpdatedAt).Error; err != nil {
return true, err
}

// 删除旧数据
if err = tx.Unscoped().Table(loginLog.TableName()).Delete(model.LoginLog{Id: dataID}).Error; err != nil {
return true, err
}
}
}

// 如果获取的数据已经不够,那么我们就认为它已经是最后一页了
eol = len(logs) < limit

return eol, nil
}

func ensureLoginLogTableExist(tableName string, db *gorm.DB) error {
// 如果表不存在,那么创建表
if db.HasTable(tableName) == false {
if err := db.Table(tableName).CreateTable(model.LoginLog{}).Error; err != nil {
return err
}
}

return nil
}

// 定时切割用户登录记录
// 因为这个表的内容是在是太大了
func SplitLoginLog() {
var err error
now := time.Now()

oldestLoginLog := model.LoginLog{}

if err = database.Db.Model(oldestLoginLog).Order("created_at ASC").First(&oldestLoginLog).Error; err != nil {
return
}

startAt := time.Date(oldestLoginLog.CreatedAt.Year(), oldestLoginLog.CreatedAt.Month(), 1, 0, 0, 0, 0, now.Location())
endAt := startAt.AddDate(0, 1, 0)

// 如果最旧的数据是在本月或者上个月产生的,那么跳过任务
if endAt.After(now.AddDate(0, -1, 0)) {
return
}

for {
if eol, err := moveLoginLog(startAt, endAt); err != nil {
return
} else if eol == true {
// 开始时间往后推一个月,继续遍历
startAt = startAt.AddDate(0, 1, 0)
endAt = startAt.AddDate(0, 1, 0)

// 如果最旧的数据是在本月或者上个月产生的,那么跳过任务
if endAt.After(now.AddDate(0, -1, 0)) {
break
}
}
}
}
57 changes: 57 additions & 0 deletions cmd/scheduled/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
package main

import (
"github.com/axetroy/go-server/cmd/scheduled/job"
"github.com/axetroy/go-server/internal/library/daemon"
"github.com/jasonlvhit/gocron"
"github.com/urfave/cli/v2"
"log"
"os"
)

func runJobs() error {
// 每天凌晨 3 点检查 login_log 表,并且进行切割数据
// 选择半夜主要是因为怕影响性能,在用户最少的情况下执行
if err := gocron.Every(1).Day().At("03:00:01").Do(job.SplitLoginLog); err != nil {
return err
}

// 启动定时任务
<-gocron.Start()

return nil
}

func main() {
app := cli.NewApp()
app.Usage = "定时任务"

app.Commands = []*cli.Command{
{
Name: "start",
Usage: "启动定时任务",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "daemon, d",
Usage: "是否以守护进程运行",
},
},
Action: func(c *cli.Context) error {
// 判断当其是否是子进程,当父进程return之后,子进程会被系统1号进程接管
return daemon.Start(runJobs, c.Bool("daemon"))
},
},
{
Name: "stop",
Usage: "停止定时任务",
Action: func(c *cli.Context) error {
return daemon.Stop()
},
},
}

if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}
6 changes: 5 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

### 2. 进程

程序又分有 4 个独立的进程
程序又分有 5 个独立的进程

1. 消息队列进程

Expand All @@ -31,3 +31,7 @@
4. 用户接口进程

该进程提供了用户相关的接口

5. 定时任务进程

定时任务进程定义了一些定时任务,例如自定切割表,把冷数据移动到新表中
19 changes: 16 additions & 3 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@
| FACEBOOK_KEY | `string` | oAuth 认证的 `Facebook Key` | `""` |
| TWITTER_KEY | `string` | oAuth 认证的 `Twitter Key` | `""` |
| TWITTER_SECRET | `string` | oAuth 认证的 `Twitter Secret` | `""` |
| 消息队列配置 | - | - | - |
| MSG_QUEUE_SERVER | `string` | 消息队列服务器地址 | `localhost` |
| MSG_QUEUE_PORT | `int` | 消息队列服务器端口 | `4150` |

### 管理员端配置

Expand Down Expand Up @@ -125,3 +122,19 @@
| 推送服务器 | - | - | - |
| ONE_SIGNAL_APP_ID | `string` | 推送服务器 one signal 的 APP ID | `` |
| ONE_SIGNAL_REST_API_KEY | `string` | 推送服务器 one signal 的 REST API KEY | `` |

### 定时任务配置

> 定义了一些列的定时任务
| 环境变量 | 类型 | 说明 | 默认值 |
| ----------- | -------- | ---------------------------------------------- | ------------ |
| 通用配置 | - | - | - |
| GO_MOD | `string` | 处于开发模式(development)/生产模式(production) | `production` |
| 数据库配置 | - | - | - |
| DB_HOST | `string` | 连接的数据库地址 | `localhost` |
| DB_PORT | `int` | 连接的数据库端口 | `65432` |
| DB_DRIVER | `string` | 数据库驱动器, 即数据库类型 | `postgres` |
| DB_NAME | `string` | 数据库名称 | `gotest` |
| DB_USERNAME | `string` | 连接数据库的用户名 | `gotest` |
| DB_PASSWORD | `string` | 连接数据库的密码 | `gotest` |
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/gorilla/mux v1.7.4
github.com/holdno/snowFlakeByGo v0.0.0-20180510033652-d23f8a8cadd7
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/jasonlvhit/gocron v0.0.0-20200423141508-ab84337f7963
github.com/jinzhu/gorm v1.9.12
github.com/joho/godotenv v1.3.0
github.com/jordan-wright/email v0.0.0-20200521030443-c069f37d901d
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJY
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o=
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
Expand Down Expand Up @@ -119,6 +120,8 @@ github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0Gqw
github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+yaDA=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4=
github.com/jasonlvhit/gocron v0.0.0-20200423141508-ab84337f7963 h1:IFvW+Yz/6m9m+TU/IiZjXiSP0V8GQHD6yoy4J2Os/VA=
github.com/jasonlvhit/gocron v0.0.0-20200423141508-ab84337f7963/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4=
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
Expand Down Expand Up @@ -297,6 +300,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down
1 change: 1 addition & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ targets=(
user
resource
message_queue
scheduled
)

get_arch() {
Expand Down
2 changes: 2 additions & 0 deletions internal/library/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ func Start(action Action, shouldRunInDaemon bool) error {
return err
}

// TODO: 监听信号,优雅地推出

return action()
}
}
Expand Down
26 changes: 26 additions & 0 deletions vendor/github.com/jasonlvhit/gocron/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b55a8d6

Please sign in to comment.