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

使用 Golang 通道处理 HTTP 请求

使用 Golang 通道处理 HTTP 请求

Go
倚天杖 2021-08-16 16:04:27
我正在尝试构建一个简单的 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 任务队列一次处理一个计算。

旁注:标题提出了问题正文中所述问题的解决方案。最好直接说明问题。我会在上面对此发表评论,但我没有所需的果汁。


查看完整回答
反对 回复 2021-08-16
  • 2 回答
  • 0 关注
  • 230 浏览
慕课专栏
更多

添加回答

举报

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