Spring Cloud - 断路器+(普通调用和feign封装调用)
(三) Spring Cloud - 断路器+(普通调用和feign封装调用)
1. Ribbon+Hystrix(断路器), 普通调用方式
pom.xml加入两个Hystrix依赖maven
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
<groupId>com.sample</groupId>
-
<artifactId>2017-Netflix_Ribbon</artifactId>
-
<version>1.0.1-SNAPSHOT</version>
-
<packaging>war</packaging>
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.apache.maven.plugins</groupId>
-
<artifactId>maven-compiler-plugin</artifactId>
-
<version>3.3</version>
-
<configuration>
-
<!-- 指定source和target的版本 -->
-
<source>1.8</source>
-
<target>1.8</target>
-
</configuration>
-
</plugin>
-
</plugins>
-
</build>
-
<parent>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-parent</artifactId>
-
<version>1.5.2.RELEASE</version>
-
</parent>
-
<dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-dependencies</artifactId>
-
<version>Dalston.RELEASE</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
</dependencies>
-
</dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-config</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-eureka</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-hystrix</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>com.netflix.hystrix</groupId>
-
<artifactId>hystrix-javanica</artifactId>
-
</dependency>
-
</dependencies>
-
</project>
Ribbon启动的boot application,修改如下
-
package com.jack.ssm;
-
import org.springframework.boot.SpringApplication;
-
import org.springframework.boot.autoconfigure.SpringBootApplication;
-
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
-
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.web.client.RestTemplate;
-
/**
-
* ClassName:RibbonApplication.java
-
* Date: 2017年5月13日下午5:06:00
-
* @author Jack.Huang
-
* @version V1.0
-
* @since JDK 1.7.0_60/JDK 1.8.0_45
-
*/
-
@SpringBootApplication
-
@EnableDiscoveryClient
-
@EnableCircuitBreaker // 注解开启断路器功能
-
public class RibbonApplication {
-
@Bean
-
@LoadBalanced
-
RestTemplate restTemplate() {
-
return new RestTemplate();
-
}
-
public static void main(String[] args) {
-
SpringApplication.run(RibbonApplication.class, args);
-
}
-
}
-
package com.jack.ssm.controller;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestMethod;
-
import org.springframework.web.bind.annotation.RestController;
-
import org.springframework.web.client.RestTemplate;
-
import com.jack.ssm.service.ComputeService;
-
/**
-
* ClassName:ConsumerController.java
-
* Date: 2017年5月13日下午5:10:00
-
* @author Jack.Huang
-
* @version V1.0
-
* @since JDK 1.7.0_60/JDK 1.8.0_45
-
*/
-
@RestController
-
public class ConsumerController {
-
/*
-
* 没有使用断路器之前的代码
-
*
-
@Autowired
-
RestTemplate restTemplate;
-
@RequestMapping(value = "/ribbonCallAddService", method = RequestMethod.GET)
-
public String add() {
-
// return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
-
return restTemplate.getForEntity("http://NETFLIX-SERVICE/add?a=10&b=20", String.class).getBody();
-
}
-
*/
-
/*
-
* 使用断路器之后的代码
-
*/
-
@Autowired
-
private ComputeService computeService;
-
@RequestMapping(value = "/ribbonCallAddService", method = RequestMethod.GET)
-
public String add() {
-
return computeService.addService();
-
}
-
}
-
package com.jack.ssm.service;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Service;
-
import org.springframework.web.client.RestTemplate;
-
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
-
/**
-
* ClassName:ComputeService.java
-
* Date: 2017年5月15日下午5:18:45
-
* @author Jack.Huang
-
* @version V1.0
-
* @since JDK 1.7.0_60/JDK 1.8.0_45
-
*/
-
@Service
-
public class ComputeService {
-
@Autowired
-
RestTemplate restTemplate;
-
@HystrixCommand(fallbackMethod = "addServiceFallback")
-
public String addService() {
-
return restTemplate.getForEntity("http://NETFLIX-SERVICE/add?a=10&b=20", String.class).getBody();
-
}
-
public String addServiceFallback() {
-
return "Error sevice";
-
}
-
}
调用链接:http://localhost:8000/ribbonCallAddService
2. Feign+Hystrix(断路器)调用方式
pom.xml, feign的依赖已经引入了hystrix,无需再引入也可以实现断路器
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
<groupId>com.sample</groupId>
-
<artifactId>2017-Netflix_Feign</artifactId>
-
<version>1.0.1-SNAPSHOT</version>
-
<packaging>war</packaging>
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.apache.maven.plugins</groupId>
-
<artifactId>maven-compiler-plugin</artifactId>
-
<version>3.3</version>
-
<configuration>
-
<!-- 指定source和target的版本 -->
-
<source>1.8</source>
-
<target>1.8</target>
-
</configuration>
-
</plugin>
-
</plugins>
-
</build>
-
<parent>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-parent</artifactId>
-
<version>1.5.2.RELEASE</version>
-
</parent>
-
<dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-dependencies</artifactId>
-
<!-- <version>Camden.SR6</version> -->
-
<version>Dalston.RELEASE</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
</dependencies>
-
</dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-config</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-eureka</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-feign</artifactId>
-
</dependency>
-
<!-- <dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-hystrix</artifactId>
-
</dependency> -->
-
</dependencies>
-
</project>
application.yml, Dalston.RELEASE版本默认关闭hystrix, 其它版本则是默认打开
https://github.com/spring-cloud/spring-cloud-netflix/issues/1277这是spring社区关于为什么默认关闭的解析
-
server:
-
port: 8001
-
spring:
-
application:
-
name: feign-consumer
-
eureka:
-
service-url:
-
defaultZone: http://localhost:8761/eureka/
-
feign:
-
hystrix:
-
enabled: true
-
package com.jack.ssm.service;
-
import org.springframework.cloud.netflix.feign.FeignClient;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestMethod;
-
import org.springframework.web.bind.annotation.RequestParam;
-
import com.jack.ssm.service.hystrix.ComputeServiceHystrix;
-
/**
-
* ClassName:ComputeService.java
-
* Date: 2017年5月13日下午10:06:07
-
* @author Jack.Huang
-
* @version V1.0
-
* @since JDK 1.7.0_60/JDK 1.8.0_45
-
*/
-
@FeignClient(name = "NETFLIX-SERVICE", fallback = ComputeServiceHystrix.class)
-
public interface ComputeService {
-
@RequestMapping(method = RequestMethod.GET, value = "/add")
-
String add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);
-
}
-
package com.jack.ssm.service.hystrix;
-
import org.springframework.stereotype.Component;
-
import org.springframework.web.bind.annotation.RequestParam;
-
import com.jack.ssm.service.ComputeService;
-
/**
-
* ClassName:ComputeClientHystrix.java
-
* Date: 2017年5月15日下午4:14:54
-
* @author Jack.Huang
-
* @version V1.0
-
* @since JDK 1.7.0_60/JDK 1.8.0_45
-
*/
-
@Component
-
public class ComputeServiceHystrix implements ComputeService {
-
@Override
-
public String add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {
-
return "Error service or service both down!";
-
}
-
}
调用链接http://localhost:8001/feignCallAddService
3.至于feign哪里默认关闭hystrix的源码如下
-
/*
-
* Copyright 2013-2016 the original author or authors.
-
*
-
* Licensed under the Apache License, Version 2.0 (the "License");
-
* you may not use this file except in compliance with the License.
-
* You may obtain a copy of the License at
-
*
-
* http://www.apache.org/licenses/LICENSE-2.0
-
*
-
* Unless required by applicable law or agreed to in writing, software
-
* distributed under the License is distributed on an "AS IS" BASIS,
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
* See the License for the specific language governing permissions and
-
* limitations under the License.
-
*/
-
package org.springframework.cloud.netflix.hystrix.security;
-
import javax.annotation.PostConstruct;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
-
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-
import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition;
-
import org.springframework.context.annotation.Conditional;
-
import org.springframework.context.annotation.Configuration;
-
import org.springframework.security.core.context.SecurityContext;
-
import com.netflix.hystrix.Hystrix;
-
import com.netflix.hystrix.strategy.HystrixPlugins;
-
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
-
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
-
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
-
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
-
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
-
/**
-
* @author Daniel Lavoie
-
*/
-
@Configuration
-
@Conditional(HystrixSecurityCondition.class)
-
@ConditionalOnClass({ Hystrix.class, SecurityContext.class })
-
public class HystrixSecurityAutoConfiguration {
-
@Autowired(required = false)
-
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
-
@PostConstruct
-
public void init() {
-
// Keeps references of existing Hystrix plugins.
-
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
-
.getEventNotifier();
-
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
-
.getMetricsPublisher();
-
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
-
.getPropertiesStrategy();
-
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
-
.getCommandExecutionHook();
-
HystrixPlugins.reset();
-
// Registers existing plugins excepts the Concurrent Strategy plugin.
-
HystrixPlugins.getInstance().registerConcurrencyStrategy(
-
new SecurityContextConcurrencyStrategy(existingConcurrencyStrategy));
-
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
-
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
-
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
-
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
-
}
-
static class HystrixSecurityCondition extends AllNestedConditions {
-
public HystrixSecurityCondition() {
-
super(ConfigurationPhase.REGISTER_BEAN);
-
}
-
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)
-
static class HystrixEnabled {
-
}
-
@ConditionalOnProperty(name = "hystrix.shareSecurityContext")
-
static class ShareSecurityContext {
-
}
-
}
-
}
-
/*
-
* Copyright 2013-2016 the original author or authors.
-
*
-
* Licensed under the Apache License, Version 2.0 (the "License");
-
* you may not use this file except in compliance with the License.
-
* You may obtain a copy of the License at
-
*
-
* http://www.apache.org/licenses/LICENSE-2.0
-
*
-
* Unless required by applicable law or agreed to in writing, software
-
* distributed under the License is distributed on an "AS IS" BASIS,
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
* See the License for the specific language governing permissions and
-
* limitations under the License.
-
*/
-
package org.springframework.cloud.netflix.feign;
-
import java.util.ArrayList;
-
import java.util.List;
-
import org.springframework.beans.factory.ObjectFactory;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
-
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
-
import org.springframework.cloud.netflix.feign.support.SpringDecoder;
-
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
-
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.context.annotation.Configuration;
-
import org.springframework.context.annotation.Scope;
-
import org.springframework.core.convert.ConversionService;
-
import org.springframework.format.support.DefaultFormattingConversionService;
-
import org.springframework.format.support.FormattingConversionService;
-
import com.netflix.hystrix.HystrixCommand;
-
import feign.Contract;
-
import feign.Feign;
-
import feign.Logger;
-
import feign.Retryer;
-
import feign.codec.Decoder;
-
import feign.codec.Encoder;
-
import feign.hystrix.HystrixFeign;
-
/**
-
* @author Dave Syer
-
* @author Venil Noronha
-
*/
-
@Configuration
-
public class FeignClientsConfiguration {
-
@Autowired
-
private ObjectFactory<HttpMessageConverters> messageConverters;
-
@Autowired(required = false)
-
private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();
-
@Autowired(required = false)
-
private List<FeignFormatterRegistrar> feignFormatterRegistrars = new ArrayList<>();
-
@Autowired(required = false)
-
private Logger logger;
-
@Bean
-
@ConditionalOnMissingBean
-
public Decoder feignDecoder() {
-
return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));
-
}
-
@Bean
-
@ConditionalOnMissingBean
-
public Encoder feignEncoder() {
-
return new SpringEncoder(this.messageConverters);
-
}
-
@Bean
-
@ConditionalOnMissingBean
-
public Contract feignContract(ConversionService feignConversionService) {
-
return new SpringMvcContract(this.parameterProcessors, feignConversionService);
-
}
-
@Bean
-
public FormattingConversionService feignConversionService() {
-
FormattingConversionService conversionService = new DefaultFormattingConversionService();
-
for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) {
-
feignFormatterRegistrar.registerFormatters(conversionService);
-
}
-
return conversionService;
-
}
-
@Configuration
-
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
-
protected static class HystrixFeignConfiguration {
-
@Bean
-
@Scope("prototype")
-
@ConditionalOnMissingBean
-
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)
-
public Feign.Builder feignHystrixBuilder() {
-
return HystrixFeign.builder();
-
}
-
}
-
@Bean
-
@ConditionalOnMissingBean
-
public Retryer feignRetryer() {
-
return Retryer.NEVER_RETRY;
-
}
-
@Bean
-
@Scope("prototype")
-
@ConditionalOnMissingBean
-
public Feign.Builder feignBuilder(Retryer retryer) {
-
return Feign.builder().retryer(retryer);
-
}
-
@Bean
-
@ConditionalOnMissingBean(FeignLoggerFactory.class)
-
public FeignLoggerFactory feignLoggerFactory() {
-
return new DefaultFeignLoggerFactory(logger);
-
}
-
}
这两个地方都默认关闭了hystrix,@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false),实际两个都一起工作,这个有待后续研究
本文依然是参考http://blog.didispace.com/springcloud3/,再加上自己翻阅官网源码。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.****.net/yehuang_0801/article/details/72367096