golang并发http请求处理 [英] golang concurrent http request handling

查看:234
本文介绍了golang并发http请求处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用golang创建一个简单的http服务器.我有两个问题,一个是理论上的问题,另一个是关于实际程序的问题.

I am creating a simple http server using golang. I have two questions, one is more theoretic and another one about the real program.

  1. 并发请求处理

我创建了一个服务器,并使用s.ListenAndServe()处理请求.据我了解,这些请求是同时服务的.我使用一个简单的处理程序进行检查:

I create a server and use s.ListenAndServe() to handle the requests. As much as I understand the requests served concurrently. I use a simple handler to check it:

func  ServeHTTP(rw http.ResponseWriter, request *http.Request) {  
    fmt.Println("1")  
    time.Sleep(1 * time.Second)       //Phase 2 delete this line
    fmt.Fprintln(rw, "Hello, world.")
    fmt.Println("2")  
}

我看到,如果我发送多个请求,我将看到所有的"1"出现,而仅一秒钟之后,所有的"2"都出现.但是,如果我删除了睡眠行,我会看到该程序永远不会在上一个请求结束之前开始一个请求(输出为1 2 1 2 1 2 ...).所以我不明白它们是否是并发的.如果他们是我,我希望在印刷品中看到一些混乱……

I see that if I send several requests, I will see all the "1" appear and only after a second all the "2" appear. But if I delete the Sleep line, I see that program never start a request before it finishes with the previous one (the output is 1 2 1 2 1 2 ...). So I don't understand, if they are concurrent or not really. If they are I would expect to see some mess in prints...

  1. 现实生活中的问题

在真实的处理程序中,我将请求发送到另一台服务器,然后将答案返回给用户(对请求和答案进行了一些更改,但从思想上讲,这是一种代理).所有这些当然都需要时间,而且从可见的角度来看(通过向处理程序添加一些打印),请求是一个接一个地处理的,它们之间没有并发性(我的打印向我显示了请求已开始,经过所有步骤,结束,然后我才看到一个新的开始.如何使它们真正并发?
将处理程序函数设置为goroutine会产生错误,该请求的主体已经关闭.另外,如果已经并发了,那么添加更多的goroutine只会使情况变得更糟.

In the real handler, I send the request to another server and return the answer to the user (with some changes to request and the answer but in idea it is kind of a proxy). All this of course takes time and from what can see (by adding some prints to the handler), the requests are handled one by one, with no concurrency between them (my prints show me that a request starts, go through all the steps, ends and only then I see a new start....). What can I do to make them really concurrent?
Putting the handler function as goroutine gives an error, that body of the request is already closed. Also if it is already concurrent adding more goroutines will make things only worse.

谢谢!

推荐答案

您的示例很难说明正在发生的事情.

Your example makes it very hard to tell what is happening.

下面的示例将清楚地说明请求是并行运行的.

The below example will clearly illustrate that the requests are run in parallel.

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if len(r.FormValue("case-two")) > 0 {
            fmt.Println("case two")
        } else {
            fmt.Println("case one start")
            time.Sleep(time.Second * 5)
            fmt.Println("case one end")
        }
    })

    if err := http.ListenAndServe(":8000", nil); err != nil {
        log.Fatal(err)
    }
}

http://localhost:8000

向内的 http://localhost:8000?case-two = true 发出另一个请求5秒

Make another request to http://localhost:8000?case-two=true within 5 seconds

控制台输出为

case one start
case two
case one end

这篇关于golang并发http请求处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆