LINUX.ORG.RU

Параллельная обработка запросов для одного URL

 , ,


0

1

Всем привет!

Как в Go сделать, чтоб функция заданная в http.HandleFunc на один и тот же паттерн URL работала параллельно, а не последовательно?

Например, если запустить код размещённый ниже и открыть два раза http://127.0.0.1:8080/test, то в первый раз страница загружается через 10 секунд, а во второй раз – через 20 сек., вместо 10, а это означает, что обработка запросов выполняется последовательно. Как сделать чтоб было параллельно?

package main

import (
	"net/http"
	"time"
)

func main() {
	http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(10 * time.Second)
		w.Write([]byte("Hello world!"))
	})

	http.ListenAndServe(":8080", nil)
}

Забавно. Судя по всему это только браузеру он так отвечает. Если тыкать curl/wget то всё нормально, по 10 секунд на каждый параллельный запрос.

Toxo2 ★★★
()

Параллельность зависит не от сервера, а от клиента. Если клиент открыл два соединения и в каждом послал запрос, будет параллельно. Если клиент открыл одно соединение и послал в нем два запроса, будет последовательно.

iliyap ★★★★★
()

отдельное соединение на каждый запрос или пайплайнинг(малоприменимо в общем случае, но может подойдет). в общем, без костылей хттп так не умеет.

если и сервер, и клиент твои, можешь нормальный пайплайнинг сделать(с идентификаторами запросов). или хттп 2/3 посмотри, может быть там это починили.

jsforever
()
Ответ на: комментарий от jsforever

Поясните все-таки что значит «хттп так не умеет» ?

Если в Firefox и одновременно в Chromium (например) слать два запроса к этому серверу - это ведь два соединения. И работают каждое по 10 секунд.

Почему же в двух вкладках одного браузера они считаются как одно? Точнее даже - как это зависит от самого протокола?

Toxo2 ★★★
()
Ответ на: комментарий от Toxo2

HTTP позволяет переиспользовать соединение для повторных запросов. Броузеры этим также пользуются. Видимо, броузер решил, что для выполнения данной задачи одного соединения достаточно, поэтому оба запроса решил отправить через него.

HTTP 1.1 позволяет отправить сразу несколько запросов через одно соединение, без последовательного ожидания ответов. Но это достаточно криво реализовано в протоколе, так что не факт, что в данном случае это гарантированно сработает - для отправки именно двух запросов, даже если клиент и сервер это поддерживают.

Sorcerer ★★★★★
()
Ответ на: комментарий от Toxo2

В общем наигрался в эту игру.

Максимум, что у меня получилось (если хотеть видеть глазами параллельное исполнение в разных вкладках ОДНОГО браузера) - поотключать везде Keep-Alive, и насильно заставить браузер разговаривать по протоколу HTTP/1.0.

Иначе - браузер шибко умничает и делает так, как считает нужным. В HTTP/1.1 KeepAlive вообще не отключается, как я понял.

Только делать это нормальным людям не надо. Просто любопытно было.

Toxo2 ★★★
()

Всем спасибо!

Действительно, дело в особенности работы клиента и версии протокола HTTP. Кстати, запросы на разные URL к одному серверу он делает параллельно.

Разные клиенты будут сервером обрабатываться параллельно, мне этого и нужно.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от Toxo2

Поясните все-таки что значит «хттп так не умеет» ?

не умеет - это значит не умеет. не может. не способен. не предоставляет возможности реализовать указанное поведение.

Если в Firefox и одновременно в Chromium (например) слать два запроса к этому серверу - это ведь два соединения. И работают каждое по 10 секунд.

и? я ведь тебе написал про костыли, в том числе два соединения. к хттп это никакого отношения не имеет. это свойство серверов. для чего угодно можно просто взять несколько инстансов и сказать «оно умеет параллельно». возьми однопоточный блокирующий хттпд и попробуй два соединения - увидишь те же самые 20 секунд.

Почему же в двух вкладках одного браузера они считаются как одно? Точнее даже - как это зависит от самого протокола?

в том то и дело, что никак это от протокола не зависит. скорее всего браузер открывает по одному соединению на домен/адрес. почему считаются как одно - потому что одно и есть.

jsforever
()
Ответ на: комментарий от Toxo2

В общем наигрался в эту игру.

Не наигрался.

Пришло в голову во сне, проснулся, пошел проверять - оказывается можно проще обмануть браузер: тупо один и тот же запрос на разные IP на этой машине. Один на 127.0.0.1, другой на 192.168.88.10.

Тут браузер уже перестает умничать и создает разные соединения для вкладок на один и тот же сервер.

Вот теперь наигрался.

Toxo2 ★★★
()