1、SpringGateway简介
核心功能有三个:
-
路由:用于设置转发地址的
-
断言:用来判断真实应该请求什么地址
-
过滤器:可以过滤地址和处理参数
1、什么是网关
网关是后台服务的统一入口,类似于平时网络里提到的网关。
2、为什么用网关【为了跨服务转发】
在微服务架构开发中,网关是必要有的服务,它可以统一入口,解决跨域,负载均衡,各微服务通信等微服务整体管理和通信的。
场景:如果没有网关,前台要查用户信息,先往user的微服务下发送请求。然后又要查学生的信息,再往student的微服务下发送请求。这样的话,我要知道所有的微服务,他们的ip是什么?他们的端口是什么?才能把请求发送到他们的里面。那对于前端来讲的话,他要管理的微服务就太多了。而且还有一个问题,前端这么做,它是没有负载均衡的。它不知道我究竟应该发给谁?比如说user这个服务现在搭建了集群有三个,那请求过来了,我究竟是往集群里的哪一个发送呢?对于前端来说也是不知道的。
后台为了解决这个问题,就是你别搞这么复杂了,发送请求的时候都往一个地址发,但是url不一样。至于跳到哪个微服务,我后台来解决。Gateway就是专门来处理这个事的。在网关里面 集成了负载均衡 咱们就不用考虑这集群起来的微服务该给哪一个发了。
对于前端来讲,它发的不是网关的请求地址,而是nginx 的请求地址。发送到nginx地址后,再通过反向代理,代理到网关上。所以对于前端来说,只需要知道nginx就可以了,网关是不暴露给前端的。
一般来说都会为网关建立一个单独的微服务。
2、应用:
1.启动nacos
2.创建网关项目
【2.1添加依赖】
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
<jwt.version>0.7.0</jwt.version>
<fastjson.version>1.2.60</fastjson.version>
<spring-cloud-alibaba.version>2.0.3.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
【2.2】创建启动类:
package com.jr;
@SpringBootApplication
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class,args);
}
}
【注意】
网关是一个非常干净的工程,不会添加其它中间件的配置,所以网关工程里只有一个Application的启动类和配置文件。
启动类的注解@SpringBootApplication注解中可能开启的其它中间件的@EnableXXX,可以把其它中间件的注解排除掉,保证网关只启动自己的应用,只完成网关功能。
# 如果导入别人的项目,依赖是有传递性的这样你的项目里依赖的中间件就会很多,可以通过exclude属性排除掉。这样其他的中间件就不会启动了。 @SpringBootApplication(exclude = {XXXX.class, YYYY.class})
【2.3】编写bootstrap.yml配置文件
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.43.8:8848
config:
server-addr: 192.168.43.8:8848
inetutils:
preferred-networks: 192.168.56
【2.4】编写application.properties配置文件
spring.application.name=gateway ##设置项目的注册名
server.port=300 ## 设置项目的端口号 以上两个设置放在同一个配置文件里。
【2.5】启动项目
需要编写一个public包下的index.html页面
3.网关配置1
网关配置官方文档: Spring Cloud Gateway
【3.0】改动:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
修改为:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>compile</scope>
</dependency>
【3.1】添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
【3.2】添加application.yml 配置文件:
spring: cloud: gateway: routes: - id: baidu_route(路由id唯一,是一个数组,可以配置多个路由) uri: https://www.baidu.com(路由到的地址) predicates:(断言) - Query=url, baidu(如果存在url和baidu,那么跳转到uri地址)
spring:
cloud:
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Query=baidu
【3.3】启动项目:
http://localhost:300/baidu不会跳转到百度,http://localhost:300/baidu?baidu才会跳转到百度,是根据参数做断言。
【说明:】
http://127.0.0.1:300/baidu?empno 不能跳转到百度
http://127.0.0.1:300/baidu?ename 可以跳转到百度
【启动过程中,报错 java52版本过低,不能启动60版本,--->试着修改下面的的java版本】
4.网关配置2【了解】
-
The Path Route Predicate Factory
Path路由断言工厂接受一个参数:采用Spring PathMatcher 模式。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
请求需要以red或者blue结尾,后面的参数会路由过去 例如:/red/1 ,/red/blue ,/blue/green等。
spring:
cloud:
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Path=/red/**
5.过滤器配置【了解】
公式模板
- id: third_party_route
uri: lb://service-name
predicates:
- Path=/url1/url2/urln/**
filters:
- RewritePath=/url1/url2/urln/(?<segment>/?.*),/$\{segment}
例子代码
spring:
cloud:
gateway:
routes:
#用户中心
- id: user-route
uri: lb://user
predicates:
- Path=/api/services/user/**
filters:
- RewritePath=/api/services/user/(?<segment>/?.*),/user/$\{segment}
id:取一个名字,自定义,见名知意,不要有下划线(规约)
uri:接收请求后真实转发的地址,lb:开头代表用负载均衡的方式找注册中心名字叫user服务的微服务
predicates:请求地址是以/api/services/user/开头,后接任意字符
filters:将请求地址重写成:/user/+参数/方法等