Udostępnij przez


Umożliwianie komunikacji dla instancji ról w klasycznych usługach Azure Cloud Services

Ważne

Usługi Cloud Services (wersja klasyczna) są teraz przestarzałe dla wszystkich klientów od 1 września 2024 r. Wszystkie istniejące uruchomione wdrożenia zostaną zatrzymane i zamknięte przez firmę Microsoft, a dane zostaną trwale utracone od października 2024 r. Nowe wdrożenia powinny używać nowego modelu wdrażania opartego na usłudze Azure Resource Manager w usługach Azure Cloud Services (wsparcie dodatkowe).

Role usługi w chmurze komunikują się za pośrednictwem połączeń wewnętrznych i zewnętrznych. Połączenia zewnętrzne są nazywane wejściowymi punktami końcowymi , podczas gdy połączenia wewnętrzne są nazywane wewnętrznymi punktami końcowymi. W tym artykule opisano sposób modyfikowania definicji usługi w celu tworzenia punktów końcowych.

Punkt końcowy wejścia

Punkt końcowy wejściowy jest używany, gdy chcesz udostępnić port na zewnątrz. Należy określić typ protokołu i port punktu końcowego, który następnie ma zastosowanie zarówno dla portów zewnętrznych, jak i wewnętrznych dla punktu końcowego. Jeśli chcesz, możesz określić inny port wewnętrzny punktu końcowego za pomocą atrybutu localPort .

Punkt końcowy wejściowy może używać następujących protokołów: http, https, tcp, udp.

Aby utworzyć wejściowy punkt końcowy, dodaj element podrzędny InputEndpoint do elementu Endpoints roli sieci Web lub procesu roboczego.

<Endpoints>
  <InputEndpoint name="StandardWeb" protocol="http" port="80" localPort="80" />
</Endpoints> 

Punkt końcowy wejściowy wystąpienia

Punkty końcowe wejściowe dla wystąpień są podobne do standardowych punktów końcowych wejściowych, ale umożliwiają mapowanie określonych publicznych portów dla każdego indywidualnego wystąpienia roli przy użyciu przekierowywania portów na równoważniku obciążenia. Można określić jeden publiczny port lub zakres portów.

Punkt końcowy wejściowy wystąpienia może używać tylko tcp lub udp jako protokołu.

Aby utworzyć punkt końcowy wejściowy wystąpienia, dodaj element podrzędny InstanceInputEndpoint do elementu Endpoints roli sieci Web lub procesu roboczego.

<Endpoints>
  <InstanceInputEndpoint name="Endpoint2" protocol="tcp" localPort="10100">
    <AllocatePublicPortFrom>
      <FixedPortRange max="10109" min="10105" />
    </AllocatePublicPortFrom>
  </InstanceInputEndpoint>
</Endpoints>

Wewnętrzny punkt końcowy

Wewnętrzne punkty końcowe są dostępne do komunikacji między instancjami. Port jest opcjonalny i jeśli zostanie pominięty, do punktu końcowego zostanie przypisany port dynamiczny. Można użyć zakresu portów. Istnieje limit pięciu wewnętrznych punktów końcowych dla jednej roli.

Wewnętrzny punkt końcowy może używać następujących protokołów: http, tcp, udp, dowolny.

Aby utworzyć wewnętrzny punkt końcowy wejściowy, dodaj element podrzędny InternalEndpoint do elementu Endpoints roli sieci Web lub roli roboczej.

<Endpoints>
  <InternalEndpoint name="Endpoint3" protocol="any" port="8999" />
</Endpoints> 

Można również użyć zakresu portów.

<Endpoints>
  <InternalEndpoint name="Endpoint3" protocol="any">
    <FixedPortRange max="8999" min="8995" />
  </InternalEndpoint>
</Endpoints>

Role pracownika a role internetowe

Istnieje jedna niewielka różnica w przypadku punktów końcowych podczas pracy z rolami roboczymi i webowymi. Rola sieci Web musi mieć co najmniej jeden punkt końcowy wejściowy przy użyciu protokołu HTTP .

<Endpoints>
  <InputEndpoint name="StandardWeb" protocol="http" port="80" localPort="80" />
  <!-- more endpoints may be declared after the first InputEndPoint -->
</Endpoints>

Uzyskiwanie dostępu do punktu końcowego przy użyciu zestawu SDK platformy .NET

Biblioteka zarządzana platformy Azure zapewnia metody umożliwiające komunikację wystąpień ról podczas wykonywania. Z kodu uruchomionego w wystąpieniu roli można pobrać informacje o istnieniu innych wystąpień roli i ich punktów końcowych. Możesz również uzyskać informacje o bieżącym wystąpieniu roli.

Uwaga

Możesz pobrać tylko informacje o wystąpieniach ról uruchomionych w usłudze w chmurze, które mają zdefiniowany co najmniej jeden wewnętrzny punkt końcowy. Nie można uzyskać danych dotyczących wystąpień ról uruchomionych w innej usłudze.

Możesz użyć właściwości Instances , aby pobrać wystąpienia roli. Najpierw użyj CurrentRoleInstance, aby zwrócić odwołanie do bieżącego wystąpienia roli, a następnie użyj właściwości Role, aby zwrócić odwołanie do samej roli.

Podczas programowego łączenia się z instancją roli za pośrednictwem zestawu SDK platformy .NET dostęp do informacji o punkcie końcowym jest stosunkowo łatwy. Na przykład po nawiązaniu połączenia z określonym środowiskiem roli można pobrać port określonego punktu końcowego za pomocą następującego kodu:

int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["StandardWeb"].IPEndpoint.Port;

Właściwość Instances zwraca kolekcję obiektów RoleInstance . Ta kolekcja zawsze zawiera bieżące wystąpienie. Jeśli rola nie definiuje wewnętrznego punktu końcowego, kolekcja zawiera bieżące wystąpienie, ale nie ma innych wystąpień. Liczba wystąpień ról w kolekcji jest zawsze jedna w przypadku, gdy dla roli nie zdefiniowano żadnego wewnętrznego punktu końcowego. Jeśli rola definiuje wewnętrzny punkt końcowy, jego wystąpienia są wykrywalne w czasie wykonywania, a liczba wystąpień w kolekcji odpowiada liczbie wystąpień określonych dla roli w pliku konfiguracji usługi.

Uwaga

Biblioteka zarządzana platformy Azure nie zapewnia sposobu określania kondycji innych wystąpień ról, ale możesz zaimplementować takie oceny kondycji samodzielnie, jeśli usługa wymaga tej funkcji. Aby uzyskać informacje na temat działających wystąpień ról, możesz użyć Azure Diagnostics.

Aby określić numer portu wewnętrznego punktu końcowego w wystąpieniu roli, możesz użyć właściwości InstanceEndpoints, aby zwrócić obiekt słownik, który zawiera nazwy punktów końcowych i odpowiadające im adresy IP i porty. Właściwość IPEndpoint zwraca adres IP i port dla określonego punktu końcowego. Właściwość PublicIPEndpoint zwraca port dla punktu końcowego o zrównoważonym obciążeniu. Element adresu IP w ramach właściwości PublicIPEndpoint nie jest używany.

Oto przykład, który iteruje wystąpienia ról.

foreach (RoleInstance roleInst in RoleEnvironment.CurrentRoleInstance.Role.Instances)
{
    Trace.WriteLine("Instance ID: " + roleInst.Id);
    foreach (RoleInstanceEndpoint roleInstEndpoint in roleInst.InstanceEndpoints.Values)
    {
        Trace.WriteLine("Instance endpoint IP address and port: " + roleInstEndpoint.IPEndpoint);
    }
}

Oto przykład roli roboczej, która uzyskuje dostęp do punktu końcowego udostępnionego w definicji usługi i rozpoczyna nasłuchiwanie połączeń.

Ostrzeżenie

Ten kod będzie działać tylko dla wdrożonej usługi. Podczas uruchamiania w emulatorze usługi Azure Compute elementy konfiguracji usługi tworzące punkty końcowe portów bezpośrednich (elementy InstanceInputEndpoint ) są ignorowane.

using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

namespace WorkerRole1
{
  public class WorkerRole : RoleEntryPoint
  {
    public override void Run()
    {
      try
      {
        // Initialize method-wide variables
        var epName = "Endpoint1";
        var roleInstance = RoleEnvironment.CurrentRoleInstance;

        // Identify direct communication port
        var myPublicEp = roleInstance.InstanceEndpoints[epName].PublicIPEndpoint;
        Trace.TraceInformation("IP:{0}, Port:{1}", myPublicEp.Address, myPublicEp.Port);

        // Identify public endpoint
        var myInternalEp = roleInstance.InstanceEndpoints[epName].IPEndpoint;

        // Create socket listener
        var listener = new Socket(
          myInternalEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

        // Bind socket listener to internal endpoint and listen
        listener.Bind(myInternalEp);
        listener.Listen(10);
        Trace.TraceInformation("Listening on IP:{0},Port: {1}",
          myInternalEp.Address, myInternalEp.Port);

        while (true)
        {
          // Block the thread and wait for a client request
          Socket handler = listener.Accept();
          Trace.TraceInformation("Client request received.");

          // Define body of socket handler
          var handlerThread = new Thread(
            new ParameterizedThreadStart(h =>
            {
              var socket = h as Socket;
              Trace.TraceInformation("Local:{0} Remote{1}",
                socket.LocalEndPoint, socket.RemoteEndPoint);

              // Shut down and close socket
              socket.Shutdown(SocketShutdown.Both);
              socket.Close();
            }
          ));

          // Start socket handler on new thread
          handlerThread.Start(handler);
        }
      }
      catch (Exception e)
      {
        Trace.TraceError("Caught exception in run. Details: {0}", e);
      }
    }

    public override bool OnStart()
    {
      // Set the maximum number of concurrent connections 
      ServicePointManager.DefaultConnectionLimit = 12;

      // For information on handling configuration changes
      // see the MSDN topic at https://go.microsoft.com/fwlink/?LinkId=166357.
      return base.OnStart();
    }
  }
}

Reguły ruchu sieciowego do kontrolowania komunikacji przypisanej do roli

Po zdefiniowaniu wewnętrznych punktów końcowych można dodać reguły ruchu sieciowego (na podstawie utworzonych punktów końcowych), aby kontrolować, jak wystąpienia ról mogą komunikować się ze sobą. Na poniższym diagramie przedstawiono niektóre typowe scenariusze kontrolowania komunikacji ról:

Scenariusze reguł ruchu sieciowego

Poniższy przykład kodu przedstawia definicje ról dla ról pokazanych na poprzednim diagramie. Każda definicja roli zawiera co najmniej jeden wewnętrzny punkt końcowy zdefiniowany:

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole1" vmsize="Medium">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
      <InternalEndpoint name="InternalTCP1" protocol="tcp" />
    </Endpoints>
  </WebRole>
  <WorkerRole name="WorkerRole1">
    <Endpoints>
      <InternalEndpoint name="InternalTCP2" protocol="tcp" />
    </Endpoints>
  </WorkerRole>
  <WorkerRole name="WorkerRole2">
    <Endpoints>
      <InternalEndpoint name="InternalTCP3" protocol="tcp" />
      <InternalEndpoint name="InternalTCP4" protocol="tcp" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>

Uwaga

Ograniczenie komunikacji między rolami może wystąpić z wewnętrznymi punktami końcowymi zarówno portów stałych, jak i portów automatycznie przypisanych.

Domyślnie po zdefiniowaniu wewnętrznego punktu końcowego komunikacja może przepływać z dowolnej roli do wewnętrznego punktu końcowego roli bez żadnych ograniczeń. Aby ograniczyć komunikację, należy dodać element NetworkTrafficRules do elementu ServiceDefinition w pliku definicji usługi.

Scenariusz 1

Zezwalaj tylko na ruch sieciowy z elementu WebRole1 do elementu WorkerRole1.

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
</ServiceDefinition>

Scenariusz 2

Zezwala tylko na ruch sieciowy z WebRole1 do WorkerRole1 i WorkerRole2.

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
        <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
      </Destinations>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
</ServiceDefinition>

Scenariusz 3

Zezwala na ruch sieciowy z WebRole1 do WorkerRole1, i z WorkerRole1 do WorkerRole2.

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
      </Destinations>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WorkerRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
</ServiceDefinition>

Scenariusz 4

Zezwala tylko na ruch sieciowy z WebRole1 do WorkerRole1, WebRole1 do WorkerRole2 i WorkerRole1 do WorkerRole2.

<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo >
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WorkerRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo >
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP4" roleName="WorkerRole2"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
</ServiceDefinition>

Odwołanie do schematu XML dla elementów używanych można znaleźć tutaj.

Następne kroki

Przeczytaj więcej na temat modelu usługi w chmurze.