Gateway 路由网关

2年前未命名101
Gateway 路由网关 散漫的大学生 于2023-01-07 20:55:32发布 459 收藏 文章标签: gateway java

一般情况下,并不是所有的微服务都需要直接暴露给外部调用,这时就可以使用路由机制,添加一层防护,让所有的请求全部通过路由来转发到各个微服务,并且转发给多个相同微服务实例时还也可以实现负载均衡。为此SpringCloud官方推出了Gateway路由

部署网关

创建一个新的项目,作为网关服务,并添加两个依赖

<dependencies>     <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-starter-gateway</artifactId>     </dependency>     <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>     </dependency> </dependencies>

第一个依赖就是网关的依赖,而第二个则跟其他微服务一样,需要注册到Eureka才能生效,注意别添加Web依赖

修改配置文件

server:   port: 8500 eureka:   client:     service-url:       defaultZone: http://localhost:8801/eureka, http://localhost:8802/eureka spring:   application:     name: gateway

接着将路由功能进行配置

spring:   cloud:     gateway:         # 配置路由,注意这里是个列表,每一项都包含了很多信息       routes:        - id: borrow-service   # 路由名称          uri: lb://borrowservice  # 路由的地址,lb表示使用负载均衡到微服务,也可以使用http正常转发          predicates: # 路由规则,断言什么请求会被路由          - Path=/borrow/**  # 只要是访问的这个路径,一律都被路由到上面指定的服务

路由规则的详细列表(断言工厂列表)

Spring Cloud Gateway

可以指定多种类型,包括指定时间段、Cookie携带情况、Header携带情况、访问的域名地址、访问的方法、路径、参数、访问者IP等。也可以使用配置类进行配置,推荐直接配置文件

现在可以直接通过路由来访问服务了

这样就可以将不需要外网直接访问的微服务全部放到内网环境下,而只依靠网关来对外进行交涉。

路由过滤器

路由过滤器支持修改传入的 HTTP 请求或传出的 HTTP 响应,路由过滤器的范围是某一个路由,跟之前的断言一样,Spring Cloud Gateway 也包含许多内置的路由过滤器工厂,详细列表:Spring Cloud Gateway

样例

比如我们现在希望在请求到达时,在请求头中添加一些信息再转发给相关的服务

只需要对配置文件进行修改

spring:   application:     name: gateway   cloud:     gateway:       routes:       - id: borrow-service         uri: lb://borrowservice         predicates:         - Path=/borrow/**       # 继续添加新的路由配置,这里就以书籍管理服务为例       - id: book-service         uri: lb://bookservice         predicates:         - Path=/book/**         filters:   # 添加过滤器         - AddRequestHeader=test, HelloWorld         # AddRequestHeader 就是添加请求头信息,其他工厂查阅官网

接着可以在bookservice的controller中获取一下

@RestController public class BookController { @Resource BookService service; @RequestMapping("/book/{bid}") Book findBookById(@PathVariable("bid") int bid, HttpServletRequest request){ System.out.println(request.getHeader("test")); return service.getBookById(bid); } }

除了针对于某一个路由配置过滤器之外,也可以自定义全局过滤器,它能够作用于全局

此时需要实现globalFilter接口并实现它唯一的方法,再将该类注册为bean

@Component //需要注册为Bean public class TestFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //先获取ServerHttpRequest对象,注意不是HttpServletRequest ServerHttpRequest request = exchange.getRequest(); //打印一下所有的请求参数 System.out.println(request.getQueryParams()); //判断是否包含test参数,且参数值为1 List<String> value = request.getQueryParams().get("test"); if(value != null && value.contains("1")) { //将ServerWebExchange向过滤链的下一级传递 return chain.filter(exchange); }else { //直接在这里不再向下传递,然后返回响应 return exchange.getResponse().setComplete(); } } }

当过滤器存在很多个时,可以手动指定过滤器之间的顺序,实现Ordered接口,方法返回数值越小,过滤器越靠前

@Component public class TestFilter implements GlobalFilter, Ordered { //实现Ordered接口 @Override public int getOrder() { return 0; } }

无论是在配置文件中编写的单个路由过滤器还是全局路由过滤器,都会受到Order值影响(单个路由的过滤器Order值按从上往下的顺序从1开始递增),最终是按照Order值决定哪个过滤器优先执行,当Order值一样时 全局路由过滤器执行优于单独的路由过滤器执行

标签: [db:标签TAG]

相关文章

一文说清楚http、tcp、socket、websocket区别

一文说清楚http、tcp、socket、websocket区别...

2022个人年度总结:拒绝无效努力,实现破圈成长。

2022个人年度总结:拒绝无效努力,实现破圈成长。...

再不跳槽,就晚了

再不跳槽,就晚了...

【Spring事务】声明式事务 使用详解

【Spring事务】声明式事务 使用详解...

学习 Python 之 Pygame 开发魂斗罗(一)

学习 Python 之 Pygame 开发魂斗罗(一)...

MySQL 高级查询

MySQL 高级查询...