上面一篇文章实现了sentinel容错:spring cloud alibaba (4)-sentinel实现容错
这篇文章介绍一下spring cloud alibaba 实现gateway网关功能。
实现流程:
网关作为spring cloud一个重要组成部分,主要是用来保护和控制API接口的访问。
gateway的主要作用是所有微服务的“入口”。
核心功能有三个:路由、权限控制、限流。
几个重要的概念:
- 路由:路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组成。如果断言路由为真,则说明请求的URL和配置匹配
- 断言:匹配的规则。Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自于httprequest中的任何信息,比如请求头和参数等。
- 过滤器:一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理。
1.创建gateway模块
我们右击父模块,创建一个子module,命名为gateway。
引入pom文件参考如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>s-cloud-alibaba</artifactId> <groupId>site.longkui</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>gateway</artifactId> <dependencies> <!--nacos 服务注册与发现模块--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--nacos Config 依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <!-- gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> </dependencies> </project>
这个地方需要说明的是,不要引入spring web boot模块,会有如下报错:
***************************
APPLICATION FAILED TO START
***************************
Description:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
Action:
Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
然后创建application.yml配置文件,参考如下:
server: port: 10050 #服务的端口 #spring相关配置 spring: application: name: service-gateway #服务的名称 cloud: nacos: discovery: server-addr: localhost:8848 #注册到nacos gateway: discovery: locator: enabled: true #开启注册中心路由功能 routes: #路由数组可以放多个路由。满足什么条件转发到哪个微服务上 - id: gateway1 # 路由ID,命名随意,只要保证唯一性即可 uri: http://127.0.0.1:8010 #要转发的地址 (这里是前面创建的一个生产者的接口) predicates: - Path=/service-consumer/** #当请求路径满足path指定的规则时,才进行路由转发 filters: - StripPrefix=1 #转发之前去掉1层路径
这个地方首先建议,不熟的话就直接赋值下来然后自己改,有的地方必须满足空格的要求。这里我们网关为了测试,指向的端口是8010端口。
然后创建启动类,参考如下:
package site.longkui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class GateWay { public static void main(String[] args) { SpringApplication.run(GateWay.class, args); } }
然后启动这个模块。
在nacos中查看是否正常注册:
2.基础测试
我们这里要测试网关,所以访问10050端口,访问测试如下:
http://localhost:10050/service-consumer/user/getUser
可以看出,我们访问的是网关的接口,正常访问到前面已经创建的生产者的端口的数据。
3.以服务的方式访问
我们修改pom文件:
server: port: 10050 #服务的端口 #spring相关配置 spring: application: name: service-gateway #服务的名称 cloud: nacos: discovery: server-addr: localhost:8848 #注册到nacos gateway: discovery: locator: enabled: true #开启注册中心路由功能 routes: #路由数组可以放多个路由。满足什么条件转发到哪个微服务上 - id: gateway1 # 路由ID,命名随意,只要保证唯一性即可 uri: lb://service-producer #以服务名获取,并遵循负载均衡策略 predicates: - Path=/abc/** #当请求路径满足path指定的规则时,才进行路由转发 filters: - StripPrefix=1 #转发之前去掉1层路径
这里需要说明的是,使用lb,需要引入下面的依赖,
<!-- 负载均衡--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
如果没有引入这个依赖,有可能会出现下面的报错:
[e0270bdf-6] There was an unexpected error (type=Service Unavailable, status=503).
效果:
4.简写版
很多时候为了简单起见,就直接简写了。直接把路由部分注释掉即可:
server: port: 10050 #服务的端口 #spring相关配置 spring: application: name: service-gateway #服务的名称 cloud: nacos: discovery: server-addr: localhost:8848 #注册到nacos gateway: discovery: locator: enabled: true #开启注册中心路由功能 # routes: #路由数组可以放多个路由。满足什么条件转发到哪个微服务上 # 直接访问模式 # - id: gateway1 # 路由ID,命名随意,只要保证唯一性即可 # uri: http://127.0.0.1:8010 #要转发的地址 (这里是前面创建的一个生产者的接口) # predicates: # - Path=/abc/** #当请求路径满足path指定的规则时,才进行路由转发 # filters: # - StripPrefix=1 #转发之前去掉1层路径 # 服务访问模式 # - id: gateway1 # 路由ID,命名随意,只要保证唯一性即可 # uri: lb://service-producer #以服务名获取,并遵循负载均衡策略 # predicates: # - Path=/abc/** #当请求路径满足path指定的规则时,才进行路由转发 # filters: # - StripPrefix=1 #转发之前去掉1层路径
就发现只要按照 网关地址/微服务/接口 的格式去访问,就可以得到成功响应。比如这样:
http://localhost:10050/service-producer/user/getUser
这里service-producer 是微服务名。后面就是具体接口。localhost:10050是网关地址。