Отражение для асинхронного API - PullRequest
0 голосов
/ 16 октября 2018

У нас есть 2 службы, давайте позвоним, затем S и G. У S есть ряд шагов, скажем, a, b, c, d, e, f, и на шаге d выполняется вызов службы G. G часто занимает многовремени (в течение нескольких минут) для обработки вызова, что приводит к множеству проблем с тайм-аутом.Чтобы решить эту проблему, мы планируем сделать API-интерфейсы G асинхронными.G имеет почти 20 API, которые нужно сделать асинхронными.У меня есть 2 вопроса при проектировании этого:

  1. идеальный способ сделать эти асинхронные - использовать тему SQS или SNS и заставить S слушать их.Но это навязчивое изменение и потребует большого количества рефакторинга кода, в этом случае разделение шагов a, b, c, d, e, f.Мы ищем что-то быстрое.Следовательно, мы планируем сохранить идентификатор запроса в некотором хранилище значений ключа и позволить API G возвращать успех после базовых проверок работоспособности и в фоновом режиме продолжать обработку запроса.Как только это будет сделано, результат обновляется в хранилище значений ключей, и тем временем G продолжает опрашивать хранилище через регулярные промежутки времени.Похоже ли это на правильный подход?

  2. Чтобы сделать API-интерфейсы G асинхронными, мы должны были бы изменить / написать целую партию кода для всех 20 API.Я думал о предоставлении одного API, который использует отражение, чтобы определить, какой метод вызывать во время выполнения.Я знаю о проблемах, связанных с отражением, таких как отсутствие обнаружения ошибок во время компиляции, сложность рефакторинга, более низкая производительность, и, поскольку мы внедряем отражение в API, обращенном к внешним клиентам, было бы много проблем с проверкой работоспособности передаваемого имени метода.Единственный плюс - это делает мой код намного чище с минимальными помехами.

Я хотел бы знать, каким должен быть мой путь для решения вышеуказанной проблемы.

Спасибо

1 Ответ

0 голосов
/ 16 октября 2018

Асинхронность API G не делает это быстрым.Это позволяет только запустить его параллельно с шагами e и f.Если эти шаги не занимают много времени, то общее время не будет значительно уменьшено.

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

Когда вы решите, что распараллеливание имеет смысл, вы можете выбрать для каждой параллельной ветви, будет ли она реализована в виде потока или асинхронноговызов процедуры (APC).Потоки легче программировать, но они занимают некоторое количество памяти (0,5-1,0 мегабайта на поток).Обычно стоит применять асинхронное программирование, если в вашем графике выполнения есть сотни и тысячи параллельных ветвей.Я не вижу такого большого параллелизма в вашей задаче, поэтому я рекомендую использовать потоки вместо асинхронных процедур.

И никогда не использовать опрос - и многопоточность, и асинхронное программирование имеют достаточно средств для реагирования на события во времени.

Что касается второго вопроса, в любом случае требуется некоторая ручная работа.Предположим, у вас есть API:

interface SyncApi {
    boolean isPositive(int v1);
    int sum(int v1, int v2);
}

, тогда вы должны написать

interface AsyncApi {
    Future<Boolean> isPositive(int v1);
    Future <Integer> sum(int v1, int v2);
}

. Вы можете создать инструмент, который создает AsyncApi.java, когда ему надоело SyncApi.java, но в любом случае вам нужноИнтерфейс AsyncApi во время компиляции, чтобы иметь возможность написать вызов для этого интерфейса.

Адаптер для создания экземпляра AsyncApi при наличии экземпляра SyncApi может быть создан во время выполнения с использованием Java Proxy механизм.

...