前言
相关Golang 全部分类:
https://blog.csdn.net/freewebsys/category_2120333.html
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/105003261
未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys
1,关于Golang 中goroutine
使用Golang中的goroutine 做一个简单的后台任务,比如下载文件,然后放到 map 存储,使用另外一个接口进行check检查状态。可以支持多个任务,使用jobId区分。
golang 处理速度非常快,但是在和其他服务进行对接的时候,比如下载任务。
需要放到后台执行,而且要检查状态。
需要开发两个 http 接口。一个作为创建任务,一个检查任务状态。
同时使用最简单的sync lock 锁住。防止并发问题。不知道对不对。
2,代码
package main
import (
"fmt"
"log"
"net/http"
"strings"
"sync"
"time"
)
// 先声明map
var statusMap = make(map[string]string)
var memoryAccess sync.Mutex
func create(w http.ResponseWriter, req *http.Request) {
rawQuery := req.URL.RawQuery
if !strings.Contains(rawQuery,"jobId=") {
fmt.Fprintf(w, `{"message" :"jobId is not exist ."}`)
}
jobId := strings.Replace(rawQuery,"jobId=","",-1)
if !strings.Contains(rawQuery,"jobId=") {
fmt.Fprintf(w, `{"message" :"jobId is empty ."}`)
}
// 传入参数。
go func(statusMap map[string]string) {
for i := 0; i <= 10; i++ {
//使用最简单的加个锁。
memoryAccess.Lock()
if i == 10 {
statusMap[jobId] = `{"message" :"finish"}`
//return //如果不解锁看看效果。
} else {
statusMap[jobId] = `{"message" :"downloading"}`
}
memoryAccess.Unlock()
// 暂停 1 秒
time.Sleep(1 * time.Second)
log.Println(statusMap)
}
//新增一个5秒执行一次的计时器
ticker := time.NewTicker(5 * time.Second)
defer func(){
//使用最简单的加个锁。
memoryAccess.Lock()
delete(statusMap,jobId)//不存在没有关系。
memoryAccess.Unlock()
ticker.Stop()
log.Println("clear job id ")
}()
}(statusMap)
fmt.Fprintf(w, `{"message" :"create job"}`)
}
func check(w http.ResponseWriter, req *http.Request) {
rawQuery := req.URL.RawQuery
jobId := strings.Replace(rawQuery,"jobId=","",-1)
if strTmp, ok := statusMap[jobId]; ok {
//存在
fmt.Fprintf(w, strTmp)
}else {
msg := fmt.Sprintf(`{"message" :"%s jobId no found ."}`,jobId)
fmt.Fprintf(w, msg)
}
}
func headers(w http.ResponseWriter, req *http.Request) {
for name, headers := range req.Header {
for _, h := range headers {
fmt.Fprintf(w, "%v: %v\n", name, h)
}
}
}
func main() {
http.HandleFunc("/job/create", create)
http.HandleFunc("/job/check", check)
// 测试 head 头信息。
http.HandleFunc("/headers", headers)
http.ListenAndServe(":8090", nil)
}
效果:
http://localhost:8090/job/create?jobId=2021
http://localhost:8090/job/check?jobId=2021
3,总结
代码是一方面,后续还要考虑下逻辑。在创建任务之后,最后定时 5 秒把 map 的数据删除。防止,程序运行map 越来越大。
同时等待 5 秒钟时间,给 http 请求做好 check 时间。能够访问到 finish 的数据。
要不然数据直接就没有了。后续可以通过 chanel 在优化下。
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/105003261