【Gateway】网关服务快速上手

微服务的接口都是直接对外暴露的,可以直接通过外部访问,为了保证对外服务的安全性服务端实现的微服务接口通常都带有一定的权限校验机制,由于使用了微服务,原本一个应用的的多个模块拆分成了多个应用,我们不得不实现多次校验逻辑,当这套逻辑需要修改时,我们需要修改多个应用,加重了开发人员的负担。

针对以上问题,一个常用的解决方案就是使用API网关

1. 什么是API网关

API网关(简称网关) 也是一个服务,通常是后端服务的唯一入口.它的定义类似设计模式中的Facade模式(门面模式,也称外观模式).它就类似整个微服务架构的门面,所有的外部客户端访问,都需要经过它来进行调度和过滤.

网关的核心功能

  • 权限控制: 作为微服务的入口,对用户进行权限校验,如果校验失败则进行拦截
  • 动态路由:一切请求先经过网关,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务
  • 负载均衡: 当路由的目标服务有多个时,还需要做负载均衡
  • 限流: 请求流量过高时,按照网关中配置微服务能够接受的流量进行放行,避免服务压力过大

类似前台的⼯作

  1. 权限控制: ⾝份验证
  2. 动态路由: 根据外来客⼾的需求, 把客⼾带到指定的部⻔去处理
  3. 负载均衡: ⼀个部⻔有很多⼈时, 前台会帮客⼾选择具体某个⼈处理
  4. 限流: 公司到访客⼾较多时, 进⾏流量限制, ⽐如告知明天再来

2. 常见的网关实现

业界常⽤的⽹关⽅式有很多, 技术⽅案也较成熟, 其中不乏很多开源产品, ⽐如Nginx, Kong, Zuul,
Spring Cloud Gateway等. 下⾯介绍两种常⻅的⽹关⽅案.
Zuul

Zuul 是 Netflix 公司开源的一个API网关组件,是Spring Cloud Netflix 子项目的核心组件之它可以和 Eureka、Ribbon、Hystrix等组件配合使用.在Spring Cloud Finchley正式版之前, Spring Cloud推荐的网关是Netflix提供的Zuul(此处指Zuul 1.X)然而Netflix在2018年宣布一部分组件进入维护状态,不再进行新特性的开发,这部分组件中就包含Zuul.

Spring Cloud Gateway

Spring Cloud Gateway是Spring Cloud的一个全新的API网关项目,基于Spring+SpringBoot等技术开发,目的是为了替换掉Zuu!.旨在为微服务架构提供一种简单而有效的途径来转发请求,并为他们提供横切关注点,比如: 安全性,监控/指标和弹性。

在性能方面,根据官方提供的测试报告,Spring Cloud Gateway的RPS(每秒请求数)是Zuul的1.6倍.测试报告参考: https://github.com/spencergibb/spring-cloud-gateway-bench

3. Spring cloud gateway

3.1 快速上手

3.1.1 创建网关项目

API⽹关也是⼀个服务.

3.1.2 引入依赖

bash 复制代码
<!--⽹关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--基于nacos实现服务发现依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

3.1.3 编写启动类

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class , args);
    }
}

3.1.4 添加Gateway的路由配置

bash 复制代码
server:
  port: 10030 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      discovery:
        server-addr: nacosIp:端口
    gateway:
      routes: # 网关路由配置
        - id: product-service # 路由ID, 自定义, 唯一即可
          uri: lb://product-service # 目标服务地址
          predicates: # 路由条件
            - Path=/product/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

3.1.5 测试

启动网关服务。

1. 通过网关服务访问product-service,http://127.0.0.1:10040/product/1001

url符合yml文件中配置的 /product/**规则,路由转发到product-service: http://product-service/product/1001

通过网关服务的日志,可以观察到,网关服务从Nacos获取服务列表

bash 复制代码
2024-09-12T17:32:13.372+08:00  INFO 3356 --- [t.remote.worker] com.alibaba.nacos.common.remote.client   : [9f9c4461-ebf3-41cd-b9ee-17605253a90b] Notify connected event to listeners.
2024-09-12T17:32:13.372+08:00  INFO 3356 --- [t.remote.worker] com.alibaba.nacos.client.naming          : Grpc connection connect
2024-09-12T17:32:13.372+08:00  INFO 3356 --- [           main] com.alibaba.nacos.common.remote.client   : [9f9c4461-ebf3-41cd-b9ee-17605253a90b] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler
2024-09-12T17:32:13.374+08:00  INFO 3356 --- [           main] com.alibaba.nacos.common.remote.client   : [9f9c4461-ebf3-41cd-b9ee-17605253a90b] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$845/0x000002623b5a34f8
2024-09-12T17:32:13.376+08:00  INFO 3356 --- [           main] com.alibaba.nacos.client.naming          : [REGISTER-SERVICE] fcc2c221-085b-4864-bff4-f1f18f734cb0 registering service gateway with instance Instance{instanceId='null', ip='192.168.5.1', port=10040, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='DEFAULT', serviceName='null', metadata={IPv6=[2001:0:2851:b9f0:24d7:f521:fe3d:44e3], preserved.register.source=SPRING_CLOUD}}
2024-09-12T17:32:13.421+08:00  INFO 3356 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP gateway 192.168.5.1:10040 register finished
2024-09-12T17:32:13.498+08:00  INFO 3356 --- [           main] com.guan.gateway.GatewayApplication      : Started GatewayApplication in 8.144 seconds (process running for 9.467)
2024-09-12T17:41:02.993+08:00  INFO 3356 --- [oundedElastic-1] com.alibaba.nacos.client.naming          : [SUBSCRIBE-SERVICE] service:product-service, group:DEFAULT_GROUP, clusters: 
2024-09-12T17:41:03.079+08:00  INFO 3356 --- [oundedElastic-1] com.alibaba.nacos.client.naming          : init new ips(1) service: DEFAULT_GROUP@@product-service -> [{"instanceId":"192.168.5.1#9090#BJ#DEFAULT_GROUP@@product-service","ip":"192.168.5.1","port":9090,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"BJ","serviceName":"DEFAULT_GROUP@@product-service","metadata":{"preserved.register.source":"SPRING_CLOUD","IPv6":"[2001:0:2851:b9f0:24ce:ef45:fe3d:44e3]"},"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000}]
2024-09-12T17:41:03.090+08:00  INFO 3356 --- [oundedElastic-1] com.alibaba.nacos.client.naming          : current ips:(1) service: DEFAULT_GROUP@@product-service -> [{"instanceId":"192.168.5.1#9090#BJ#DEFAULT_GROUP@@product-service","ip":"192.168.5.1","port":9090,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"BJ","serviceName":"DEFAULT_GROUP@@product-service","metadata":{"preserved.register.source":"SPRING_CLOUD","IPv6":"[2001:0:2851:b9f0:24ce:ef45:fe3d:44e3]"},"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000}]
2024-09-12T17:41:03.615+08:00  INFO 3356 --- [.42.168.168-161] com.alibaba.nacos.common.remote.client   : [9f9c4461-ebf3-41cd-b9ee-17605253a90b] Receive server push request, request = NotifySubscriberRequest, requestId = 3
2024-09-12T17:41:03.616+08:00  INFO 3356 --- [.42.168.168-161] com.alibaba.nacos.common.remote.client   : [9f9c4461-ebf3-41cd-b9ee-17605253a90b] Ack server push request, request = NotifySubscriberRequest, requestId = 3

2. 通过网关访问order-service

http://127.0.0.1:10040/order/1

url符合yml文件中配置的 /order/**规则,路由转发到product-service: http://product-order/product/1

相关推荐
ruleslol1 分钟前
java基础概念37:正则表达式2-爬虫
java
I_Am_Me_7 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
重生之我是数学王子17 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
xmh-sxh-131417 分钟前
jdk各个版本介绍
java
Ai 编码助手18 分钟前
使用php和Xunsearch提升音乐网站的歌曲搜索效果
开发语言·php
学习前端的小z22 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
神仙别闹30 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE31 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
天天扭码37 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶37 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露