为了账号安全,请及时绑定邮箱和手机立即绑定

在单个 gofiber 进程中运行后台任务

在单个 gofiber 进程中运行后台任务

Go
蝴蝶刀刀 2023-03-07 13:55:05
我有一个cleanUp删除过时文件的后台任务 ( )。func main() {    // 4 procs/childs max    runtime.GOMAXPROCS(4)    // start a cleanup cron-job    go cleanUp()    app := fiber.New(fiber.Config{        Prefork:   true,    })    app.Post("/", handleFileupload)    log.Fatal(app.Listen(":4000"))}func cleanUp() {    fmt.Println("Cleaning Up..")    for {        // deletes old files here        time.Sleep(60 * time.Second)    }}目前cleanUp在所有 4 个进程上运行并打印Cleaning Up..4 次。但我希望它只在单个进程上运行并打印单个Cleaning Up... 我已经尝试过 waitGroups 和 channels 但未能实现我想要的。我怎样才能只在单个进程上运行它以避免竞争条件?这是输出:Cleaning Up.. ┌───────────────────────────────────────────────────┐  ┌───────────────────────────────────────────────────┐ │                   Fiber v2.38.1                   │  │ Child PIDs ... 79378, 79379, 79380, 79381         │ │               http://127.0.0.1:4000               │  └───────────────────────────────────────────────────┘ │       (bound on host 0.0.0.0 and port 4000)       │  │                                                   │  │ Handlers ............. 5  Processes ........... 4 │  │ Prefork ........ Enabled  PID ............. 79377 │  └───────────────────────────────────────────────────┘ Cleaning Up..Cleaning Up..Cleaning Up..Cleaning Up..
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

Fiber 生成多个进程来处理传入的请求。您需要的是在主进程中启动清理例程并在子进程中跳过它。

纤维提供fiber.IsChild功能:

    // start a cleanup cron-job
    if !fiber.IsChild() { 
           go cleanUp()
    }

我稍微修改了您的示例以在处理程序和清理 goroutine 中打印进程 ID:

func main() {

    // 4 procs/childs max

    runtime.GOMAXPROCS(4)


    // start a cleanup cron-job

    if !fiber.IsChild() {

        go cleanUp()

    }


    app := fiber.New(fiber.Config{

        Prefork: true,

    })

    app.Post("/", handleFileupload)

    log.Fatal(app.Listen(":4000"))

}


func cleanUp() {

    fmt.Println("Cleaning Up.. Pid:", syscall.Getpid())

    for {

        // deletes old files here

        time.Sleep(1 * time.Second)

        fmt.Println("Cleaning Up.. Pid:", syscall.Getpid())

    }

}


func handleFileupload(ctx *fiber.Ctx) error {

    println("Upload: pid ", syscall.Getpid())

    return nil

}

结果:


Cleaning Up.. Pid: 27035


 ┌───────────────────────────────────────────────────┐  ┌───────────────────────────────────────────────────┐

 │                   Fiber v2.39.0                   │  │ Child PIDs ... 27041, 27042, 27044, 27045         │

 │               http://127.0.0.1:4000               │  └───────────────────────────────────────────────────┘

 │       (bound on host 0.0.0.0 and port 4000)       │ 

 │                                                   │ 

 │ Handlers ............. 1  Processes ........... 4 │ 

 │ Prefork ........ Enabled  PID ............. 27035 │ 

 └───────────────────────────────────────────────────┘ 


Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

Cleaning Up.. Pid: 27035

如您所见,清理仅在主进程中运行。


查看完整回答
反对 回复 2023-03-07
  • 1 回答
  • 0 关注
  • 75 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信