среда, 14 августа 2013 г.

Подготовка релиза сервисной шины предприятия на нашем проекте

На своем текущем месте работы Суровый занимается интеграцией внедряемой CRM с другими информационными системами телеком-оператора: биллингами, техническим учетом, ERP, активацией, Ordering Management System (OMS) и т.д. Сейчас у нас подключено к сервисной шине четыре макрорегиональных филиала, при этом стоит отметить, что в каждом макрорегиональном филиале свой IT-ландшафт, что делает проект еще более интересным.

О чем хочется рассказать в данной заметке. Нам на проекте необходимо обеспечить работоспособность конкретного подмножества сервисов на шине для одного основного клиента (CRM), при этом у нас есть временной лаг между разработкой клиента (CRM), разработкой сервисной шины и разработкой (внедрением) внешних систем - поставщиков сервисов. При этом нам нужно иметь гарантированно стабильный и готовый для развертывания код шины.

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

При этом у нашего проекта есть следующие особенности.

1. Небольшая команда разработки сервисной шины - порядка 5-ти человек.

2. Несмотря на скромный размер команды за год разработано и внедрено 13 сервисов и 46 экземпляров адаптеров к информационным системам. Сложность логики сервисов весьма разнообразна - от простого оборачивания вызова хранимой процедуры в SOAP, до сложной оркестровки с использованием компонента Split-Join.

3. В качестве системы контроля версий исходного кода используется SVN.

4. Технологическая платформа - Oracle Service Bus - не поддерживает "из коробки" версионирование сервисов, т.е. мы не можем иметь в продуктиве несколько версий одного и того же сервиса одновременно. С учетом того, что у нас всего один основной клиент и с его разработчиками всегда можно договориться, то мы вполне можем обойтись без данной возможности.

5. Разработка ведется по гибкой методологии. К сожалению это иногда приводит к непродуманности технических решений и несогласованности изменений, особенно с поставщиками внешних систем.



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

1. Разработка ведется в транке (trunk), для каждого релиза из транка вместе с кодом CRM отцепляется ветка, в которой есть код шины, затем этот код стабилизируется. При этом шину из ветки можно собрать как целиком (и она должна быть стабильна и полностью поддерживаема внешними системами и CRM), так и частично - просто перечисляются требующие обновления сервисы и адаптеры в файле свойств сборки шины. Нет смысла собирать шину целиком, это занимает слишком много времени - порядка нескольких часов, когда обновить в текущем релизе нужно всего один - два сервиса.

2. Синхронизация разработки и внедрения шины и CRM обеспечивается следующим образом.

  • CRM берет в работу задачу, требующую интеграции/доработки интеграции, только если обновленные интерфейсы
    соответствующих сервисов разработаны на шине.

  • Изменение активируется в CRM, только если соответствующий сервис разработан на шине и протестирован.

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

  • Стоит отметить, что мы используем на шине общие для всех сервисов компоненты - каноническую модель данных и таблицу маршрутизации. При этом в нашем проекте CRM сразу вызывает канонические сервисы непосредственно, а не через адаптер. Таким образом возможна ситуация, при которой изменение в канонической модели изменяет интерфейс сервиса и обновленный интерфейс еще не поддерживается клиентом. В данном случае мы перед релизом просим команду CRM перегенерировать код клиентов веб-сервисов. До сих пор данный подход не приводил к появлению проблем, наоборот проблемы были в случае необновления соответствующего WSDL на шине.

3. Синхронизация разработки и внедрения шины и внешних систем обеспечивается следующим образом.

  • Команда шины берет в работу задачу по доработке адаптера только в том случае, если соответствующий сервис готов
    и предоставляется тестовым/разработческим стендом внешней системы (это может быть пакет СУБД Oracle, веб-сервис, REST-сервис и т.д.)

  • По-умолчанию считается, что к моменту развертывания и использования адаптера на продуктивной инсталляции шины,
    соответствующая версия сервиса будет предоставляться продуктивным экземпляром внешней системы. Опыт подсказывает,
    что в 90% случаев это так. Есть сервисы, разработка которых ведется месяцами (например сервис проверки технической возможности при подключении услуги, сервис непосредственного подключения услуги (fulfillment) и т.д., но к моменту внедрения разработка таких сервисов и со стороны шины, и со стороны внешней системы завершается и их можно безболезненно внедрять). Если же некоторые изменения были сделаны, но стало видно, что внешняя система их не поддерживает и будет поддерживать только в будущем (если вообще будет), то такие изменения переносятся
    из транка в отдельную ветку. В данной ветке можно сделать тег, чтобы в последующем было проще найти отложенное изменение. Пример последнего случая: доработка получения информации из внешней системы с помощью хранимой процедуры Oracle выполненная в феврале, при этом сама хранимая процедура до сих пор не развернута на продуктиве.

4. На шине возможна и всегда ведется опережающая разработка новых сервисов, т.е. сервисов, которые еще не используются в CRM и предоставление которых в продуктиве внешних систем - поставщиков сервисов - задерживается. При этом в CRM уже могут начать разработку клиента к такому сервису. В данном случае разработанный клиент в CRM не активируется, а сервис на шине не развертывается. При таком подходе нужно стараться ослаблять связь между сервисами на шине, чтобы активация одного сервиса не требовала установки другого - еще не готового. При использовании Oracle Service Bus мы используем следующий подход: проксирующий сервис всегда вызывает адаптер посредством динамической маршрутизации даже если гарантированно, что данный адаптер единственный.

5. Так как мы обновляем сервисную шину на продуктиве частями, то должна быть четкая процедура описания изменений, т.е. ведения некоего Change Log'а, чтобы всегда можно было сказать какие именно сервисы и адаптеры на шине требуют обновления в текущем релизе. При этом нужно понимать, что обновление шины по частям добавляет риски - можно обновить не все нужные сервисы и тем более адаптеры. В нашем случае такой лог состоит из списка историй, в каждую из которых, предполагающую интеграцию, в системе управления задачами (в нашем случае - JIRA) прикреплена соответствующая задача. По описанию задачи видно, какие сервисы и адаптеры были изменены и протестированы ли данные изменения. Если какие-то изменения на шине не протестированы, то релиз считается недотестированным и внедряться не должен. Изменения на шине равноправны изменениям в CRM.

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

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

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

Понравилось сообщение - подпишитесь на блог и Twitter

7 комментариев:

Анонимный комментирует...

Павел, добрый день. Вопрос не совсем по теме, но не могли бы вы рассказать как вы контролируете целостность данных на источнике данных и на потребителе. Т.е. как можно быть уверенным, что данные у потребителя полностью соответствуют (конечно с определенной задержкой) данным поставщика?
По работе занимаемся интеграцией на основе сервисной шины. Отвечаем только за слой интеграции. Процедуры на БД источнике и приемнике, в простейшем случае, просто оборачиваем в SOAP. Возникают ситуации (например, в результате ошибок в реализации или логики этих процедур), когда данные начинают расходится. Нормального инструмента мониторинга таких проблем у нас пока не реализовано. Конечно в случае явных ошибок (нет связи с БД или deadlock) у нас данные автоматом повторяются. Но вот более тонкие проблемы, отследить не можем и узнаем уже от заказчика, когда каких-то данных не хватает.
Возникают ли у вас подобные проблемы и как бы их отлавливаете?

Unknown комментирует...

Здравствуйте.

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

Unknown комментирует...

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

Анонимный комментирует...

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

Unknown комментирует...

У нас львиная доля рассогласований связана с качеством исходных данных. Т.е. банально у разных пользователей даже одной и той же версии системы свои политики по заполнению полей. Какие-то поля заполняются, другие - нет. А при этом в системе-приемнике незаполненные поля являются обязательными и она не может принять такое сообщение. Вот решение данной проблемы никак не автоматизируешь кроме введения каких-то политик уровня предприятия или хотя бы подразделения по обеспечению качества данных, но это уже не наш уровень.

Igorok комментирует...

Ещё был бы очень благодарен Вам, если бы Вы помогли мне понять некоторые вещи по почте, аське или скайпу. Моя почта tanderbold@rambler.ru, аська 458002964.

Unknown комментирует...

Здравствуйте, можете писать на samolisov@gmail.com или стучаться в скайп samolisov.

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!