Почему мой веб-сервер в golang не обрабатывает одновременные запросы?
Этот простой HTTP-сервер содержит вызов time.Sleep(), который делает
каждый запрос занимает пять секунд. Когда я пытаюсь быстро загрузить несколько
вкладки в браузере, очевидно, что каждый запрос
помещается в очередь и обрабатывается последовательно. Как я могу заставить его обрабатывать параллельные запросы?
package main
import (
"fmt"
"net/http"
"time"
)
func serve(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world.")
time.Sleep(5 * time.Second)
}
func main() {
http.HandleFunc("/", serve)
http.ListenAndServe(":1234", nil)
}
Собственно, я только что нашел ответ на этот вопрос после написания вопроса, и он очень тонкий. Я отправляю его в любом случае, потому что я не смог найти ответ на Google. Вы видите, что я делаю неправильно?
Ответы
Ответ 1
Ваша программа уже обрабатывает запросы одновременно. Вы можете протестировать его с помощью ab
, эталонного инструмента, который поставляется с Apache 2:
ab -c 500 -n 500 http://localhost:1234/
В моей системе эталонная программа рассчитана на 5043 мс, чтобы обслуживать все 500 одновременных запросов. Это только ваш браузер, который ограничивает количество подключений на веб-сайт.
Программы Benchmarking Go не так просто, потому что вам нужно убедиться, что ваш тестовый инструмент не является узким местом и что он также способен обрабатывать многие параллельные соединения. Поэтому для генерации нагрузки рекомендуется использовать несколько выделенных компьютеров.
Ответ 2
Из Server.go, процедура запуска генерируется в функции "Подача", когда соединение принимается. Ниже приведен фрагмент: -
// Serve accepts incoming connections on the Listener l, creating a
// new service goroutine for each. The service goroutines read requests and
// then call srv.Handler to reply to them.
func (srv *Server) Serve(l net.Listener) error {
for {
rw, e := l.Accept()
if e != nil {
......
c, err := srv.newConn(rw)
if err != nil {
continue
}
c.setState(c.rwc, StateNew) // before Serve can return
go c.serve()
}
}
Ответ 3
Если вы используете запрос xhr, убедитесь, что экземпляр xhr является локальной переменной.
Например, xhr = new XMLHttpRequest()
- глобальная переменная. Когда вы выполняете параллельный запрос с той же переменной xhr, вы получаете только один результат. Итак, вы должны объявить xhr локально следующим образом var xhr = new XMLHttpRequest()
.