Pull to refresh

Реализация proxy-сервера на интеграционной шине

Reading time4 min
Views2.7K
Описаны предпосылки создания proxy-cache на уровне ESB, а также и причины перехода с одной его версии на другую. После внедрения решения в одном из крупных банков, оно было оставлено, и в данный момент его судьба до конца не известна. Статья имеет целью поделиться образом мыслей и возможностями, которые предоставляет предложенное решение.

Контекст


Прикладной бизнес-процесс помещает в очередь request_queue Tibco EMS запрос в каноническом формате:

<request>
    <service>service_name</service>
    <client>client_id</client>
    <requestData>request_data</requestData >
    <replyTo>response_queue</replyTo>
</request>

  • service_name – имя сервиса, реализуемого одной из ИС
  • client_id – идентификатор клиента, для которого происходит обращение
  • request_data – тело запроса к сервису
  • response_queue – имя очереди для асинхронного ответа

Интеграционный процесс Tibco BW анализирует service_name и перенаправляет запрос соответствующему сервису. Ответ сервиса помещается в очередь response_queue, откуда он извлекается прикладным процессом:

<response>
    <service>service_name</service>
    <client>client_id</client>
    <responseData>response_data</responseData >
</response> 

  • response_data – тело ответа

Некоторые сервисы отвечают несколько секунд, некоторые – десятки секунд. Это слишком долго для прикладного процесса. Особенно, если учесть, что один и тот же запрос может повториться тем же или другим прикладным процессом.

Это логичные предпосылки для создания proxy-cache.

Первая версия и предпосылки


Вариант proxy был реализован. Он имел рад особенностей, которые стали предпосылками для дальнейших доработок:

1: Хранение бизнес-данных


Ответ каждого сервиса хранился в отдельной таблице БД как бизнес-данные. Так перечень идентификаторов клиента в разных системах хранился в таблице со столбцами:

  • клиент
  • система
  • ид.
  • дата обновления

2: Логика на уровне БД


Ответ каждого сервиса имел свою логику обслуживания на уровне БД. Так идентификаторы клиента разбирались из XML ответа, снабжались датой обновления и сохранялись в БД.

3: Обращение к БД из прикладных процессов


Логика прикладных процессов была связана со структурой БД. Так идентификатор клиента в системе, получался обращением к соответствующему полю таблицы.

4: Дополнительный функционал прикладных процессов


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

5: Изменения на нескольких уровнях


При потребности в кэшировании новых бизнес-данных требовались изменения на нескольких уровнях. Так добавление нового признака к идентификатору клиента в системе требовало:

  • добавления нового поля в таблицу
  • изменения логики разбора XML
  • указания имени нового столбца в связанных прикладных процессах

Задачи


Из предпосылок возник ряд задач доработки решения:

1: Упрощение


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

2: Прозрачность при подключении нового сервиса


Необходимо было сделать простыми и понятными действия для кэширования нового сервиса или модификации существующего.

3: Уменьшение связанности


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

Решение


Новая версия proxy была реализована как отдельный сервис со своей входящей очередью. Прикладной процесс помещает в очередь request_queue запрос к proxy:

<request>
    <service>proxy</service>
    <client>client_id</client>
    <requestData>
        service_name
        request_data
        live_time
    </requestData >
    <replyTo>response_queue</replyTo>
</request>

  • live_time – время актуальности ответа от сервиса service_name

На основании параметров service_name и client_id proxy производит поиск в кэше актуального ответа от сервиса service_name для клиента client_id. Если ответ есть, он отправляется в очередь response_queue как ответ сервиса service_name. Если ответа нет, формируется запрос к сервису service_name:

<request>
    <service>service_name</service>
    <client>client_id</client>
    <requestData>request_data</requestData >
    <replyTo>proxy_response_queue</replyTo>
</request>

  • proxy_response_queue – входящая очередь proxy для ответов сервисов

Когда в очередь proxy_response_queue приходит ответ, он запоминается в кэше. Затем в очередь response_queue помещается ответ proxy:
<response>
    <service>service_name</service>
    <client>client_id</client>
    <responseData>response_data</responseData >
</response>

Следует отметить, что в кэше ответы сервисов хранятся целиком, как XML.

Профит


Достоинствами решения, окупающими затраты на разработку, представляется:

1: Простота реализации


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

2: Разгрузка прикладных процессов


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

3: Инкапсуляция


Функционал proxy инкапсулирован в отдельный механизм с фиксированными точками входа. Кэш (база данных) заменяем и не имеет прямых обращений из прикладных процессов.

4: Универсальность


Изменение структуры кэшируемых ответов сервисов и потребностей в бизнес-данных не требует корректировки proxy.

5: Прозрачность


Кэширование нового ответа требует административных настроек proxy.

Спасибо за внимание!
Tags:
Hubs:
Total votes 6: ↑4 and ↓2+2
Comments6

Articles