2011-12-27 16 views

答えて

11

同時HTTP接続の数は、使用可能なメモリとオペレーティングシステムの制限によって制限されます。

Linuxでは、ソフト・オペレーティング・システムの制限(オープン・ファイルの最大数など)は、ulimitを使用して出力および変更できます。

メモリに関しては、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) 
     } 
    } 
} 
+2

すべてのポートが単なるポートである一方で、低グループは予約されているとみなされます。 1024未満のものにぶつかることの影響は、予期しない何かを破る可能性があります。たとえば、要求を受け入れるためにポート80を開いたが、そこからデータを送信しているために何も受け入れることはできません。 – Incognito

+0

シークレット、私のコメントは好きですが、もう少し説明してください。 1024バイトまたはKBですか? 64ビットUNIXサーバーからHTTPリクエストを送信している場合、同時に送信できる最大値は何ですか?ありがとう! – trillions

+0

@Atom 3/23/13時点のgo v1.0.3ではコードがコンパイルされなくなりました。それを修正できますか? –

関連する問題