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

Я также настоятельно рекомендую ознакомиться с книгой Enterprise Integration Patterns (Addison-Wesley), в которой содержится намного больше подробностей о различных шаблонах программирования, чем вам может понадобиться рассмотреть в данной области.

Сервисы как машины состояний

Если вы решите стать мастером REST-технологии или остановите свой выбор на таком механизме на основе RPC, как SOAP, в действие вступит понятие сервиса как машины состояния. Раньше мы уже достаточно (возможно, даже чрезмерно) наговорились о сервисах, выстраиваемых вокруг ограниченных контекстов. Наши потребительские микросервисы содержат всю логику, связанную с поведением в конкретном контексте.

Когда потребитель хочет внести изменения в данные о клиенте, он отправляет соответствующий запрос в сервис клиентов. Этот сервис, основываясь на своей логике, принимает решение, принять этот запрос или нет. Наш сервис клиентов сам контролирует все события жизненного цикла, связанные с клиентом. Хотелось бы избежать создания немых, безжизненных сервисов, представляющих собой практически простые CRUD-оболочки. Если решение о том, какие изменения разрешено вносить в данные о клиенте, будет вытекать из самого сервиса клиентов, мы утратим зацепление.

Когда жизненный цикл основных понятий заданной области четко смоделирован подобным образом, достигается вполне приемлемый эффект. У нас получается не только одно место для рассмотрения несоответствий состояния (например, когда кто-то пытается обновить данные об уже удаленном клиенте), но также место для придания поведения на основе таких изменений состояния.

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

Реактивные расширения

Реактивные расширения (reactive extensions, часто сокращается до Rx) представляют собой механизм компоновки результатов нескольких вызовов и запуска операций по их обработке. Сами вызовы могут быть как блокирующими, так неблокирующими. В основном Rx меняют порядок традиционных потоков. Вместо запрашивания каких-либо данных с последующим выполнением в отношении этих данных каких-либо операций изучается исход операции (или набора операций) и происходит реагирование на какие-либо изменения. Некоторые реализации Rx позволяют выполнять какие-либо функции над этими наблюдаемыми результатами, например в RxJava допускается использование таких традиционных функций, как map или filter.

Различные Rx-реализации очень неплохо прижились в распределенных системах. Они позволяют абстрагироваться от подробностей того, каким образом осуществляются вызовы, и намного проще рассуждать о происходящем. Наблюдается результат вызова какого-либо нижестоящего сервиса. И тут все равно, блокирующий это вызов или нет, ожидается лишь ответ, на который происходит какая-либо реакция. Вся красота в том, что можно компоновать результаты нескольких вызовов, существенно упрощая тем самым обработку конкурирующих вызовов к нижестоящим сервисам.

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

DRY и риски повторного использования кода в мире микросервисов

Одним из часто употребляемых акронимов является DRY: don’t repeat yourself — «не повторяйтесь». Хотя это определение зачастую упрощенно рассматривается как попытка избежать использования продублированного кода, более точное значение DRY заключается в стремлении избежать продублированности поведения и осведомленности нашей системы. В целом это весьма разумный совет. Наличие большого количества строк кода, выполняющих одно и то же, делает объем исходного кода больше необходимого, затрудняя тем самым его осмысление. При желании изменить поведение, продублированное во многих частях системы, совсем не трудно забыть о каких-либо местах, в которые нужно вносить изменения, что может привести к появлению ошибок. Поэтому в целом придерживаться DRY-принципа все же стоит.

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги