Что не так с этой асинхронной HystrixCommand?

Мне нужно время от времени отправлять уведомления, я выполняю эту задачу асинхронно. Я использую HystrixCommand, как показано ниже, для выполнения асинхронного вызова RestTemplate, который не работает:

@HystrixCommand
    public Future<String> notify(final Query query) {
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                String result = null;
                try {
                    ResponseEntity<HashMap> restExchange = restTemplate.exchange(url,
                            HttpMethod.POST,
                            new HttpEntity<String>(mapper.writeValueAsString(queryMap), httpHeaders),
                            HashMap.class);
                    LOGGER.info("Response code from " + url + " = " + restExchange.getStatusCodeValue());
                    result = ""+ restExchange.getStatusCodeValue();
                } catch(Exception e) {
                    LOGGER.error("Exception while sending notification! Message = " + e.getMessage(), e);
                }
                return result;
            }
        };
    }

Это то, что я пытался сделать ранее (что тоже не сработало):

@HystrixCommand
    public String notify(final Query query) {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    ResponseEntity<HashMap> restExchange = restTemplate.exchange(url, HttpMethod.POST,
                            new HttpEntity<String>(mapper.writeValueAsString(queryMap), httpHeaders), HashMap.class);
                    LOGGER.info("Response code from " + url + " = " + restExchange.getStatusCodeValue());

                } catch (Exception e) {
                    LOGGER.error("Exception while sending notification! Message = " + e.getMessage(), e);
                }

            }
        }).start();
    }  

PS: Причина добавления сыщика в теги заключается в том, что выполнение этого в новом потоке не распространяет заголовки (багаж-*), поэтому попробуйте это, надеясь, что команда Hystrix добьется цели.


person Abhilash Gopal    schedule 14.06.2017    source источник
comment
Можете ли вы вставить то, что вы изначально пытались сделать?   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
Я думаю, вы можете неправильно использовать будущее, разве вам не нужно выполнять его явно? Не так много опыта работы с Future, обычно используют CompletableFuture.   -  person Jeff    schedule 14.06.2017
comment
@MarcinGrzejszczak Весь метод был завернут в исполняемый файл, и я вызывал start() на месте. Никогда не работал, я отредактирую вопрос с более ранним кодом, тем временем вы видите что-нибудь, что я могу сделать для выполнения асинхронной HystrixCommand, элемент управления даже не входит в метод вызова.   -  person Abhilash Gopal    schedule 14.06.2017
comment
Вы знаете, что это должно быть завернуто в TraceRunnable ?   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
Также я предполагаю, что RestTemplate - это bean-компонент? Этот пример настолько зависит от потока, что без его отладки я, к сожалению, мало что могу сказать. Возможно, это связано с github.com/spring-cloud/spring-cloud- сыщик/вопросы/612 ?   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
@Jeff Нет, Spring Cloud использует Hystrix-javanica, которая заботится о выполнении HystrixCommand, будь то выполнение, очередь и т. д.   -  person Abhilash Gopal    schedule 14.06.2017
comment
I had the entire method wrapped in a runnable and was calling start() ‹-- Я имею в виду это.   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
@MarcinGrzejszczak Нет, я ничего не знаю о TraceRunnable. Да, RestTemplate — это компонент LoadBalanced, который подключается автоматически. Я отредактировал вопрос, чтобы показать вам мой предыдущий код.   -  person Abhilash Gopal    schedule 14.06.2017
comment
Spring не выполняет HystrixCommand, он упаковывает его при выполнении метода.   -  person Jeff    schedule 14.06.2017
comment
Это написано в документации - cloud.spring.io/ весеннее облако-сыщик/   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
@MarcinGrzejszczak Спасибо за ссылку на документы, просмотрев ее. Я могу распространять заголовки багажа во всех моих других вызовах, я уверен, что они будут распространены, если я смогу выполнить эту асинхронную команду Hystrix, проблема в том, что элемент управления никогда не достигает кода внутри асинхронной команды HystrixCommand.   -  person Abhilash Gopal    schedule 14.06.2017
comment
@MarcinGrzejszczak Просто к вашему сведению, заголовки распространяются, когда я использую простой инжектированный Spring ThreadPool TaskExecutor без необходимости оборачивать его в какой-либо Traceable. Я предполагаю, что HystrixCOncurrencyStrategy автоматически распространяет эти заголовки без вмешательства Sleuth?   -  person Abhilash Gopal    schedule 14.06.2017
comment
Да, это то, что делает стратегия. Возможно, при выполнении комбинации, которую вы имеете в этом примере, мы неправильно делегируем вызов в стратегии, и это не работает нормально.   -  person Marcin Grzejszczak    schedule 14.06.2017
comment
@MarcinGrzejszczak Обертывание с помощью TraceRunnable сработало для меня, спасибо за указатель. Если вы можете указать это в ответе, я приму это. Хотя это и не связано с сыщиком, у вас есть идеи, почему мой первоначальный код в @AsyncResult никогда не выполнялся?   -  person Abhilash Gopal    schedule 14.06.2017
comment
@Jeff Spring не может выполнять его напрямую, за выполнение отвечает: github.com/Netflix/Hystrix/tree/master/hystrix-contrib/   -  person ChrisOdney    schedule 14.06.2017


Ответы (2)


Вызывается ли метод notify из метода того же класса? Если это так, попробуйте вызвать метод уведомления непосредственно из другого класса, где класс, охватывающий метод уведомления, внедряется как зависимость.

В общем, попробуйте сделать так:

введите здесь описание изображения

Вместо этого:

введите здесь описание изображения

person ChrisOdney    schedule 15.06.2017

При использовании Runnable вы должны обернуть их в представление трассировки. то есть TraceRunnable. Это есть в документации — http://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html#_runnable_and_callable .

Что касается того, почему материал Hystrix не работает - скорее всего, это связано с https://github.com/spring-cloud/spring-cloud-sleuth/issues/612.

person Marcin Grzejszczak    schedule 14.06.2017
comment
@marcun Подтвердил, что проблема не в сыщике, я удалил зависимость сыщика из службы, но элемент управления все равно не входит в метод «вызов» AsyncResult . - person Abhilash Gopal; 14.06.2017