使用 Spring Cloud Gateway 隱藏服務 & 執行階段探索

工程 | Ben Wilcock | 2019年7月1日 | ...

Ben Wilcock – Spring Marketing, Pivotal. Brian McClain – Technical Marketing, Pivotal.

很少有公司希望每個 API 都可公開存取。大多數公司更喜歡預設情況下將其服務保密,僅在絕對必要時才公開公開 API。

Spring Cloud Gateway 可以提供協助。Spring Cloud Gateway 允許您使用簡單的 Java™ 指令(我們在上一篇文章中看到了)或 YAML 組態檔(我們將在本篇文章中示範)將流量路由到您的 API。要隱藏您的服務,您可以設定您的網路,以便唯一可以從外部存取的伺服器是 gateway。然後,gateway 成為一個守門員,控制來自外部的進入和退出。這是一個非常流行的模式。

基於雲端的服務也經常在沒有太多警告的情況下更改位置和粒度。為了更好地應對這一點,您可以將 gateway 與服務註冊表結合使用,以允許網路上的應用程式在執行階段動態地找到彼此。如果您這樣做,您的應用程式將更能適應變化。Spring Cloud Netflix Eureka Server 就是這樣一個服務註冊表。

在這篇文章中,我們將研究 Spring Cloud 的 gateway 和註冊表元件,並說明如何將它們結合使用,使您的應用程式更安全、更可靠。

由於這種安排需要特定的設定,我們提供了現成的程式碼供您下載和執行。我們將使用 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 將 gateway、registry 和 service 建置 & 封裝到 JAR 中,然後為每個建立 Docker 容器。我們提供了一個方便的 pack-images 腳本來執行此操作

 ./pack-images.sh

步驟 3

在背景啟動 Docker 測試環境。我們在這裡使用 docker-compose,因為它可以啟動多個容器並建立一個私有網路供它們進行通訊

docker-compose up

步驟 4

等待。Docker 將啟動所有容器(使用 docker-compose.yml 檔案中提供的組態)。建議在這裡多等待幾分鐘。它讓 Docker 有時間啟動所有東西,並讓應用程式有機會進行通訊和穩定下來。如果您等待,您應該會看到 Gateway 和 Greeting Service 向 Registry 註冊自己。將會有大量的日誌,但其中將包含來自註冊表之類的行

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 Service 是否已隱藏

Greeting Service 在連接埠 8762 上運作,並隱藏在 Docker 網路中。讓我們嘗試使用 https://127.0.0.1:8762/greeting 從您最喜歡的瀏覽器呼叫它。您的瀏覽器應該會告訴您「無法連線到該網站」。這是因為 Greeting Service 隱藏在 Docker 網路中(就像它在公司防火牆後面一樣)。我們不應該可以直接與 Greeting Service 進行通訊。相反,您會看到類似於下面顯示的錯誤頁面。

Screenshot from the browser window showing that the service is unreachable

下一步,透過 Gateway 存取 Greeting Service

現在,將您的瀏覽器導覽至 https://127.0.0.1:8080/service/greeting。您現在應該會收到有效的響應,其內容類似於下面顯示的「Hello, World」JSON

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

當您從瀏覽器發出這個新的 HTTP 請求時,它會傳送到 Gateway 並由 Gateway 處理。Gateway 服務可以公開存取(它對應到連接埠 8080)。您的請求由 Gateway 代表您轉發到 Greeting Service,然後響應由 Gateway 路由回給您。

現在,檢視服務註冊表

Docker 網路上的微服務會各自向註冊伺服器註冊(這可能需要幾分鐘,請耐心等候)。註冊伺服器充當服務的通訊錄。如果服務移動,或建立新的實例,它們會將自己新增到註冊表中。

若要檢視目前已註冊的服務清單,請將瀏覽器指向 https://127.0.0.1:8080/registry。您應該會看到類似於以下的畫面。

Screenshot from the Registry console, listing several services

最後,關閉

完成後,請在終端機中使用 ctrl-C 來關閉 Docker 服務。如果由於任何原因而無法運作,您也可以從 runtime-discovery 資料夾中使用 docker-compose down。使用任一種技術,您都應該會看到類似於此的輸出

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

可以使用 docker-compose rm -f 來達成進一步的清除。

運作方式

在此示範中,我們有 3 個伺服器。這些伺服器全部都在由 Docker Compose 提供的「隱藏」網路內執行。只有 閘道伺服器 暴露於外部世界,因此所有 HTTP 流量都必須透過此閘道。

以下是 3 個伺服器的說明,以及每個伺服器的用途...

  1. 閘道 – 充當所有 HTTP 流量的守門員。所有傳入和傳出的流量都會通過此入口網站 – 它充當外部世界 (您的瀏覽器) 與內部 Docker 網路上的服務之間的橋樑。閘道有一個組態,指定可用於與網路內服務通訊的路徑。這些路徑使用目標服務的「邏輯」名稱。這些邏輯名稱會由註冊伺服器轉換為真實位址。

  2. 註冊表 – 充當隱藏網路上所有服務的電話簿。它允許閘道僅使用其邏輯名稱來尋找問候服務。

  3. 問候服務 – 是一個基於熱門 Spring.io 指南「建立 RESTful Web 服務」的簡單 REST 服務。

如您在 docker-compose.yml 中所見,Docker 已設定為僅允許外部呼叫到達連接埠 80 上的閘道。其他伺服器(註冊表和問候服務)無法從外部直接連線。

閘道已設定的 URL 傳遞路徑可在閘道的 application.yml 檔案中看到。此組態使用這些伺服器的「邏輯」名稱,以及 lb: (負載平衡器) 協定,如下面的摘錄所示

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

透過使用這些「邏輯」伺服器名稱,閘道可以使用註冊表來探索這些服務在執行階段的真實位置。

總結

有了整個 Spring 工具組可供您使用,Spring Cloud Gateway 的彈性和強大功能很快就會變得顯而易見。如果您深入研究 原始碼,您會注意到,只需幾行 Java 和幾個相依性,我們就可以輕鬆地將 Spring Boot 微服務與 Eureka 整合,並控制對服務 API 的存取。

在您完成之前,何不註冊參加 SpringOne Platform 2019 – 這是建立可擴充且讓使用者滿意的應用程式的首要會議。加入成千上萬志同道合的 Spring 開發人員,在德州奧斯丁從 10 月 7 日到 10 日學習、分享和享受樂趣。註冊時使用折扣代碼 S1P_Save200 即可省錢購買門票。如果您需要協助說服您的經理,請使用此頁面。到時候見。

取得 Spring 電子報

與 Spring 電子報保持連線

訂閱

取得領先

VMware 提供訓練和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部