1hermn | +_-
Доброго всем вечера! Подскажите какой-нибудь примерный код для отправки http запросов. Интересует отправка пару тысяч запросов в секунду. Делал через горутины и получилось, что на 400 запросов ушло 1.9s. Что как-то слишком медленно ( на node.js через библиотеку async у меня 1000 запросов в секунду)
1hermn | +_-
А можно код изначальный
https://pastebin.com/vqetAPHd
Gosha
Привет! Подскажите, какие объекты в го хранятся в стеке, а какие в куче? я так понял в куче - глобальные переменные, ссылочные типы(каналы, слайсы, мапы, функции), сами указатели. А всё остальное(локальные переменные, аргументы функции, ...) - на стеке
Eugene 🇺🇦 | KIRA Staking | WON'T PM YOU FIRST
https://github.com/goreleaser/goreleaser
спасибо, это сработало. Но всё же хотелось иметь возможность собирать пакеты обычными средствами dpkg-buildpackage и dh-golang может кому попадалась статья на эту тему или хоть какая то документация - буду очень признателен
Тимофей
https://pastebin.com/vqetAPHd
А если замерить время выполнения самих запросов
Тимофей
Можно ещё раскинуть цикл for на несколько горутин
Тимофей
Допустим 200 запросов разбить по 50 на 4 горутины
Тимофей
Хотя, не то
Тимофей
Я тупой соре
🅞leksiy
Вот с ним интересно
🅞leksiy
Каждый запрос возвращает время близкое к первому старт
🅞leksiy
Ощущение, что обрабатываются запросы последовательно, а не конкурентно
🅞leksiy
О замере внутри ф-ии
🅞leksiy
Тимофей
на 200 запросов ушло 1,37 секунд
🅞leksiy
на 200 запросов ушло 1,37 секунд
Ну я 2К запросов делал, еще клиент: t := http.DefaultTransport.(*http.Transport).Clone() t.MaxIdleConns = 200 t.MaxConnsPerHost = 200 t.MaxIdleConnsPerHost = 200 return &http.Client{ Timeout: 10 * time.Second, Transport: t, }
🅞leksiy
Но это мало что дало. Вообще, я не умею готовить клиент. Кроме того, что на дефолтном не стоит делать запросы ничего особо о нем не знаю. Как-то он мне никогда не нужен был
🅞leksiy
Я кстати увидел нихеровый прирост на fasthttp клиенте. Очень удивился и проверил ответ. А там приходит редирект на https. И пустой body 🤣 Я так понял, что net/http клиент переходит по редиректу автоматически.
🅞leksiy
0.31 elapsed with response length: 0 http://requestbin.net/ip HTTP/1.1 301 Moved Permanently Server: cloudflare Date: Sun, 06 Feb 2022 21:24:46 GMT Content-Length: 0 ...
🅞leksiy
Зато 2K запросов за 0.3сек
Тимофей
у меня после нескольких запусков результат 0,87 секунд
Тимофей
да
Тимофей
сначала 3 с
Тимофей
потом 1,5
Тимофей
потом 0,87
🅞leksiy
А внутреннее время растет?
🅞leksiy
Какая-то херня с клиентом, или я чего-то не понимаю
🅞leksiy
Он как-будто синхронно данные получает
🅞leksiy
Когда body пустой, все очень быстро отрабатывает, конкурентно, при том что body 15 байт, а хедеров на 600 байт.
Alexander
притом обычный еще и запросы фейлил
Alexander
ну для сложных задач прироста нет в целом, а вот для апишек есть
🅞leksiy
ну для сложных задач прироста нет в целом, а вот для апишек есть
Там ip адрес возвращается, прирост должен быть по идее
🅞leksiy
ну для сложных задач прироста нет в целом, а вот для апишек есть
Ладно, фиг с ним. А что с клиентом вообще? Либо это баг в го, либо я туплю и чего-то не понимаю
Alexander
https://pastebin.com/vqetAPHd
ну тут дефолтный клиент, который помойму 2 соединения на хост держит. то есть по факту 2 одновременных запроса, а с нодой ничего неизвестно
🅞leksiy
func doRequest(url string, ch chan<- string) { start := time.Now() req := fasthttp.AcquireRequest() req.SetRequestURI(url) resp := fasthttp.AcquireResponse() client := &fasthttp.Client{} if err := client.Do(req, resp); err != nil { fmt.Println(err) } secs := time.Since(start).Seconds() body := string(resp.Body()) ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url) }
Тимофей
у меня почему-то при увеличении числа запросов (я просто везде 200 заменил на 1000) начинает nil pointer exception кидать
Тимофей
почему
🅞leksiy
почему
В его коде нет проверок на ошибки
Тимофей
ясно
Тимофей
ваш код тоже кидает мне exception
Тимофей
может это винда?
🅞leksiy
Что за ексепшн?
Тимофей
package main import ( "fmt" "time" "github.com/valyala/fasthttp" ) func MakeRequest(url string, ch chan<- string) { start := time.Now() req := fasthttp.AcquireRequest() req.SetRequestURI(url) resp := fasthttp.AcquireResponse() client := &fasthttp.Client{} if err := client.Do(req, resp); err != nil { fmt.Println(err) } secs := time.Since(start).Seconds() body := string(resp.Body()) ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url) } func MakeReq(ch chan string) { for i := 0; i <= 1000; i++ { go MakeRequest("http://requestbin.net/ip", ch) } } func main() { start := time.Now() ch := make(chan string, 1000) for i := 0; i <= 1000; i++ { fmt.Println(<-ch) } fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) }
Тимофей
куча ошибок
Тимофей
и в конце deadlock
🅞leksiy
DoRedirects надо
Это в клиенте настраивается? Не смотрел доку по нему, если честно
🅞leksiy
Ну да я прямо на https тестил
Alexander
Не, вместо Do DoRedirects. я не помню уже всех нюансов
Тимофей
Что за ексепшн?
это было из-за ограничения размера канала
Alexander
там еще странно, что есть DoTimeout и DoRedirects
Alexander
и я уже не помню как совмещал
Тимофей
а что если в конце не закрыть канал? у меня будет вечно выделена память, или в конце его сборщик мусора всё равно почистит?
🅞leksiy
Короче, расходимся
🅞leksiy
Тимофей
там сервер не выдерживает?
🅞leksiy
У меня go ровно столько же отрабатывает запросов
🅞leksiy
Как и wrk
Alexander
а да, там все-таки таймауты можно в клиенте настроить
🅞leksiy
А я уже начал на него грешить
Alexander
короче очень странная тема. притом что есть не только DoTimeout, но и DoDeadline
Alexander
искренне бы хотелось спросить автора почему так
Alexander
не знаю, может до этого не он сам дошел
Alexander
там основной мейнтейнер как понял другой чел достаточно давно уже
Нат
Привет всем! Подскажите, как можно в Chi передать несколько key в роутер? В fasthttp это делается через /:value1/:value2, а вот в Chi надо использовать метод context.WithValue и я что-то не нашла, как передать этому методу более одного ключа и соответствующего ему интерфейса
Нат
вот например я хочу передать не только email, но и password router.Route("/delete_acc/{email}/{delete}", func(router chi.Router) { router.Use(PostCtx) router.Get("/", DeleteAccount) })
Нат
func PostCtx(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), "email", chi.URLParam(r, "email")) next.ServeHTTP(w, r.WithContext(ctx)) }) }
🅞leksiy
Вроде в примерах все есть...
🅞leksiy
Или речь о том, как впихнуть в контекст несколько значений?
Нат
В контекст несколько значений
🅞leksiy
В контекст несколько значений
Как вариант - передать структуру, в которой будет несколько полей
🅞leksiy
Или так: ctx := context.WithValue(context.Background(), "1", "one") ctx = context.WithValue(ctx, "2", "two") fmt.Println(ctx.Value("1")) fmt.Println(ctx.Value("2"))
Нат
поняла, спасибо большое!