Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件-Nacos 、Sentinel等

概述

  • Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件。
  • 方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
  • 依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置。
  • 就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

版本介绍

组件关系

在这里插入图片描述

依赖关系
在这里插入图片描述

Nacos概述

什么是Nacos

  • Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集。
  • 帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
    关键特性

搭建NacosServer

  • 官网下载解压启动

在这里插入图片描述

  • 打开浏览器, 在浏览器当中输入: http://localhost:8848/nacos/
  • 账号:nacos
  • 密码:nacos
    在这里插入图片描述

服务注册与发现

工程准备

1.创建父工程 spring-cloud-alibaba-parent ,在父工程当中导入依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.3.RELEASE</version>
</parent>
<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR1</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.1.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

2.创建两个子工程 user 与 goods 工程

我创建一个user为例,goods就自己创建了

  • 依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
  • controller
@RestController
public class UserController {@RequestMapping("/getUser")public ResponseResult getUser() {return ResponseResult.success("My User");}}
  • util
public class ResponseResult extends HashMap {public static String SUCCESS_CODE = "200";public static String ERROR_CODE = "500";public static String DATA_KEY = "data";public static String MSG_KEY = "msg";private ResponseResult() {}public ResponseResult set(String key, Object object) {super.put(key, object);return this;}private static ResponseResult newResponseResult() {return new ResponseResult();}public static ResponseResult success() {return ResponseResult.newResponseResult().set("code", ResponseResult.SUCCESS_CODE).set(ResponseResult.MSG_KEY, "操作成功");}public static ResponseResult success(String msg) {return ResponseResult.newResponseResult().set("code", ResponseResult.SUCCESS_CODE).set(ResponseResult.MSG_KEY, msg);}public static ResponseResult success(String msg, Object object) {return ResponseResult.newResponseResult().set("code", ResponseResult.SUCCESS_CODE).set(ResponseResult.MSG_KEY, msg).set(ResponseResult.DATA_KEY, object);}public ResponseResult data(Object obj) {return this.set("data", obj);}public static ResponseResult error() {return ResponseResult.newResponseResult().set(ResponseResult.MSG_KEY, "操作失败").set("code", ResponseResult.ERROR_CODE);}public static ResponseResult error(String msg) {return ResponseResult.newResponseResult().set(ResponseResult.MSG_KEY, msg).set("code", ResponseResult.ERROR_CODE);}public static ResponseResult error(String msg, Object object) {return ResponseResult.newResponseResult().set(ResponseResult.MSG_KEY, msg).set(ResponseResult.DATA_KEY, object).set("code", ResponseResult.ERROR_CODE);}}
  • 启动类
@SpringBootApplication
public class AppUser {public static void main(String[] args) {SpringApplication.run(AppUser.class, args);}
}
  • 配置文件 application.yml
logging:level:cn.ddossec: debug # 日志级别
server:port: 5000 # 端口号
spring:application:name: consumption-user # 服务名称
  • 在user工程当中添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> 
  • 在启动类上添加注解 @EnableDiscoveryClient

  • 在配置文件添加添加配置

cloud:nacos:discovery:server-addr: localhost:8848 #nacos服务的地址 不要加http
  • 启动工程后, 在nacos当中查询服务列表
    在这里插入图片描述

  • 使用相同方式 把goods服务注册到nacos上

  • 在 user 工程中通过服务发现调用goods工程

  • 在启动类配置 RestTemplate

@Bean
public RestTemplate restTemplate(){return new RestTemplate();
}
  • 服务发现调用
@RestController
public class UserController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/getUser")public ResponseResult getUser() {List<ServiceInstance> instances = discoveryClient.getInstances("provide-goods");ServiceInstance serviceInstance = instances.get(0);System.out.println(serviceInstance);String url = serviceInstance.getUri() + "/getGoods".toString();return ResponseResult.success("调用成功",restTemplate.getForObject(url, Object.class));}}

nacos集群

1.编译源码, 支持mysql8数据库

  • 1.下载nacos源码

  • 2.下载后, 修改源码进行编译,把mysql数据库改为mysql8
    修改pom文件
    在这里插入图片描述

  • 修改 MysqlHealthCheckProcessor 导入的包为mysql8的驱动包
    在这里插入图片描述

  • 修改数据库连接配置为mysql8的配置
    在这里插入图片描述

db.url.0=jdbc:mysql://11.162.196.161:3306/diamond_devtest?serverTimezone=GMT%2B8&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.url.1=jdbc:mysql://11.163.152.91:3306/diamond_devtest?serverTimezone=GMT%2B8&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
  • 进入到源码根目录,使用mvn进行打包
mvn -Prelease-nacos clean install -U -Dmaven.skip.test=true
  • 打包后, 找到nacos-1.1.4\distribution\target\nacos-server-1.1.4\nacos\conf

2.在数据库当中创建 nacos_config,导入nacos中sql数据
在这里插入图片描述

3.复制3份nacos工程,分别配置信息

  • 设置端口号:8849、8850、8851
  • 示例

在这里插入图片描述

在这里插入图片描述

  • 分别设置每一个工程的端口号

  • 设置数据库连接信息

在这里插入图片描述

指定数据源为
Mysqlspring.datasource.platform=mysql
数据库实例数量

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=1234
  • 分别设置每一个工程的 application.properties 文件当中进行设置

  • 集群信息

  • 复制一份 cluster.conf.example 文件改为 cluster.conf 配置以下信息

192.168.43.95:8849
192.168.43.95:8850
192.168.43.95:8851
  • 192.168.43.95:是本机IP

在这里插入图片描述

  • 每一份工程复制一份过去就行

4.分别进入到每一份工程bin目录下,修改 startup.cmd

在这里插入图片描述

cluster

  • 修改完毕后,开始分别启动每一个

5.在nginx当中配置反向代理

在这里插入图片描述


upstream nacos {server 169.254.108.9:8849;server 169.254.108.9:8850;server 169.254.108.9:8851;
}
location /nacos {proxy_pass http://nacos/nacos;
}

6.启动 nginx 地址栏访问: http://localhost/nacos/

7.将服务注册到Nacos当中,直接写上nginx的地址

在这里插入图片描述

集成Ribbon

使用Ribbon
1.不需要添加依赖

2.在 RestTemplate 上添加注解 @LoadBalanced

在这里插入图片描述

3.在调用时, 就可以使用服务名称来进行调用 , 和之前的使用方式 是一样的

在这里插入图片描述

@RequestMapping("/getGoods")
public ResponseResult getGoods() {String url = "http://provide-goods/getGoods";return ResponseResult.success("调用成功",restTemplate.getForObject(url, Object.class));
}

默认使用是 轮询 策略

自定义负载均衡策略

配置方式与之前一样
在这里插入图片描述

配置懒加载
在这里插入图片描述

ribbon:eager-load:enabled: trueclients: provide-goods  #多个服务使用逗号隔开

Nacos集成Ribbon,支持权重的负载均衡算法
1.自定义权重算法

在这里插入图片描述

public class NacosWeightRule extends AbstractLoadBalancerRule {

@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {}@Override
public Server choose(Object o) {BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();// 获取请求微服务的名称String name = loadBalancer.getName();// 获取nacos服务发现相关名称NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();// nacos client自动通过基于权重的负载均衡算法,选择实例try {Instance instance = namingService.selectOneHealthyInstance(name);return new NacosServer(instance);} catch (NacosException e) {e.printStackTrace();}return null;
}

}
2.配置使用自定义的算法
在这里插入图片描述

3.在nacos服务中心当中配置服务的权重

在这里插入图片描述

集成Feign

使用步骤
在客户端引入依赖

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

在启动类上面加上注解 @EnableFeignClients

创建服务 FeignClient

创建一个 service 文件夹,在该文件下创建一个接口

在接口加上添加 @FeignClient() 注解,参数就是你的微服务名字

示例
在这里插入图片描述

@FeignClient(name = "provide-goods")
public interface GoodsFeignClient {@RequestMapping("/getGoods")public Object getGoods();}

控制器调用
在这里插入图片描述

单个参数请求
goods工程

在这里插入图片描述

@RequestMapping("/getGoodsWithID/{id}")
public ResponseResult getGoodsWithID(@PathVariable Integer id){return ResponseResult.success("goods___id="+id);
}

Feign客户端

在这里插入图片描述


@RequestMapping("/getGoodsWithID/{id}")
public ResponseResult getGoodsWithID(@PathVariable Integer id);

user工程调用
在这里插入图片描述

多个参数请求
goods工程

在这里插入图片描述
Feign客户端
在这里插入图片描述

user工程调用
在这里插入图片描述

Sentinel

什么是 Sentinel
Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。

使用 Sentinel

  • 下载 sentinel 控制台服务器

  • 在 jar 目录当中打开控制台,输入 java -jar sentinel-dashboard-1.7.0.jar

在这里插入图片描述

  • 可以修改端口号:
java -Dserver.port=8088 -Dcsp.sentinel.dashboard.server=localhost:8088 -jar sentinel-dashboard-1.7.0.jar

在浏览器当中输入:localhost:8080
在这里插入图片描述

用户名和密码为 sentinel

  • 添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • 添加配置
    在这里插入图片描述
sentinel:transport:dashboard: localhost:8080
  • 在浏览器当中进行访问:http://localhost:5000/getGoodsWithId/1

  • 访问完成后,再次查看控制台
    在这里插入图片描述

功能介绍

  • 实时监控
    1、 实时监控aip的执行通过/拒绝和对应响应时长

  • 簇点链路
    1、曾经被访问过的路径
    2、流控
    在这里插入图片描述

  • 资源名称,访问的路径,唯一名称

  • 针对来源
    1、可以针对调用者进行限流
    2、假设两个微服务a和b调用,可以对a和b单独的设置限流规则
    3、default为不区别来源

  • 阈值类型
    1、QPS:当调用api的QPS达到阈值时,就去做限流
    2、线程数:当调用api的线程数达到一定的域值时就去做限流
    3、是否集群
    4、流控模式
    4.1、直接:当违反定义的api规则时, 直接快速失败
    示例
    在这里插入图片描述

一秒种超过一次时, 就会触发限流

在这里插入图片描述

4.2、关联

当关联的资源达到阈值时, 限流自己

示例

在这里插入图片描述
在这里插入图片描述

http://localhost:5000/getGoodsWithObj?name=leader_tblog&id=18 访问时, 就会被限流

查询接口调用过快, 如果影响修改接口,或者修改接口影响查询接口, 根据业务需求,来进行关联限流

4.3、链路

指定资源从入口资源进来的流量,如果达到阈值,就开启限流

4.4、流控效果

  • 快速失败
    直接失败,抛出异常信息
  • Warm Up
    1、根据 codeFactor 从设置的阈值除以codeFactor,经过预热时长,才到达设置的QPS阈值
    2、假设设置的阈值为90 那么就会90/3(默认) 30 作为最初的阈值 ,预热指定的时长 才去达到90的值限流
  • 排队等待
    1、匀速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS,否则无效
    2、超过了定义的时长, 就会抛出异常

代码配置

引入依赖

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.7.0</version>
</dependency>
  • 定义资源名称
private static final String GET_GOODS_KEY = "getMyGoods";
  • 定义限流规则
@RequestMapping("/initFlowRules")
public void initFlowRules(){List<FlowRule> rules = new ArrayList<>();FlowRule rule = new FlowRule();//设置资源名称rule.setResource(GET_GOODS_KEY);//设置针对来源rule.setLimitApp("default");//设置阈值类型rule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置阈值rule.setCount(1);rules.add(rule);FlowRuleManager.loadRules(rules);
}
  • 应用到被限流的接口上
@RequestMapping("/getMyGoods")
public String getMyGoods(){try (Entry entry = SphU.entry(GET_GOODS_KEY)) {// 被保护的逻辑return "getMyGoods";} catch (BlockException ex) {// 处理被流控的逻辑return "被限流了";}
}

自动执行流控代码

使用 springboot 自带的 ApplicationRunner 接口

使用方式,实现 ApplicationRunner 接口,在 run 方法当中执行流控代码

示例
在这里插入图片描述

@Component
public class SentinelRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {initFlowRules();}private static final String GET_GOODS_KEY = "getMyGoods";public void initFlowRules(){List<FlowRule> rules = new ArrayList<>();FlowRule rule = new FlowRule();//设置资源名称rule.setResource(GET_GOODS_KEY);//设置针对来源rule.setLimitApp("default");//设置阈值类型rule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置阈值rule.setCount(1);rules.add(rule);FlowRuleManager.loadRules(rules);}
}

使用注解改进代码

  • Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandler 和 fallback 函数来进行限流之后的处理
  • blockHandler 函数会在原方法被限流/降级/系统保护的时候调用
  • fallback 函数会针对所有类型的异常
    示例
    在这里插入图片描述
private static final String GET_GOODS_KEY = "getMyGoods";@SentinelResource(value = GET_GOODS_KEY, blockHandler = "blockHandlerMethod")
@RequestMapping("/getMyGoods")
public String getMyGoods() {return "getMyGoods";
}public String blockHandlerMethod(BlockException e) {e.printStackTrace();return "被限流了----";
}

降级规则
降级策略

RT

平均响应时间 (DEGRADE_GRADE_RT):当 1s 内持续进入 5 个请求,
对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位)
那么在接下的时间窗口之内,对这个方法的调用都会自动地熔断

异常比例

当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后
资源进入降级状态

在这里插入图片描述

在这里插入图片描述

异常次数

当资源近 1 分钟的异常数目超过阈值之后会进行熔断。
注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。
在这里插入图片描述

热点规则

在这里插入图片描述
在这里插入图片描述

指定索引参数,如果在时间窗口内超过了指定的阈值,就会触发熔断

  • 参数例外项
    1、可以对指定的参数再进行设置限流
    2、参数级别

对指定的参数限流,甚至对指定参数的值进行限流

注意事项

参数必须是基本数据类型或String类型
在这里插入图片描述

系统规则

和其他的规则不太一样,它是针对应用来设的
前面设置的都是争对某一个资源。某一个方法来设置的

阈值类型

load: load是负载,只有在linux机器上才会生效。根据当前系统的负载来决定是不是触发保护。
RT: 这个应用上所有的流量的平均的响应时间,所有服务的平均响应时间超过一个值,那么我就停止接收新的请求。
线程数: 所有服务访问的线程数加起来。
入口qps: 所有服务的qps加起来达到一个值。
cpu使用率: cpu的使用率超过一个百分比
发生以上这些情况的时候把你整个应用给你断掉。所有服务都不提供了

授权规则

使用授权时要先指定来源,对指定来源的内容进行限流

指定来源方式

@Component
public class RequestOrigin implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {//从请求参数中获取origin的参数并返回String origin = httpServletRequest.getParameter("origin");//如果获取不到origin 就抛出异常if (StringUtils.isBlank(origin)){throw new IllegalArgumentException("必须指定origin");}return origin;}
}

在这里插入图片描述

整合Feign

开启 feign 与 Sentinel 集成

feign:sentinel:enabled: true

整合方式与 Hystrix 一样

规则持久化

使用 Nacos 配置中心实现规则持久化

  • 在 nacos 配置中心当中添加配置 json 规则
[{"resource": "getMyGoods2","limitApp": "default","grade": 1,"count": 5,"strategy": 0,"controlBehavior": 0,"clusterMode": false}
]

在这里插入图片描述

  • 在工程当中添加依赖
<!--添加此依赖,项目一启动时, 就去到nacos当中读取配置中心-->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId><version>1.7.0</version>
</dependency>

在配置文件当中添加 sentinel 读取 nacos 地址

eager: true
datasource:ds:nacos:server-addr: localhost:8849group-id: DEFAULT_GROUPrule-type: flowdata-id: my-goods-sentineldata-type: json

Spring-Cloud-GateWay

概述
什么是 Spring-Cloud-GateWay

Spring Cloud Gateway 基于 Spring Boot 2, 是 Spring Cloud 的 全新 项目, 该项 目 提供 了 一个 构建 在 Spring 生态 之上 的 API 网关
Spring Cloud Gateway 旨在 提供 一种 简单 而 有效 的 途径 来 转发 请求, 并为 它们 提供 横 切 关注 点, 例如: 安全性、 监控/ 指标 和 弹性

优点

性能比较高, 是第一代网关 zuul 的 1.6 倍
功能强大, 内置了很多功能,转发/监控/限流
容易扩展

缺点

实现依赖 Netty 和 WebFlux,不是传统的 Servet 模型
不能将其部署在 Tomcat,Jetty 等 Servelt 容器当中,只能打成 Jar 包执行
需要 springboot2.0 及以上版本才支持

词汇

Route路由: 路由网关的基本构建块。 它由ID,目标URI,谓词集合和过滤器集合定义。 如果聚合谓词为真,则匹配路由
Predicate谓词: 对请求的内容进行匹配,条件筛选
Filter过滤器: 可以对请求进行过滤,在发送下游请求之前或之后修改请求和响应

快速入门

创建 gateWay 服务

添加依赖

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>io.projectreactor.netty</groupId><artifactId>reactor-netty</artifactId><version>0.9.4.RELEASE</version></dependency>
</dependencies>

创建 启动类

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

添加 配置文件

logging:pattern:console: "%d{HH:mm:ss.SSS} %clr(%5p) %clr(-){faint} %clr(%-80.80logger{79}){cyan} %clr(:) %m%n"server:port: 9000spring:application:name: api-gatewaycloud:gateway:routes: #当请求满足要求时,转发到指定的服务当中- id: goods_route  #唯一标识,默认是uuiduri: http://localhost:5000/ #请求要转发的地址order: 1 #路由优先级 越小, 优先级越高predicates: #谓词,断言(条件判断 转发请求要满足什么条件)- Path=/consumer-user/**  #当路径中有指定内容时, 才会转发到指定urifilters: #过滤器,拦截请求做一些额外处理- StripPrefix=1  #去掉添加的path内容

在浏览器 当中访问
http://localhost:9000/consumer-user/getGoodsWithId/1

GateWay整合Nacos

  • 在配置文件中添加 Nacos 的依赖, 把 gatWay 注册到 Nacos 当中
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  • 在配置文件当中添加 nacos 的地址
cloud:nacos:discovery:server-addr: localhost:80 #nacos服务的地址 不要加http
  • 在启动类上添加注解
    @EnableDiscoveryClient
  • 配置 gateWay 从 nacos 中获取服务信息
discovery:locator:enabled: true #从nacos当中获取服务信息
  • 信息 uri 为服务地址
    lb: //服务名称
    lb: 为负载均衡调用
    lb: //consumer-user

在这里插入图片描述

谓词
什么是谓词 ( 断言 )
用于对请求进行判断 ,只有断言都返回值,才会真正的执行路由
满足条件,才能进行过滤,转发

内置断言工厂
基于 Datetime

AfterRoutePredicateFactory

判断请求日期是否晚于指定的日期

参数: 传递一个日期

示例

在这里插入图片描述

  • After=2020-12-30T23:59:59.789+08:00[Asia/Shanghai]
    BeforeRoutePredicateFactory

判断请求日期是否早于指定日期

参数: 传递一个日期

BetweenRoutePredicateFactory

判断请求日期是否在指定日期之间

参数: 传递两个日期

基于远程地址

RemoteAddrRoutePredicateFactory

判断请求主机地址是否在指定地址段时

参数: IP地址段

示例

在这里插入图片描述

  • RemoteAddr=192.168.1.1/24

基于 Cookie 的断言

CookieRoutePredicateFactory

判断请求 cookie 是否具有给定名称且值与正则表达式匹配

参数: cookie 名称 , 正则表达式
在这里插入图片描述

示例

  • Cookie=myCookName,[^gao]

基于 header

HeaderRoutePredicateFactory

判断请求 Header 是否具有给定名称且值与正则表达式匹配

参数: 标题名称 , 正则表达式

示例

  • Header=Request-Id,\d+

基于 Host

HostRoutePredicateFactory

判断请求的 Host 是否满足匹配条件

参数: 主机名模式

示例

  • Host=**.testhost.org

基于 Methods

MethodRoutePredicateFactory

判断请求类型是否为指定的类型

参数: 请求类型

示例

  • Method=GET

基于 Query 请求参数

QueryRouterPredicateFactory

判断请求参数是否具有给定名称且值与正则表达式匹配

参数: 请求参数名,正则表达式

示例

  • Query=name,test.

基于权重的断言工厂

WeightRoutePredicateFactory

对于同一组内容的路由,按权重进行转发

参数 : 组名,权重

示例

在这里插入图片描述

两个对于 / weight/** 路径转发的路由定义,这两个路由是同一个权重分组,且 weight_ route1 权重为 1, weight_ route2 权重为 9

对于 10 个访问 /weight/** 路径的请求来说,将会有 9 个路由到 weight_ route2,1 个路由到 weight_ route1

自定义谓词工厂
要求

名字必须是 配置+RoutePredicateFactory
必须继承 AbstractRoutePredicateFactory

方法介绍

List shortcutFieldOrder()

读取配置文件当中的参数,赋值到配置类中的属性上
要求和配置类当中的属性名称一致

Predicate apply

断言逻辑

class Config 内部类

接收配置文件当中对应的参数

示例

在这里插入图片描述
在这里插入图片描述

package cn.ddossec.factory;import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;@Component
class AppTypeRoutePredicateFactory extends AbstractRoutePredicateFactory<AppTypeRoutePredicateFactory.Config> {//构造器public AppTypeRoutePredicateFactory() {super(AppTypeRoutePredicateFactory.Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("appType");}@Overridepublic Predicate<ServerWebExchange> apply(AppTypeRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {//接收参数String app = serverWebExchange.getRequest().getQueryParams().getFirst("app");if (StringUtils.isNotEmpty(app)) {if (config.getAppType().equals(app))return true;elsereturn false;}return false;}};}public static class Config {private String appType;public Config(String appType) {this.appType = appType;}public String getAppType() {return appType;}public void setAppType(String appType) {this.appType = appType;}}}

过滤器
什么是过滤器
GatewayFilter 网关过滤器用于拦截并链式处理 web 请求,可以实现横切的与应用无关的需求,比如:安全、访问超时的设置等
在请求传递过程当中,对请求和响应进行一些额外的处理

生命周期
pre

在 pre 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等

post

在 post 类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等

分类
局部过滤器

只作用在某 一个路由上

全局过滤器

作用在全部路由上

内置局部过滤器

  • AddRequestHeader
    为原始请求添加 Header
    Header 名称及值

  • AddRequestParameter
    为原始请求添加请求参数
    参数名及值

  • AddResponseHeader
    为原始响应添加Header
    Header名称及值

  • DedupeResponseHeader
    剔除响应头中重复的值
    需要去重的Header名称及重复策略

  • Hystrix
    为路由引入 Hystrix 的断路器保护
    HystrixCommand 名称

  • FallBackHeader
    为fallbackUri的请求头中添加具体的异常信息
    Header的名称

  • PrefixPath
    为原始请求添加前缀
    前缀路径

  • PreserveHostHeader
    为请求添加一个PreservHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
    没有参数

  • RequestRateLimiter
    用于对请求限流

  • RedirectTo
    将原始请求重定向到指定的URL
    http状态码及重定向的url

  • RemoveHopByHopHeadersFilter
    为原始请求删除IETF组织规定的一系列Header
    默认就会启用

  • RewritePath
    重写原始请求路径
    原始路径正则表达式及重写后路径的正则表达式

  • RewriteResponseHeader
    重写原始请求中的某个Header
    Header名称,值的正则表达式,重写后的值

  • SaveSession
    在请求转发之前,强制执行webSession::save操作

  • secureHeaders
    为原始响应添加一系列安全作用的响应头

  • SetStatus
    修改响应的状态码
    HTTP状态码,可以是数字也可以是字符串

  • StripPrefix
    用于截断原始请求的路径
    使用数字表示要截断的路径的数量

  • Retry
    针对不同的响应进行重试

  • RequestSize
    设置允许接收最大请求包的大小
    请求包大小,单位为字节

  • ModifyRequestBody
    在转发请求之前修改原始请求体内容
    修改后的请求体内容

  • ModifyResponseBody
    修改原始响应体的内容
    修改后的响应体内容

自定义局部过滤器
与自定义谓词方式大致一样

@Component
public class LogStatusGatewayFilterFactory extends AbstractGatewayFilterFactory<LogStatusGatewayFilterFactory.Config> {public LogStatusGatewayFilterFactory() {super(LogStatusGatewayFilterFactory.Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("cacheStatus", "consoleStatus");}@Overridepublic GatewayFilter apply(Config config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {if (config.getCacheStatus())System.out.println("缓存状态");if (config.getConsoleStatus())System.out.println("控制台状态");return chain.filter(exchange);}};}@Validatedpublic static class Config {private Boolean cacheStatus;private Boolean consoleStatus;public Boolean getCacheStatus() {return cacheStatus;}public void setCacheStatus(Boolean cacheStatus) {this.cacheStatus = cacheStatus;}public Boolean getConsoleStatus() {return consoleStatus;}public void setConsoleStatus(Boolean consoleStatus) {this.consoleStatus = consoleStatus;}}
}

全局内置过滤器
在这里插入图片描述

@Component
public class TokenClobalFilter implements GlobalFilter, Ordered {/*** 过滤器执行的顺序* @return*/@Overridepublic int getOrder() {return 0;}/*** 执行过滤器逻辑* @param exchange* @param chain* @return*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if(!"admin".equals(token)){exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}
}

工作流程
示例图
在这里插入图片描述

介绍

DispatcherHandler

所有请求的调度器,负载请求分发

RoutePredicateHandlerMapping

路由谓语匹配器,用于路由的查找,以及找到路由后返回对应的 WebHandler

DispatcherHandler 会依次遍历 HandlerMapping 集合进行处理

FilteringWebHandler

使用Filter链表处理请求的 WebHandler

RoutePredicateHandlerMapping 找到路由后返回对应的 FilteringWebHandler 对请求进行处理。
FilteringWebHandler 负责组装Filter链表并调用链表处理请求。

Nacos配置中心

概述
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。
使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

快速入门

  • 客户端使用方式
    添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

编写 bootstrap.yml 配置文件

spring:profiles:active: dev  #${spring.profile.active}application:name: consumer-user  #${prefix}cloud:nacos:config:server-addr: localhost:80file-extension: yaml  #${file-extension}
  • 在 Nacos 管理中心添加配置
    在这里插入图片描述

动态刷新
在这里插入图片描述

@Value("${user.name}")
private String username;@RequestMapping("/getUserName")
public String getUserName(){return username;
}

在控制器当中添加注解 @RefreshScope

命名空间与分组
namespace 命名空间

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。
Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespae。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Group 分组

将不同的微服务划分到不同的分组当中

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

DataID

具体的配置文件地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:SpringCloud-Ali

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

猜你喜欢

转载自blog.csdn.net/lqzixi/article/details/130696393