《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
Spring Cloud Gateway是Spring官方基于Spring5.0、SpringBoot2.0和Project Reactor等技术开发的网关
旨在为微服务框架提供一种简单而有效的统一的API路由管理方式,统一访问接口。
Spring Cloud Gateway作为Spring Cloud生态体系中的网关,目标是替代Netflix的Zuul,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等等。
它是基于Netty的响应式开发模式。
1、路由(route):路由是网关最基础的部分,路由信息由一个ID,一个目的URL、一组断言工厂和一组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。
2、断言(Predicate):Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自http Request中的任何信息,比如请求头和参数等。
3、过滤器(Filter):一个标准的Spring WebFilter,Spring Cloud Gateway中的Filter分为两种类型:Gateway Filter和Global Filter。过滤器Filter可以对请求和响应进行处理
2、基本搭建
①、新建模块
②、导入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
4.0.0
com.gateway
code
0.0.1-SNAPSHOT
gateway
Demo project for Spring Boot
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-boot.version>2.4.1</spring-boot.version>
<spring-cloud.version>2020.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
org.springframework.boot
spring-boot-starter-webflux
org.springframework.boot
spring-boot-starter-test
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.boot
spring-boot-starter-actuator
org.projectlombok
lombok
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
org.springframework.cloud
spring-cloud-loadbalancer
com.alibaba
fastjson
1.2.35
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.81.8
UTF-8
org.springframework.boot
spring-boot-maven-plugin
2.4.1
com.gateway.code.GatewayApplication
repackage
repackage
③、nacos中注册服务
yml文件:
server:
#此处的8084端口号,就好像以前外置的tomcat的8080,让我们通过浏览器进行访问
#但此服务只是做了一个路由,它会将请求路由到其它微服务(一般是消费者)进行处理
port: 8084
spring:
application:
#微服务名
name: gateway
cloud:
nacos:
discovery:
#指定nacos注册中心的地址
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
以前:localhost:8082/user/aa
路由:localhost:8084/consumer/user/aa
路由:localhost:8084/provider/user/aa
#是否与服务发现组件进行结合,通过service-id(必须设置成大写)转发到具体的服务实例。默认false
#为true代表开启基于服务发现的路由规则。
enabled: false
#配置之后访问时service-id无需大写
lower-case-service-id: true
routes: #路由
# 路由标识(id:标识,具有唯一性)
- id: user-consumer-api
#目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死
uri: lb://consumer
#优先级,越小越优先
#order: 999
#路由条件(predicates:断言)
predicates:
# 路径匹配,
localhost:8082/user/aa 不能进入
localhost:8082/cum/user/aa 能
- Path=/cum/**
filters: #过滤器
#路径前缀删除示例:请求/name/bar/foo,StripPrefix=2,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo
#前缀过滤,请求地址:http://localhost:8084/usr/hello
#此处配置去掉1个路径前缀,再配置上面的 Path=/usr/,就将转发到指定的微服务
#因为这个api相当于是服务名,只是为了方便以后nginx的代码加上去的,对于服务提供者service-client来说,不需要这段地址,所以需要去掉
- StripPrefix=1
#生产者
# 路由标识(id:标识,具有唯一性)
- id: user-provider-api
#目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死
uri: lb://provider
#优先级,越小越优先
#order: 999
#路由条件(predicates:断言)
predicates:
# 路径匹配,
- Path=/api/prv/**
filters:
#路径前缀删除示例:请求/name/bar/foo,StripPrefix=2,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo
#前缀过滤,请求地址:http://localhost:8084/usr/hello
#此处配置去掉1个路径前缀,再配置上面的 Path=/usr/,就将转发到指定的微服务
#因为这个api相当于是服务名,只是为了方便以后nginx的代码加上去的,对于服务提供者service-client来说,不需要这段地址,所以需要去掉
- StripPrefix=2
logging:
level:
#开启spring-Cloud-gateway的日志级别为debug,方便debug调试
org.springframework.cloud.gateway: trace
org.springframework.http.server.reactive: debug
org.springframework.web.reactive: debug
reactor.ipc.netty: debug
#springboot监控Actuator,暴露所有端点
management:
endpoints:
web:
exposure:
include: ‘*’
#自定义配置
gateway:
nacos:
#配置中心地址
server-addr: ${spring.cloud.nacos.discovery.server-addr}
#指定环境
namespace: xxx-xx-xx-xx
#读取配置管理中的Data Id
data-id: dynamic-routing.json
group: DEFAULT_GROUP
④、启动类GatewayApplication
增加注解
@EnableDiscoveryClient
运行:
3、路由方式1
yml文件:
gateway:
discovery:
locator:
#是否与服务发现组件进行结合,通过service-id(必须设置成大写)转发到具体的服务实例。默认false
#为true代表开启基于服务发现的路由规则。
enabled: true
#配置之后访问时service-id无需大写
lower-case-service-id: true
得到三种服务方式:
4、路由定义
路径分离:
yml文件:
routes: #路由
路由标识(id:标识,具有唯一性)
- id: user-consumer-api
#目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死
uri: lb://consumer
#优先级,越小越优先
#order: 999
#路由条件(predicates:断言)
predicates:
路径匹配,
localhost:8082/user/aa 不能进入
localhost:8082/cum/user/aa 能
- Path=/cum/**
filters: #过滤器
#路径前缀删除示例:请求/name/bar/foo,StripPrefix=2,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo
#前缀过滤,请求地址:http://localhost:8084/usr/hello
#此处配置去掉1个路径前缀,再配置上面的 Path=/usr/,就将转发到指定的微服务
#因为这个api相当于是服务名,只是为了方便以后nginx的代码加上去的,对于服务提供者service-client来说,不需要这段地址,所以需要去掉
- StripPrefix=1
#生产者
路由标识(id:标识,具有唯一性)
- id: user-provider-api
#目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死
uri: lb://provider
#优先级,越小越优先
#order: 999
#路由条件(predicates:断言)
predicates:
路径匹配,
- Path=/api/prv/**
filters:
#路径前缀删除示例:请求/name/bar/foo,StripPrefix=2,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo
#前缀过滤,请求地址:http://localhost:8084/usr/hello
#此处配置去掉1个路径前缀,再配置上面的 Path=/usr/,就将转发到指定的微服务
#因为这个api相当于是服务名,只是为了方便以后nginx的代码加上去的,对于服务提供者service-client来说,不需要这段地址,所以需要去掉
- StripPrefix=2
5、动态路由设置
①、自定义配置
yml文件:
#自定义配置
gateway:
nacos:
#配置中心地址
server-addr: ${spring.cloud.nacos.discovery.server-addr}
#指定环境
namespace: xxx-xx-xx-xx
#读取配置管理中的Data Id
data-id: dynamic-routing.json
group: DEFAULT_GROUP
在配置列表中新增配置dynamic-routing.json:
配置内容:
{
“refreshGatewayRoute”: true,
“routeList”: [
{
“id”: “consumer-api”,
“predicates”: [
{
“name”: “Path”,
“args”: {
“_genkey_0”: “/cum/**”
}
}
],
“filters”: [
{
“name”: “StripPrefix”,
“args”: {
“_genkey_0”: “1”
}
}
],
“uri”: “lb://consumer”,
“order”: 0
},
{
“id”: “provider-api”,
“predicates”: [
{
“name”: “Path”,
“args”: {
“_genkey_0”: “/api/pvr/**”
}
}
],
“filters”: [
{
“name”: “StripPrefix”,
“args”: {
“_genkey_0”: “2”
}
}
],
“uri”: “lb://provider”,
“order”: 0
}
]
}
②、解析
Ⅰ、yml注入到实体类
FilterEntity:
package com.gateway.code.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- @author hgh
*/
@SuppressWarnings(“all”)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class FilterEntity {
//过滤器对应的Name
private String name;
//路由规则
private Map<String, String> args = new LinkedHashMap<>();
}
GatewayNacosProperties:
package com.gateway.code.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@SuppressWarnings(“all”)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ConfigurationProperties(prefix = “gateway.nacos”)
@Component
public class GatewayNacosProperties {
private String serverAddr;
private String dataId;
private String namespace;
private String group;
}
PredicateEntity:
package com.gateway.code.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- @author hgh
*/
@SuppressWarnings(“all”)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class PredicateEntity {
//断言对应的Name
private String name;
//断言规则
private Map<String, String> args = new LinkedHashMap<>();
}
结语
小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。
我们选择的这个行业就一直要持续的学习,又很吃青春饭。
虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
送给每一位想学习Java小伙伴,用来提升自己。
本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
PredicateEntity:
package com.gateway.code.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- @author hgh
*/
@SuppressWarnings(“all”)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class PredicateEntity {
//断言对应的Name
private String name;
//断言规则
private Map<String, String> args = new LinkedHashMap<>();
}
结语
小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。
我们选择的这个行业就一直要持续的学习,又很吃青春饭。
虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
送给每一位想学习Java小伙伴,用来提升自己。
[外链图片转存中…(img-9EL5qp7Y-1714760931519)]
本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!