V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
chengxuyuan0917
V2EX  ›  问与答

关于 golang 一分钟处理百万请求的疑问

  •  
  •   chengxuyuan0917 · 2018-09-29 19:18:05 +08:00 · 1192 次点击
    这是一个创建于 2273 天前的主题,其中的信息可能已经有所发展或是发生改变。

    每分钟百万级请求

    比如这段是这样子的回调,http.HandleFunc("/", payloadHandler), 只是把一个 http 请求塞进 chan chan Job 里,可能并没有等到处理就返回给请求 200 了。

    func payloadHandler(w http.ResponseWriter, r *http.Request) {
    
        if r.Method != "POST" {
            w.WriteHeader( http.StatusMethodNotAllowed)
            return
        }
    
        // Read the body into a string for json decoding
        var content = &PayloadCollection{}
        err := json.NewDecoder(io.LimitReader(r.Body, MaxLength)).Decode(&content)
        if err != nil {
            w.Header().Set("Content-Type", "application/json; charset=UTF-8")
            w.WriteHeader( http.StatusBadRequest)
            return
        }
    
        // Go through each payload and queue items individually to be posted to S3
        for _, payload := range content.Payloads {
    
            // let's create a job with the payload
            work := Job{Payload: payload}
    
            // Push the work onto the queue.
            JobQueue <- work
        }
    
        w.WriteHeader( http.StatusOK)
    }
    

    到了从双层队通道取 Job 时候,处理的结果并不会通知给 http 请求方,

    // Start method starts the run loop for the worker, listening for a quit channel in
    // case we need to stop it
    func (w Worker) Start() {
        go func() {
            for {
                // register the current worker into the worker queue.
                w.WorkerPool <- w.JobChannel
    
                select {
                case job := <-w.JobChannel:
                    // we have received a work request.
                    if err := job.Payload.UploadToS3(); err != nil {
                        log.Errorf("Error uploading to S3: %s", err.Error())
                    }
    
                case <-w.quit:
                    // we have received a signal to stop
                    return
                }
            }
        }()
    }
    

    我是想实现能实时支持的方式,还把w http.ResponseWriter也套进了 Job 里面,想等真正有结果在w.Write。 结果发现接受的不到 Response.Body。应该是返回比处理要早。 所以不知道是不是这种模式 ,只能实现异步。

    2 条回复    2018-09-30 11:31:34 +08:00
    gfreezy
        1
    gfreezy  
       2018-09-29 19:25:37 +08:00
    原文跟 go 没啥关系啊。收到请求入队列,然后开一大波 worker 处理。只要队列扛得住,不停加 worker 就可以了。跟 go 没啥关系,而且都是 io bound 的,ruby 完全也可以达到这个效果
    yph007595
        2
    yph007595  
       2018-09-30 11:31:34 +08:00
    @gfreezy 你没明白楼主的意思,楼主意思是在 worker 里面处理完消息后,还要把消息结果通过 http 返回给调用方。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5754 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 06:27 · PVG 14:27 · LAX 22:27 · JFK 01:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.