Condividi tramite


Abilitare la comunicazione delle istanze del ruolo in Servizi cloud di Azure (versione classica)

Importante

Servizi cloud (versione classica) è ora deprecato per tutti i clienti a partire dal 1° settembre 2024. Eventuali distribuzioni esistenti in esecuzione saranno arrestate e chiuse da Microsoft e i dati andranno persi in modo permanente a partire da ottobre 2024. Le nuove distribuzioni devono usare il nuovo modello di distribuzione basato su Azure Resource Manager Servizi cloud di Azure (supporto "Extended").

I ruoli del servizio cloud comunicano tramite connessioni interne ed esterne. Le connessioni esterne vengono chiamate endpoint di input mentre le connessioni interne vengono chiamate endpoint interni. Questo articolo descrive come modificare la definizione del servizio per creare endpoint.

Endpoint di input

L'endpoint di input viene utilizzato quando si desidera esporre una porta all'esterno. Specificare il tipo di protocollo e la porta dell’endpoint che quindi si applica per le porte esterne e interne per l’endpoint. Se si desidera, è possibile specificare una porta interna diversa per l'endpoint con l’attributo localPort .

L'endpoint di input può utilizzare i seguenti protocolli: http, https, tcp, udp.

Per creare un endpoint di input, aggiungere elemento figlio InputEndpoint all'elemento Endpoints del ruolo di lavoro o del ruolo Web.

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

Endpoint di input dell'istanza

Gli endpoint di input dell’istanza sono simili agli endpoint di input, ma consentono di eseguire il mapping di porte pubbliche specifiche per ogni singola istanza di ruolo usando il port forwarding nel servizio di bilanciamento del carico. È possibile specificare una singola porta pubblica o un intervallo di porte.

L'endpoint di input dell’istanza può usare solo i protocolli tcp o udp.

Per creare un endpoint di input dell'istanza, aggiungere l'elemento figlio InstanceInputEndpoint all'elemento Endpoints del ruolo di lavoro o del ruolo Web.

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

Endpoint interno

Gli endpoint interni sono disponibili per la comunicazione da istanza a istanza. La porta è facoltativa e se omessa, viene assegnata una porta dinamica all'endpoint. Può essere utilizzato un intervallo di porte. È previsto un limite di cinque endpoint interni per ogni ruolo.

L'endpoint interno può utilizzare i seguenti protocolli: http, https, tcp, udp.

Per creare un endpoint di input interno, aggiungere l'elemento figlio InternalEndpoint all'elemento Endpoints del ruolo di lavoro o del ruolo Web.

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

È possibile inoltre utilizzare un intervallo di porte.

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

Ruoli di lavoro a confronto con Ruoli Web

C’è una differenza minore con gli endpoint quando si lavora con ruoli di lavoro e ruoli Web. Il ruolo web deve disporre almeno di un singolo endpoint di input che utilizzi il protocollo HTTP .

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

Uso di .NET SDK per accedere ad un endpoint

La libreria gestita di Azure fornisce metodi per la comunicazione di istanze del ruolo in fase di esecuzione. Dal codice in esecuzione all’interno di un’istanza di ruolo, è possibile recuperare informazioni sull’esistenza di altre istanze di ruolo e sui relativi endpoint. È anche possibile ottenere informazioni sull’istanza di ruolo corrente.

Nota

È possibile recuperare solo le informazioni sulle istanze dei ruoli che sono in esecuzione nel servizio cloud e che definiscono almeno un endpoint interno. Non è possibile ottenere dati sulle istanze dei ruoli in esecuzione in un altro servizio.

È possibile utilizzare la proprietà Istanze per recuperare le istanze di un ruolo. Usare prima di tutto CurrentRoleInstance per restituire un riferimento all'istanza del ruolo corrente, quindi usare la proprietà Role per restituire un riferimento al ruolo stesso.

Quando ci si connette a un'istanza del ruolo a livello di programmazione tramite il SDK di .NET, è relativamente semplice accedere alle informazioni relative all’endpoint. Ad esempio, dopo la connessione a un ambiente di ruolo specifico, è possibile ottenere la porta di un endpoint specifico con questo codice:

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

La proprietà Instances restituisce una raccolta di oggetti RoleInstance. Tale raccolta contiene sempre l'istanza corrente. Se il ruolo non definisce un endpoint interno, la raccolta include l’istanza corrente ma nessun’altra istanza. Il numero di istanze di ruolo nella raccolta è sempre uno nel caso in cui non sia definito alcun endpoint interno per il ruolo. Se il ruolo definisce un endpoint interno, le relative istanze sono individuabili in fase di runtime e il numero di istanze nella raccolta corrisponde al numero di istanze specificate per il ruolo nel file di configurazione del servizio.

Nota

La libreria gestita di Azure non rappresenta un mezzo per determinare lo stato di altre istanze del ruolo, ma è possibile implementare tali valutazioni manualmente se il servizio necessita di tale funzionalità. È possibile utilizzare la Diagnostica di Azure per ottenere informazioni sull'esecuzione di istanze del ruolo.

Per determinare il numero di porta per un endpoint interno in un'istanza del ruolo, è possibile usare la proprietà InstanceEndpoints per restituire un oggetto Dictionary che contiene i nomi degli endpoint con gli indirizzi IP e le porte corrispondenti. La proprietà IPEndpoint restituisce l'indirizzo IP e la porta per un endpoint specificato. La proprietà PublicIPEndpoint restituisce la porta per un endpoint con carico bilanciato. La parte dell’indirizzo IP della proprietà PublicIPEndpoint non viene usata.

Ecco un esempio che esegue l’iterazione delle istanze di ruolo.

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);
    }
}

Ecco un esempio di ruolo di lavoro che ottiene l’endpoint esposto tramite la definizione del servizio e inizia ad ascoltare le connessioni.

Avviso

Questo codice funziona solo per un servizio distribuito. Durante l'esecuzione nell'emulatore di calcolo di Azure, gli elementi di configurazione del servizio che creano endpoint porte dirette (elementiInstanceInputEndpoint ) vengono ignorati.

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();
    }
  }
}

Regole di traffico di rete per controllare la comunicazione di ruolo

Dopo aver definito gli endpoint interni, è possibile aggiungere regole del traffico di rete (in base agli endpoint che sono stati creati) per controllare il modo in cui le istanze del ruolo possono comunicare tra loro. Nel diagramma seguente vengono illustrati alcuni scenari comuni relativi al controllo della comunicazione del ruolo:

Scenari di regole del traffico di rete

Il seguente esempio di codice mostra le definizioni di ruolo per i ruoli illustrati nel diagramma precedente. Ogni definizione di ruolo include almeno un endpoint interno definito:

<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>

Nota

La restrizione della comunicazione tra ruoli può verificarsi con endpoint interni di porte fisse o assegnate automaticamente.

Per impostazione predefinita, dopo aver definito un endpoint interno, la comunicazione può avvenire tra qualsiasi ruolo e l’endpoint interno di un ruolo senza restrizioni. Per limitare la comunicazione, è necessario aggiungere un elemento NetworkTrafficRules all'elemento ServiceDefinition nel file di definizione del servizio.

Scenario 1

Consentire solo il traffico di rete da WebRole1 a 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>

Scenario 2

Consente solo il traffico di rete da WebRole1 a WorkerRole1 e 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>

Scenario 3

Consente solo il traffico di rete da WebRole1 a WorkerRole1 e da WorkerRole1 a 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>

Scenario 4

Consente solo il traffico di rete da WebRole1 a WorkerRole1, WebRole1 a WorkerRole2 e da WorkerRole1 a 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>

Un riferimento a XML Schema per gli elementi usati è disponibile qui.

Passaggi successivi

Ulteriori informazioni sul modellodel servizio Cloud.