Spring Cloud Gateway组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。 Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,从而加强安全保护。Spring Cloud Gateway本身也是一个微服务,需要注册进服务注册中心。
<I–图片均来自尚硅谷–>
Nginx 和 Spring Cloud Gateway 都是流行的网关技术,但它们在多个方面有所不同。Nginx 是一个用 C 语言编写的高性能 Web 服务器和反向代理,适合处理静态资源和负载均衡。而 Gateway 是基于 Spring 生态系统的响应式 API 网关,专为微服务设计,提供动态路由和细粒度的 API 管理。Nginx 通过 Lua 脚本扩展,而 Gateway 支持在 Java 框架上进行代码扩展。选择使用哪一个通常取决于项目需求:Nginx 适合作为流量入口和负载均衡器,Gateway 适合作为微服务架构中的业务网关。
三大核心: 路由(Route) 断言(Predicate) 过滤器(Filter)
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(Pre)或之后(Post)执行业务逻辑。
在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等;
在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。
核心逻辑: 路由转发+断言判断+执行过滤器链
//新建Module
//改pom
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--服务注册发现consul discovery,网关也要注册进服务注册中心统一管控-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 指标监控健康检查的actuator,网关是响应式编程删除掉spring-boot-starter-web dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
//改yml
server:
port: 9527
spring:
application:
name: cloud-gateway #以微服务注册进consul或nacos服务列表内
cloud:
consul: #配置consul地址
host: localhost
port: 8500
discovery:
prefer-ip-address: true
service-name: ${spring.application.name}
//启动类
@SpringBootApplication
@EnableDiscoveryClient//注册服务与发现
public class Main9527 {
public static void main(String[] args) {
SpringApplication.run(Main9527.class,args);
}
}
GateWay也会作为一个微服务入驻进服务注册中心
在8001端口新建PayGateWayController类
@RestController
public class PayGateWayController {
@Resource
PayService payService;
@GetMapping(value = "/pay/gateway/get/{id}")
public ResultData<Pay> getById(@PathVariable("id") Integer id)
{
Pay pay = payService.getById(id);
return ResultData.success(pay);
}
@GetMapping(value = "/pay/gateway/info")
public ResultData<String> getGatewayInfo()
{
return ResultData.success("gateway info test:"+ IdUtil.simpleUUID());
}
}
修改9527端口yml配置
server:
port: 9527
spring:
application:
name: cloud-gateway #以微服务注册进consul或nacos服务列表内
cloud:
consul: #配置consul地址
host: localhost
port: 8500
discovery:
prefer-ip-address: true
service-name: ${spring.application.name}
gateway:
routes:
- id: pay_routh1 #pay_routh1 #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/pay/gateway/get/** # 断言,路径相匹配的进行路由
- id: pay_routh2 #pay_routh2 #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/pay/gateway/info/** # 断言,路径相匹配的进行路由
访问9527映射到了8001
在通用接口新增
@GetMapping(value = "/pay/gateway/get/{id}")
public ResultData getById(@PathVariable("id") Integer id);
@GetMapping(value = "/pay/gateway/info")
public ResultData<String> getGatewayInfo();
在feign80端口新增OrderGateWayController类
@RestController
public class OrderGateWayController
{
@Resource
private PayFeignApi payFeignApi;
@GetMapping(value = "/feign/pay/gateway/get/{id}")
public ResultData getById(@PathVariable("id") Integer id)
{
return payFeignApi.getById(id);
}
@GetMapping(value = "/feign/pay/gateway/info")
public ResultData<String> getGatewayInfo()
{
return payFeignApi.getGatewayInfo();
}
}
网关关闭和网关开启都能正常访问
这是因为:同一个项目内部自己人,不经过网关,直接找微服务 外部人员访问才会经过网关
在通用接口修改代码(模拟外部人员访问)
//@FeignClient(value="cloud-payment-service")
@FeignClient(value="cloud-gateway")
网关关闭
网关开启