移动网站自助制作,黑龙江建设网政务系统,wordpress分享qq插件下载,中国招标采购网gateway-网关 网关spring cloud gatewaygateway初体验gateway整合nacos简写方式 内置路由断言工厂内置断言工厂 自定义路由断言工厂自定义路由工厂 内置/自定义过滤器典型内置过滤器自定义过滤器 全局过滤器自定义全局过滤器 请求日志记录跨域处理Gateway跨域配置#xf… gateway-网关 网关spring cloud gatewaygateway初体验gateway整合nacos简写方式 内置路由断言工厂内置断言工厂 自定义路由断言工厂自定义路由工厂 内置/自定义过滤器典型内置过滤器自定义过滤器 全局过滤器自定义全局过滤器 请求日志记录跨域处理Gateway跨域配置CORS Configration gateway整合sentinel流控降级设置dashboard流控规则进行测试gateway整合sentinel流控降级详细配置还可以根据api分组对不同的api接口进行流控自定义流控异常 网关 在微服务架构中一个系统会被拆分成多个微服务。那么作为客户端(前端)要如何去调用这么多的微服务如果没有网关的存在我们只能在客户端记录每个微服务的地址然后分别去用。 这样的架构会存在诸多的问题
每个业务都会需要鉴权、限流、权限校验、跨域等逻辑如果每个业务都各自为站。自己造轮子实现一遍完全没必要完全可以抽离出来放到一个统一的地方去做。 上面的问题可以借助网关来解决。 网关所谓API网关就是指系统的同一入口它封装了应用程序的内部结构为客户端提供统一服务一些与业务功能本身无关的公共逻辑可以在这里实现诸如认证、鉴权、监控、路由转发等待 添加上API网关之后,系统变成三层结构系统的架构图如下 加入网关之后的架构图
spring cloud gateway 功能特征基于spring5.0和springboot2.0进行构建动态路由可以匹配任何请求属性支持路径重写集成服务发现nacos、ereka可集成流控降级功能sentinel、hystrix可以对路由指定易于编写的断言和过滤器 路由 路由是网关中最基础的部分路由信息包括一个ID、一个目的URL、一组断言工厂、一组filter组成。如果断言为真则说明请求的RUL和配置的路由匹配断言 Java8中的断言函数gateway中的断言函数类型是spring5.0框架中的servletWebExchange断言函数允许开发者去定义匹配http request中的任何信息比如请求头和参数等。过滤器 gateway中的filter分为Gateway Filter和Global Filter,filter可以对请求和响应处理 工作原理 spring cloud gateway的工作原理和zuul的差不多最大的区别就是gateway的filter只有pre和post两种。
gateway初体验
添加依赖 !--添加springcloud gateway依赖--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependency配置文件
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order-server/**# http://localhost:8090/order-server/order/buyProduct 路由到↓# http://localhost:8081/order-server/order/buyProductfilters:- StripPrefix1 #内置过滤器转发之前去掉第一层路径# http://localhost:8081/order-server/order/buyProduct 去掉后 ↓# http://localhost:8081/order/buyProductgateway整合nacos 你这个是springcloud gateway吧我跟你说一下为什么这么写配置是这样的lb代表了负载均衡有这个标志后gateway就知道需要进行负载均衡转发到lb://后面跟的服务名对应的某台服务器上至于如何实现负载均衡是通过负载均衡组件来的比如ribbon或者springcloud-loadbalancer组件拿到服务列表从而进行服务的转发。所以lb://其实跟服务注册中心没有关系就算不是nacos用其它的比如eureka也是这么写lb://。 server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: lb://order-service #需要转发的地址 lb:使用nacos中的本地负载均衡策略#断言规则 用于路由规则的匹配predicates:- Path/order-server/**# http://localhost:8090/order-server/order/buyProduct 路由到↓# http://localhost:8081/order-server/order/buyProductfilters:- StripPrefix1 #内置过滤器转发之前去掉第一层路径# http://localhost:8081/order-server/order/buyProduct 去掉后 ↓# http://localhost:8081/order/buyProduct简写方式
当服务注册到nacos后断言规则可以用服务名来进行匹配此时配置可以进行简化(约定服务名和断言规则都从nacos获取)
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:discovery:locator:enabled: true #是否启动自动识别nacos服务约定大于配置测试 此时访问http://localhost:8090/order-service/order/buyProduct
内置路由断言工厂 作用当请求gateway的时候使用断言对请求进行匹配如果匹配成功就进行路由转发如果匹配失败就返回404 内置断言工厂 基于Datetime类型的断言工厂 此类型的断言根据时间做判断主要有三个AfterRoutePredicateFactory:接收一个日期参数判断请求日期是否晚于指定日期BeforeRoutePredicateFactory:接收一个日期参数判断请求日期是否早于指定日期BetweenRoutePredicateFactory:接收一个日期参数判断请求日是否在指定时间段内 类型zoneDateTime.now():System.out.println(ZonedDateTime.now()); -After2024-12-31T23:59:59.78908:00[Asia/Shanghai] #第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2024-12-31T23:59:59.78908:00[Asia/Shanghai]基于请求头Headder的断言工厂HeaderRoutePredicateFactory:接收两个参数标题名称和正则表达式判断请求Header是否具有给定名称且值与正则表达式匹配。 HeaderX-Request-Id,\d #第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d测试 基于Method请求方法的断言工厂MethodRoutePredicateFactory:接收一个参数判断请求类型是否跟指定的类型匹配 MethodGET #第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET 基于Query请求参数的断言工厂QueryRoutePredicateFactory:接收两个参数请求param和正则表达式判断请求参数是否具有给定名称且值与正则表达式匹配。 Queryid,\d #第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d测试
自定义路由断言工厂 自定义路由断言工厂需要继承AbstractRoutePredicateFactory类重写apply方法的逻辑。在apply方法中可以通过exchange.getRequest()拿到serverletRequest对象从而可以获取到请求的参数、请求方式、请求头等信息。 1、必须是bean组件 2、由于约定大于配置类名必须加上RoutePredicateFactory作为结尾 3、必须继承AbstractRoutePredicateFactory类 4、必须声明一个静态内部类声明属性来接收配置文件中对应的信息 5、需要结合shortcutFieldOrder来进行绑定 6、通过apply进行逻辑判断true就是匹配成功false匹配失败
自定义路由工厂 -checkAuthzzq如果配置文件中checkAuthzzq则匹配通过否则匹配失败 配置文件
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzq自定义代码
Component
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactoryCheckAuthRoutePredicateFactory.Config {public CheckAuthRoutePredicateFactory() {super(CheckAuthRoutePredicateFactory.Config.class);}/*** 绑定配置信息* return*/Overridepublic ListString shortcutFieldOrder() {return Arrays.asList(name);}public PredicateServerWebExchange apply(Config config) {return new GatewayPredicate() {Overridepublic boolean test(ServerWebExchange exchange) {if (config.getName().equals(zzq)){return true;}return false;}};}/*** 用于接收配置文件中 断言的信息*/ValidatedDatapublic static class Config {private String name;}
}
测试 修改配置后
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthqwee测试
内置/自定义过滤器 gateway内置了很多的过滤器工厂我们通过一些过滤器工厂可以进行一些业务逻辑处理器添加去除参数等。 典型内置过滤器 添加请求头 AddRequestHeaderX-Request-color,red #添加请求头 #第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzqfilters:- AddRequestHeaderX-Request-color,red #添加请求头为匹配的路由添加统一前缀 PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path order.yml配置context-path
server:port: 8081servlet:context-path: /shanghaiservergateway为了适配添加前缀
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzqfilters:- AddRequestHeaderX-Request-color,red #添加请求头- PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path自定义过滤器 继承AbstractGatewayFilterFactory且自定义类的名称必须以GatewayFilterFactory结尾且必须交给spring进行管理 自定义过滤器
package com.springcloudalibaba.gateway.config;import com.alibaba.nacos.api.utils.StringUtils;
import lombok.Data;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Arrays;
import java.util.List;/*** author : zhouzhiqiang* date : 2024/6/19 12:51* description :*/
Component
public class CheckParamGatewayFilterFactory extends AbstractGatewayFilterFactoryCheckParamGatewayFilterFactory.Config {public CheckParamGatewayFilterFactory() {super(CheckParamGatewayFilterFactory.Config.class);}Overridepublic ListString shortcutFieldOrder() {return Arrays.asList(name);}Overridepublic GatewayFilter apply(Config config) {return new GatewayFilter() {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {String name exchange.getRequest().getQueryParams().getFirst(name);if (!StringUtils.isBlank(name)) {//如果相等请求被放过if (config.getName().equals(name)) {return chain.filter(exchange);} else {//如果不相等返回404exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);return exchange.getResponse().setComplete();}}return chain.filter(exchange);}};}/*** 用于接收配置文件中 过滤器的信息*/ValidatedDatapublic static class Config {private String name;}
}
配置自定义的过滤器工厂
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzqfilters:- AddRequestHeaderX-Request-color,red #添加请求头- PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path- CheckParamzzq测试成功 失败
全局过滤器 对比局部过滤器全局过滤器会对所有的路由请求进行过滤 局部局部针对某个路由需要在路由中进行配置 全局针对所有路由一旦定义了就会投入使用 自定义全局过滤器
Component
public class LogFilter implements GlobalFilter {Logger log LoggerFactory.getLogger(this.getClass());Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(请求地址{}, exchange.getRequest().getPath().value());return chain.filter(exchange);}
}此时gateway会拦截所有的请求并打印出请求地址
请求日志记录跨域处理
要启用Reactor Netty访问日志请设置-Dreactor.netty.http.server.accessLogEnabledtrue 它必须是Java系统属性而不是Spring Boot属性
配置文件
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzqfilters:- AddRequestHeaderX-Request-color,red #添加请求头- PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path- CheckParamzzq
logging:file:name: D:/logs/service.logmax-size: 500MB测试 此时日志会被记录到D:\logs\service.log
Gateway跨域配置CORS Configration
配置文件
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- HeaderX-Request-Id,\d- MethodGET- Queryid,\d- CheckAuthzzqfilters:- AddRequestHeaderX-Request-color,red #添加请求头- PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path- CheckParamzzqglobalcors:cors-configurations:[/**]: #允许跨域访问的资源allowedOrigins: * #跨域允许的来源allowedMethods:- GET- POST
logging:file:name: D:/logs/service.logmax-size: 500MB在springboot中还可以通过配置类的方式进行配置
Configuration
public class CorsFilter {Beanpublic CorsWebFilter corsWebFilter(){CorsConfiguration config new CorsConfiguration();config.addAllowedOrigin(*); //允许的来源config.addAllowedHeader(*); //允许的请求头config.addAllowedMethod(*); //允许的请求方法UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration(/**,config);return new CorsWebFilter(source);}
}gateway整合sentinel流控降级 网关作为内部系统外的一层屏障对内起到一定的保护作用限流就是其中之一。网关层的限流可以简单地针对不同路由进行限流也可针对业务的接口进行限流或者根据接口的特征分组限流。 添加依赖 !--gateway整合sentinel进行限流--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-sentinel-gateway/artifactId/dependency添加配置
#第一版
server:port: 8090
# gateway配置
spring:application:name: api-gatewaycloud:#nacos配置nacos:discovery:server-addr: 192.168.184.15:8848username: nacospassword: nacos#gateway配置gateway:#路由规则routes:- id: order_router #路由的唯一标识,路由到orderuri: http://localhost:8081 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path/order/**- After2023-12-31T23:59:59.78908:00[Asia/Shanghai]- MethodGETfilters:- PrefixPath/shanghaiserver #添加前缀 对应微服务需要配置context-path# 整合sentinelsentinel:transport:dashboard: 192.168.184.15:8080
logging:file:name: D:/logs/service.logmax-size: 500MB测试代码
RestController
RequestMapping(/order)
public class OrderController {Autowiredprivate IStockService stockService;RequestMapping(/buyProduct)public String buyProduct(RequestHeader(X-Request-color) String color){System.out.println(开始下单);System.out.println(color);//开始扣减库存stockService.detectStock();return 下单并扣除库存成功;}/*** QPS流控规则测试* return*/RequestMapping(/flow)public String flow(){return 正常访问;}/*** 并发线程数流控规则测试* return*/RequestMapping(/flowThread)public String flowThread(){try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}return 正常访问;}}启动dashboard 请求接口进行测试
设置dashboard流控规则进行测试 QPS测试dashboard配置 测试结果
gateway整合sentinel流控降级详细配置
通过请求属性就和之前配置的断言一样 案例测试–比如URL参数设置为namezzq 测试 此时限流 案例测试–比如把Header设置为X-Request-Idzzq 测试结果 此时限流
还可以根据api分组对不同的api接口进行流控
添加api分组 配置api流控 测试
自定义流控异常
Configuration
public class GateWayExceptionConfig {PostConstructpublic void sentinelResponse(){BlockRequestHandler requestHandler new BlockRequestHandler() {Overridepublic MonoServerResponse handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {//自定义异常MapString,String exMapnew HashMap();exMap.put(code, HttpStatus.TOO_MANY_REQUESTS.toString());exMap.put(msg,限流了);return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(exMap));}};GatewayCallbackManager.setBlockHandler(requestHandler);}
}
测试