gateway<1>

1,我们今天说下网关gateway ,如果没有网关的话我们 前端 调用后台服务的话 每一个服务都的要配置一个ip:port,假如我们的服务比较多的话  我前端要维护这个ip:port 都很多

在这里插入图片描述

所以使用了网关这个组件  gateway 网关

在这里插入图片描述

我们这里的网关就相当于nginx 的作用 前端只需要配置网关地址 就可以了让网关去做对应的路由转发
1.网关 配置 1,pom--nacos 因为网关是从 nacos拉取服务的--<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>--gateway 的pom--<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
2. application.yml
server:port: 9901
spring:application:name: mall-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848 # nacos gateway:discovery:locator:# 开启微服务的调用    一般是要关闭 的  配置这个 当我们#用 localhost:9901/微服务名:就能调用到对应微服务了   一般是要求关闭的 因为这样保护我们对应的服务(不让微服务暴露在外面)enabled: true # 开启网关enabled: true

在这里插入图片描述

我这里order服务  9900
和gateway 服务  9901
我此时 吧这2个服务都注册在nacos 上了  因为我现在		gateway.discovery.locator.true 所以 我此时
通过
http://localhost:9901/mall-order/就可以访问到order上的方法 mall-order  为order服务的spring:application:name: mall-order
    order 服务 中很简单  就一个类
@RestController
@Slf4jpublic class OrderService {@GetMapping("/")public String getOrder() {log.info("order.info..." + "1");return "hellOrder";}
}

在这里插入图片描述

我通过http://localhost:9901/mall-order/
这样就访问到了 order服务
gateway中有
路由
断言
过滤器
server:port: 9901
spring:application:name: mall-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:discovery:locator:# 关闭微服务的调用enabled: false# 开启网关enabled: true--# 引用配置文件profiles:active: after-route

在这里插入图片描述

我此时用这个 断言工厂 他的predicates  这个是断言的意思在 2020-12-16T15:53:22.999+08:00 以后我才可以访问我的 mall-order
spring:cloud:gateway:routes:- id: before-route #id必须要唯一uri: lb://mall-orderpredicates:#通过System.out.println(ZonedDateTime.now())- Before=2030-12-16T15:53:22.999+08:00[Asia/Shanghai]##  当引入这个的时候 就意味着在
2030-12-16T15:53:22.999+08:00[Asia/Shanghai]  以前才可以访问我的mall-order
#
spring:cloud:gateway:routes:- id: between-route #id必须要唯一uri: lb://mall-orderpredicates:#通过System.out.println(ZonedDateTime.now())- Between=2020-12-16T15:53:22.999+08:00[Asia/Shanghai],2030-12-16T15:53:22.999+08:00[Asia/Shanghai]
#  当引入这个的时候 就意味着 时间介于
2020-12-16T15:53:22.999+08:00[Asia/Shanghai]2030-12-16T15:53:22.999+08:00[Asia/Shanghai]
中间才可以访问我的 mall-order  微服务
predicates 断言就意味着符合条件可以访问我的微服务, 不符合条件就访问不了我的微服务
spring:cloud:gateway:routes:- id: cookie-route #id必须要唯一uri: lb://mall-orderpredicates:#当我们的请求中包含了Cookie name=Company value=Tuling- Cookie=Company,Tuling
#  这里就是 我们的请求的Cookie必须要有Company=Tuling 才可以访问

在这里插入图片描述

此时我浏览器 没有加对应cookie,我在postman中加入了cookie,这样我在浏览器中就访问不到 , 我在postman中就可以访问到

在这里插入图片描述

# 一样header中
spring:cloud:gateway:routes:- id: header-route #id必须要唯一uri: lb://mall-orderpredicates:#header的k=X-Request-appId v=Tuling才会被转发到- Header=X-Request-appId,Tuling

在这里插入图片描述

此时header 在浏览器中中 没有X-Request-appId  因此转发不到对应的请求
我的请求在 http://localhost:9901/  在postman中 因此可以转发该请求在请求头中添加这个header了

在这里插入图片描述

predicates  有这个条件我就让你过  没有这个条件我就不让你过
我们可以自定义断言类 比如说现在是23.20  我让时间在早上7点到晚上1133的时候
经过请求spring:cloud:gateway:routes:- id: xiaolv-timeBetween #id必须要唯一uri: lb://mall-orderpredicates:- XiaoLvTimeBetween=上午7:00,下午11:33

在这里插入图片描述

我们可以自定义断言规则
@Component
///  XiaoLvTimeBetween【这里和配置xml的 】  - XiaoLvTimeBetween=上午7:00,下午11:33 保持一致
public class XiaoLvTimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<XiaoLvTimeBetweenConfig> {public XiaoLvTimeBetweenRoutePredicateFactory() {super(XiaoLvTimeBetweenConfig.class);}@Overridepublic Predicate<ServerWebExchange> apply(XiaoLvTimeBetweenConfig config) {//获取配置 中的开始时间LocalTime startTime = config.getStartTime();LocalTime endTime = config.getEndTime();return new Predicate<ServerWebExchange>(){@Overridepublic boolean test(ServerWebExchange serverWebExchange) {LocalTime now = LocalTime.now();///  对应业务逻辑  和xml的匹配规则return now.isAfter(startTime) && now.isBefore(endTime);}};}public List<String> shortcutFieldOrder() {return Arrays.asList("startTime", "endTime");}}
#  配置类
@Data
public  class XiaoLvTimeBetweenConfig {private LocalTime startTime;private LocalTime endTime;
}
上述就是断言机制  下来就过滤器 过滤器 就是 经过网关的请求 我们都会给他加上对应的参数 
这下我吧order中的代码改了@GetMapping("/")public String getOrder() {ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();// 获取响应体 responseHttpServletResponse response = ((ServletRequestAttributes) requestAttributes).getResponse();HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();String headValue = request.getHeader("X-Request-Foo");//获取单个请求头name对应的value值System.out.println("请求头...."+headValue+"....");String foo = request.getParameter("foo");System.out.println("请求参数...."+foo+"....");log.info("order.info..." + "1");return "hellOrder";}yml
spring:cloud:gateway:routes:- id: before-route #id必须要唯一uri: lb://mall-orderpredicates:#通过System.out.println(ZonedDateTime.now())- Before=2030-12-16T15:53:22.999+08:00[Asia/Shanghai]filters:# 过滤器 经过每一次网关的请求都会携带请求头 key = X-Request-Foo value=Bar- AddRequestHeader=X-Request-Foo, Bar# 过滤器 经过每一次网关的请求都会携带请求参数 key =foo value=bar- AddRequestParameter=foo, bar-   # 过滤器 经过每一次网关的请求都会携带响应头参数 key =X-Response-Foo  value=bar- AddResponseHeader=X-Response-Foo, Bar# https://blog.csdn.net/weixin_45829957/article/details/120210979?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-1-120210979-blog-102564769.pc_relevant_default&spm=1001.2101.3001.4242.2&utm_relevant_index=4具体可以看大佬博客

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

# 满足我的请求 我都会给添加一个请求参数
我们看看啊日志就能拿到对应的数据了  这样就可以给每一个过网关的请求和响应增加对应参数了
我也可以自定义过滤器 比如说我要实现一个耗时的监控 类似于aopspring:cloud:gateway:routes:- id: before-route #id必须要唯一uri: lb://mall-orderpredicates:#通过System.out.println(ZonedDateTime.now())- After=2020-12-16T15:53:22.999+08:00[Asia/Shanghai]filters:#  是否是开启 的 是 - TimeMonitor=enabled,true

在这里插入图片描述

package com.lvhao.filter;import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Slf4j
@Component
public class TimeMonitorGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {private static final String COUNT_START_TIME = "countStartTime";@Overridepublic GatewayFilter apply(NameValueConfig config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String name = config.getName();String value = config.getValue();log.info("name:{},value:{}",name,value);#false 不做处理if(value.equals("false")) {return chain.filter(exchange);}// 我拿到开始时间exchange.getAttributes().put(COUNT_START_TIME, System.currentTimeMillis());//then方法相当于aop的后置通知一样return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {///  调用完毕整个链路会回调 这里的run方法@Overridepublic void run() {System.out.println("shart 耗时");Long startTime = exchange.getAttribute(COUNT_START_TIME);if (startTime != null) {StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath()).append(": ")// 运行结束时间.append(System.currentTimeMillis() - startTime).append("ms");sb.append(" params:").append(exchange.getRequest().getQueryParams());log.info("耗时:"+sb.toString());}}}));}};}}

在这里插入图片描述

如果想实现过滤器的排序问题 我们可以用order   order 越低越靠前 
我此时的过滤器是作用在 微服务上,也就是说我一个微服务上可以作用1个或者多个Filter
我如何设置一个全局Filter

在这里插入图片描述

设置全局网关 全局Filter @Component
@Slf4j
public class  AuthGateWayFilter implements GlobalFilter,Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {List<String> token = exchange.getRequest().getHeaders().get("token");if(StringUtils.isEmpty(token)) {.. 如果token 为空 返回json 格式响应前端ServerHttpResponse response = exchange.getResponse();JSONObject jsonObject = new JSONObject();jsonObject.put("code","401");jsonObject.put("message","非法请求");byte[] datas = JSON.toJSONString(jsonObject).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(datas);response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");return response.writeWith(Mono.just(buffer));}else {.. 如果token 不为空 呢么就 将token传递到下面的微服务中log.info("token:{}",token);return chain.filter(exchange);}}@Overridepublic int getOrder() {return 0;}
}
我们接下来看下gateway +sentinel 做网关级别的限流
1.pom <dependencies><!-- SpringCloud Gateway --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- SpringCloud Ailibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Ailibaba Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- SpringCloud Ailibaba Sentinel Gateway --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency></dependencies>
2.
# 端口
server:port: 10010
#应用名
spring:application:name: mall-gateway-sentinel# 网关要从nacos 拉取服务名称  nacos 配置cloud:nacos:discovery:server-addr: localhost:8848# 网关配置gateway:discovery:locator:# 开启微服务的调用enabled: false# 开启网关enabled: true# sentinel 面板地址sentinel:transport:dashboard: localhost:8080
#  加载网关 路由设置  还是跟以前一样profiles:active: before-route
#  网关路由设置
spring:cloud:gateway:routes:- id: before-route #id必须要唯一uri: lb://mall-orderpredicates:#通过System.out.println(ZonedDateTime.now())- After=2020-12-16T15:53:22.999+08:00[Asia/Shanghai]

在这里插入图片描述

当我们启动该工程的时候,并且启动sentinel ,  访问
http://localhost:10010/  进行跳转到对应的微服务时候 

在这里插入图片描述

我们就可以看到sentinel 面板上面的的 东西了
api名称是资源名称 然后他此时只有一个流控和降级 当我们设置流控规则

在这里插入图片描述

我此时基于微服务做的流控规则

在这里插入图片描述

他此时的RouteId 是基于微服务做的限流策略 ,api分组可以让我们的限流做到一个更加细粒化,比如这里我要/a,/b的请求归为一组 组名叫做【test1】

在这里插入图片描述

在这里插入图片描述

这里我们就能够对具体的接口进行限流策略了当然当前后端分离的时候 我们可以做到网管级别的跨域  以及在网关级别做自定义全局异常


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部