Hystrix
Fegin
gateway
概念:熔断器,延迟容错库
作用:隔离远程服务调用,防止出现级联失败、雪崩效应,保护服务
解决“级联失败、雪崩效应”方案,服务降级(线程隔离、服务熔断) 线程隔离:不直接访问服务,使用空闲线程访问,没有空闲线程,直接返回错误信息(加速失败判断) 服务熔断:及时返回错误信息,不用线程等待(close、open、halfopen)
使用步骤:
1)导入起步依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2)配置
hystrix:
command:
default:
execution: #线程隔离相关配置
isolation:
thread:
timeoutInMilliseconds: 2000
circuitBreaker: #服务熔断相关配置
errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20
3)代码
@SpringBootApplication
@EnableCircuitBreaker //开启熔断
@EnableFeignClients(basePackages = {"com.heima.userconsumer.feignservice"})
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class, args);
}
}
服务降级方法实现三种方式:
//方法级别服务降级:
@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerController {
@GetMapping("/{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallback")
public String queryById(@PathVariable Long id){
if (id == 1) {
throw new RuntimeException("太忙了");
}
return "abc";
}
public String queryByIdFallback(Long id){
log.error("查询用户信息失败。id:{}", id);
return "对不起,网络太拥挤了!";
}
}
/*服务降级,“具体方法”和“失败方法”返回值类型都要为String*/
//类级别服务降级
@RestController
@RequestMapping("/consumer")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")//全局失败返回
public class ConsumerController {
@GetMapping("/{id}")
@HystrixCommand //要进行服务降级的方法,需要添加该注解
public String queryById(@PathVariable Long id){
if (id == 1) {//为了模拟“服务熔断”
throw new RuntimeException("太忙了");
}
return "abc";
}
public String defaultFallback(){
log.error("查询用户信息失败。id:{}", id);
return "对不起,网络太拥挤了!";
}
}
//hystrix+Fegin 自定义服务降级方法
//注意:在application.yml中开启fegin对hystrix的支持
//1)定义Fegin接口,声明当前远程调用服务降级方法
@Component
@FeignClient(name = "eureka-client", fallback = FeignFallback.class)
public interface FeignInterface {
@GetMapping(value = "/helloWorld/{name}")
User feignClient(@PathVariable("name") String name) throws Exception;
}
//2)定义实现类实现Fegin接口,实现类中每个方法即接口中方法的服务降级方法
@Component
public class FeignFallback implements FeignInterface {
@Override
public User feignClient(String name) throws Exception {
System.out.println("当前网络不稳定,请稍后再尝试");
throw new Exception("当前网络不稳定,请稍后再尝试");
}
}
线程隔离:加速失败返回
服务熔断:达到一定限度拒绝所有请求或者服务半开服务能力减半
限流:限制流量(请求、访问)
令牌桶、漏桶、计数器
熔断器的断路器工作机制:
? 在服务正常工作时,断路器是关闭的;
? 但是当在一定的时间内(默认5s内20次),服务失败(降级)的次数达到阈值时,断路器会打开,当断路器开启了一段时间后,他会切换到半开状态,在半开状态时,接受到的服务成功调用次数达到了阈值时,断路器会关闭,服务回复正常;如果没达到阈值,断路器还会转到打开状态,在打开和半开之间切换,直到关闭.
概念:SpringCloud远程服务调用组件,内部封装了Http请求
作用:远程服务调用、负载均衡
使用步骤:
1)导入起步依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)配置
#使用Feign的默认配置
3)代码
Feign功能开启:
@SpringBootApplication
@EnableEurekaClient //开启Eureka客户端发现功能
@EnableFeignClients(basePackages = {"fegin接口包路径",...}) //开启Feign功能,扫描Feign接口
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Feign接口代码:
@FeignClient("user-service") //"user-service"必须是服务名,和注册中心服务名称一致
public interface XxxFegin{
@GetMapping("/user/{id}")
public User queryById(@PathVariable Long id);
}
/*
规范:
1.@XxxxMapping必须和远程调用的controller中的mapping保持一致
2.@XxxxMapping中的路径也必须和controller中的mapping的路径保持一致
3.接口方法的参数类型、个数、顺序必须和controller中方法保持一致
4.接口方法返回值类型必须和controller中方法保持一致
推荐:定义Feign接口时,直接从controller中拷贝方法,去除方法体,注意路径要完整
完整路径=controller类上的路径+方法上的路径
注意事项:要保证@FeignClient中服务名“serviceId”唯一,一个微服务只定义一个@FeignClient。
*/
Feign接口调用:
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private XxxFeign xxxFeign;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id){
User user = xxxFeign.queryById(id);
return user;
}
}
总结:Feign内置了hystrix、ribbon,可以进行hystrix、ribbon相关配置和操作。
概念:SpringCloud 网关组件
作用:安全、鉴权、监控、限流、负载均衡、缓存、路由
核心:断言-->过滤-->路由
过滤器: 全局过滤器(对所有路由都生效):不需要配置,对所有的路由都生效 实现“GlobalFilter”、“Ordered”接口,重写接口中方法即可 非正常结束:return exchange.getResponse().setComplete(); 继续执行:return chain.filter(exchange); 局部过滤器(对某些路由生效):那个路由配置了,就对那个路由生效 1)命名规范:XxxxGatewayFilterFactory,“GatewayFilterFactory”固定 2)一般继承“AbstractGatewayFilterFactory”,指定泛型(参考Gateway内置的过滤器即可) 3)在重写的apply方法中接收泛型参数、进行业务逻辑处理即可 特殊情况: default-filters: #默认过滤器设置,局部过滤器全局化 - AddResponseHeader=X-Response-Foo, Bar - AddResponseHeader=abc-myname,heima 目的:让Gateway自带的一些局部过滤器能全局生效
使用步骤:
1)导入起步依赖
<!--网关工程依赖坐标-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--网关工程也需要注册到注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2)配置
server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:
routes: #路由设置
# 路由id,可以任意
- id: user-service-route
# 代理的服务地址
#uri: http://127.0.0.1:9091
# lb表示从eureka中获取具体服务
uri: lb://user-service/
# 路由断言: 可以匹配映射路径
predicates:
#- Path=/user/**
#- Path=/**
- Path=/api/user/**
filters:
# 添加请求路径的前缀
#- PrefixPath=/user
#1表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1
- MyParam=name
- id:
...
# 默认过滤器,对所有路由都生效
default-filters: #默认过滤器设置
- AddResponseHeader=X-Response-Foo, Bar
- AddResponseHeader=abc-myname,heima
globalcors: #跨域设置
corsConfigurations:
‘[/**]‘:
#allowedOrigins: * # 这种写法或者下面的都可以,*表示全部
allowedOrigins:
- "http://docs.spring.io"
allowedMethods:
- GET
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
网关核心流程详解
1)前端浏览器发送请求,请求网关工程
例如:http://localhost:10010/api/user/123
2)网关工程接收请求,进行”断言“
”断言“:对请求路径进行判断,判断是否符合网关拦截规则,如下:
predicates:
- Path = 请求路径规则
3)网关工程对符合拦截规则的请求,进行“过滤”,如下:
“过滤”:使用“过滤器”增强请求
filters:
- StripPrefix=1
http://localhost:10010/api/user/123--->http://localhost:10010/user/123
4)网关工程对“过滤(增强)”后的请求,执行“路由”,如下:
“路由”:请求转发(网关工程不提供服务,只是一个中转站)
uri: lb://user-service/
1.http://localhost:10010/user/123--->
2.根据服务名称“user-service”去Eureka注册中心拉取服务列表,使用负载均衡算法从地址列表中选中一个服务 地址,然后替换“网关服务地址:http://localshot:10010”--->
3.最终结果:“获取的服务地址”+“/user/123”
3)代码
@SpringBootApplication
@EnableEurekaClient //声明为Eureka客户端工程
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
//其他,自定义过滤器(鉴权、监控、限流都是通过过滤器实现)
SpringCloud(二)-Hystrix&Fegin&gateway
原文:https://www.cnblogs.com/zhang-blog/p/14100579.html