2011-12-27 36 views

Trả lời

11

Số lượng kết nối HTTP đồng thời bị giới hạn bởi bộ nhớ khả dụng và theo giới hạn của hệ điều hành.

Trong Linux, giới hạn hệ điều hành mềm - chẳng hạn như số lượng tệp mở tối đa - có thể được in ra và thay đổi bằng cách sử dụng ulimit.

Về mặt bộ nhớ, mỗi kết nối HTTP trong máy chủ HTTP Go tối thiểu chạy trên 32 bit bit tiêu thụ 21 KiB bộ nhớ (mã nguồn của máy chủ này, có thể kết hợp với phiên bản Go 2013-03-23, là phía dưới). Trên Linux 64 bit, mức tiêu thụ bộ nhớ có thể cao hơn.

Trên hệ thống 32 bit có bộ nhớ 1GB có sẵn cho máy chủ, 21 KiB có nghĩa là có thể kết nối đồng thời 50.000 đồng thời. Điều này không không bao gồm bộ nhớ được nhân Linux sử dụng.

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) 
     } 
    } 
} 
+2

Cần lưu ý rằng mặc dù tất cả các cổng chỉ là cổng, nhóm thấp được xem là đã đặt trước. Tác động của việc gây rối với bất cứ thứ gì dưới 1024 có thể làm hỏng một điều gì đó bất ngờ. Ví dụ, bạn đã mở cổng 80 để chấp nhận yêu cầu, nhưng bạn không thể chấp nhận bất kỳ vì bạn đang gửi dữ liệu ra khỏi nó. – Incognito

+0

Ẩn danh, tôi thích nhận xét của bạn, nhưng bạn có thể giải thích thêm một chút không? Là 1024 byte hoặc KB? Nếu tôi gửi yêu cầu http ra từ một máy chủ Unix 64 bit, thì tối đa tôi có thể gửi đồng thời là gì? Cảm ơn! – trillions

+0

@Atom Mã không còn biên dịch trên go v1.0.3 kể từ ngày 3/23/13. Bạn có thể sửa nó không? –

Các vấn đề liên quan