Сообщение Re[21]: REST: прохой\хороший интерфейс от 14.02.2020 5:39
Изменено 14.02.2020 5:57 Sinclair
Re[21]: REST: прохой\хороший интерфейс
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ладно, пора заканчивать.
Ну естественно. Как дело доходит до конкретики, фанаты RPC разбегаются из треда.
PD>Ты упорно мыслишь в психологии HTTP.
Павел. Психология тут ни при чём.
PD>Какое такое перенаправление ? В HTTP — понятно, а в вызове процедуры на сервере о чем вообще речь может идти ? Я обращаюсь к серверу, вызываю его метод. Нет тут URL (точнее, он один был при соединении) и нечего перенаправлять. Если нужно, пусть сервер и перенаправляет куда хочет — тем же способом. Клиента это не интересует.
PD>Остальное аналогично. Пусть сервер там и разбирается, что modified, а что нет.
PD>Какие метаданные и в каких хидерах ? Нет тут хидеров и нет метаданных. Есть Person, которую надо с сервера получить. Здесь столько же метаданных и хидеров, сколько в SELECT * FROM persons WHERE
PD>Сжатие — ну если нужно, пусть метод делает zip и возвращает byte[] или ByteBuffer. thrift, кстати, ByteBuffer очень любит и все двоичные данные именно в виде его и передает
Павел, вот реально у тебя всё мышление с ног на голову повёрнуто. Пятнадцать лет на этом форуме — а ничего не изменилось.
Все рассуждения — на уровне байтовых буферов. "Нету хидеров и метаданных" — ну так это как раз и плохо!!!
Поясню ещё раз, в надежде, на проблески озарения.
Когда мы проектируем протокол, у нас задача не сводится к "передаче байтов по сети". Задача формулируется в терминах прикладных сценариев.
И в REST, даже если архитектор заранее не подумал о каком-то аспекте, то можно задним числом этот аспект добавить, не ломая прямую и обратную совместимость!
Одно это ставит REST на две ступени выше, чем любой RPC.
"Пусть сервер и перенаправляет" — отлично. Вот тебе сценарий: клиент запрашивает данные у сервера. Данных — относительно много, этот наш person содержит в себе его автобиографическое видео — 1 минута, 50 мегабайт.
Вот мы запустили всё это в производство, посмотрели метрики — тяжеловато, наш сервер перегружен. Перегружен он потому, что отдаёт данные со скоростью клиента; поэтому далёкие клиенты в Мексике, которых оказалось неожиданно много, удерживают соединение открытым очень долго, и наш COM-объект отжирает нужные другим ресурсы. Снижается степень параллелизма.
Что, Павел, ты будешь делать? Ссылаться на то, что заказчики — козлы, и никогда заранее не описывают все требования?
Ну ок, эффективность фермы — никакая. Если бы у тебя был REST, то ты, не трогая само приложение, спокойно бы начал с того, что развернул бы на исходном адресе reverse proxy, чтобы разгрузить свой бэк-енд. Не написав ни строчки кода, получил бы расшивание боттлнека на порядок.
Далее, проанализировав нагрузку, поставил бы локальный прокси в Мексике, а на исходном адресе нарулил бы правило "если клиент пришёл из такого-то IP диапазона, то перенаправь его на мексиканский гейт".
Теперь у клиентов раундтрип до точки входа не 1200мс, а 80мс.
Опять — не написав ни строчки кода, ты меняешь потоки данных, и масштабируешь приложение. Более того — тебе даже не надо обзванивать мексиканских клиентов и говорить им "пожалуйста, пропишите у себя в конфиге вот такой адрес сервера".
"Нечего перенаправлять" — это не значит "не нужно перенаправлять", а "тупой RPC неспособен перенаправить".
Я на голом HTTP могу изваять geo-redundancy и load-balancing. А что ты предложишь делать с RPC?
Далее, "пусть сервер разбирается, что modified, а что нет" — ты вот сядь, напиши сигнатуру метода. Это в теории всё кажется понятным. Если своего опыта работы с сетью нету — ты уж не стесняйся, поверь более опытным товарищам.
А на практике внезапно оказывается, что запилить хотя бы треть того, что в REST идёт из коробки, в RPC руки не доходят. Влаги в организме столько нету, сколько пота потребуется пролить.
И на фоне этого делается вывод, что "ну, REST — это применение неудачной концепции за рамками изначальной задачи, бла-бла-бла". Да какая разница, кто для чего исходно предназначался. Мы же инженеры — нам важно то, какие результаты можем мы получить. Ай-яй-яй, атом изначально разлагали для получения оружия. А теперь его зачем-то применяют для выработки электричества. Ну давайте, вернёмся к основам! А электричество будем вырабатывать как деды завещали — бензиновым генератором.
PD>Ладно, пора заканчивать.
Ну естественно. Как дело доходит до конкретики, фанаты RPC разбегаются из треда.
PD>Ты упорно мыслишь в психологии HTTP.
Павел. Психология тут ни при чём.
PD>Какое такое перенаправление ? В HTTP — понятно, а в вызове процедуры на сервере о чем вообще речь может идти ? Я обращаюсь к серверу, вызываю его метод. Нет тут URL (точнее, он один был при соединении) и нечего перенаправлять. Если нужно, пусть сервер и перенаправляет куда хочет — тем же способом. Клиента это не интересует.
PD>Остальное аналогично. Пусть сервер там и разбирается, что modified, а что нет.
PD>Какие метаданные и в каких хидерах ? Нет тут хидеров и нет метаданных. Есть Person, которую надо с сервера получить. Здесь столько же метаданных и хидеров, сколько в SELECT * FROM persons WHERE
PD>Сжатие — ну если нужно, пусть метод делает zip и возвращает byte[] или ByteBuffer. thrift, кстати, ByteBuffer очень любит и все двоичные данные именно в виде его и передает
Павел, вот реально у тебя всё мышление с ног на голову повёрнуто. Пятнадцать лет на этом форуме — а ничего не изменилось.
Все рассуждения — на уровне байтовых буферов. "Нету хидеров и метаданных" — ну так это как раз и плохо!!!
Поясню ещё раз, в надежде, на проблески озарения.
Когда мы проектируем протокол, у нас задача не сводится к "передаче байтов по сети". Задача формулируется в терминах прикладных сценариев.
И в REST, даже если архитектор заранее не подумал о каком-то аспекте, то можно задним числом этот аспект добавить, не ломая прямую и обратную совместимость!
Одно это ставит REST на две ступени выше, чем любой RPC.
"Пусть сервер и перенаправляет" — отлично. Вот тебе сценарий: клиент запрашивает данные у сервера. Данных — относительно много, этот наш person содержит в себе его автобиографическое видео — 1 минута, 50 мегабайт.
Вот мы запустили всё это в производство, посмотрели метрики — тяжеловато, наш сервер перегружен. Перегружен он потому, что отдаёт данные со скоростью клиента; поэтому далёкие клиенты в Мексике, которых оказалось неожиданно много, удерживают соединение открытым очень долго, и наш COM-объект отжирает нужные другим ресурсы. Снижается степень параллелизма.
Что, Павел, ты будешь делать? Ссылаться на то, что заказчики — козлы, и никогда заранее не описывают все требования?
Ну ок, эффективность фермы — никакая. Если бы у тебя был REST, то ты, не трогая само приложение, спокойно бы начал с того, что развернул бы на исходном адресе reverse proxy, чтобы разгрузить свой бэк-енд. Не написав ни строчки кода, получил бы расшивание боттлнека на порядок.
Далее, проанализировав нагрузку, поставил бы локальный прокси в Мексике, а на исходном адресе нарулил бы правило "если клиент пришёл из такого-то IP диапазона, то перенаправь его на мексиканский гейт".
Теперь у клиентов раундтрип до точки входа не 1200мс, а 80мс.
Опять — не написав ни строчки кода, ты меняешь потоки данных, и масштабируешь приложение. Более того — тебе даже не надо обзванивать мексиканских клиентов и говорить им "пожалуйста, пропишите у себя в конфиге вот такой адрес сервера".
"Нечего перенаправлять" — это не значит "не нужно перенаправлять", а "тупой RPC неспособен перенаправить".
Я на голом HTTP могу изваять geo-redundancy и load-balancing. А что ты предложишь делать с RPC?
Далее, "пусть сервер разбирается, что modified, а что нет" — ты вот сядь, напиши сигнатуру метода. Это в теории всё кажется понятным. Если своего опыта работы с сетью нету — ты уж не стесняйся, поверь более опытным товарищам.
А на практике внезапно оказывается, что запилить хотя бы треть того, что в REST идёт из коробки, в RPC руки не доходят. Влаги в организме столько нету, сколько пота потребуется пролить.
И на фоне этого делается вывод, что "ну, REST — это применение неудачной концепции за рамками изначальной задачи, бла-бла-бла". Да какая разница, кто для чего исходно предназначался. Мы же инженеры — нам важно то, какие результаты можем мы получить. Ай-яй-яй, атом изначально разлагали для получения оружия. А теперь его зачем-то применяют для выработки электричества. Ну давайте, вернёмся к основам! А электричество будем вырабатывать как деды завещали — бензиновым генератором.
Re[21]: REST: прохой\хороший интерфейс
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ладно, пора заканчивать.
Ну естественно. Как дело доходит до конкретики, фанаты RPC разбегаются из треда.
PD>Ты упорно мыслишь в психологии HTTP.
Павел. Психология тут ни при чём.
PD>Какое такое перенаправление ? В HTTP — понятно, а в вызове процедуры на сервере о чем вообще речь может идти ? Я обращаюсь к серверу, вызываю его метод. Нет тут URL (точнее, он один был при соединении) и нечего перенаправлять. Если нужно, пусть сервер и перенаправляет куда хочет — тем же способом. Клиента это не интересует.
PD>Остальное аналогично. Пусть сервер там и разбирается, что modified, а что нет.
PD>Какие метаданные и в каких хидерах ? Нет тут хидеров и нет метаданных. Есть Person, которую надо с сервера получить. Здесь столько же метаданных и хидеров, сколько в SELECT * FROM persons WHERE
PD>Сжатие — ну если нужно, пусть метод делает zip и возвращает byte[] или ByteBuffer. thrift, кстати, ByteBuffer очень любит и все двоичные данные именно в виде его и передает
Павел, вот реально у тебя всё мышление с ног на голову повёрнуто. Пятнадцать лет на этом форуме — а ничего не изменилось.
Все рассуждения — на уровне байтовых буферов. "Нету хидеров и метаданных" — ну так это как раз и плохо!!!
Поясню ещё раз, в надежде, на проблески озарения.
Когда мы проектируем протокол, у нас задача не сводится к "передаче байтов по сети". Задача формулируется в терминах прикладных сценариев.
И в REST, даже если архитектор заранее не подумал о каком-то аспекте, то можно задним числом этот аспект добавить, не ломая прямую и обратную совместимость!
Одно это ставит REST на две ступени выше, чем любой RPC.
"Пусть сервер и перенаправляет" — отлично. Вот тебе сценарий: клиент запрашивает данные у сервера. Данных — относительно много, этот наш person содержит в себе его автобиографическое видео — 1 минута, 50 мегабайт.
Вот мы запустили всё это в производство, посмотрели метрики — тяжеловато, наш сервер перегружен. Перегружен он потому, что отдаёт данные со скоростью клиента; поэтому далёкие клиенты в Мексике, которых оказалось неожиданно много, удерживают соединение открытым очень долго, и наш COM-объект отжирает нужные другим ресурсы. Снижается степень параллелизма.
Что, Павел, ты будешь делать? Ссылаться на то, что заказчики — козлы, и никогда заранее не описывают все требования?
Ну ок, эффективность фермы — никакая. Если бы у тебя был REST, то ты, не трогая само приложение, спокойно бы начал с того, что развернул бы на исходном адресе reverse proxy, чтобы разгрузить свой бэк-енд. Не написав ни строчки кода, получил бы расшивание боттлнека на порядок.
Далее, проанализировав нагрузку, поставил бы локальный прокси в Мексике, а на исходном адресе нарулил бы правило "если клиент пришёл из такого-то IP диапазона, то перенаправь его на мексиканский гейт".
Теперь у клиентов раундтрип до точки входа не 1200мс, а 80мс.
Опять — не написав ни строчки кода, ты меняешь потоки данных, и масштабируешь приложение. Более того — тебе даже не надо обзванивать мексиканских клиентов и говорить им "пожалуйста, пропишите у себя в конфиге вот такой адрес сервера".
"Нечего перенаправлять" — это не значит "не нужно перенаправлять", а "тупой RPC неспособен перенаправить".
Я на голом HTTP могу изваять geo-redundancy и load-balancing. А что ты предложишь делать с RPC?
Далее, "пусть сервер разбирается, что modified, а что нет" — ты вот сядь, напиши сигнатуру метода. Это в теории всё кажется понятным. Если своего опыта работы с сетью нету — ты уж не стесняйся, поверь более опытным товарищам.
А на практике внезапно оказывается, что запилить хотя бы треть того, что в REST идёт из коробки, в RPC руки не доходят. Влаги в организме столько нету, сколько пота потребуется пролить.
Для начала тебе придётся сделать тип данных вариативным — чтобы можно было вернуть как person, так и "ничего".
Далее, тебе придётся добавить в person какой-то индикатор, который ты потом будешь использовать в условных запросах. И не только в person, а во все типы, которые ты собрался тащить к себе через RPC.
Сжатие — то же самое. Один сервер умеет сжатие, а другой — нет. То есть мало того, что клиент не обязан указывать свои предпочтения; сервер ещё и не обязан их выполнять.
То есть мы не можем просто выставить два метода GetPerson и GetPersonCompressed. У нас один метод возвращает либо person, либо "байтовый поток".
Что у нас со штатным маршалингом? Вкорзинку?
Ок, остаётся простой способ — делать свой велосипед поверх RPC. То есть приделываем метаданные — те самые "хидеры", которых в RPC нет — дату изменения контента или его тег, признак сжатия. Тащим данные в виде байтового потока.
Вытащив их в клиента, вручную выполняем маршаллинг в зависимости от того, какие флаги приехали в метаданных.
А потом заказчик говорит "а что, вы не можете сделать докачку частично загруженного person при обрыве соединения?", и ты начинаешь всё переписывать сначала — потому что теперь тебе нужен какой-то способ передать в GetPerson информацию о том, что "треть данных у меня уже есть, давай остальное", и опять расширять набор флагов. Потому что сервер по-прежнему не обязан уметь частичную закачку, и он может в ответ на такой запрос передать цельного пёрсона.
И на фоне этого делается вывод, что "ну, REST — это применение неудачной концепции за рамками изначальной задачи, бла-бла-бла". Да какая разница, кто для чего исходно предназначался. Мы же инженеры — нам важно то, какие результаты можем мы получить. Ай-яй-яй, атом изначально разлагали для получения оружия. А теперь его зачем-то применяют для выработки электричества. Ну давайте, вернёмся к основам! А электричество будем вырабатывать как деды завещали — бензиновым генератором.
PD>Ладно, пора заканчивать.
Ну естественно. Как дело доходит до конкретики, фанаты RPC разбегаются из треда.
PD>Ты упорно мыслишь в психологии HTTP.
Павел. Психология тут ни при чём.
PD>Какое такое перенаправление ? В HTTP — понятно, а в вызове процедуры на сервере о чем вообще речь может идти ? Я обращаюсь к серверу, вызываю его метод. Нет тут URL (точнее, он один был при соединении) и нечего перенаправлять. Если нужно, пусть сервер и перенаправляет куда хочет — тем же способом. Клиента это не интересует.
PD>Остальное аналогично. Пусть сервер там и разбирается, что modified, а что нет.
PD>Какие метаданные и в каких хидерах ? Нет тут хидеров и нет метаданных. Есть Person, которую надо с сервера получить. Здесь столько же метаданных и хидеров, сколько в SELECT * FROM persons WHERE
PD>Сжатие — ну если нужно, пусть метод делает zip и возвращает byte[] или ByteBuffer. thrift, кстати, ByteBuffer очень любит и все двоичные данные именно в виде его и передает
Павел, вот реально у тебя всё мышление с ног на голову повёрнуто. Пятнадцать лет на этом форуме — а ничего не изменилось.
Все рассуждения — на уровне байтовых буферов. "Нету хидеров и метаданных" — ну так это как раз и плохо!!!
Поясню ещё раз, в надежде, на проблески озарения.
Когда мы проектируем протокол, у нас задача не сводится к "передаче байтов по сети". Задача формулируется в терминах прикладных сценариев.
И в REST, даже если архитектор заранее не подумал о каком-то аспекте, то можно задним числом этот аспект добавить, не ломая прямую и обратную совместимость!
Одно это ставит REST на две ступени выше, чем любой RPC.
"Пусть сервер и перенаправляет" — отлично. Вот тебе сценарий: клиент запрашивает данные у сервера. Данных — относительно много, этот наш person содержит в себе его автобиографическое видео — 1 минута, 50 мегабайт.
Вот мы запустили всё это в производство, посмотрели метрики — тяжеловато, наш сервер перегружен. Перегружен он потому, что отдаёт данные со скоростью клиента; поэтому далёкие клиенты в Мексике, которых оказалось неожиданно много, удерживают соединение открытым очень долго, и наш COM-объект отжирает нужные другим ресурсы. Снижается степень параллелизма.
Что, Павел, ты будешь делать? Ссылаться на то, что заказчики — козлы, и никогда заранее не описывают все требования?
Ну ок, эффективность фермы — никакая. Если бы у тебя был REST, то ты, не трогая само приложение, спокойно бы начал с того, что развернул бы на исходном адресе reverse proxy, чтобы разгрузить свой бэк-енд. Не написав ни строчки кода, получил бы расшивание боттлнека на порядок.
Далее, проанализировав нагрузку, поставил бы локальный прокси в Мексике, а на исходном адресе нарулил бы правило "если клиент пришёл из такого-то IP диапазона, то перенаправь его на мексиканский гейт".
Теперь у клиентов раундтрип до точки входа не 1200мс, а 80мс.
Опять — не написав ни строчки кода, ты меняешь потоки данных, и масштабируешь приложение. Более того — тебе даже не надо обзванивать мексиканских клиентов и говорить им "пожалуйста, пропишите у себя в конфиге вот такой адрес сервера".
"Нечего перенаправлять" — это не значит "не нужно перенаправлять", а "тупой RPC неспособен перенаправить".
Я на голом HTTP могу изваять geo-redundancy и load-balancing. А что ты предложишь делать с RPC?
Далее, "пусть сервер разбирается, что modified, а что нет" — ты вот сядь, напиши сигнатуру метода. Это в теории всё кажется понятным. Если своего опыта работы с сетью нету — ты уж не стесняйся, поверь более опытным товарищам.
А на практике внезапно оказывается, что запилить хотя бы треть того, что в REST идёт из коробки, в RPC руки не доходят. Влаги в организме столько нету, сколько пота потребуется пролить.
Для начала тебе придётся сделать тип данных вариативным — чтобы можно было вернуть как person, так и "ничего".
Далее, тебе придётся добавить в person какой-то индикатор, который ты потом будешь использовать в условных запросах. И не только в person, а во все типы, которые ты собрался тащить к себе через RPC.
Сжатие — то же самое. Один сервер умеет сжатие, а другой — нет. То есть мало того, что клиент не обязан указывать свои предпочтения; сервер ещё и не обязан их выполнять.
То есть мы не можем просто выставить два метода GetPerson и GetPersonCompressed. У нас один метод возвращает либо person, либо "байтовый поток".
Что у нас со штатным маршалингом? Вкорзинку?
Ок, остаётся простой способ — делать свой велосипед поверх RPC. То есть приделываем метаданные — те самые "хидеры", которых в RPC нет — дату изменения контента или его тег, признак сжатия. Тащим данные в виде байтового потока.
Вытащив их в клиента, вручную выполняем маршаллинг в зависимости от того, какие флаги приехали в метаданных.
А потом заказчик говорит "а что, вы не можете сделать докачку частично загруженного person при обрыве соединения?", и ты начинаешь всё переписывать сначала — потому что теперь тебе нужен какой-то способ передать в GetPerson информацию о том, что "треть данных у меня уже есть, давай остальное", и опять расширять набор флагов. Потому что сервер по-прежнему не обязан уметь частичную закачку, и он может в ответ на такой запрос передать цельного пёрсона.
И на фоне этого делается вывод, что "ну, REST — это применение неудачной концепции за рамками изначальной задачи, бла-бла-бла". Да какая разница, кто для чего исходно предназначался. Мы же инженеры — нам важно то, какие результаты можем мы получить. Ай-яй-яй, атом изначально разлагали для получения оружия. А теперь его зачем-то применяют для выработки электричества. Ну давайте, вернёмся к основам! А электричество будем вырабатывать как деды завещали — бензиновым генератором.