熔断
概述
服务响应变得非常慢,导致这个结果可以有多种原因,如高并发、缓存击穿等,在微服务下不同服务的相互依赖造成了服务雪崩,服务熔断就是解决这一问题的一种方式
熔断即上游的服务在调用下游服务时出现响应非常慢的现象,为了不影响整体服务的可用性,不再继续调用目标服务,直接返回
整合实现
- 添加依赖Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
- 实现熔断回调
import com.demo.commons.entity.ResponseVO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/***
* @author shaofan
* @Description
* @Date 2021-8-10
* @Time 17:58
*/
@FeignClient(value = "service-user",fallback = UserService.UserServiceCallback.class)//value参数为被调用方的名称
public interface UserService {
@GetMapping("user/get/{id}")//被调用的方法路径
ResponseVO getById(@PathVariable Integer id);
static class UserServiceCallback implements UserService{
@Override
public ResponseVO getById(Integer id) {
return ResponseVO.FORBIDDEN;
}
}
}
Gateway
概述
Gateway是网关组件,替代了维护中的zuul,与zuul相同,gateway能起到的作用就是路由、认证鉴权、限流
路由
gateway路由由三个部分组成:id、uri、predicates
- id:自定义的路由ID,唯一
- uri:目标服务地址
- predicates(断言):路由条件(路由规则),Predicate是Java8中引入的一个接口,它接收一个参数然后返回一个布尔值结果,该接口包含多种默认方法来讲Predicate组合程其他复杂的逻辑(比如与、或、非)
路由断言规则
- After:一个参数datetime,匹配发生在指定datetime之后的请求
- Before:一个参数datetime,匹配发生在指定datetime之前的请求
- Between:两个参数preDatetime与afterDatetime,匹配发生在两个指定的datetime之间的请求
- Cookie:两个参数Cookiename和regexp(正则表达式),匹配某个Cookie属性和正则表达式相匹配的请求
- Header:两个参数Headername和regexp,匹配某个header属性和正则表达式相匹配的请求
- Host:一个参数hostList(主机名称列表),匹配主机名称与列表中的某个表达式相匹配的请求,列表中的表达式使用Ant-style模式(?表示一个字符,*表示一段字符,**表示多段字符,用.作分隔)
- Method:一个参数methods,通过请求方式匹配(GET/POST)
- Path:两个参数Spring PathMatcher patterns(Spring的路径匹配模式,如/user/{userid})和matchTrailingSlash(可选,默认为true),通过请求路径匹配
- Query:两个参数param(请求参数)和regexp(可选),通过参数匹配
- RemoteAddr:一个参数IpList,通过ip地址匹配
- Weight:两个参数group和weight,根据权重匹配不同的路由进行负载均衡
代码演示(路径匹配)
- 引入依赖loadbalanceer
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
nacos不兼容gateway自带的负载均衡,如果没有这个依赖,路由使用负载均衡时会报错503
- 路由配置
server:
port: 8888
spring:
application:
name: service-gateway
cloud:
nacos:
config:
server-addr: localhost:8848
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: user_route
uri: lb://service-user # 负载均衡的效果
predicates:
- Path=/user/**
gateway整合jwt认证思路
定义一个过滤器实现顶级过滤器GlobalFilter,实现方法filter,方法有两个参数exchange和chain,通过exchange可以获得request和response
通过认证:chain.filter(exchange)
认证失败:
ReturnData<String> returnData = new ReturnData<>(org.apache.http.HttpStatus.SC_UNAUTHORIZED, mess, mess);
String returnStr = "";
try {
returnStr = objectMapper.writeValueAsString(returnData);
} catch (JsonProcessingException e) {
log.error(e.getMessage(),e);
}
DataBuffer buffer = resp.bufferFactory().wrap(returnStr.getBytes(StandardCharsets.UTF_8));
return resp.writeWith(Flux.just(buffer));
springcloud和springcloudalibaba组件对比
组件 | Spring Cloud | Spring Cloud Alibaba |
注册中心 | Eureka | Nacos |
服务调用 | Ribbon | OpenFien/Dubbo(RPC) |
网关 | Zuul | Gateway(Spring官方) |
熔断 | Hystrix | Sentinal |
配置中心 | Config | Nacos |
链路跟踪 | Sleuth(Zipkin) | Sleuth(Spring官方) |
消息队列 | 无(第三方替代RabbitMQ) | RecketMQ |
调度 | 无(第三方替代Quartz) | SchedulerX |
分布式事务 | 无(第三方替代Seata) | Seata |