golang并发http请求处理

Ety*_*Ety 0 concurrency multithreading go httpserver

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

  1. 并发请求处理

我创建一个服务器并使用s.ListenAndServe()来处理请求.尽管我理解同时提供的请求.我使用一个简单的处理程序来检查它:

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")  
}
Run Code Online (Sandbox Code Playgroud)

我看到,如果我发送了几个请求,我会看到所有"1"出现,并且只有在第二个出现"2"之后.但是如果我删除了Sleep行,我会看到该程序在完成前一个请求之前从未启动过请求(输出为1 2 1 2 1 2 ...).所以我不明白,如果他们是并发或不是真的.如果他们是我希望看到一些混乱的印刷品......

  1. 现实生活中的问题

在真正的处理程序中,我将请求发送到另一个服务器并将答案返回给用户(对请求和答案进行了一些更改,但在想法中它是一种代理).所有这些当然需要时间和从可以看到的内容(通过向处理程序添加一些打印),请求被逐个处理,它们之间没有并发(我的打印显示请求开始,执行所有步骤,结束,然后才看到一个新的开始......).我该怎么做才能让它们真正并发?
将处理程序函数设置为goroutine会产生错误,请求的主体已经关闭.此外,如果已经并发添加更多goroutines将使事情变得更糟.

谢谢!

jma*_*ney 5

你的例子很难说出发生了什么.

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

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

http:// localhost:8000发出一个请求

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

控制台输出将是

case one start
case two
case one end
Run Code Online (Sandbox Code Playgroud)