目录
- gateway基础版本
- pom.xml
- application.yml
- 启动类
- 测试
- gateway集成nacos
- order-nacos和stock-nacos项目微调
- cloud-gateway调整
- 测试
- gateway集成nacos简写版本
- 内置断言
- 自定义断言工厂
- 规范
- 全局过滤器
- gateway流控降级
- pom.xml
- application.yml
- 测试
- 流控具体配置
- api流控
- 降级
- 代码版本方式一
- 配置方式二
为什么要用gatewary
一般微服务项目,都是十来个服务器,大家想一下,如果我需要做限流,鉴权、项目调用参数日志等等,总不可能每个服务器都做一遍,这就也是我们要用网关的原因。
- 注意: 本文请引入父项目依赖
项目下载地址
gateway基础版本
第一步先创建cloud-gateway模块
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 引入gateway是cloud开发的,所以只要在父项目中引入cloud后,这里是不需要指定版本的
application.yml
server:
port: 8088
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
## 路由唯一id
- id: order
## 需要转发的地址
uri: http://localhost:8021
### 断言用于路由的匹配
predicates:
- Path=/order-service/**
## 转发去掉第一层路径
filters:
- StripPrefix=1
- 因为只是测试一下转发,所以暂时写死http://localhost:8021,正常应该是服务名,不然,订单服务集群后,这里一直该来该去的
- 8021是order项目的端口,之前是8001,因为端口冲突,调整成8021
启动类
package com.lcs.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication
{
public static void main(String[] args)
{
SpringApplication.run(GatewayApplication.class);
}
}
测试
运行order以及stock项目
- 注意调整一下order的端口为8021,不然启动会报端口已存在的错
输入http://localhost:8088/order-service/order/add
- 说明网关已初步完成
gateway集成nacos
order-nacos和stock-nacos项目微调
- 忘了order和stock项目都没有集成nacos配置,所以,改为用order-nacos,和stock-nacos项目
- 注意: order-nacos和stock-nacos这两个项目,之前nacos的端口写的8860,现在调整为8848
- 类似于这个图
cloud-gateway调整
server:
port: 8088
spring:
application:
name: cloud-gateway
cloud:
#配置nacos
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway:
discovery:
locator:
# 是否启动自动识别的nacos服务
# enabled: true
routes:
## 路由唯一id
- id: order
## 需要转发的地址 lb表示使用nacos里面本地负载均衡策略
uri: lb://order-service
### 断言用于路由的匹配
predicates:
- Path=/order-service/**
## 转发去掉第一层路径
filters:
- StripPrefix=1
- bak的配置文件,是基础版本的
- yml是基础nacos版本的
测试
输入http://localhost:8088/order-service/order/add/1访问订单接口
- 8088 是gateway的端口
- order-service 是路由
- /order/add/1 是接口地址
- 说明集成nacos是成功的
gateway集成nacos简写版本
在gateway集成nacos的代码版本上,只修改yml的配置
server:
port: 8088
spring:
application:
name: cloud-gateway
cloud:
#配置nacos
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
## gateway配置
gateway:
discovery:
locator:
## 是否自动识别nacos服务
enabled: true
- 删除了之前配置的断言、 过滤器等一堆代码,就简单的一行代码,做了很多的事。这就是所谓的约定大约配置,但是不太推荐使用,代码可阅读信比较差
- application.bak.yml 基本版本配置
- application.nacos.yml 跟nacos集成版本配置
- application.yml 跟nacos集成版本,简写配置
简写后,我们通过gateway怎么访问项目
以前的第一级别路径,变成我们要调用项目的服务名
- 标红就是第一次级别服务名
- 访问后,能返回结果,说明成功,记得重启gateway项目,如果觉得是不是上一次gateway修改后,是不是没有生效的原因,可以修改order-nacos的服务名来进行测试。
内置断言
当我们通过调用gateway时,匹配成功就路由转发,匹配失败,就404报错
内置断言别人博客地址
自定义断言工厂
idea中按住shift,两次
输入QueryRoute
点击抽象类,输入
Ctrl + Alt + B,可以跳转到实现该方法的类
规范
- 必须被spring容器管理
- 类名以RoutePredicateFactory结尾
- 必须集成AbstractRoutePredicateFactory类
- 必须声明静态内部类
- 结合shortcutFieldOrder来进行绑定
- 通过apply方法来判断,true表示成功
- 这就是静态内部类
全局过滤器
- lb就是使用的负载均衡过滤器
package com.lcs.springcloud.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author wu
* @version 1.0
* @date 2024/4/10 15:28
*/
@Component
public class LogFilter implements GlobalFilter {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info(exchange.getRequest().getPath().value());
return chain.filter(exchange);
}
}
- 分别启动这三个项目
输入http://localhost:8088/order-service/order/add/1
- 打印日志成功
#gateway跨域处理
### 跟nacos集成版本
server:
port: 8088
spring:
application:
name: cloud-gateway
cloud:
#配置nacos
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway:
discovery:
locator:
# 是否启动自动识别的nacos服务
# enabled: true
routes:
## 路由唯一id
- id: order
## 需要转发的地址 lb表示使用nacos里面本地负载均衡策略
uri: lb://order-service
### 断言用于路由的匹配
predicates:
- Path=/order-service/**
## 转发去掉第一层路径
filters:
- StripPrefix=1
globalcors:
cors-configurations:
'[/**]':
allowedMethods: "*"
allowedHeaders: "*"
allowedOriginPatterns: "*"
allowCredentials: true
gateway流控降级
在这个项目基础上调整
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</project>
application.yml
### 跟nacos集成版本
server:
port: 8088
spring:
application:
name: cloud-gateway
cloud:
#配置nacos
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway:
discovery:
locator:
# 是否启动自动识别的nacos服务
# enabled: true
routes:
## 路由唯一id
- id: order
## 需要转发的地址 lb表示使用nacos里面本地负载均衡策略
uri: lb://order-service
### 断言用于路由的匹配
predicates:
- Path=/order-service/**
## 转发去掉第一层路径
filters:
- StripPrefix=1
globalcors:
cors-configurations:
'[/**]':
allowedMethods: "*"
allowedHeaders: "*"
allowedOriginPatterns: "*"
allowCredentials: true
sentinel:
transport:
dashboard: 127.0.0.1:8080
- 增加如上配置,记得启动sentinel服务。端口是8080
测试
输入http://localhost:8088/order-service/order/add/1
去流控的管理界面输入localhost:8080. 账号和密码都是sentinel。如果不熟悉,请跳转到sentinel篇
- 多了一个cloud-gateway服务
- 设置api请求,一秒2次
再去访问接口
http://localhost:8088/order-service/order/add/1
- 表示流控成功
流控具体配置
- 增加一个匹配固定127.0.0.1的流控
- 只有访问的地址是127.0.0.1的时候,才会流控
api流控
可以理解会一次对多个接口进行流控处理
再去访问order/add接口,效果跟之前一样
降级
- 不要通过请求来设置降级,会提示这个报错,通过流控规则去设置,跟sentinel一样,不清楚的,可以查看我历史博客。
代码版本方式一
package com.lcs.springcloud.filter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import javax.annotation.PostConstruct;
import java.util.HashMap;
/**
* 限流降级方式一
*/
@Configuration
public class GatewayConfig {
@PostConstruct
public void init() {
BlockRequestHandler blockRequestHandler = (serverWebExchange, throwable) -> {
HashMap<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.TOO_MANY_REQUESTS.value());
map.put("msg", "请稍后再试...");
map.put("success", true);
//自定义异常处理
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(map));
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
- 正常里面会判断流控、降级、热点 等等
配置方式二
sentinel:
transport:
dashboard: 127.0.0.1:8080
# 限流降级方式二
scg:
fallback:
# 响应模式 response、redirect
mode: response
# 响应状态码
response-status: 444
# 响应信息
response-body: "{\"code\":\"429\",\"msg\":\"请求太多了\"}"
- 记得注释代码版本,方便测试
代码