barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

суббота, 6 апреля 2013 г.

WSO2 ESB: некорректное поведение throttle-медиатора при fault`ах конечного сервиса

Проблема:

В прокси-сервисе WSO2 ESB 4.5.1 нужно ограничить число параллельных вызовов конечного веб-сервиса. Для этого использован throttle-медиатор (используется именно медиатор, а не policy сервиса по той причине, что необходимо контролировать поведение при превышении лимита, что при использовании policy невозможно):

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="MyThrottlingProxy" ... >
<target>
<inSequence>
<throttle id="wsthrottle">
<policy>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:throttle="http://www.wso2.org/products/wso2commons/throttle">
<throttle:ThrottleAssertion>
<throttle:MaximumConcurrentAccess>1</throttle:MaximumConcurrentAccess>
</throttle:ThrottleAssertion>
</wsp:Policy>
</policy>
<onAccept>
<!-- ... -->
<send/>
</onAccept>
<onReject>
<!-- ... -->
<drop/>
</onReject>
</throttle>
</inSequence>
<outSequence>
<throttle id="wsthrottle"/>
<!-- ... -->
</outSequence>
<faultSequence>
<throttle id="wsthrottle"/>
<!-- ... -->
</faultSequence>
</target>
<!-- ... -->
</proxy>
(в данном случае число параллельных вызовов ограничено одним).
Здесь throttle-медиаторы с одинаковыми id размещены во всех трех последовательностях: in, out и fault. При выполнении медиатора в inSequence счетчик параллельно выполняющихся запросов инкрементируется и сравнивается с установленным ограничением. Если порог не превышен - запрос на конечный сервис отправляется, если превышен - сообщение отбрасывается. Выполнение throttle-медиатора в outSequence/faultSequence должно декрементировать счечик, т.к. запрос уже выполнился. Однако не тут то было. При выполнении faultSequence декремента не происходит, что приводит к тому, что упавший с ошибкой запрос с точки зрения throttle-медиатора становится бесконечно выполняющимся, что моментально парализует прокси-сервис, т.к. установлено ограничение всего в 1 параллельный запрос.
Чтобы разобраться в проблеме, пришлось включить логирование для throttle-медиатора добавлением в log4j.properties шины строчки:
log4j.logger.org.apache.synapse.mediators.throttle.ThrottleMediator=DEBUG
, а также посмотреть таки в исходники медиатора: http://www.docjar.com/html/api/org/apache/synapse/mediators/throttle/ThrottleMediator.java.html. Выяснилось, что декремент происходит, только если медиатор выполняется в последовательности обработки ответа, коей faultSequence почему-то не считается. Чтобы скорректировать поведение throttle-медиатора в faultSequence, пришлось перед ним добавить установку свойства RESPONSE в true:
<faultSequence>
<property name="RESPONSE" value="true"/>
<throttle id="wsthrottle"/>
<!-- ... -->
</faultSequence>


Комментариев нет:

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