英文:
What is the theoretical max number of concurrent (simultaneous) HTTP connections in a Go server?
问题
非常简单的Go实现的服务器能够处理的并发HTTP连接数量的上限是多少?
英文:
What is the upper limit on the number of concurrent HTTP connections that a very simple server implemented in Go can handle?
答案1
得分: 17
并发HTTP连接的数量受可用内存和操作系统限制的限制。
在Linux中,软操作系统限制(如最大打开文件数)可以通过使用<code>ulimit</code>来打印和更改。
就内存而言,在运行在32位Linux上的最小Go HTTP服务器中,每个HTTP连接消耗21 KiB的内存(此服务器的源代码可使用Go版本2013-03-23进行编译,如下所示)。在64位Linux上,内存消耗可能会更高。
在具有1GB可用内存的32位系统上,21 KiB意味着可以有大约50,000个同时连接。这不包括Linux内核消耗的内存。
package main
import (
"flag"
"fmt"
"net/http"
"os"
"runtime"
"sync"
)
var isClient = flag.Bool("client", false, "Whether to start the HTTP server or the HTTP client")
var N = flag.Int("n", 1000, "Number of concurrent HTTP requests")
var wait = make(chan byte)
var counter = 0
var reachedN = make(chan byte)
func handler(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "some text")
counter++
if counter == *N {
reachedN <- 0
}
<-wait // Block this goroutine
}
func main() {
flag.Parse()
if *N <= 0 {
fmt.Fprintf(os.Stderr, "invalid number of goroutines")
os.Exit(1)
}
if *isClient {
// Initiate N http connections
var wg sync.WaitGroup
for i := 0; i < *N; i++ {
wg.Add(1)
go func(ii int) {
_, err := http.Get("http://127.0.0.1:12345")
if err != nil {
fmt.Fprintf(os.Stderr, "client %d: %s\n", ii, err)
os.Exit(1)
}
wg.Done()
}(i)
}
wg.Wait()
} else {
runtime.GOMAXPROCS(1) // No concurrency
// Read MemStats
var m0 runtime.MemStats
runtime.ReadMemStats(&m0)
go func() {
<-reachedN // Wait until there are *N concurrent requests
// Read MemStats
var m1 runtime.MemStats
runtime.ReadMemStats(&m1)
fmt.Printf("Number of HTTP connections: %d\n", *N)
fmt.Printf("Memory consumption per connection: %.2f bytes\n", float64(m1.Sys-m0.Sys)/float64(*N))
os.Exit(1)
}()
http.HandleFunc("/", handler)
err := http.ListenAndServe(":12345", nil)
if err != nil {
fmt.Fprintf(os.Stderr, "server: %s\n", err)
os.Exit(1)
}
}
}
英文:
The number of concurrent HTTP connections is limited by available memory and by operating system limits.
In Linux, the soft operating system limits - such as the maximum number of open files - can be printed out and changed by using <code>ulimit</code>.
In terms of memory, each HTTP connection in a minimal Go HTTP server running on 32-bit Linux consumes 21 KiB of memory (the source code of this server, compilable with Go version 2013-03-23, is below). On 64-bit Linux, the memory consumption can be expected to be higher.
On a 32-bit system with 1GB of memory available to the server, 21 KiB means that about 50,000 simultaneous connections are possible. This does not include memory consumed by the Linux kernel.
package main
import (
"flag"
"fmt"
"net/http"
"os"
"runtime"
"sync"
)
var isClient = flag.Bool("client", false, "Whether to start the HTTP server or the HTTP client")
var N = flag.Int("n", 1000, "Number of concurrent HTTP requests")
var wait = make(chan byte)
var counter = 0
var reachedN = make(chan byte)
func handler(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "some text")
counter++
if counter == *N {
reachedN <- 0
}
<-wait // Block this goroutine
}
func main() {
flag.Parse()
if *N <= 0 {
fmt.Fprintf(os.Stderr, "invalid number of goroutines")
os.Exit(1)
}
if *isClient {
// Initiate N http connections
var wg sync.WaitGroup
for i := 0; i < *N; i++ {
wg.Add(1)
go func(ii int) {
_, err := http.Get("http://127.0.0.1:12345")
if err != nil {
fmt.Fprintf(os.Stderr, "client %d: %s\n", ii, err)
os.Exit(1)
}
wg.Done()
}(i)
}
wg.Wait()
} else {
runtime.GOMAXPROCS(1) // No concurrency
// Read MemStats
var m0 runtime.MemStats
runtime.ReadMemStats(&m0)
go func() {
<-reachedN // Wait until there are *N concurrent requests
// Read MemStats
var m1 runtime.MemStats
runtime.ReadMemStats(&m1)
fmt.Printf("Number of HTTP connections: %d\n", *N)
fmt.Printf("Memory consumption per connection: %.2f bytes\n", float64(m1.Sys-m0.Sys)/float64(*N))
os.Exit(1)
}()
http.HandleFunc("/", handler)
err := http.ListenAndServe(":12345", nil)
if err != nil {
fmt.Fprintf(os.Stderr, "server: %s\n", err)
os.Exit(1)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论