前言
场景:后台服务经常要给各个服务发送请求,想要发送请求就要知道地址,比如写了一个端口在1号机器,如果1号机器掉线了,难道要手动在前段切换到2号机器吗?我们这个服务可能是十几台机器同时上线,某一个用不了要能动态的自动切换,不可能天天去后台修改端口,这样肯定不合格的。所以就有了网关,向后台发送的所有请求都要经过网关,网关帮我们动态的路由到各个服务,网关还能从注册中心实时的感知某个服务注册上线或者下线,总是能帮我们把请求正确的路由到指定位置;不止如此,后期还会有这种需求,某一个请求过来,我们需要加上权限,鉴权或者监控,如果我们把这些写在各个服务上,就会有许多重复开发,我们可以有一个统一的鉴权,限流、日志等处理,随后再讲请求发往各个服务。所以使用spring-cloud提供的Gateway来实现这个功能。
Gateway 网关是流量的入口,常用功能包括路由转发。权限校验。限流控制等。Spring-cloud gateway作为SpringCloud官方提供的第二代网关框架,取代了zuul网关。
官方文档:https://spring.io/projects/spring-cloud-gateway
官方文档都是一些专业的术语,初次接触也看不懂,直接搬视频中的实例,以谷粒商城为例
首先,创建一个springboot module,搜索gateway,finish
同样需要依赖common,在pom中添加common依赖,因为网关也需要注册到注册中心,也要发现其他服务所在的位置,这样请求过来的时候,才能准确的把请求路由到指定位置
检查一下springboot的版本,要和之前的服务的版本一致
接着想测试一下网关注册到注册中心,首先,在启动类,添加@EnableDiscoveryClient
开启服务注册发现,在application.properties配置好配置中心地址和应用名
然后添加配置中心的配置文件bootstrap.properties,在nacos命名空间新建一个命名空间gateway,以后gateway的所有配置修改都可以在这个命名空间下进行修改发布
新建一个配置,使用默认的group,点击发布
这样就有了一个gateway专属的命名空间
在bootstrap.properties配置文件中添加相关的配置,应用名称、注册中心地址、命名空间的id,然后就可以启动服务测试
**PS:**如果此时启动报错,应该是因为有test包,每次运行都会先打包运行测试类,也不想删test类,就引入这个依赖,跳过测试类的打包执行,不太了解,先解决再说
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
重新启动,test是解决了,又会报一个错,是我们没有数据库等相关的配置,因为我们依赖了common这个服务,而common的pom总引入了mybatisplus,那就会有数据源的相关自动配置,而在gateway中没有配置相关的数据源,所以启动失败。因为网关也不需要和数据库打交道,就可以排除掉数据库有关的依赖,可以在pom中使用exclude排除,也可以在启动类中添加注解
排除掉数据源的配置
再次启动,成功,修改下端口,改为88
现在没有做什么的配置,如果我们想用这个网关转发,不如输入http://localhost:88/hello?url=qq xaingzhuan到qq的页面,那就要按照官方文档的配置来设置
新建一个application.yml,开发时可以先将配置写在本地,上线可以搬到配置中心,先配置路由规则,这个规则是一个数组,意思是可以配置同级很多个,判断规则是,满足某种断言,就可以转到某个给定的地址
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com //满足下面的断言条件就跳转到这个地址
predicates:
- Query=url,baidu //地址中包含url,baidu就跳转到上面的地址
启动服务,浏览器输入地址http://localhost:88/hello?url=baidu
虽然是404,但是这是代表真的去转发到我们配置的地址了,只不过我们在url的?前面加了hello,浏览器就去访问www.baidu.com/hello,这个地址当然是不存在的
当吧?前面的hello去掉,再次访问,这样就访问成功了。