Golang Go语言中如何通过一个http请求触发一个长时间运行的函数?

Golang Go语言中如何通过一个http请求触发一个长时间运行的函数?

这里的 doSomething 可能会因为 http 超时或者各种原因中断,如何让 longTimeTask() 持续运行下去呢?

func doSomething(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, "start!\n")
    longTimeTask()
}

func longTimeTask() {
    ...
}

func main() {
    http.HandleFunc("/do", doSomething)
    err := http.ListenAndServe(":12345", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

更多关于Golang Go语言中如何通过一个http请求触发一个长时间运行的函数?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

13 回复

新开一个 goroutine ?

更多关于Golang Go语言中如何通过一个http请求触发一个长时间运行的函数?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你是说这样?
func doSomething(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, “start!\n”)
go longTimeTask()
}

当 doSomething 退出,函数里面的 goroutine 也退出了。

func longTimeTask() {
go func() {
tick := time.Tick(time.Second)
for range tick {
log.Println(“fucker”)
}
}()
}

结果:
curl 127.0.0.1:12345/do [11:37:17]
start!

2019/08/30 11:37:21 fucker
2019/08/30 11:37:22 fucker
2019/08/30 11:37:23 fucker
2019/08/30 11:37:24 fucker
2019/08/30 11:37:25 fucker
2019/08/30 11:37:26 fucker
2019/08/30 11:37:27 fucker
2019/08/30 11:37:28 fucker
2019/08/30 11:37:29 fucker
2019/08/30 11:37:30 fucker
2019/08/30 11:37:31 fucker
2019/08/30 11:37:32 fucker
……

你最好试一下再说

建议用 channel 触发 goroutine, 这样子可以通过调节 sigChan 的 size 来控制 goroutine 的数量

func doSomething(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, “start!\n”)
sigChan <- 1
}

func goroutine() {
for {
select {
case _ = <- sigChan:
go longTimeTask()
}
}
}

func longTimeTask() {

}



真的可以!看来自己对 goroutine 理解不够。

意思是函数退出了
协程依然在运行
看来我也对 GO 协程理解不到位

三楼的回答有声音怎么回事

这个也解开了我以前的一个提问
当时用时时间定时器
很奇怪,函数推出
然后还显示了协程里面的内容
现在知道了,原来是时间定时器那个协程还能在运行的原因

不会的 建议看下 go 的调度

你最好试试再说

我之前写了一个求素数的,当值特别大时,运行时间要好久,10 几秒把,后来我用 grpc 调用,无论这个值多大,运行一二十秒,结果也会顺利得到,后来我用 http 调用,刚开始我以为我是用微服务 micro 做得,api 负责处理 http 请求,然后再调用 grpc 调用方法求素数,这时候如果超时 5 秒,就会报错,但是 grpc 调用的代码依旧在运行,后来我就搜索英文和中文,因为我不知道是 micro 框架限定超时时间还是注册服务 consul,但是没收到,后来我无意中在那里看到有人回复说,是 http 里面 ctx 会默认 timeout 时间为 5 秒,所以应该是这个问题,因为就算开启一个协程,http 在 5 秒内没有得到结果,也会返回

在Golang中,通过HTTP请求触发长时间运行的函数通常涉及并发处理,以确保HTTP服务器不会阻塞并快速响应客户端。以下是一个基本方法来实现这一功能:

  1. 使用Goroutine:在HTTP处理函数中启动一个新的Goroutine来执行长时间运行的任务。这样可以保证HTTP请求能够立即返回响应,而长时间运行的任务在后台执行。

  2. 同步机制:如果需要在任务完成后进行某些操作(例如更新状态或通知客户端),可以使用通道(Channel)或其他同步机制来协调。

示例代码:

package main

import (
    "fmt"
    "net/http"
    "time"
)

func longRunningTask() {
    fmt.Println("Task started")
    time.Sleep(30 * time.Second) // 模拟长时间运行的任务
    fmt.Println("Task completed")
}

func handler(w http.ResponseWriter, r *http.Request) {
    go longRunningTask() // 启动Goroutine执行长时间任务
    fmt.Fprintln(w, "Task started in the background")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

在这个例子中,当访问http://localhost:8080时,handler函数会启动一个新的Goroutine来执行longRunningTask,同时立即返回响应给客户端。longRunningTask会在后台运行,不会阻塞HTTP服务器处理其他请求。

注意,对于需要长时间运行且可能涉及大量资源或复杂逻辑的任务,应考虑使用工作池(Worker Pool)或任务队列(Task Queue)来管理任务执行,以确保系统的稳定性和可扩展性。

回到顶部