我正在尝试构建一个简单的 Golang/Appengine 应用程序,它使用一个通道来处理每个 http 请求。原因是我希望每个请求都执行合理的大内存计算,并且每个请求都以线程安全的方式执行(即并发请求的计算不会混合)很重要。本质上,我需要一个同步队列,它一次只能处理一个请求,而通道看起来很自然。但是,我无法让我的简单 hello world 示例工作。它似乎在“go process(w,cr)”行失败;我从服务器收到 200 响应,但没有内容。如果我从这条线上消除“go”,效果很好,但是我猜我没有正确调用通道。有人指出我哪里出错了吗?// curl -X POST "http://localhost:8080/add" -d "{\"A\":1, \"B\":2}"package helloimport ( "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)}
2 回答
慕容森
TA贡献1853条经验 获得超18个赞
如果大型计算不使用共享可变状态,则编写一个普通处理程序。不需要频道,什么都不需要。
好的,大型计算确实使用共享可变状态。如果只有一个应用程序实例在运行,则使用 sync.Mutex 来控制对可变状态的访问。与将工作改组到单个 goroutine 以一次处理一个计算相比,这很简单。
您是否在 App Engine 上运行?您可能无法保证只有一个应用程序实例在运行。您需要将数据存储或内存缓存用于可变状态。如果计算可以离线完成(在请求完成后),那么您可以使用 App Engine 任务队列一次处理一个计算。
旁注:标题提出了问题正文中所述问题的解决方案。最好直接说明问题。我会在上面对此发表评论,但我没有所需的果汁。
- 2 回答
- 0 关注
- 230 浏览
添加回答
举报
0/150
提交
取消