Spring Cloud(Hystrix,Gateway)

Hystrix服务雪崩
分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图
Spring Cloud(Hystrix,Gateway)
如果各个服务正常运行,那大家齐乐融融,高高兴兴的,但是如果其中一个服务崩坏掉会出现什么样的情况呢?如下图,
Spring Cloud(Hystrix,Gateway)
引起雪崩的原因和服务雪崩的三个阶段
第一个是:硬件故障
第二个是:程序Bug;
第三个是:缓存击穿(用户大量访问缓存中没有的键值,导致大量请求查询数据库,使数据库压力过大);
第四个是:硬件故障
首先需要在消费端的pom文件引入

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

开启熔断
在启动类 ConsumerApplication 上添加注解:@EnableCircuitBreaker

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class ConsumerApplication {
// ...
}

可以看到,我们类上的注解越来越多,在微服务中,经常会引入上面的三个注解,于是Spring就提供了一个组合注解:@SpringCloudApplication
Spring Cloud(Hystrix,Gateway)

编写降级逻辑
当目标服务的调用出现故障,我们希望快速失败,给用户一个友好提示。因此需要提前编写好失败时的降级处理逻辑,要使用HystrixCommand来完成。

@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallback")
public String queryById(@PathVariable Long id) {
String url = "http://user-service/user/" + id;
	return restTemplate.getForObject(url, String.class);
}
public String queryByIdFallback(Long id) {
	log.error("查询用户信息失败。id:{}", id);
	return "对不起,网络太拥挤了!";
	}
}

当 生产者正常提供服务时,访问与以前一致。但是当将 生产者 停机时,会发现页面返回了降级处理信息
Spring Cloud(Hystrix,Gateway)
超时设置
Hystrix的默认超时时长为1,我们可以通过配置application.yml来改变超时时间

hystrix:
	command:
		default:
			execution:
				isolation:
					thread:
						timeoutInMilliseconds: 2000

Spring Cloud(Hystrix,Gateway)
熔断原理
在服务熔断中,使用的熔断器,也叫断路器,其英文单词为:Circuit Breaker 熔断机制与家里使用的电路熔断原理类似;当如果电路发生短路的时候能立刻熔断电路,避免发生灾难。在分布式系统中应用服务熔断后;服务调用方可以自己进行判断哪些服务反应慢或存在大量超时,可以针对这些服务进行主动熔断,防止整个系统被拖垮。Hystrix的服务熔断机制,可以实现弹性容错;当服务请求情况好转之后,可以自动重连。通过断路的方式,将后续请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则回到断路器关闭状态,否则继续打开,拒绝请求的服务。
Hystrix的熔断状态机模型
Spring Cloud(Hystrix,Gateway)
状态机有3个状态
1.Closed:关闭状态(断路器关闭),所有请求都正常访问。
2.Open:打开状态(断路器打开),所有请求都会被降级。Hystrix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
3.Half Open:半开状态,不是永久的,断路器打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会关闭断路器,否则继续保持打开,再次进行休眠计时
Spring Cloud(Hystrix,Gateway)
我们可以通过配置YML来改变

hystrix:
	command:
		default:
			execution:
				isolation:
					thread:
						timeoutInMilliseconds: 2000 #服务降级超时时间
			circuitBreaker:
						errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
						sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
						requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20

Feign
在消费者中

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

开启Feign功能
在 ConsumerApplication 启动类上,添加注解,开启Feign功能

@SpringCloudApplication
@EnableFeignClients //开启feign功能
public class ConsumerApplication {
public static void main(String[] args) {
	SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
	return new RestTemplate();
	}
}

负载均衡
Feign中本身已经集成了Ribbon依赖和自动配置:
Spring Cloud(Hystrix,Gateway)
Fegin内置的ribbon默认设置了请求超时时长,默认是1000,我们可以通过手动配置来修改这个超时时长

ribbon:
	ReadTimeout: 2000 # 读取超时时长
	ConnectTimeout: 1000 # 建立链接的超时时长

或者为某一个具体service指定

user-service
	ribbon:
	ReadTimeout: 2000 # 读取超时时长
	ConnectTimeout: 1000 # 建立链接的超时时长

因为ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以添加配置:

ribbon:
	ConnectTimeout: 1000 # 连接超时时长
	ReadTimeout: 2000 # 数据通信超时时长
	MaxAutoRetries: 0 # 当前服务器的重试次数
	MaxAutoRetriesNextServer: 0 # 重试多少次服务
	OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试

Gateway网关
简介
Spring Cloud Gateway是Spring官网基于Spring 5.0、 Spring Boot 2.0、Project Reactor等技术开发的网关服务。
Spring Cloud Gateway基于Filter链提供网关基本功能:安全、监控/埋点、限流等。
Spring Cloud Gateway为微服务架构提供简单、有效且统一的API路由管理方式。
Spring Cloud Gateway是替代Netflix Zuul的一套解决方案。
Spring Cloud Gateway组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。 Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,
从而加强安全保护。Spring Cloud Gateway本身也是一个微服务,需要注册到Eureka服务注册中心
Spring Cloud(Hystrix,Gateway)
核心概念
路由(route) 路由信息的组成:由一个ID、一个目的URL、一组断言工厂、一组Filter组成。如果路由断言为真,说明请求URL和配置路由匹配。
断言(Predicate) Spring Cloud Gateway中的断言函数输入类型是Spring 5.0框架中的
ServerWebExchange。Spring Cloud Gateway的断言函数允许开发者去定义匹配来自于HTTP Request中的任何信息比如请求头和参数。
过滤器(Filter) 一个标准的Spring WebFilter。 Spring Cloud Gateway中的Filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理
穿件一个新得工程
Spring Cloud(Hystrix,Gateway)
在pom文件中导入

<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
		<artifactId>lxs-springcloud</artifactId>
		<groupId>com.lxs</groupId>
		<version>1.0-SNAPSHOT</version>
</parent>
		<modelVersion>4.0.0</modelVersion>
		<artifactId>lxs-gateway</artifactId>
<dependencies>
<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>
</dependencies>
</project>

编写GatewayApplication启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(GatewayApplication.class, args);
	}
}

编写配置YML

server:
	port: 10010
spring:
	application:
		name: api-gateway
	cloud:
	gateway:
		routes:
# 路由id,可以随意写
		- id: user-service-route
		# 代理的服务地址
		# uri: HTTP://127.0.0.1:9091
		  uri: lb://user-service
# 路由断言,可以配置映射路径
predicates:
- Path=/user/**
eureka:
	client:
		service-url:
			defaultZone: HTTP://127.0.0.1:10086/eureka
instance:
	prefer-ip-address: true

启动测试
在日志中就能看见负载均衡器:
Spring Cloud(Hystrix,Gateway)

上一篇:vue2与vue3实现响应式的区别及提升


下一篇:SpringCloud Gateway 自定义 过滤器: