-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: ListenAndServeTLS performs badly on Windows #4073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Labels
Milestone
Comments
R, I think the only way for you to advance your issue is to convince us that there is a problem here: bug in code somewhere, leaking resources, great inefficiencies. It is on you to demonstrate that. Best way to do it, I think, is to write a Go test that establishes connection between SSL client and server - all in one test. You could run this test in a loop to measure performance. You could use runtime memory stats to show memory increases. You could use benchmarking tools in test package to measure your findings. Please, have a go and report your findings. Alex |
Comment 6 by [email protected]: On Ubuntu, the ListenAndServerHTTPS performs badly too. siege --benchmark --concurrent=100 "https://localhost:8082" gives 21.01 trans/sec while to a similar hello world node.js app, which uses the same SSL certs, the benchmark gives 508.64 trans/sec. |
Comment 8 by [email protected]: I generated the keys with: openssl genrsa 2048 > key.pem openssl req -new -x509 -key key.pem -out cert.pem -days 1095 and the code that was benchmark on dual core i7 with hyperthreading is: package main import ( "log" "net/http" "runtime" ) func handler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("This is an example server.\n")) } func main() { runtime.GOMAXPROCS(runtime.NumCPU()) http.HandleFunc("/", handler) log.Printf("About to listen on 8082. Go to https://127.0.0.1:8082/") err := http.ListenAndServeTLS(":8082", "cert.pem", "key.pem", nil) if err != nil { log.Fatal(err) } } |
Thank you for your instructions. I tested my both (linux and windows) computers. And they give similar figures: linux: Lifting the server siege... done. Transactions: 1867 hits Availability: 100.00 % Elapsed time: 118.75 secs Data transferred: 0.05 MB Response time: 6.23 secs Transaction rate: 15.72 trans/sec Throughput: 0.00 MB/sec Concurrency: 97.89 Successful transactions: 1867 Failed transactions: 0 Longest transaction: 13.59 Shortest transaction: 0.32 windows: Lifting the server siege... done. Transactions: 779 hits Availability: 100.00 % Elapsed time: 40.56 secs Data transferred: 0.02 MB Response time: 4.85 secs Transaction rate: 19.21 trans/sec Throughput: 0.00 MB/sec Concurrency: 93.11 Successful transactions: 779 Failed transactions: 0 Longest transaction: 10.22 Shortest transaction: 0.34 Alex |
Comment 10 by [email protected]: Alex, I was just chiming in to say that the performance of ListenAndServerTLS appears to be as slow on linux as it is on on Windows. My ideal web server setup with Go is having all SSL without any type of SSL accelerator in front of my Go web app. The current implementation calls for having a very beefy server if there is a great load on my Go web app. |
Comment 12 by [email protected]: Alex, I agree with you. -rambocoder |
created new issue https://golang.org/issue/4299 for data I see myself. Status changed to Duplicate. Merged into issue #4299. |
Let me write down my benchmarks and a temporary fix. On my laptop (with core 2 duo) I measure the Go server's performance by time ./myServer and watched the row "user" in the result. The server only establish the connection. I tested it with the following benchmark: for ((i=0;i<100;i++)); do curl --insecure https://127.0.0.1/test& done The results: without cipher: 8 sec CPU load (it is using ECDHE) with --ciphers AES256-SHA (or any other without ECDHE): 2 sec with --ciphers ECDHE-RSA-AES128-SHA (or any other with ECDHE): 8 sec So I modified the src/pkg/crypto/tls/handshake_server.go to prefer non-ECDHE handshake if it's possible. In readClientHello(...) function I replaced for _, id := range preferenceList { if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil { break } } with // We prefer everything which is not elliptic for _, id := range preferenceList { if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, false, hs.ecdsaOk); hs.suite != nil { break } } // If there is no match, let's allow elliptic if hs.suite == nil && hs.ellipticOk { for _, id := range preferenceList { if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil { break } } } With this fix I have: without cipher: 2 sec CPU load (because we prefer non-ECDHE handshake now) with --ciphers AES256-SHA (or any other without ECDHE): 2 sec with --ciphers ECDHE-RSA-AES128-SHA (or any other with ECDHE, the server still support it if no other handshake is possible): 8 sec By the way, I believe that the handshake should be around 0.5 sec (same machine, openssl). |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by raheelgup:
The text was updated successfully, but these errors were encountered: