Проект Spring Cloud обеспечивает всестороннюю поддержку библиотеки Netflix OSS Hystrix . Ранее я писал о том, как использовать необработанную библиотеку Hystrix для переноса удаленных вызовов. Здесь я расскажу, как можно использовать Hystrix с Spring Cloud.
основы
На самом деле в этом нет ничего особенного, концепции просто переносятся с определенными улучшениями, специфичными для загрузки Spring. Рассмотрим простую команду Hystrix, которая объединяет вызов к удаленной службе:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
 | 
import agg.samples.domain.Message;import agg.samples.domain.MessageAcknowledgement;import agg.samples.feign.RemoteServiceClient;import com.netflix.hystrix.HystrixCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class RemoteMessageClientCommand extends HystrixCommand<MessageAcknowledgement> {    private static final String COMMAND_GROUP = "demo";    private static final Logger logger = LoggerFactory.getLogger(RemoteMessageClientCommand.class);    private final RemoteServiceClient remoteServiceClient;    private final Message message;    public RemoteMessageClientCommand(RemoteServiceClient remoteServiceClient, Message message) {        super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP));        this.remoteServiceClient = remoteServiceClient;        this.message = message;    }    @Override    protected MessageAcknowledgement run() throws Exception {        logger.info("About to make Remote Call");        return this.remoteServiceClient.sendMessage(this.message);    }    @Override    protected MessageAcknowledgement getFallback() {        return new MessageAcknowledgement(message.getId(), message.getPayload(), "Fallback message");    }} | 
Здесь нет связанных с Spring классов, и эту команду можно использовать непосредственно в проекте на основе Spring, например, в контроллере следующим образом:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
@RestControllerpublic class RemoteCallDirectCommandController {    @Autowired    private RemoteServiceClient remoteServiceClient;    @RequestMapping("/messageDirectCommand")    public MessageAcknowledgement sendMessage(Message message) {        RemoteMessageClientCommand remoteCallCommand = new RemoteMessageClientCommand(remoteServiceClient, message);        return remoteCallCommand.execute();    }} | 
Настройка поведения команды Hystrix обычно выполняется через свойства NetflixOSS Archaius , однако Spring Cloud предоставляет мост для отображения свойств, определенных в Spring, в виде свойств Archaius, это означает, что я могу определить свои свойства, используя специфические для Spring файлы конфигурации, и они будет видно при настройке поведения команды.
Так что, если раньше вы настраивали, скажем, поведение HelloWorldCommand, используя свойства Archaius, которые выглядят так:
| 
 1 
2 
3 
4 
5 
6 
 | 
hystrix.command.HelloWorldCommand.metrics.rollingStats.timeInMilliseconds=10000hystrix.command.HelloWorldCommand.execution.isolation.strategy=THREADhystrix.command.HelloWorldCommand.execution.isolation.thread.timeoutInMilliseconds=1000hystrix.command.HelloWorldCommand.circuitBreaker.errorThresholdPercentage=50hystrix.command.HelloWorldCommand.circuitBreaker.requestVolumeThreshold=20hystrix.command.HelloWorldCommand.circuitBreaker.sleepWindowInMilliseconds=5000 | 
это можно сделать в мире Spring Cloud точно таким же образом в файле application.properties или в файле application.yml следующим образом:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
 | 
hystrix:  command:    HelloWorldCommand:      metrics:        rollingStats:          timeInMilliseconds: 10000      execution:        isolation:          strategy: THREAD          thread:            timeoutInMilliseconds: 5000      circuitBreaker:        errorThresholdPercentage: 50        requestVolumeThreshold: 20        sleepWindowInMilliseconds: 5000 | 
Основанный на аннотации подход
Лично я предпочитаю подход, основанный на прямых командах, однако лучше использовать Hystrix в мире Spring, а не аннотации на основе Hystrix -javanica . Использование этой аннотации лучше всего иллюстрируется на примере. Вот удаленный вызов, заключенный в команду Hystrix с аннотациями:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
 | 
import agg.samples.domain.Message;import agg.samples.domain.MessageAcknowledgement;import agg.samples.feign.RemoteServiceClient;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class RemoteMessageAnnotationClient  {    private final RemoteServiceClient remoteServiceClient;    @Autowired    public RemoteMessageAnnotationClient(RemoteServiceClient remoteServiceClient) {        this.remoteServiceClient = remoteServiceClient;    }    @HystrixCommand(fallbackMethod = "defaultMessage", commandKey = "RemoteMessageAnnotationClient" )    public MessageAcknowledgement sendMessage(Message message) {        return this.remoteServiceClient.sendMessage(message);    }    public MessageAcknowledgement defaultMessage(Message message) {        return new MessageAcknowledgement("-1", message.getPayload(), "Fallback Payload");    }} | 
Эти аннотации транслируются с использованием аспекта в обычные команды Hystrix за кулисами, однако следует отметить, что использование этого в проекте Spring Cloud не церемонится, оно просто работает. Как и раньше, если поведение необходимо настроить, это можно сделать с помощью специальных свойств команды. Одна небольшая загвоздка в том, что имя команды по умолчанию является именем метода, поэтому в моем примере имя команды было бы «sendMessage», которое я настроил, используя аннотацию для другого имени.
- Если вы заинтересованы в дальнейшем изучении этого примера, вот мой проект на github .
 
| Ссылка: | Поддержка Spring Cloud для Hystrix от нашего партнера JCG Биджу Кунджуммена в блоге all and sundry. |