一、hystrix简述
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:
- 雪崩效应
如上图可以看出微服务是非常多的,同时可能出现多个微服务之间进行复杂的通信,那么如果有一个服务出现问题,就会引起雪崩效应,导致整个系统瘫痪
spring cloud hystrix提供了一个类似于保险丝的作用,当服务不可用的时候,hystrix打开断路器,不再进行服务通信。从而保证自身服务的可用性。
- 服务降级
服务降级就是在系统高并发的情况下,可以将一些边缘服务进行降级(服务暂停),将资源优先供给核心服务的处理。
例如:在每年年底的时候,12306网站都是最繁忙的时候,那么这个时候细心的朋友就会发现一个情况:当到了指定的时间,大家开始抢票的时候,如果你不抢票,而是查询一些冷门的车次,你可能会发现票有时候查询不出来。因为这个时候比较冷门的服务,由于不太受到过多关注,可以考虑将服务降级。
二、ribbon整合hystrix使用
1.添加依赖
<!--hystrix jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.在启动类添加注解@EnableCircuitBreaker开启hystrix
@SpringBootApplication
@MapperScan("com.wangcongming")
@EnableEurekaClient
@EnableCircuitBreaker
public class OrderSystemApplication {
public static void main(String[] args) {
SpringApplication.run(OrderSystemApplication.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
//连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
httpRequestFactory.setConnectionRequestTimeout(3000);
//设置连接超时时间
httpRequestFactory.setConnectTimeout(3000);
//设置读超时时间,即请求处理超时时间
httpRequestFactory.setReadTimeout(3000);
// 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。
// clientHttpRequestFactory.setBufferRequestBody(false);
return new RestTemplate(httpRequestFactory);
}
}
3.开发示例
package com.wangcongming.shop.order.service.impl;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.wangcongming.shop.order.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class UserServiceImpl implements UserService{
@Autowired
private RestTemplate restTemplate;
/**
* @HystrixCommand注解用于开启断路器,fallbackMethod方法为当断路器打开时执行此方法
* commandProperties属性中的@HystrixProperty用来指定熔断机制执行策略指定,有两种策略THREAD|SEMAPHORE
* 默认使用THREAD,官方推荐使用THREAD,也就是不指定commandProperties
* 以上操作,同样适用于使用@SessionScope或@RequestScope的时候。
* 当抛出“无法找到范围内的上下文”的运行时异常,就需要执行这些操作。
* 所以正常情况不需要配置这些数据
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "findByIdFallback",
commandProperties = {@HystrixProperty(name="execution.isolation.strategy",
value="SEMAPHORE")})
public String getUserById(String id){
ResponseEntity<String> entity = restTemplate.getForEntity("http://user-system/user/findUser/" + id, String.class);
String body = entity.getBody();
return body;
}
public String findByIdFallback(String id){
return id;
}
}
如代码中所示,通过注解@HystrixCommand来指明fallback方法(当hystrix打开或者调用异常时执行的方法)和一些其他属性。
三、feign整合hystrix
1.添加依赖
<!--hystrix jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.修改配置文件
在配置文件中添加开启feign对hystrix的支持
#Dalston SR1(待定)之后的版本默认关闭hystrix对feign的支持,如果想要使用fallback功能这里必须启用
feign:
hystrix:
enabled: true
3.示例
package com.wangcongming.shop.score.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author wangcongming
* @Package com.wangcongming.shop.score.entity
* @Description: feign调用
* @RequestParam @RequestBody @RequestHeader
* @date 2018/5/19 14:24
*/
@FeignClient(name = "user-system",fallback = UserClientFallBack.class)
public interface UserClient {
@RequestMapping(value="/user/findUser/{id}", method = RequestMethod.GET)
public String getUserInfo(@PathVariable("id") String id);
@RequestMapping(value="/user/addScore", method = RequestMethod.GET)
public String update(@RequestParam("uid") String uid,@RequestParam("score") String score);
}
package com.wangcongming.shop.score.feign;
import org.springframework.stereotype.Component;
/**
* 当UserClient中的feign调用失败或超时时,会调用该实现类的方法
*/
@Component
public class UserClientFallBack implements UserClient {
@Override
public String getUserInfo(String id) {
System.out.println("------------------" + id + "**********************");
String ss = id;
return null;
}
@Override
public String update(String uid, String score) {
return null;
}
}
需要注意的是fallback指定的类一定要添加@Component将其加入到spring 容器
4.针对某一个@FeignClient禁用hystrix
修改configuration配置即可,代码示例如下
package com.wangcongming.shop.score.feign;
import com.wangcongming.shop.score.config.FeignOneConfiguration;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* @author wangcongming
* @Package com.wangcongming.shop.score.entity
* @Description: feign调用
* @date 2018/5/19 14:24
*/
@FeignClient(name = "user-system2",configuration = FeignOneConfiguration.class)
public interface UserClient2 {
@RequestLine("GET /user/findUser/{id}")
public String getUserInfo(@Param("id") String id);
}
package com.wangcongming.shop.score.config;
import com.wangcongming.annotation.ExcludeFilter;
import feign.Contract;
import feign.Feign;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
@ExcludeFilter
public class FeignOneConfiguration {
@Bean
public Contract feignContract(){
return new feign.Contract.Default();
}
/**
* 查看org.springframework.cloud.netflix.feign.FeignClientsConfiguration可以发现
* @Bean
* @Scope("prototype")
* @ConditionalOnMissingBean
* @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)
* public Feign.Builder feignHystrixBuilder() {
* return HystrixFeign.builder();
* }
* 可以看出当feign.hystrix.enabled配置为true时,默认开启HystrixFeign.builder()
* @return
*/
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
需要注意的是,一定要在入口类bean扫描时,将此类排除在外。具体代码如下
package com.wangcongming.shop.score;
import com.wangcongming.annotation.ExcludeFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @author wangcongming
* @Package com.wangcongming.shop.score
* @Description:
* @date 2018/5/18 14:46
*/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@ComponentScan(basePackages = { "com.wangcongming" },excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = ExcludeFilter.class
)
})
public class ScoreApplication {
public static void main(String[] args) {
SpringApplication.run(ScoreApplication.class,args);
}
}
其中ExcludeFilter注解为自定义注解,用于标明需要排除在组件扫描之外的类
推荐一套spring cloud学习视频 下载地址:https://download.csdn.net/download/linhui258/10525913