共用方式為


線上並與 Service Fabric 中的服務通訊

在 Service Fabric 中,服務會在 Service Fabric 叢集中的某處執行,通常是分散到多個 VM。 它可以由服務擁有者或 Service Fabric 自動從某個位置移至另一個位置。 服務不會以靜態方式系結至特定計算機或位址。

Service Fabric 應用程式通常由許多不同的服務組成,其中每個服務都會執行特製化工作。 這些服務可能會彼此通訊以形成完整的功能,例如轉譯 Web 應用程式的不同部分。 也有用戶端應用程式會連線到服務並與其通訊。 本文件討論如何在 Service Fabric 中設定與服務之間的通訊。

如需也會討論服務通訊的訓練影片,請查看此頁面:

攜帶您自己的通訊協定

Service Fabric 可協助管理服務的生命週期,但不會決定您的服務用途。 這包括通訊。 當 Service Fabric 開啟您的服務時,這是您的服務使用您想要的任何通訊協定或通訊堆棧,為連入要求設定端點的機會。 您的服務會使用任何尋址配置來接聽一般 IP:埠 位址,例如URI。 多個服務實例或複本可能會共用主機進程,在此情況下,它們將需要使用不同的埠或使用埠共享機制,例如 Windows 中的 http.sys 核心驅動程式。 不論是哪一種情況,主機進程中的每個服務實例或複本都必須是唯一可尋址的。

服務端點

服務發現與解析

在分散式系統中,服務可能會隨著時間從一部計算機移至另一部計算機。 這可能會因為各種原因而發生,包括資源平衡、升級、故障轉移或向外延展。這表示服務端點位址會隨著服務移至具有不同IP位址的節點而變更,如果服務使用動態選取的埠,可能會在不同的埠上開啟。

服務的分配

Service Fabric 提供稱為命名服務的探索和解析服務。 命名服務會維護一個表格,將命名服務的實例對應至其接聽的端點位址。 Service Fabric 中的所有具名服務實例都有唯一的名稱,以 URI 表示,例如 "fabric:/MyApplication/MyService"。 服務的名稱不會在服務的存留期內變更,它只是服務移動時可以變更的端點位址。 這類似於具有常數 URL 但 IP 位址可能會變更的網站。 與將網站 URL 解析為 IP 位址的 Web DNS 類似,Service Fabric 具有將服務名稱對應至其端點地址的註冊機構。

此圖顯示 Service Fabric 具有將服務名稱對應至其端點地址的註冊機構。

解析並連線到服務包括在迴圈中執行下列步驟:

  • 解決:取得服務從命名服務發佈的端點。
  • 線上:透過它在該端點上使用的任何通訊協定連接到服務。
  • 重試:連線嘗試可能會因為任何原因而失敗,例如,如果服務自上次解析端點位址之後已移動。 在此情況下,必須重試上述的解析和連線步驟,而且此循環會重複,直到連線成功為止。

聯機到其他服務

聯機到叢集內彼此的服務通常可以直接存取其他服務的端點,因為叢集中的節點位於相同的局域網路上。 為了方便在服務之間連線,Service Fabric 會提供使用命名服務的其他服務。 DNS 服務和反向 Proxy 服務。

DNS 服務

由於許多服務,特別是容器化服務,可以有現有的URL名稱,因此能夠使用標準 DNS 通訊協定來解析這些服務(而不是命名服務通訊協定),非常方便,特別是在應用程式「隨即轉移」案例中。 這正是 DNS 服務的功能。 它可讓您將 DNS 名稱對應至服務名稱,進而解析端點 IP 位址。

如下圖所示,在 Service Fabric 叢集中執行的 DNS 服務會將 DNS 名稱對應至服務名稱,然後由命名服務解析,以傳回要連線的端點位址。 建立時會提供服務的 DNS 名稱。

此圖顯示 DNS 服務如何在 Service Fabric 叢集中執行時,將 DNS 名稱對應至服務名稱,然後由命名服務解析,以傳回要連線的端點位址。

如需如何使用 DNS 服務的詳細資訊,請參閱 Azure Service Fabric 中的 DNS 服務 一文。

反向 Proxy 服務

反向代理會處理叢集中公開的 HTTP 和 HTTPS 端點的服務。 反向代理具備特定的 URI 格式,並負責處理解析、連接、重試步驟,使用命名服務讓一個服務能夠與另一個服務通訊,從而大幅簡化呼叫其他服務及其方法的過程。 換句話說,當呼叫其他服務時,它會對您隱藏命名服務,讓這個過程就像呼叫一個URL一樣簡單。

本圖示展示反向代理伺服器如何在叢集中指向公開 HTTP 端點的服務,並包括 HTTPS 支援。

如需如何使用反向 Proxy 服務的詳細資訊,請參閱 Azure Service Fabric 中的反向 Proxy 一文。

來自外部客戶端的連線

聯機到叢集內彼此的服務通常可以直接存取其他服務的端點,因為叢集中的節點位於相同的局域網路上。 不過,在某些環境中,叢集可能位於負載平衡器後方,該負載平衡器會透過一組有限的埠路由傳送輸入流量。 在這些情況下,服務仍然可以彼此通訊,並使用命名服務解析位址,但必須採取額外的步驟,讓外部用戶端連線到服務。

Azure 中的 Service Fabric

Azure 中的 Service Fabric 叢集位於 Azure Load Balancer 後方。 叢集的所有外部流量都必須通過負載平衡器。 負載平衡器會自動將指定埠上的流量輸入轉送至已開啟相同埠的隨機 節點 。 Azure Load Balancer 只知道 節點上開啟的埠,它不知道個別 服務所開啟的埠。

Azure 負載均衡器和 Service Fabric 拓撲

例如,若要接受埠 80 上的外部流量,必須設定下列事項:

  1. 撰寫一個在埠 80 上接聽的服務。 在服務的 ServiceManifest.xml 中設定埠 80,並在服務中開啟監聽器,例如自行架設的網頁伺服器。

    <Resources>
        <Endpoints>
            <Endpoint Name="WebEndpoint" Protocol="http" Port="80" />
        </Endpoints>
    </Resources>
    
        class HttpCommunicationListener : ICommunicationListener
        {
            ...
    
            public Task<string> OpenAsync(CancellationToken cancellationToken)
            {
                EndpointResourceDescription endpoint =
                    serviceContext.CodePackageActivationContext.GetEndpoint("WebEndpoint");
    
                string uriPrefix = $"{endpoint.Protocol}://+:{endpoint.Port}/myapp/";
    
                this.httpListener = new HttpListener();
                this.httpListener.Prefixes.Add(uriPrefix);
                this.httpListener.Start();
    
                string publishUri = uriPrefix.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);
                return Task.FromResult(publishUri);
            }
    
            ...
        }
    
        class WebService : StatelessService
        {
            ...
    
            protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
            {
                return new[] { new ServiceInstanceListener(context => new HttpCommunicationListener(context))};
            }
    
            ...
        }
    
        class HttpCommunicationlistener implements CommunicationListener {
            ...
    
            @Override
            public CompletableFuture<String> openAsync(CancellationToken arg0) {
                EndpointResourceDescription endpoint =
                    this.serviceContext.getCodePackageActivationContext().getEndpoint("WebEndpoint");
                try {
                    HttpServer server = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(endpoint.getPort()), 0);
                    server.start();
    
                    String publishUri = String.format("http://%s:%d/",
                        this.serviceContext.getNodeContext().getIpAddressOrFQDN(), endpoint.getPort());
                    return CompletableFuture.completedFuture(publishUri);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
            ...
        }
    
        class WebService extends StatelessService {
            ...
    
            @Override
            protected List<ServiceInstanceListener> createServiceInstanceListeners() {
                <ServiceInstanceListener> listeners = new ArrayList<ServiceInstanceListener>();
                listeners.add(new ServiceInstanceListener((context) -> new HttpCommunicationlistener(context)));
                return listeners;		
            }
    
            ...
        }
    
  2. 在 Azure 中建立 Service Fabric 叢集,並將埠 80 指定為將裝載服務的節點類型自定義端點埠。 如果您有多個節點類型,您可以在服務上設定 放置條件約束 ,以確保它只會在開啟自定義端點埠的節點類型上執行。

    在節點類型上開啟埠

  3. 建立叢集之後,請在叢集的資源群組中設定 Azure Load Balancer,以轉送埠 80 上的流量。 透過 Azure 入口網站建立叢集時,這會針對已設定的每個自定義端點埠自動設定。

    醒目提示 [負載平衡規則] 底下 [後端埠] 字段的螢幕快照。

  4. Azure Load Balancer 會使用探查來判斷是否要將流量傳送至特定節點。 探查會定期檢查每個節點上的端點,以判斷節點是否回應。 如果探查在設定的次數之後無法接收回應,負載平衡器會停止將流量傳送至該節點。 透過 Azure 入口網站建立叢集時,會自動為每個已設定的自訂端點埠設置探查。

    將流量轉發至 Azure Load Balancer

請務必記住,Azure Load Balancer 和探查只會知道 節點,而不會知道在節點上執行的 服務。 Azure Load Balancer 一律會將流量傳送至回應探查的節點,因此必須小心確保能夠回應探查的節點上提供服務。

Reliable Services:內建通訊 API 選項

Reliable Services 架構隨附數個預先建置的通訊選項。 決定哪一個最適合您,取決於程序設計模型的選擇、通訊架構,以及您服務所撰寫的程式設計語言。

  • 沒有特定的通訊協定: 如果您沒有特定的通訊架構選擇,但想要快速啟動並執行一些工作,那麼最適合您的選擇是 服務遠端處理,它允許強型別的遠端程序呼叫以支援 Reliable Services 和 Reliable Actors。 這是開始使用服務通訊的最簡單且最快的方式。 服務遠端處理負責解析服務位址、建立連線、重試以及錯誤處理。 這適用於 C# 和 Java 應用程式。
  • HTTP:針對語言無關的通訊,HTTP 提供業界標準選擇,並提供許多不同語言的工具和 HTTP 伺服器,且都由 Service Fabric 支援。 服務可以使用任何可用的 HTTP 堆疊,包括適用於 C# 應用程式的 ASP.NET Web API 。 以 C# 撰寫的用戶端可以利用 ICommunicationClientServicePartitionClient 類別,而針對 Java,請使用 CommunicationClientFabricServicePartitionClient 類別,以用於服務解析、HTTP 連線和重試迴圈
  • WCF:如果您有使用 WCF 作為通訊架構的現有程式代碼,則可以將WcfCommunicationListener用於伺服器端,並將WcfCommunicationClientServicePartitionClient類別用於客戶端。 不過,這僅適用於以 Windows 為基礎的叢集上的 C# 應用程式。 如需詳細資訊,請參閱本文以 WCF為基礎的通訊堆疊實作

使用自訂通訊協定和其他通訊架構

服務可以使用任何通訊協定或架構進行通訊,無論是透過 TCP 套接字的自定義二進位通訊協議,還是透過 Azure 事件 中樞或 Azure IoT 中樞串流事件。 Service Fabric 提供了可以整合您的通訊堆疊的通訊 API,同時會將探索和連接的所有工作進行抽象化以簡化您的操作。 如需詳細資訊,請參閱這篇文章,以瞭解 Reliable Service 通訊模型

後續步驟

深入瞭解 Reliable Services 通訊模型中可用的概念和 API,接著可迅速上手 服務遠端處理,或徹底研究如何使用 Web API 搭配 OWIN 自我裝載撰寫通訊接聽程式。