Pull to refresh
1
0
Григорий Добряков @dgstudio

User

Send message
Эй-эй, это что за хренотень? :)

find_defects();

if (defects_found()) {

}


У вас что, функция хранит результат своей работы в каком-то внешнем состоянии? Может быть, вы ещё Stateful-код пишете и глобальными переменными балуетесь? А с параллелизацией никогда не имели дел?

Функция, выполняющая работу, должна возвращать инкапсулированный объект, из которого можно достать результат операции. Должно быть так:

# псевдокод
if ( find_defects().getResult().isSuccess() ) {… }

Или хотя бы так:

# псевдокод
try { find_defects(); } catch Exception $e {… }

А совсем правильно — так:

# псевдокод:
successManager.subscribe('find_defects.results.success');
failManager.subscribe('find_defects.results.fail');

function find_defects() {
# do some work…
dispatch(results)
}

Так оно будет правильно работать в распределённых системах.
А, Мосигра, привет конкурентам.

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

В то время как в зарубежной практике тема вполне популярная, примеры [раз], [два], под тем же соусом — чем больше человечной коммуникации — тем успешнее бизнес.

Ах, SOA и REST — мои любимые инструменты :) 975 ресурсов — респект парням!

Очень любопытно, почему отказавшись от концепции прямых вызовов RPC, они не перешли на очереди. Так как в отличие от REST (я имею в виду традиционно over http — ожидающего ответ в цикле запроса), очереди позволили бы отправлять ответ асинхронно, добавив ещё одну нотку к отказоустойчивости.
Пффф… Маркетинг буллшит.

Когда я работал руководителем в одной русской CMS, мы такое тоннами писали.
Когда я работал руководителем в веб-студии, мы писали ровно то же самое, но наоборот, про самописный продукт.
А когда я работал в энтерпрайзе, и мы выбирали между коробкой или наймом команды, на нас лилось такое с обоих строн.

Хотите правды? Вообще по**й, самописный софт или коробочный, — если его пишут и внедряют дураки, которыми руководят м**аки, то жопа будет абсолютно одинаковая в обоих случаях.
Пытаться идти в IT-шные компании через резюме и HR — это тупиковый путь :) Вот недавно я приехал поговорить на топовую позицию (типа начальник всея девелопмента) к ребятам в Питере — так они не то чтобы по ссылкам на лэндинг не ходили, они вообще не имели никакого понятия о моём карьерном опыте, не читали мой профессиональный блог, не искали код моих проектов, не изучали посты в соцсетях. Они моё резюме в первый раз там и увидели — а оно большое, за 17 лет всякого набралось… Сидели, читали, угукали.

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

В общем, фигня это всё про резюме и HR :) Их надо годами учить, чтобы они действительно разбирались в теме. Хотите нормально трудоустроиться — контачьте напрямую с целевыми людьми, тогда и никакого резюме не понадобится.

соотношение сигнал-шум в вашей цифровой жизни тут же катастрофически увеличивается
Гуманитарий статью писал? :) Сигнал-шум это дробь: «сигнал / шум» (сигнал разделить на шум). Когда оно увеличивается — это хорошо, это значит что полезного сигнала стало больше. А когда становится больше шума, то оно уменьшается.

Если хотели литературно выразиться в переносном смысле, можно было написать «катастрофически ухудшается».
Почему Redis, а не Rabbit?
Rabbit как-то более предназначен для каналов (очередей) сообщений, да и с роутингом значительно интереснее.
Не сочтите за троллинг, я сам занимаюсь виртуализацией и сервисной архитектурой. Но мой самый больной вопрос: а зачем это всё, если ресурсы железа ограничены? Вы всё равно не сможете запустить больше воркеров (инстансов?) приложения, чем допустимо в рамках суммарного железа этого кластера. Вы не сможете сказать приложению «иди и запустись где-нибудь, где есть 512Mb оперативной памяти», если этой свободной оперативной памяти не осталось на железных машинах.

Популярные аргументы виртуализаторов о том, что дескать «если у нас возрастёт нагрузка — мы стартуем ещё 100500 воркеров и обслужим её» разбиваются элементарным утверждением, что достаточно держать постоянно запущенными 100500 воркеров — в режиме ожидания они всё равно практически не жрут ни память, ни CPU, ни электропитание. А в случае хостинга на арендованном железе, как правило, цена за него — фиксированная независимо от нагрузки.

Что полезного конкретно вам дала описанная виртуализация?
Респект! Но почему бы не искать прямо по EAV-модели в SQL? Это же очень легко делается, даже по произвольному количеству атрибутов. Взяли первый атрибут, по таблице связей entity_id — value_id получили множество товаров (entity_ids), далее взяли второй атрибут и сократили это множество, далее взяли следующий атрибут… и так далее.

По каким причинам этот подход был отвергнут?
Респект! Я делал похожую штуку, на несколько ином наборе инструментов.
Если позволите, несколько вопросов :)

— какой у вас роутинг в раббите? (директ, топик, фанаут?)
— как оно переживает деплой новой версии программного кода?
— что происходит в системе, если актор не справляется с обработкой сообщения и падает?
— данные о пользователях отдаются по явному запросу, или доставляются потребителям так же через очереди?
О, ещё немного и люди вспомнят про переписку в FIDO :)
Отличная статья, но я огорчён тем что в ней нет даже попытки представить проектирование API как полностью идемпотентной системы — и соответственно, полностью иммутабельных данных.

Например, в идемпотентной системе не будет операции Edit Item — вместо неё будет каждый раз Create Item с новой версией содержимого. Тем самым мы «из коробки» получили бы историю версий (черновиков) документа, возврат к любой из них, статистику и т.д., и убрали бы риск ошибочной перезаписи документа. // Если кому-то это кажется экзотикой — знайте, что банальный Wordpress ведёт себя именно так.

В идемпотентной системе Status был бы не атрибутом документа, а отдельной сущностью, по которой предоставлялся бы отдельный «коробочный» CRUD-интерфейс (и далее либо document has status_id, либо status has document_id). Этот подход:
— решил бы задачи однозначности состояния документа (перевод в статус возможен только однократно, даже если кто-то по ошибке пошлёт несколько запросов),
— предоставил бы возможность указывать статусы для разных версий (черновиков) документов,
— возможность гибкого разграничения прав доступа для клиентов API (кто-то может только редактировать документ, а кто-то другой может задавать его статус),
— и «из коробки» дал бы возможность сохранять timestamp перехода в тот или иной статус.

То есть уже на втором пункте авторы вместо «придумайте сущность для каждого состояния» сразу идут по пути неиммутабельной системы, что уже неправильно.
Когда же Эми научится предоставлять секс по телефону?
Почему же вы не вставили в пост этот прекрасный интернет-мем? :)

image
Ребята, а нельзя было очередь перед демоном поставить? Ну повисели бы запросы в очереди пару миллисекунд, пока демон рестартует. Зачем так сложно делать то?
У вас по ТЗ сразу получился сервер задач, а не сервер очередей сообщений. Ключевое отличие как раз в том, с чего у вас начинается первая картинка — существование такого признака как «время активации». Отсюда и причины некоторых других различий.
А в целом всё круто, респект. Особенно респект за каскадные очереди, мы тоже голову сломали в своё время, пока додумались.
Респект.
Тоже пишу про SOA, но не на хабре, а в личном блоге.
На мой взгляд, осталась нераскрытой тема межсервисной коммуникации.
А это очень важно, например вопрос — синхронная она или нет. Должен ли отправляющий сервис ждать, пока получатель получит и обработает вызов. Может ли один бизнес-процесс распараллелиться на несколько одновременных межсервисных взаимодействий, а потом собраться в единый результат.
Мы на этом достаточно голову поломали в своё время.
Хороший пост, спасибо!
Однако, не раскрыты темы Dead-Letter Routing (роутинг при истечении срока хранения), Headers Routing, и определение отправителя сообщения (кто нам его прислал).

З.Ы.: там в предыдущем посте развернулось обсуждение за архитектуру :)
Именно 2 НЕуспеха здесь для иллюстрации ситуации, когда на одном неуспехе нельзя сделать окончательный вывод. Например, если у пользователя 99 рублей на счету, то можно его кредитовать на рубль (или уйти в минус на рубль), но всё равно предоставить услугу. Два фейла — это просто пример, но его тоже нужно учесть в проектировании.

Если пойти на то, чтобы хранить состояние [между сообщениями], то вся задача теряет актуальность. Однако и здесь вопрос гораздо шире. Дело в том, что «серьёзные» распределённые системы вообще требуют иного подхода, нежели общепринятый подход к программированию как к последовательности команд в программе.

В идеале, SOA-архитектура должна быть построена без хранимых состояний и разделяемой памяти. Почему этих штук следует избегать — вопрос слишком большой, чтобы описать его в рамках топика. Говоря кратко, надо строить систему из «тупых», легко заменяемых и дублируемых кирпичиков — конечных автоматов, а функционировать они должны по принципам архитектуры потока данных.

Материалы для любопытных читателей:
— общий обзор habrahabr.ru/post/122479/
— для самостоятельного гугления: event-driven development, паттерн observer-notifier, SOA-архитектура, архитектура потока данных, основы философии erlang, конечные автоматы, принципы фон-неймана.

Если мы разрешаем себе хранение состояний, тогда (казалось бы) вся задача теряет актуальность: храним промежуточные результаты в редисе и не паримся. Однако я могу совершенно точно сказать, что нельзя иметь хранимые состояния «на входе» в систему, где любой неавторизованный пользователь может нам этот редис засрать, навалив кучу (миллионы) входящих запросов. Это компромисс, на который надо идти очень осторожно.

Information

Rating
Does not participate
Location
Санкт-Петербург и область, Россия
Date of birth
Registered
Activity