如何在Go编程语言中处理并行的HTTP请求?

huangapple go评论87阅读模式
英文:

How to process parallel HTTP request in go programming language?

问题

我正在使用go的HTTP包进行编程。我想要像在Java中一样并行处理请求。但是我做不到。

我创建了一个简单的Web服务器,在中间加了一个延时,然后发现go一次只能处理一个请求,所以如果我在浏览器上刷新,第一个请求的处理必须完成,才能开始处理第二个请求。以下是代码:

func main(){
	
	//处理http命令
	fmt.Printf("启动http服务器...")
	http.Handle("/", http.HandlerFunc(sayHello))
	err := http.ListenAndServe("0.0.0.0:8080", nil)
	if err != nil {
		fmt.Printf("ListenAndServe错误",err)
	}
}

func sayHello(c http.ResponseWriter, req *http.Request) {
	fmt.Printf("新请求\n")
	processRequest(c, req)
}

func processRequest(w http.ResponseWriter, req *http.Request){
	time.Sleep(time.Second*3)
	w.Write([]byte("Go说你好(通过http)"))
	fmt.Println("结束")
}

因为我想要并行处理两个请求,所以我在"sayHello"函数的"processRequest(c, req)"之前添加了"go"命令,以便在不同的goroutine中处理每个请求。但是...它不起作用...我不知道为什么。我知道两个请求都被处理了,因为我在控制台上看到了打印的行,但是浏览器一直等待信息...并且没有显示我的响应。

所以...我的问题是,

每个请求是否创建一个新的http.ResponseWriter?还是使用同一个?
你知道如何告诉Web服务器使用不同的线程处理每个请求吗?

任何帮助都受欢迎...

Fersca

英文:

I was playing with the go HTTP package. I wanted to process request in parallel as I do in java. But I couldn't.

I created a simple web server, put a sleep in the middle and realized that go process one request per time, so if I did a refresh on my browser, the process of the first request has to finish until the second request start processing, here is the code:

func main(){
	
	//Process the http commands
	fmt.Printf("Starting http Server ... ")
	http.Handle("/", http.HandlerFunc(sayHello))
	err := http.ListenAndServe("0.0.0.0:8080", nil)
	if err != nil {
		fmt.Printf("ListenAndServe Error",err)
	}
}

func sayHello(c http.ResponseWriter, req *http.Request) {
	fmt.Printf("New Request\n")
	processRequest(c, req)
}

func processRequest(w http.ResponseWriter, req *http.Request){
	time.Sleep(time.Second*3)
	w.Write([]byte("Go Say’s Hello(Via http)"))
	fmt.Println("End")
}

As I wanted to process both request in parallel I added the "go" command before "processRequest(c, req)" in "sayHello" function in order to process each request in a different gorutine. But... it doesn't work.... I don't know why. I know that both request are processed because I see the printed line at the console but the browser keep waiting for information..... and don't show my response.

So... my questions,

Does each request create a new http.ResponseWriter? or it's use the same?
Do you know how to indicate the web server to process each request with different threads?

Any help is welcomed....

Fersca

答案1

得分: 22

所有连接都会自动并发处理。每个TCP连接(不是请求)都会有自己的goroutine。

在一个使用HTTP流水线和重用连接的浏览器的世界中,这种方式可能并不总是有效。很可能你的浏览器正在重用一个连接,直到当前由goroutine处理的请求完成之前,它会一直处于停滞状态。

英文:

All connections are automatically handled concurrently. Each TCP connection (not request) gets its own goroutine.

In a world with http pipelining and browsers that reuse connections, this may not always work out well. Most likely your browser is reusing a connection which stalls it until the current request being processed by the goroutine finishes.

答案2

得分: 0

为了让运行时支持利用多个操作系统线程,您可以通过以下方式设置数量:

 runtime.GOMAXPROCS(n)

或者设置GOMAXPROCS环境变量。

要获取可用核心数,可以使用

 runtime.NumCPU()

因此,您经常会使用

 runtime.GOMAXPROCS(runtime.NumCPU())
英文:

To allow the run-time support to utilize more than one OS thread you might want to set that number via:

 runtime.GOMAXPROCS(n)

or set the GOMAXPROCS environment variable.

To get the number of available cores, use

 runtime.NumCPU()

So you often end up with

 runtime.GOMAXPROCS(runtime.NumCPU())

答案3

得分: 0

我认为你的浏览器正在等待,因为你没有向它发送回应。你的浏览器发送了一个请求给sayHello,而sayHello也发送了一个请求给processRequest。从你的代码来看,processRequest向sayHello发送了一个回应,但是sayHello没有向浏览器发送回应。

你可以使用http.Get或http.Post来调用processRequest。

英文:

I think your browser is waiting because you did not sent a response back to it
Your browser made a request to sayHello and sayHello also made a request to processRequest,
from your code processRequest sent back a response to sayHello but sayHello did not send back a response to the browser.

you can use http.Get or http.Post to call processRequest

huangapple
  • 本文由 发表于 2012年6月26日 05:53:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/11197906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定