为 Azure 中的角色实例启用通信Enable communication for role instances in azure

云服务角色通过内部和外部连接进行通信。Cloud service roles communicate through internal and external connections. 外部连接称为“输入终结点”,而内部连接称为“内部终结点”。External connections are called input endpoints while internal connections are called internal endpoints. 本主题介绍如何修改服务定义来创建终结点。This topic describes how to modify the service definition to create endpoints.

输入终结点Input endpoint

想要向外部公开某个端口时,使用输入终结点。The input endpoint is used when you want to expose a port to the outside. 可以指定该终结点的协议类型和端口,然后,这些指定值将同时应用到该终结点的外部和内部端口。You specify the protocol type and the port of the endpoint which then applies for both the external and internal ports for the endpoint. 如果需要,可以使用 localPort 属性为终结点指定不同的内部端口。If you want, you can specify a different internal port for the endpoint with the localPort attribute.

输入终结点可以使用以下协议: http、https、tcp、udpThe input endpoint can use the following protocols: http, https, tcp, udp.

若要创建输入终结点,请将 InputEndpoint 子元素添加到 Web 角色或辅助角色的 Endpoints 元素。To create an input endpoint, add the InputEndpoint child element to the Endpoints element of either a web or worker role.

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

实例输入终结点Instance input endpoint

实例输入终结点类似于输入终结点,但允许通过使用负载均衡器上的端口转发,映射每个角色实例的面向公众的特定端口。Instance input endpoints are similar to input endpoints but allows you map specific public-facing ports for each individual role instance by using port forwarding on the load balancer. 可以指定单个面向公众的端口,也可以指定一系列端口。You can specify a single public-facing port, or a range of ports.

实例输入终结点只能使用 tcp 或 udp 作为协议。The instance input endpoint can only use tcp or udp as the protocol.

若要创建实例输入终结点,请将 InstanceInputEndpoint 子元素添加到 Web 角色或辅助角色的 Endpoints 元素。To create an instance input endpoint, add the InstanceInputEndpoint child element to the Endpoints element of either a web or worker role.

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

内部终结点Internal endpoint

内部终结点可用于实例间的通信。Internal endpoints are available for instance-to-instance communication. 端口是可选的,如果省略端口,将为终结点分配动态端口。The port is optional and if omitted, a dynamic port is assigned to the endpoint. 可以使用端口范围。A port range can be used. 每个角色的内部终结点数不能超过五个。There is a limit of five internal endpoints per role.

内部终结点可以使用以下协议: http、tcp、udp、任何The internal endpoint can use the following protocols: http, tcp, udp, any.

若要创建内部输入终结点,请将 InternalEndpoint 子元素添加到 Web 角色或辅助角色的 Endpoints 元素。To create an internal input endpoint, add the InternalEndpoint child element to the Endpoints element of either a web or worker role.

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

也可以使用端口范围。You can also use a port range.

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

辅助角色与Web 角色Worker roles vs. Web roles

使用辅助角色和 web 角色时,在终结点方面需要注意一个细微的差别。There is one minor difference with endpoints when working with both worker and web roles. Web 角色必须至少有一个使用 HTTP 协议的输入终结点。The web role must have at minimum a single input endpoint using the HTTP protocol.

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

使用 .NET SDK 访问终结点Using the .NET SDK to access an endpoint

Azure 托管库提供了角色实例在运行时用来通信的方法。The Azure Managed Library provides methods for role instances to communicate at runtime. 可以从角色实例中运行的代码检索有关其他角色实例及其终结点是否存在的信息,以及有关当前角色实例的信息。From code running within a role instance, you can retrieve information about the existence of other role instances and their endpoints, as well as information about the current role instance.

备注

只能检索有关正在云服务中运行且定义了至少一个内部终结点的角色实例的信息。You can only retrieve information about role instances that are running in your cloud service and that define at least one internal endpoint. 无法获取有关其他服务中运行的角色实例的数据。You cannot obtain data about role instances running in a different service.

可以使用 Instances 属性检索角色的实例。You can use the Instances property to retrieve instances of a role. 首先,使用 CurrentRoleInstance 返回对当前角色实例的引用,然后使用 Role 属性返回对角色本身的引用。First use the CurrentRoleInstance to return a reference to the current role instance, and then use the Role property to return a reference to the role itself.

通过 .NET SDK 以编程方式连接到角色实例时,可以相对较容易地访问终结点信息。When you connect to a role instance programmatically through the .NET SDK, it's relatively easy to access the endpoint information. 例如,在连接到特定的角色环境后,可以使用以下代码获取特定终结点的端口:For example, after you've already connected to a specific role environment, you can get the port of a specific endpoint with this code:

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

Instances 属性将返回一个 RoleInstance 对象集合。The Instances property returns a collection of RoleInstance objects. 此集合始终包含当前实例。This collection always contains the current instance. 如果角色未定义内部终结点,则集合包含当前实例,但不包含任何其他实例。If the role does not define an internal endpoint, the collection includes the current instance but no other instances. 如果未为角色定义内部终结点,则集合中的角色实例的数目会始终为 1。The number of role instances in the collection will always be 1 in the case where no internal endpoint is defined for the role. 如果角色定义了一个内部终结点,则其实例在运行时是可发现的,并且集合中的实例数将与在服务配置文件中为角色指定的实例数对应。If the role defines an internal endpoint, its instances are discoverable at runtime, and the number of instances in the collection will correspond to the number of instances specified for the role in the service configuration file.

备注

Azure 托管库不提供用来确定其他角色实例的运行状况的方法,但如果服务需要此功能,则可以自行实现此类运行状况评估。The Azure Managed Library does not provide a means of determining the health of other role instances, but you can implement such health assessments yourself if your service needs this functionality. 可以使用 Azure 诊断来获取有关正在运行的角色实例的信息。You can use Azure Diagnostics to obtain information about running role instances.

要确定角色实例上的内部终结点的端口号,可以使用 InstanceEndpoints 属性来返回 Dictionary 对象,该对象中包含终结点名称及其对应的 IP 地址和端口。To determine the port number for an internal endpoint on a role instance, you can use the InstanceEndpoints property to return a Dictionary object that contains endpoint names and their corresponding IP addresses and ports. IPEndpoint 属性返回指定终结点的 IP 地址和端口。The IPEndpoint property returns the IP address and port for a specified endpoint. PublicIPEndpoint 属性返回负载均衡终结点的端口。The PublicIPEndpoint property returns the port for a load balanced endpoint. 不使用 PublicIPEndpoint 属性的 IP 地址部分。The IP address portion of the PublicIPEndpoint property is not used.

下面是一个循环访问角色实例的示例。Here is an example that iterates role instances.

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

下面的辅助角色示例将获取通过服务定义公开的终结点,并开始侦听连接。Here is an example of a worker role that gets the endpoint exposed through the service definition and starts listening for connections.

警告

此代码仅适用于已部署的服务。This code will only work for a deployed service. 在 Azure 计算模拟器中运行时,将忽略创建直接端口终结点的服务配置元素(InstanceInputEndpoint 元素)。When running in the Azure Compute Emulator, service configuration elements that create direct port endpoints (InstanceInputEndpoint elements) are ignored.

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 http://go.microsoft.com/fwlink/?LinkId=166357.
      return base.OnStart();
    }
  }
}

用于控制角色通信的网络流量规则Network traffic rules to control role communication

定义内部终结点后,可以(根据创建的终结点)添加网络流量规则来控制各角色实例之间的通信方式。After you define internal endpoints, you can add network traffic rules (based on the endpoints that you created) to control how role instances can communicate with each other. 下图演示了一些用于控制角色通信的常见方案:The following diagram shows some common scenarios for controlling role communication:

网络流量规则方案Network Traffic Rules Scenarios

以下代码示例演示了上图中显示的角色的角色定义。The following code example shows role definitions for the roles shown in the previous diagram. 每个角色定义包含至少一个已定义的内部终结点:Each role definition includes at least one internal endpoint defined:

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

备注

固定端口和自动分配的端口的内部终结点会限制角色之间的通信。Restriction of communication between roles can occur with internal endpoints of both fixed and automatically assigned ports.

默认情况下,在定义内部终结点后,通信可以从任意角色流动到角色的内部终结点,而不会受到任何限制。By default, after an internal endpoint is defined, communication can flow from any role to the internal endpoint of a role without any restrictions. 若要限制通信,必须将 NetworkTrafficRules 元素添加到服务定义文件中的 ServiceDefinition 元素。To restrict communication, you must add a NetworkTrafficRules element to the ServiceDefinition element in the service definition file.

方案 1Scenario 1

仅允许从 WebRole1 到 WorkerRole1 的网络流量。Only allow network traffic from WebRole1 to 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>

方案 2Scenario 2

仅允许从 WebRole1 到 WorkerRole1 和 WorkerRole2 的网络流量。Only allows network traffic from WebRole1 to WorkerRole1 and 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>

方案 3Scenario 3

仅允许从 WebRole1 到 WorkerRole1 以及从 WorkerRole1 到 WorkerRole2 的网络流量。Only allows network traffic from WebRole1 to WorkerRole1, and WorkerRole1 to 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>

方案 4Scenario 4

仅允许从 WebRole1 到 WorkerRole1、从 WebRole1 到 WorkerRole2 以及从 WorkerRole1 到 WorkerRole2 的网络流量。Only allows network traffic from WebRole1 to WorkerRole1, WebRole1 to WorkerRole2, and WorkerRole1 to 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>

可在 此处找到上面所用元素的 XML 架构参考。An XML schema reference for the elements used above can be found here.

后续步骤Next steps

阅读有关云服务模型的详细信息。Read more about the Cloud Service model.