SpringCloud(五)Gateway 路由网关

一、路由网关

官网地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

我们需要连接互联网,那么就需要将手机或是电脑连接到家里的路由器才可以,而路由器则连接光猫,光猫再通过光纤连接到互联网,也就是说,互联网方向发送过来的数据,需要经过路由器才能到达我们的设备。而路由器充当的就是数据包中转站,所有的局域网设备都无法直接与互联网连接,而是需要经过路由器进行中转,我们一般说路由器下的网络是内网,而互联网那一端是外网。

我们的局域网设备,无法被互联网上的其他设备直接访问,肯定是能够保证到安全性的。并互联网发送过来的数据,需要经过路由器进行解析,识别到底是哪一个设备的数据包,然后再发送给对应的设备。

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

路由的实现一般使用Zuul,但是已经停更,而现在新出现了由SpringCloud官方开发的Gateway路由,它相比Zuul不仅性能上得到了一定的提升,并且是官方推出,契合性也会更好

1.部署网关

现在我们来创建一个新的项目,作为我们的网关,这里需要添加两个依赖:

<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依赖,使用的是WebFlux框架。

然后我们来完善一下配置文件:

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/**  # 只要是访问的这个路径,一律都被路由到上面指定的服务

路由规则的详细列表(断言工厂列表)在这里:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories,可以指定多种类型,包括指定时间段、Cookie携带情况、Header携带情况、访问的域名地址、访问的方法、路径、参数、访问者IP等。也可以使用配置类进行配置,但是还是推荐直接配置文件,省事。


接着启动网关可以看到,我们现在可以直接通过路由来访问我们的服务了:

 注意此时依然可以通过原有的服务地址进行访问:

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

2.路由过滤器

路由过滤器支持以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应,路由过滤器的范围是某一个路由,跟之前的断言一样,Spring Cloud Gateway 也包含许多内置的路由过滤器工厂,详细列表:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

比如我们现在希望在请求到达时,在请求头中添加一些信息再转发给我们的服务,那么这个时候就可以使用路由过滤器来完成,我们只需要对配置文件进行修改:
 

spring:application:name: gatewaycloud:gateway:routes:- id: borrow-serviceuri: lb://borrowservicepredicates:- Path=/borrow/**# 继续添加新的路由配置,这里就以书籍管理服务为例# 注意-要对齐routes:- id: book-serviceuri: lb://bookservicepredicates:- Path=/book/**filters:   # 添加过滤器- AddRequestHeader=Test, HelloWorld!# AddRequestHeader 就是添加请求头信息,其他工厂请查阅官网

接着我们在BookController中获取并输出一下,看看是不是成功添加了:


@RestController
@RequestMapping("/book")
public class BookController {@Resourceprivate BookService bookService;@GetMapping("/getBookById/{bid}")public Book getBookById(@PathVariable("bid") Integer bid,HttpServletRequest request){System.out.println(request.getHeader("Test"));return bookService.getBookById(bid);}
}

现在我们通过Gateway访问我们的图书管理服务:

 

 

可以看到这里成功获取到由网关添加的请求头信息了。

除了针对于某一个路由配置过滤器之外,我们也可以自定义全局过滤器,它能够作用于全局。但是我们需要通过代码的方式进行编写,比如我们要实现拦截没有携带指定请求参数的请求:

@Component   //需要注册为Bean
public class TestFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {   //只需要实现此方法return null;}
}

接着我们编写判断:

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

可以看到结果:

 

成功实现规则判断和拦截操作。

当然,过滤器肯定是可以存在很多个的,所以我们可以手动指定过滤器之间的顺序:

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于C语言设计的足球信息查询系统

完整资料进入【数字空间】查看——baidu搜索"writebug" 需求分析与概要设计 2.1 项目说明 我们小组的选题主要是面向足球爱好者&#xff0c;在普通社交软件的基础之上&#xff0c;围绕足球的主题展开设计&#xff0c;以便于他们能够更好的交流相关的话题&#xff…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接&#xff0c;进入国务院政策文件库&#xff0c;分为国务院文件和部门文件&#xff08;发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

C语言-排序,初识指针

目录 【1】冒泡排序&#xff08;从小到大&#xff09; 【2】选择排序 【3】二维数组 【4】指针 【5】指针修饰 【6】大小端 【7】初见二级指针 练习&#xff1a; 【1】冒泡排序&#xff08;从小到大&#xff09; #include <stdio.h> //数组哪里的\0?自己和字符串…

异步任务——CompletabelFuture

本专栏学习内容又是来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 在学习CompletableFuture之前&#xff0c;必须要先了解一下Future Future 概念 Future接口&#xff08;FutureTask实现类&#xff09;定义了操作异步任务执行的一些方法&#xff0c;如获取异…

Android应用启动全流程分析(源码深度剖析)

作者&#xff1a;努比亚技术团队 源码来源&#xff1a;努比亚技术团队 1.前言 从用户手指点击桌面上的应用图标到屏幕上显示出应用主Activity界面而完成应用启动&#xff0c;快的话往往都不需要一秒钟&#xff0c;但是这整个过程却是十分复杂的&#xff0c;其中涉及了Android系…

【java】【基础2】程序流程控制

目录 一、最经典的三种执行顺序 二、分支结构 2.1 if 2.2 switch 2.3 if与switch区别 三、循环结构 3.1 for循环 3.2 while循环 3.3 do-while循环 3.4 三种循环区别 3.5 补充知识&#xff1a;死循环 3.6 补充知识&#xff1a;循环嵌套 四、跳转关键字&#xff1a;br…

自建DNSlog服务器

DNSlog简介 在某些情况下&#xff0c;无法利用漏洞获得回显。但是&#xff0c;如果目标可以发送DNS请求&#xff0c;则可以通过DNS log方式将想获得的数据外带出来。 DNS log常用于以下情况&#xff1a; SQL盲注无回显的命令执行无回显的SSRF 网上公开提供dnslog服务有很多…

MySQL 主从复制与读写分离

概念 主从复制与读写分离的意义 企业中的业务通常数据量都比较大&#xff0c;而单台数据库在数据存储、安全性和高并发方面都无法满足实际的需求&#xff0c;所以需要配置多台主从数据服务器&#xff0c;以实现主从复制&#xff0c;增加数据可靠性&#xff0c;读写分离&#x…