Włączanie komunikacji dla wystąpień ról w usłudze Azure Cloud Services (wersja klasyczna)

Ważne

Cloud Services (wersja klasyczna) jest teraz przestarzała dla nowych klientów i zostanie wycofana 31 sierpnia 2024 r. dla wszystkich klientów. Nowe wdrożenia powinny używać nowego modelu wdrażania opartego na usłudze Azure Resource Manager 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 temacie opisano sposób modyfikowania definicji usługi w celu tworzenia punktów końcowych.

Wejściowy punkt końcowy

Wejściowy punkt końcowy jest używany, gdy chcesz uwidocznić 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 punktu końcowego. Jeśli chcesz, możesz określić inny port wewnętrzny dla punktu końcowego za pomocą atrybutu localPort .

Wejściowy punkt końcowy 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> 

Wejściowy punkt końcowy wystąpienia

Wejściowe punkty końcowe wystąpienia są podobne do wejściowych punktów końcowych, ale umożliwiają mapowania określonych portów publicznych dla każdego wystąpienia roli przy użyciu przekierowania portów w module równoważenia obciążenia. Można określić pojedynczy port publiczny lub zakres portów.

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

Aby utworzyć wejściowy punkt końcowy 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 na potrzeby komunikacji między wystąpieniami. 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 na rolę.

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

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

<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 procesów roboczych a role sieci Web

Podczas pracy z rolami procesów roboczych i sieci Web występuje jedna niewielka różnica w punktach końcowych. Rola sieci Web musi mieć co najmniej jeden wejściowy punkt końcowy 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 udostępnia metody komunikacji wystąpień ról w czasie wykonywania. Z kodu uruchomionego w wystąpieniu roli można pobrać informacje o istnieniu innych wystąpień roli i ich punktów końcowych, a także informacje o bieżącym wystąpieniu roli.

Uwaga

Można pobierać tylko informacje o wystąpieniach ról uruchomionych w usłudze w chmurze i definiujących 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 klasy CurrentRoleInstance , aby zwrócić odwołanie do bieżącego wystąpienia roli, a następnie użyj właściwości Rola , aby zwrócić odwołanie do samej roli.

Podczas programowego nawiązywania połączenia z wystąpieniem roli za pomocą 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żesz 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 żadne inne wystąpienia. Liczba wystąpień roli w kolekcji będzie zawsze wynosić 1 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ń roli, ale możesz zaimplementować te oceny kondycji samodzielnie, jeśli usługa wymaga tej funkcji. Aby uzyskać informacje o uruchamianiu wystąpień ról, można użyć Diagnostyka Azure.

Aby określić numer portu wewnętrznego punktu końcowego w wystąpieniu roli, możesz użyć InstanceEndpoints właściwości , aby zwrócić obiekt Słownik zawierający 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. Część PublicIPEndpoint adresu IP właściwości nie jest używana.

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 procesu roboczego, która pobiera punkt końcowy uwidoczniony za pośrednictwem 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, które tworzą 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 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ć sposób komunikowania się wystąpień ról ze sobą. Na poniższym diagramie przedstawiono niektóre typowe scenariusze kontrolowania komunikacji roli:

Scenariusze reguł ruchu sieciowego — scenariusze

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 stałych, jak i automatycznie przypisanych portów.

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 tylko na ruch sieciowy z webRole1 do WorkerRole1 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>
      <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żytych powyżej można znaleźć tutaj.

Następne kroki

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