使用Spring Cloud Gateway隱藏執行時的服務發現

banq發表於2019-07-02

很少人希望每個 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的訪問。

相關文章