Как стать автором
Обновить

Комментарии 42

Мне потребовался HTTP-сервер, который бы отдавал трафик с какой-то заданной скоростью, например, 512KiB/sec

Казалось бы, при чём тут man 8 tc-netem ?

Не знаю, но может вы расскажите?

Ну что-то в духе:


tc qdisc add dev lo ingress
ip addr add 127.0.0.42 dev lo # ip for each server
tc filter add dev lo parent ffff: protocol ip u32 match ip src 127.0.0.42/32 flowid :1 police rate 1.0mbit 

Дальше биндим любимый веб сервер на заданный адрес и развлекаемся. Так можно ещё и "плохое" соединение тестировать, в том числе и с заданным распределением потери пакетов.

Дальше биндим любимый веб сервер на заданный адрес и развлекаемся

И откуда возьмется этот "любимый веб сервер" и что он будет делать?

Отдавать бесконечную статику разумеется. Например тот же /dev/random, да или даже /dev/zero, что бы cpu не насиловать почём зря.


Я не большой специалист в web технологиях(и пиаре своих поделок), но кажется, что даже:


python -m SimpleHTTPServer

вполне себе сдюжил бы.


Может конечно на прикладном уровне точнее, чем специально обученным инструментом, но вот вопрос — кто вашу наколенную поделку за час написанную протестировал?

А вот этот набор команд + какой-то сервер, который будет из dev/random брать поток байт и превращать их в корректный HTTP-ответ, кто будет тестировать?

Наверное, какие-то неудачники из разработчиков ядра linux и coreutils для gnu/linux, а так же — пара полных остолопов трудящихся над стандартной библиотекой пайтон.

Я у вас не про качество реализации tc-netem спрашивал. Но, судя по вашим комментариям, вы не просто так этого не понимаете.

С удовольствием расширю свой кругозор с помощью ваших пояснений.

Дело не в кругозоре.

Дело не в кругозоре.

Ну не в нём, так не в нём, чего флудить то. Проще сказать почему не взлетит, а ваше решение лучше, если вдруг вы обладаете каким-то тайным знанием, чем ограничение скорости http будет отличаться от такого же ограничения для tcp. На уровень ниже это работало вполне себе точно. Вполне себе допускаю, что велосипед оправдан и чего-то не учёл, однако — аргументации не наблюдается.


Вроде технический ресурс был, место дискуссии имелось, а теперь спрашиваешь у рекламодателя — а чем его решение лучше практически изкоробочных средств, а он только и может что сказать, что мол автор вопроса (то бишь я) ничего не понимаю. Позовите разработчика — может он пояснит?

Так если ресурс технический, то что же вы разговор о рекламе переводите?


По сути: каждый волен выбирать те инструменты, которые он знает и с помощью которых он может решить задачу быстро и качественно. Для вас это tc-netem и Python. Для меня, который про tc-netem ничего до ваших комментариев не знал, это C++ и RESTinio. Для кого-то Go, для кого-то что-то другое.

Ну я не услышал аргументации, а упоминание одного и того же инструмента раз 50 в одном коротеньком тексте слегка напоминает знаете ли… "Покупайте наших слонов, советские слоны самые лучшие слоны в мире".


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

До определённой степени, думаю. Если бы человечество следовало этому принципу безоговорочно, то каждое поколение изобретало бы колесо раз по 5.


Меня учили, что хорошая статья должна рассматривать альтернативы или указывать на их отсутвие в разделе "мотивация". Ну либо сразу предупреждать, что это из раздела "смотрите как я могу", например, тут проскакивали реализации игры "Жизнь" на CMake или что-то в таком духе.


Также — как разработчику сетевого приложения, крайне рекомендую освоить инструменты вида tshark, ip и tc. Я вот плохо представляю как без подобного тулкита протестировать а как поведёт себя сервер в случае сбоев на строне провайдера например. Вот про что я почитал бы на самом деле — это про методики тестирования и замеров производительности вашего решения(про сам сервер разумеется а не приложение из этой статьи).

Ну я не услышал аргументации

Аргументации в чем? Если в том, что это "единственно правильный" подход, так её и не будет, поскольку у статьи не было цели показать, что подобные задачи нужно решать таким и только таким образом.


а упоминание одного и того же инструмента раз 50 в одном коротеньком тексте слегка напоминает знаете ли…

Если статья рассказывает о том, как что-то сделать с помощью инструмента X, то частое упоминание X в тексте неизбежно. Если вы напишите свою статью о том, как того же самого достичь с помощью tc-netem, то tc-netem будет упоминаться вами в тексте не реже.


Меня учили, что хорошая статья должна рассматривать альтернативы или указывать на их отсутвие в разделе "мотивация".

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


  • некоторое время назад мы стали делать встраиваемый асинхронный HTTP-сервер для C++, поскольку существовавшие тогда варианты нас не устраивали;
  • основной упор в нашей разработке был сделал именно на асинхронность. Что находило свое отражение и в примерах, и в документации;
  • тем не менее, мы регулярно сталкивались с вопросами пользователей о том, поддерживает ли наш инструмент асинхронность и как им быть, если они не могут сформировать HTTP-response прямо в момент обработки HTTP-request;
  • поток этих вопросов был настолько стабильным, что пришлось делать отдельную большую статью на эту тему;
  • но проблема той большой статьи была в отсутствии примеров из практики;
  • а данная статья такой пример как раз и приводит. Посему она является непосредственным продолжением предыдущей. Что отражается, во-первых, как в самом названии. Так и, во-вторых, в специальном предупреждении-уведомлении во вступлении:

В принципе, данную статью можно рассматривать как продолжение предыдущей статьи про RESTinio под названием "RESTinio — это асинхронный HTTP-сервер. Асинхронный".

Но вы, очевидно, увидели в статье что-то другое, то, о чем я вообще не писал. И начали спорить не со мной, а с собственным восприятием прочитанного.


Также — как разработчику сетевого приложения, крайне рекомендую освоить инструменты вида tshark, ip и tc. Я вот плохо представляю как без подобного тулкита протестировать а как поведёт себя сервер в случае сбоев на строне провайдера например.

Что еще раз говорит о вашем специфическом восприятии текста. Не нужно было тестировать поведение сервера. Ну вот вообще. Задача была в том, чтобы протестировать клиента. Для чего потребовался специализированный HTTP-сервер.


Если вы знаете, как такой специализированный сервер собрать меньшими количествами усилий на tc-netem и Python, то напишите свою статью. Наверняка многие разработчики узнают что-то новое.

Аргументации в чем? Если в том, что это "единственно правильный" подход, так её и не будет, поскольку у статьи не было цели показать, что подобные задачи нужно решать таким и только таким образом.

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


Но вы, очевидно, увидели в статье что-то другое, то, о чем я вообще не писал.

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


Что еще раз говорит о вашем специфическом восприятии текста. Не нужно было тестировать поведение сервера. Ну вот вообще. Задача была в том, чтобы протестировать клиента.

Вы плохо следите за контекстом дискуссии. Я писал про тестирование вашей разработки. Это действительно интересный и полезный материал, гораздо более интересный, чем притянутое за уши приложение(гвозди, молотки, вот это всё).


Если вы знаете, как такой специализированный сервер собрать меньшими количествами усилий на tc-netem и Python, то напишите свою статью. Наверняка многие разработчики узнают что-то новое.

Согласен, критиковать проще чем создавать контент. Ну я как могу вношу посильный вклад.

В основе рассказа лежит опыт создания тестового сервера для тестовых целей. Соответственно, откуда там могут взяться суровые требования к точности объема выдаваемого потока мне лично не ясно.


Проверить работу этого тестового сервера проще простого — натравите на него curl, например, вот так:


curl http://localhost:8080/512K > /dev/null

и посмотрите какие показатели текущей и средней скорости выдает curl. Можете натравить хоть 10, хоть 100 curl-ов одновременно.


Соответственно, ваши комментарии с моей колокольни воспринимаются вот так: "Чувак, я не дал себе труда разобраться в том, что ты сделал, но ты явно пиаришь свою поделку тогда как я бы все сделал через tc-netem". В общем, имею мнение… и далее по тексту.


Ну, OK. Вполне себе позиция. Только обсуждать ее мне вообще не интересно. Ну вот вообще.


Показали бы как тот же результат получить без написания своего специализированного HTTP-сервера., было бы что пообсуждать и читатели этой дискуссии могли бы что-то полезное для себя вынести. Но вы не даете себе труда сделать это, вам проще задвигать про молотки и гвозди.

curl http://localhost:8080/512K > /dev/null

Вот это, уже аргумент, я почти доволен.


опыт создания тестового сервера для тестовых целей.

Тестировать непротестированным — это наше всё.


"Чувак, я не дал себе труда разобраться в том, что ты сделал, но ты явно пиаришь свою поделку тогда как я бы все сделал через tc-netem"

Скорее — чувак, тестировать скорость загрузки по http с помощью http сервера это слегка не точно… Хотя тут конечно всё сильно зависит от требуемой точности.


Вполне себе позиция. Только обсуждать ее мне вообще не интересно. Ну вот вообще.

Тем не менее, 90% обсуждения вокруг этого опуса произошло в выше приведённой ветке;) Ну по крайней мере пока не случился понедельник.


Показали бы как тот же результат получить без написания своего специализированного HTTP-сервера

Дык. Добавляем адрес к петле, шейпим траффик на заданный лимит по скорости на этом адресе, запускаем любой web сервер который умеет выдавать файл произвольного размера в директории /dev/ или в директории куда кинута символическая ссылка на /dev/zero. Вроде я ж с этого и начал?

Тестировать непротестированным — это наше всё.

Я же говорил, что вы увидели в тексте статьи что-то свое. Вот вы очередное тому подтверждение и привели.


Хотя тут конечно всё сильно зависит от требуемой точности.

Зависит. Но вы не дали себе труд ознакомиться со статьей, поэтому спорите со своим восприятием, а не с тем, что я описывал.


Тем не менее, 90% обсуждения вокруг этого опуса произошло в выше приведённой ветке;)

Я был бы доволен, если бы этого пустопорожнего переливания не было совсем. Но ваше желание донести до меня свое ИМХО слишком велико.


запускаем любой web сервер который умеет выдавать файл произвольного размера в директории /dev/

Ну так проделайте этот шаг. Запустите этот любой сервер, дайте ему какой-нибудь файл на 10GiB или больше, расскажите, как он будет себя вести, когда он будет отдавать ответ с максимально возможной скоростью, а его будут резать до 20KiB/sec. Заодно расскажите как вы сделаете так, чтобы этот сервер мог на разные параллельные запросы отдавать ответы с разной скоростью.


Ну и отдельно распишите (раз уж вас этот момент так волнует), как бы вы тестировали созданную вами конструкцию. Ведь этот набор команд так же может содержать опечатки или даже неверные команды, если у человека нет опыта работы с tc-netem.

Подумал ещё, и понял откуда всё же растёт моё недовольство вашим подходом.


Если у вас в руках молоток, то всё вокруг начинает казаться гвоздём. ©


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

НЛО прилетело и опубликовало эту надпись здесь

А вы точно статью прочитали?

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

А каким боком тут tarantool?

Мне потребовался HTTP-сервер, который бы отдавал трафик с какой-то заданной скоростью, например, 512KiB/sec. Тогда бы я мог видеть, действительно ли приложение выдерживает скорость 200KiB/sec или же оно срывается на более высокие скорости.

Хм, а если ваше приложение "сорвется" до 400KBps, значит ли это, что тест пройден или провален?


Я к тому, что если вам нужна имплементация тротлинга в клиенте, то зачем тут еще и сервер с тротлингом. КМК достаточно мониторинга соединений клиента, чтобы оценить качество реализации тротлинга в нем.

Хм, а если ваше приложение "сорвется" до 400KBps, значит ли это, что тест пройден или провален?

Провален. Значит реализация ограничения скорости некорректная.


КМК достаточно мониторинга соединений клиента, чтобы оценить качество реализации тротлинга в нем

Соединений с чем? Чтобы мониторить соединение его нужно сперва создать. И вот к чему коннектиться при автономных тестах?

И вот к чему коннектиться при автономных тестах?

Да к чему угодно, что способно выдать больше, чем вам нужно в тесте.
А далее достаточно снять скорость с соединений вашего клиента.
Я понимаю, что может существовать требование поддержки тротлинга к серверу.
Но в рамках поставленной задачи такая поддержка на сервере не нужна.
Нужен мониторинг в том или ином виде.

Да к чему угодно, что способно выдать больше, чем вам нужно в тесте.

Ну и к чему это?


Нужен мониторинг в том или ином виде.

Мониторинг скорости клиента как раз таки есть.

Ну и к чему это?

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


Мониторинг скорости клиента как раз таки есть.

Прекрасно, этим можно было б и ограничиться, не трогая сервер.

Проблема была в том, что мне эта программа попала на доработку без каких-либо тестов и, уж тем более, тестовых окружений. Поэтому либо нужно было использовать какие-то сайты в Интернете, либо поднимать какой-нибудь существующий сервер и учить его отдавать "бесконечный" трафик, либо делать что-то свое. Я сделал что-то свое, благо много времени это не заняло.


можно было бы использовать тот же сервер, в который вы добавили тротлинг

Во-первых, такого сервера не было вообще.


Во-вторых, в сервере задание скорости не менее полезно. Например, в приложении делается три канала: на 128, 256 и 512 KiB/sec. И они подключаются к разным URL на тестовом сервере: скажем на 80, 256 и 1024KiB/sec. По показателям затем должно выходить 80 на первом канале, 256 на втором и 512 на третьем. И все это можно проверить на одном-единственном тестовом HTTP-сервере. Собственно, изрядная часть кода в описанном примере именно с этим и связана.

min(128,80), min(256,256), min(512,1024) разумеется, дадут 80, 256, 512.
Только вот 2 последних случая никакого отношения к тротлингу на клиенте иметь не будут.


Я не против того, что вы сделали и описали. Самому приходилось добавлять тротлинг для передачи и получения данных. Вполне понятная и востребованная "фича".


Я "придираюсь" исключительно к формулировке исходной задачи, что мол, для тестирования реализации тротлинга в клиенте вам понадобился сервер с аналогичной функциональностью. Для меня же очевидно, что для тестов, т.е. min(client_speed, server_speed) достаточно, чтобы client_speed < server_speed.
Условно, если server_speed==inf, то всё Ok ;) Отсюда и вывод, что то, что вы сделали может быть и полезно где-то ещё, но в рамках поставленной задачи бесполезно.

min(128,80), min(256,256), min(512,1024) разумеется, дадут 80, 256, 512.

Почему это разумеется? Если реализация тротлинга на клиенте некорректна, то может быть вовсе не 80, 256 и 512, а 60, 128 и 1024, к примеру.


Когда вместо inf есть четкое понимание ширины отдачи у сервера, разбираться с клиентом гораздо проще.


И это мы еще не рассматриваем случаи, когда тротлинг на клиенте может на длительном интервале времени давать 80KiB/sec, но это будет за счет того, что 10 секунд он будет вообще ничего не читать, а потом за секунду выкачает 880KiB. Что тоже как бы не есть гуд.

Почему это разумеется?

Потому, что единственным необходимым условием для корректной реализации является условие client_throttle_speed < server_bandwidth.


И это мы еще не рассматриваем случаи, когда тротлинг на клиенте может на длительном интервале времени давать 80KiB/sec, но это будет за счет того, что 10 секунд он будет вообще ничего не читать, а потом за секунду выкачает 880KiB.

Зачем рассматривать заведомо абсурдную постановку?
Bandwidth принято мерять в *bps, вот и корректный тротлинг должен давать плавный график с разрешением близким к секунде, а не измеряться за "неделю".

Потому, что единственным необходимым условием для корректной реализации является условие client_throttle_speed < server_bandwidth.

По вашему ситуация, когда client_bandwidth > server_bandwidth вообще никак не должна тестироваться? ;)


Зачем рассматривать заведомо абсурдную постановку?

Речь вообще-то не про постановку, а про реализацию. Если клиент держит 100500 подключений и по ошибке на какое-то время "забывает" про часть своих подключений, то еще и не такие фокусы могут происходить.

когда client_bandwidth > server_bandwidth вообще никак не должна тестироваться? ;)

Вы, наверное, хотели написать clientthrottlespeed > server_bandwidth? :)
В любом случае, что вы ожидаете увидеть при этом?


то еще и не такие фокусы могут происходить.

Мне кажется, что вы меня уже поняли. Я говорил исключительно об исходной постановке задачи, т.е. о юнит-тестировании реализации тротлинга в каком-то вашем HTTP-клиенте…
Предлагаю экзотические фокусы, нагрузочное тестирование и т.д. оставить за рамками обсуждения. Да и обсуждение, КМК, уже выродилось. Предлагаю на этом и закончить.

В любом случае, что вы ожидаете увидеть при этом?

Я ожидаю увидеть, что клиент качает с той скоростью, с которой сервер отдает. И чтобы не начал почему-то резать трафик.


т.е. о юнит-тестировании

Вообще-то речь про юнит-тестирование и не шла.

что клиент качает с той скоростью, с которой сервер отдает. И чтобы не начал почему-то резать трафик.

Ну так задайте throttle_speed, допустим, 200Gbps и сравнивайте со скоростью сервера :)

Давайте на пальцах: допустим, у клиента на канал задано ограничение в 128KiB/sec, а сервер может отдавать всего 80KiB/sec. Если реализация ограничителя у клиента правильная, то клиент будет качать со скоростью 80KiB/sec. Если не правильная, то возможны разные варианты, например, 60KiB/sec или 12.8KiB/sec.


И это поведение так же должно быть протестировано. Если вы думаете, что не должно, то, пожалуйста, не морочьте мне больше голову.

И это поведение так же должно быть протестировано.

Должно. См. кэйс в предыдущем сообщении.


не морочьте мне больше голову.

И вам того же. :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации