使用Spring Cloud Gateway隐藏运行时的服务发现


很少人希望每个 API都可以公开访问,大多数人更喜欢默认保密服务,只在绝对必要时公开API。
Spring Cloud Gateway可以提供帮助。Spring Cloud Gateway允许您使用简单的Java 指令(或YAML配置文件(我们将在本文中演示)将流量路由到您的API 。要隐藏服务,请设置网络,以便从外部访问的唯一服务器是网关。然后网关成为一个守门员,控制外部的入口和出口。这是一种非常流行的模式。

基于云的服务还习惯于在没有太多警告的情况下更改位置和粒度。为了更好地应对此问题,您可以将网关与服务注册表结合使用,以允许网络上的应用程序在运行时动态查找彼此。如果这样做,您的应用程序将更加适应变化。Spring Cloud Netflix Eureka Server就是这样一个服务注册中心。

在这篇文章中,我们将介绍Spring Cloud的网关和注册表组件,并说明如何将它们结合使用以使您的应用程序更安全,更可靠。
由于这种安排需要特定的设置,我们提供了可以下载和运行的可立即运行的代码。我们将使用Docker来协调我们的服务并模拟专用网络。然后我们将使用HTTPie与我们的运行服务交互。

需要:

  • Java(假设版本为8),以及您喜欢的Web浏览器和终端应用程序。
  • 源代码 - 这次没有必要编写任何代码,只需git clone(或下载unzip)来自GitHub的这个项目的源代码库
  • Docker Desktop - Docker将提供我们的伪生产环境。我们将使用它来隐藏我们在专用网络中的服务。
  • Cloud Native Buildpacks - 我们将使用Cloud Native Buildpacks为我们构建Docker容器映像。Buildpacks体现了几个DevOps最佳实践,包括强化的开源操作系统和免费使用的OpenJDK发行版。
  • 大约10-15分钟,具体取决于您的互联网速度等。

让我们开始吧…
步骤1:
从上面的列表中下载并安装所有“您需要的东西”。然后更改为源代码中的runtime-discovery文件夹,如下所示:
cd runtime-discovery

第2步:
使用Maven将网关,注册表和服务构建和打包到JAR中,然后为每个JAR创建Docker容器。我们提供了一个方便的pack-images脚本来执行此操作:
./pack-images.sh

第3步:
在后台启动Docker测试环境。我们在这里使用docker-compose,因为它可以启动多个容器并创建一个专用网络供他们进行通信:
docker-compose up

第4步:
等待。Docker将启动所有容器(使用docker-compose.yml文件中提供的配置)。建议在这里等几分钟。它为Docker提供了启动所有内容的时间,并为应用程序提供了沟通和安顿的机会。如果您确实等待,您应该看到Gateway和Greeting Service在注册表中注册。会有很多日志,但是在它们中会有来自注册表的这些行:

registry    | 2019-06-28 12:19:01.780  INFO 1 --- [nio-8761-exec-2] c.n.e.registry.AbstractInstanceRegistry  : Registered instance REGISTRY/db1d80613789:registry:8761 with status UP (replication=false)
registry    | 2019-06-28 12:19:02.380  INFO 1 --- [nio-8761-exec-6] c.n.e.registry.AbstractInstanceRegistry  : Registered instance GATEWAY/9c0c0c9ba027:gateway:8760 with status UP (replication=true)
registry    | 2019-06-28 12:19:02.382  INFO 1 --- [nio-8761-exec-6] c.n.e.registry.AbstractInstanceRegistry  : Registered instance SERVICE/fe7e38b21cac:service:8762 with status UP (replication=true)

我们来试试吧......

首先,检查Greeting服务是否隐藏:
Greeting Service在端口上运行,8762隐藏在Docker网络中。让我们尝试使用http:// localhost:8762 / greeting,您应该被告知您的浏览器“无法访问该网站”。这是因为该服务隐藏在Docker网络中(就好像它位于公司防火墙后面)。我们不应该直接与Greeting服务交互。

下来,通过网关访问Greeting服务:
现在,将浏览器导航到http:// localhost:8080 / service / greeting。您现在应该获得一个有效的响应,其内容类似于下面显示的“Hello,World”JSON:

{ "id": 1, "content": "Hello, World!"}

当您从浏览器发出此新HTTP请求时,它会被发送到网关并由网关处理。网关服务可公开访问(它映射到端口8080)。您的请求由网关代表您转发到问候服务,然后网关将响应路由回给您。


现在,查看服务注册表:
Docker网络上的微服务每个都在注册服务器上注册(这可能需要几分钟,所以请耐心等待)。Registry服务器充当服务的通讯簿。如果服务移动,或者如果创建了新实例,则它们会将自己添加到注册表中。
要查看已注册服务的当前列表,请将浏览器指向http:// localhost:8080 / registry

最后,关闭:
完成后,ctrl-C在终端中使用以关闭Docker服务。如果由于任何原因无法使用,您也可以使用docker-compose down该runtime-discovery文件夹。使用任何一种技术,您应该看到类似于此的输出:

Stopping gateway  ... done
Stopping service  ... done
Stopping registry ... done

实现进一步的清理docker-compose rm -f

运行原理
在这个演示中,我们有3台服务器。这些服务器都在Docker Compose提供的“隐藏”网络中运行。只有网关服务器暴露给外部世界,因此所有HTTP流量必须通过此网关。

这是3台服务器的描述以及各自的功能......

  1. 网关 - 充当我们所有HTTP流量的网守。所有入站和出站流量都通过此门户流动 - 它充当外部世界(您的浏览器)与内部Docker网络上的服务之间的桥梁。网关具有指定可用于与网络内部服务通信的路由的配置。这些路由使用目标服务的“逻辑”名称。这些逻辑名称由Registry服务器转换为实际地址。
  2. 注册表 - 充当隐藏网络上所有服务的电话簿。它允许网关仅使用其逻辑名称查找问候服务。
  3. Greeting Service - 是一个基于流行的Spring.io指南“ 构建RESTful Web服务 ” 的简单REST服务。

正如您所看到的docker-compose.yml,Docker配置为仅允许外部调用访问到网关端口80,无法直接从外部访问其他服务器(注册表和问候服务)。
可以在Gateway的application.yml文件中看到Gateway配置的URL直通路径。此配置使用这些服务器的“逻辑”名称和lb:(负载均衡器)协议,如下面的摘录所示:


spring:
  application:
    name: gateway  
  cloud:
    gateway:
      routes:
      - id: service
        uri: lb://service
        predicates:
        - Path=/service/**
        filters:
        - StripPrefix=1
...

通过使用这些“逻辑”服务器名称,Gateway可以使用Registry在运行时发现这些服务的真实位置。

总结
有了整个Spring工具包,很快就会发现Spring Cloud Gateway的灵活性和强大性。如果您深入了解源代码,您会发现只需几行Java和一些依赖项,我们就可以轻松地将Spring Boot微服务与Eureka集成,并控制对我们服务API的访问。