Spring Cloud - 断路器+(普通调用和feign封装调用)

(三) Spring Cloud - 断路器+(普通调用和feign封装调用)

1. Ribbon+Hystrix(断路器), 普通调用方式

pom.xml加入两个Hystrix依赖maven

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  3. <modelVersion>4.0.0</modelVersion>

  4. <groupId>com.sample</groupId>

  5. <artifactId>2017-Netflix_Ribbon</artifactId>

  6. <version>1.0.1-SNAPSHOT</version>

  7. <packaging>war</packaging>

  8.  
  9. <build>

  10. <plugins>

  11. <plugin>

  12. <groupId>org.apache.maven.plugins</groupId>

  13. <artifactId>maven-compiler-plugin</artifactId>

  14. <version>3.3</version>

  15. <configuration>

  16. <!-- 指定source和target的版本 -->

  17. <source>1.8</source>

  18. <target>1.8</target>

  19. </configuration>

  20. </plugin>

  21. </plugins>

  22. </build>

  23.  
  24. <parent>

  25. <groupId>org.springframework.boot</groupId>

  26. <artifactId>spring-boot-starter-parent</artifactId>

  27. <version>1.5.2.RELEASE</version>

  28. </parent>

  29. <dependencyManagement>

  30. <dependencies>

  31. <dependency>

  32. <groupId>org.springframework.cloud</groupId>

  33. <artifactId>spring-cloud-dependencies</artifactId>

  34. <version>Dalston.RELEASE</version>

  35. <type>pom</type>

  36. <scope>import</scope>

  37. </dependency>

  38. </dependencies>

  39. </dependencyManagement>

  40. <dependencies>

  41. <dependency>

  42. <groupId>org.springframework.cloud</groupId>

  43. <artifactId>spring-cloud-starter-config</artifactId>

  44. </dependency>

  45. <dependency>

  46. <groupId>org.springframework.cloud</groupId>

  47. <artifactId>spring-cloud-starter-eureka</artifactId>

  48. </dependency>

  49. <dependency>

  50. <groupId>org.springframework.cloud</groupId>

  51. <artifactId>spring-cloud-starter-hystrix</artifactId>

  52. </dependency>

  53. <dependency>

  54. <groupId>com.netflix.hystrix</groupId>

  55. <artifactId>hystrix-javanica</artifactId>

  56. </dependency>

  57. </dependencies>

  58.  
  59. </project>

Ribbon启动的boot application,修改如下

 
  1. package com.jack.ssm;

  2.  
  3. import org.springframework.boot.SpringApplication;

  4. import org.springframework.boot.autoconfigure.SpringBootApplication;

  5. import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;

  6. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

  7. import org.springframework.cloud.client.loadbalancer.LoadBalanced;

  8. import org.springframework.context.annotation.Bean;

  9. import org.springframework.web.client.RestTemplate;

  10.  
  11. /**

  12. * ClassName:RibbonApplication.java

  13. * Date: 2017年5月13日下午5:06:00

  14. * @author Jack.Huang

  15. * @version V1.0

  16. * @since JDK 1.7.0_60/JDK 1.8.0_45

  17. */

  18.  
  19. @SpringBootApplication

  20. @EnableDiscoveryClient

  21. @EnableCircuitBreaker // 注解开启断路器功能

  22. public class RibbonApplication {

  23.  
  24. @Bean

  25. @LoadBalanced

  26. RestTemplate restTemplate() {

  27. return new RestTemplate();

  28. }

  29. public static void main(String[] args) {

  30. SpringApplication.run(RibbonApplication.class, args);

  31. }

  32. }

 
  1. package com.jack.ssm.controller;

  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;

  4. import org.springframework.web.bind.annotation.RequestMapping;

  5. import org.springframework.web.bind.annotation.RequestMethod;

  6. import org.springframework.web.bind.annotation.RestController;

  7. import org.springframework.web.client.RestTemplate;

  8.  
  9. import com.jack.ssm.service.ComputeService;

  10.  
  11. /**

  12. * ClassName:ConsumerController.java

  13. * Date: 2017年5月13日下午5:10:00

  14. * @author Jack.Huang

  15. * @version V1.0

  16. * @since JDK 1.7.0_60/JDK 1.8.0_45

  17. */

  18.  
  19. @RestController

  20. public class ConsumerController {

  21.  
  22. /*

  23. * 没有使用断路器之前的代码

  24. *

  25. @Autowired

  26. RestTemplate restTemplate;

  27.  
  28. @RequestMapping(value = "/ribbonCallAddService", method = RequestMethod.GET)

  29. public String add() {

  30. // return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();

  31. return restTemplate.getForEntity("http://NETFLIX-SERVICE/add?a=10&b=20", String.class).getBody();

  32. }

  33. */

  34.  
  35. /*

  36. * 使用断路器之后的代码

  37. */

  38. @Autowired

  39. private ComputeService computeService;

  40.  
  41. @RequestMapping(value = "/ribbonCallAddService", method = RequestMethod.GET)

  42. public String add() {

  43. return computeService.addService();

  44. }

  45. }

 
  1. package com.jack.ssm.service;

  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;

  4. import org.springframework.stereotype.Service;

  5. import org.springframework.web.client.RestTemplate;

  6.  
  7. import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

  8.  
  9. /**

  10. * ClassName:ComputeService.java

  11. * Date: 2017年5月15日下午5:18:45

  12. * @author Jack.Huang

  13. * @version V1.0

  14. * @since JDK 1.7.0_60/JDK 1.8.0_45

  15. */

  16.  
  17. @Service

  18. public class ComputeService {

  19.  
  20. @Autowired

  21. RestTemplate restTemplate;

  22.  
  23. @HystrixCommand(fallbackMethod = "addServiceFallback")

  24. public String addService() {

  25. return restTemplate.getForEntity("http://NETFLIX-SERVICE/add?a=10&b=20", String.class).getBody();

  26. }

  27.  
  28. public String addServiceFallback() {

  29. return "Error sevice";

  30. }

  31.  
  32. }


调用链接:http://localhost:8000/ribbonCallAddService

2. Feign+Hystrix(断路器)调用方式

pom.xml, feign的依赖已经引入了hystrix,无需再引入也可以实现断路器

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  3. <modelVersion>4.0.0</modelVersion>

  4. <groupId>com.sample</groupId>

  5. <artifactId>2017-Netflix_Feign</artifactId>

  6. <version>1.0.1-SNAPSHOT</version>

  7. <packaging>war</packaging>

  8.  
  9. <build>

  10. <plugins>

  11. <plugin>

  12. <groupId>org.apache.maven.plugins</groupId>

  13. <artifactId>maven-compiler-plugin</artifactId>

  14. <version>3.3</version>

  15. <configuration>

  16. <!-- 指定source和target的版本 -->

  17. <source>1.8</source>

  18. <target>1.8</target>

  19. </configuration>

  20. </plugin>

  21. </plugins>

  22. </build>

  23.  
  24. <parent>

  25. <groupId>org.springframework.boot</groupId>

  26. <artifactId>spring-boot-starter-parent</artifactId>

  27. <version>1.5.2.RELEASE</version>

  28. </parent>

  29. <dependencyManagement>

  30. <dependencies>

  31. <dependency>

  32. <groupId>org.springframework.cloud</groupId>

  33. <artifactId>spring-cloud-dependencies</artifactId>

  34. <!-- <version>Camden.SR6</version> -->

  35. <version>Dalston.RELEASE</version>

  36. <type>pom</type>

  37. <scope>import</scope>

  38. </dependency>

  39. </dependencies>

  40. </dependencyManagement>

  41. <dependencies>

  42. <dependency>

  43. <groupId>org.springframework.cloud</groupId>

  44. <artifactId>spring-cloud-starter-config</artifactId>

  45. </dependency>

  46. <dependency>

  47. <groupId>org.springframework.cloud</groupId>

  48. <artifactId>spring-cloud-starter-eureka</artifactId>

  49. </dependency>

  50. <dependency>

  51. <groupId>org.springframework.cloud</groupId>

  52. <artifactId>spring-cloud-starter-feign</artifactId>

  53. </dependency>

  54. <!-- <dependency>

  55. <groupId>org.springframework.cloud</groupId>

  56. <artifactId>spring-cloud-starter-hystrix</artifactId>

  57. </dependency> -->

  58. </dependencies>

  59.  
  60. </project>

application.yml, Dalston.RELEASE版本默认关闭hystrix, 其它版本则是默认打开

https://github.com/spring-cloud/spring-cloud-netflix/issues/1277这是spring社区关于为什么默认关闭的解析

 
  1. server:

  2. port: 8001

  3.  
  4. spring:

  5. application:

  6. name: feign-consumer

  7.  
  8. eureka:

  9. service-url:

  10. defaultZone: http://localhost:8761/eureka/

  11.  
  12. feign:

  13. hystrix:

  14. enabled: true

 
  1. package com.jack.ssm.service;

  2.  
  3. import org.springframework.cloud.netflix.feign.FeignClient;

  4. import org.springframework.web.bind.annotation.RequestMapping;

  5. import org.springframework.web.bind.annotation.RequestMethod;

  6. import org.springframework.web.bind.annotation.RequestParam;

  7.  
  8. import com.jack.ssm.service.hystrix.ComputeServiceHystrix;

  9.  
  10. /**

  11. * ClassName:ComputeService.java

  12. * Date: 2017年5月13日下午10:06:07

  13. * @author Jack.Huang

  14. * @version V1.0

  15. * @since JDK 1.7.0_60/JDK 1.8.0_45

  16. */

  17.  
  18. @FeignClient(name = "NETFLIX-SERVICE", fallback = ComputeServiceHystrix.class)

  19. public interface ComputeService {

  20.  
  21. @RequestMapping(method = RequestMethod.GET, value = "/add")

  22. String add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);

  23.  
  24. }

 
  1. package com.jack.ssm.service.hystrix;

  2.  
  3. import org.springframework.stereotype.Component;

  4. import org.springframework.web.bind.annotation.RequestParam;

  5.  
  6. import com.jack.ssm.service.ComputeService;

  7.  
  8. /**

  9. * ClassName:ComputeClientHystrix.java

  10. * Date: 2017年5月15日下午4:14:54

  11. * @author Jack.Huang

  12. * @version V1.0

  13. * @since JDK 1.7.0_60/JDK 1.8.0_45

  14. */

  15.  
  16. @Component

  17. public class ComputeServiceHystrix implements ComputeService {

  18.  
  19. @Override

  20. public String add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {

  21. return "Error service or service both down!";

  22. }

  23. }


调用链接http://localhost:8001/feignCallAddService

3.至于feign哪里默认关闭hystrix的源码如下

 
  1. /*

  2. * Copyright 2013-2016 the original author or authors.

  3. *

  4. * Licensed under the Apache License, Version 2.0 (the "License");

  5. * you may not use this file except in compliance with the License.

  6. * You may obtain a copy of the License at

  7. *

  8. * http://www.apache.org/licenses/LICENSE-2.0

  9. *

  10. * Unless required by applicable law or agreed to in writing, software

  11. * distributed under the License is distributed on an "AS IS" BASIS,

  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  13. * See the License for the specific language governing permissions and

  14. * limitations under the License.

  15. */

  16.  
  17. package org.springframework.cloud.netflix.hystrix.security;

  18.  
  19. import javax.annotation.PostConstruct;

  20.  
  21. import org.springframework.beans.factory.annotation.Autowired;

  22. import org.springframework.boot.autoconfigure.condition.AllNestedConditions;

  23. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

  24. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

  25. import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition;

  26. import org.springframework.context.annotation.Conditional;

  27. import org.springframework.context.annotation.Configuration;

  28. import org.springframework.security.core.context.SecurityContext;

  29.  
  30. import com.netflix.hystrix.Hystrix;

  31. import com.netflix.hystrix.strategy.HystrixPlugins;

  32. import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;

  33. import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;

  34. import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;

  35. import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;

  36. import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;

  37.  
  38. /**

  39. * @author Daniel Lavoie

  40. */

  41. @Configuration

  42. @Conditional(HystrixSecurityCondition.class)

  43. @ConditionalOnClass({ Hystrix.class, SecurityContext.class })

  44. public class HystrixSecurityAutoConfiguration {

  45. @Autowired(required = false)

  46. private HystrixConcurrencyStrategy existingConcurrencyStrategy;

  47.  
  48. @PostConstruct

  49. public void init() {

  50. // Keeps references of existing Hystrix plugins.

  51. HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()

  52. .getEventNotifier();

  53. HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()

  54. .getMetricsPublisher();

  55. HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()

  56. .getPropertiesStrategy();

  57. HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()

  58. .getCommandExecutionHook();

  59.  
  60. HystrixPlugins.reset();

  61.  
  62. // Registers existing plugins excepts the Concurrent Strategy plugin.

  63. HystrixPlugins.getInstance().registerConcurrencyStrategy(

  64. new SecurityContextConcurrencyStrategy(existingConcurrencyStrategy));

  65. HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);

  66. HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);

  67. HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);

  68. HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);

  69. }

  70.  
  71. static class HystrixSecurityCondition extends AllNestedConditions {

  72.  
  73. public HystrixSecurityCondition() {

  74. super(ConfigurationPhase.REGISTER_BEAN);

  75. }

  76.  
  77. @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)

  78. static class HystrixEnabled {

  79.  
  80. }

  81.  
  82. @ConditionalOnProperty(name = "hystrix.shareSecurityContext")

  83. static class ShareSecurityContext {

  84.  
  85. }

  86. }

  87. }

 
  1. /*

  2. * Copyright 2013-2016 the original author or authors.

  3. *

  4. * Licensed under the Apache License, Version 2.0 (the "License");

  5. * you may not use this file except in compliance with the License.

  6. * You may obtain a copy of the License at

  7. *

  8. * http://www.apache.org/licenses/LICENSE-2.0

  9. *

  10. * Unless required by applicable law or agreed to in writing, software

  11. * distributed under the License is distributed on an "AS IS" BASIS,

  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  13. * See the License for the specific language governing permissions and

  14. * limitations under the License.

  15. */

  16.  
  17. package org.springframework.cloud.netflix.feign;

  18.  
  19. import java.util.ArrayList;

  20. import java.util.List;

  21.  
  22. import org.springframework.beans.factory.ObjectFactory;

  23. import org.springframework.beans.factory.annotation.Autowired;

  24. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

  25. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

  26. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

  27. import org.springframework.boot.autoconfigure.web.HttpMessageConverters;

  28. import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;

  29. import org.springframework.cloud.netflix.feign.support.SpringDecoder;

  30. import org.springframework.cloud.netflix.feign.support.SpringEncoder;

  31. import org.springframework.cloud.netflix.feign.support.SpringMvcContract;

  32. import org.springframework.context.annotation.Bean;

  33. import org.springframework.context.annotation.Configuration;

  34. import org.springframework.context.annotation.Scope;

  35. import org.springframework.core.convert.ConversionService;

  36. import org.springframework.format.support.DefaultFormattingConversionService;

  37. import org.springframework.format.support.FormattingConversionService;

  38.  
  39. import com.netflix.hystrix.HystrixCommand;

  40.  
  41. import feign.Contract;

  42. import feign.Feign;

  43. import feign.Logger;

  44. import feign.Retryer;

  45. import feign.codec.Decoder;

  46. import feign.codec.Encoder;

  47. import feign.hystrix.HystrixFeign;

  48.  
  49. /**

  50. * @author Dave Syer

  51. * @author Venil Noronha

  52. */

  53. @Configuration

  54. public class FeignClientsConfiguration {

  55.  
  56. @Autowired

  57. private ObjectFactory<HttpMessageConverters> messageConverters;

  58.  
  59. @Autowired(required = false)

  60. private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();

  61.  
  62. @Autowired(required = false)

  63. private List<FeignFormatterRegistrar> feignFormatterRegistrars = new ArrayList<>();

  64.  
  65. @Autowired(required = false)

  66. private Logger logger;

  67.  
  68. @Bean

  69. @ConditionalOnMissingBean

  70. public Decoder feignDecoder() {

  71. return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));

  72. }

  73.  
  74. @Bean

  75. @ConditionalOnMissingBean

  76. public Encoder feignEncoder() {

  77. return new SpringEncoder(this.messageConverters);

  78. }

  79.  
  80. @Bean

  81. @ConditionalOnMissingBean

  82. public Contract feignContract(ConversionService feignConversionService) {

  83. return new SpringMvcContract(this.parameterProcessors, feignConversionService);

  84. }

  85.  
  86. @Bean

  87. public FormattingConversionService feignConversionService() {

  88. FormattingConversionService conversionService = new DefaultFormattingConversionService();

  89. for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) {

  90. feignFormatterRegistrar.registerFormatters(conversionService);

  91. }

  92. return conversionService;

  93. }

  94.  
  95. @Configuration

  96. @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })

  97. protected static class HystrixFeignConfiguration {

  98. @Bean

  99. @Scope("prototype")

  100. @ConditionalOnMissingBean

  101. @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)

  102. public Feign.Builder feignHystrixBuilder() {

  103. return HystrixFeign.builder();

  104. }

  105. }

  106.  
  107. @Bean

  108. @ConditionalOnMissingBean

  109. public Retryer feignRetryer() {

  110. return Retryer.NEVER_RETRY;

  111. }

  112.  
  113. @Bean

  114. @Scope("prototype")

  115. @ConditionalOnMissingBean

  116. public Feign.Builder feignBuilder(Retryer retryer) {

  117. return Feign.builder().retryer(retryer);

  118. }

  119.  
  120. @Bean

  121. @ConditionalOnMissingBean(FeignLoggerFactory.class)

  122. public FeignLoggerFactory feignLoggerFactory() {

  123. return new DefaultFeignLoggerFactory(logger);

  124. }

  125.  
  126. }


这两个地方都默认关闭了hystrix,@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false),实际两个都一起工作,这个有待后续研究骂人

本文依然是参考http://blog.didispace.com/springcloud3/,再加上自己翻阅官网源码。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yehuang_0801/article/details/72367096

猜你喜欢

转载自blog.csdn.net/adsadadaddadasda/article/details/81287188