使用 Golang 通道处理 HTTP 请求

我正在尝试构建一个简单的 Golang/Appengine 应用程序,它使用一个通道来处理每个 http 请求。原因是我希望每个请求都执行合理的大内存计算,并且每个请求都以线程安全的方式执行(即并发请求的计算不会混合)很重要。

本质上,我需要一个同步队列,它一次只能处理一个请求,而通道看起来很自然。

但是,我无法让我的简单 hello world 示例工作。它似乎在“go process(w,cr)”行失败;我从服务器收到 200 响应,但没有内容。如果我从这条线上消除“go”,效果很好,但是我猜我没有正确调用通道。

有人指出我哪里出错了吗?

// curl -X POST "http://localhost:8080/add" -d "{\"A\":1, \"B\":2}"


package hello


import (

    "encoding/json"

    "net/http"  

)


type MyStruct struct {

    A, B, Total int64

}


func (s *MyStruct) add() {

    s.Total = s.A + s.B

}


func process(w http.ResponseWriter, cr chan *http.Request) {

    r := <- cr

    var s MyStruct

    json.NewDecoder(r.Body).Decode(&s)

    s.add()

    json.NewEncoder(w).Encode(s)

}


func handler(w http.ResponseWriter, r *http.Request) {  

    cr := make(chan *http.Request, 1)

    cr <- r

    go process(w, cr) // doesn't work; no response :-(

    // process(w, cr) // works, but blank response :-(

}


func init() {

    http.HandleFunc("/add", handler)

}


倚天杖
浏览 231回答 2
2回答

慕容森

如果大型计算不使用共享可变状态,则编写一个普通处理程序。不需要频道,什么都不需要。好的,大型计算确实使用共享可变状态。如果只有一个应用程序实例在运行,则使用 sync.Mutex 来控制对可变状态的访问。与将工作改组到单个 goroutine 以一次处理一个计算相比,这很简单。您是否在 App Engine 上运行?您可能无法保证只有一个应用程序实例在运行。您需要将数据存储或内存缓存用于可变状态。如果计算可以离线完成(在请求完成后),那么您可以使用 App Engine 任务队列一次处理一个计算。旁注:标题提出了问题正文中所述问题的解决方案。最好直接说明问题。我会在上面对此发表评论,但我没有所需的果汁。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go