Compartilhar via


Configuração de Servidor

Um silo é configurado programaticamente com o método de extensão UseOrleans(IHostBuilder, Action<HostBuilderContext,ISiloBuilder>) e várias classes de opções complementares. As classes de opções no Orleans seguem o padrão de opções no .NET e podem ser carregadas por meio de arquivos, variáveis de ambiente e qualquer provedor de configuração válido.

Há vários aspectos importantes da configuração do silo:

  • Provedor de clustering
  • (Opcional) Informações de clustering do Orleans
  • (Opcional) Pontos de extremidade a serem usados para comunicações silo a silo e cliente a silo

Este é um exemplo de uma configuração de silo que define as informações do cluster, usa o cluster do Azure e configura as partes do aplicativo:

using IHost host = Host.CreateDefaultBuilder(args)
    .UseOrleans(builder =>
    {
        builder.UseAzureStorageClustering(
            options => options.ConfigureTableServiceClient(connectionString));
    })
    .UseConsoleLifetime()
    .Build();

Dica

Ao desenvolver para Orleans, você pode chamar UseLocalhostClustering(ISiloBuilder, Int32, Int32, IPEndPoint, String, String) para configurar um cluster local. Em ambientes de produção, você deve usar um provedor de clustering adequado para sua implantação.

Provedor de clustering

siloBuilder.UseAzureStorageClustering(
    options => options.ConfigureTableServiceClient(connectionString))

Normalmente, um serviço criado no Orleans é implantado em um cluster de nós, em hardware dedicado ou na nuvem. Para desenvolvimento e testes básicos, o Orleans pode ser implantado em uma configuração de nó único. Quando implantado em um cluster de nós, o Orleans implementa internamente um conjunto de protocolos para descobrir e manter a associação de silos do Orleans no cluster, incluindo detecção de falhas de nó e reconfiguração automática.

Para gerenciamento confiável de associação de cluster, o Orleans usa Azure Table, SQL Server ou Apache ZooKeeper para a sincronização de nós.

Neste exemplo, o Azure Table é usado como provedor de associação.

Informações de clustering do Orleans

Para, opcionalmente, configurar clustering, use ClusterOptions como o parâmetro de tipo para o método Configure na instância ISiloBuilder.

siloBuilder.Configure<ClusterOptions>(options =>
{
    options.ClusterId = "my-first-cluster";
    options.ServiceId = "SampleApp";
})

Aqui, você especifica duas opções:

  • Defina o ClusterId como "my-first-cluster": esta é uma ID exclusiva para o cluster do Orleans. Todos os clientes e silos que usam esse ID poderão se comunicar diretamente entre si. No entanto, você pode optar por usar um ClusterId diferente para diferentes implantações.
  • Defina ServiceId como "SampleApp": este é um ID exclusivo para seu aplicativo que será usado por alguns provedores, como provedores de persistência. Esse ID deve permanecer estável e não mudar nas implantações.

Por padrão, Orleans usará um valor de "default" para o ServiceId e o ClusterId. Esses valores não precisam ser alterados na maioria dos casos. ServiceId é o mais significativo dos dois e é usado para distinguir diferentes serviços lógicos uns dos outros para que possam compartilhar sistemas de armazenamento de back-end sem interferir uns com os outros. ClusterId é usado para determinar quais hosts se conectarão uns aos outros e formarão um cluster.

Em cada cluster, todos os hosts devem usar o mesmo ServiceId. No entanto, vários clusters podem compartilhar um ServiceId. Isso permite cenários de implantação azul/verde em que uma nova implantação (cluster) é iniciada antes que outra seja desligada. Isso é típico para sistemas hospedados no Serviço de Aplicativo do Azure.

O caso mais comum é que ServiceId e ClusterId permaneçam fixos durante o tempo de vida do aplicativo e uma estratégia de implantação sem interrupção seja usada. Isso é típico para sistemas hospedados no Kubernetes e no Service Fabric.

Pontos de extremidade

Por padrão, Orleans escutará em todas as interfaces na porta 11111 para comunicação silo a silo e na porta 30000 para comunicação cliente a silo. Para substituir esse comportamento, chame ConfigureEndpoints(ISiloBuilder, Int32, Int32, AddressFamily, Boolean) e passe os números de porta que deseja usar.

siloBuilder.ConfigureEndpoints(siloPort: 17_256, gatewayPort: 34_512)

No código anterior:

  • A porta do silo é definida como 17_256.
  • A porta do gateway é definida como 34_512.

Um silo do Orleans tem dois tipos típicos de configuração de ponto de extremidade:

  • Pontos de extremidade de silo para silo são usados para comunicação entre silos no mesmo cluster.
  • Pontos de extremidade de cliente a silo (ou gateway) são usados para comunicação entre clientes e silos no mesmo cluster.

Esse método deve ser suficiente na maioria dos casos, mas você pode personalizá-lo ainda mais se precisar. Aqui está um exemplo de como usar um endereço IP externo com algum encaminhamento de porta:

siloBuilder.Configure<EndpointOptions>(options =>
{
    // Port to use for silo-to-silo
    options.SiloPort = 11_111;
    // Port to use for the gateway
    options.GatewayPort = 30_000;
    // IP Address to advertise in the cluster
    options.AdvertisedIPAddress = IPAddress.Parse("172.16.0.42");
    // The socket used for client-to-silo will bind to this endpoint
    options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Any, 40_000);
    // The socket used by the gateway will bind to this endpoint
    options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Any, 50_000);
})

Internamente, o silo escutará em 0.0.0.0:40000 e 0.0.0.0:50000, mas o valor publicado no provedor de associação será 172.16.0.42:11111 e 172.16.0.42:30000.

Um silo é configurado programaticamente por meio de SiloHostBuilder e várias classes de opções complementares. As classes de opções no Orleans seguem o padrão de opções no .NET e podem ser carregadas por meio de arquivos, variáveis de ambiente e qualquer provedor de configuração válido.

Há vários aspectos importantes da configuração do silo:

  • Informações de clustering do Orleans
  • Provedor de clustering
  • Pontos de extremidade a serem usados para comunicações silo a silo e cliente a silo
  • Partes do aplicativo

Este é um exemplo de uma configuração de silo que define as informações do cluster, usa o cluster do Azure e configura as partes do aplicativo:

var silo = Host.CreateDefaultBuilder(args)
    .UseOrleans(builder =>
    {
        builder
            .UseAzureStorageClustering(
                options => options.ConnectionString = connectionString)
            .Configure<ClusterOptions>(options =>
            {
                options.ClusterId = "my-first-cluster";
                options.ServiceId = "AspNetSampleApp";
            })
            .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
            .ConfigureApplicationParts(
                parts => parts.AddApplicationPart(typeof(ValueGrain).Assembly).WithReferences())
    })
    .UseConsoleLifetime()
    .Build();

Vamos detalhar as etapas usadas neste exemplo:

Provedor de clustering

siloBuilder.UseAzureStorageClustering(
    options => options.ConnectionString = connectionString)

Normalmente, um serviço criado no Orleans é implantado em um cluster de nós, em hardware dedicado ou na nuvem. Para desenvolvimento e testes básicos, o Orleans pode ser implantado em uma configuração de nó único. Quando implantado em um cluster de nós, o Orleans implementa internamente um conjunto de protocolos para descobrir e manter a associação de silos do Orleans no cluster, incluindo detecção de falhas de nó e reconfiguração automática.

Para gerenciamento confiável de associação de cluster, o Orleans usa Azure Table, SQL Server ou Apache ZooKeeper para a sincronização de nós.

Neste exemplo, estamos usando o Azure Table como provedor de associação.

Informações de clustering do Orleans

.Configure<ClusterOptions>(options =>
{
    options.ClusterId = "my-first-cluster";
    options.ServiceId = "AspNetSampleApp";
})

Aqui, fazemos duas coisas:

  • Defina o ClusterId como "my-first-cluster": esta é uma ID exclusiva para o cluster do Orleans. Todos os clientes e silos que usam esse ID poderão se comunicar diretamente entre si. No entanto, você pode optar por usar um ClusterId diferente para diferentes implantações.
  • Defina ServiceId como "AspNetSampleApp": este é um ID exclusivo para seu aplicativo que será usado por alguns provedores, como provedores de persistência. Esse ID deve permanecer estável e não mudar nas implantações.

Por padrão, Orleans usará um valor de "default" para o ServiceId e o ClusterId. Esses valores não precisam ser alterados na maioria dos casos. ServiceId é o mais significativo dos dois e é usado para distinguir diferentes serviços lógicos uns dos outros para que possam compartilhar sistemas de armazenamento de back-end sem interferir uns com os outros. ClusterId é usado para determinar quais hosts se conectarão uns aos outros e formarão um cluster.

Em cada cluster, todos os hosts devem usar o mesmo ServiceId. No entanto, vários clusters podem compartilhar um ServiceId. Isso permite cenários de implantação azul/verde em que uma nova implantação (cluster) é iniciada antes que outra seja desligada. Isso é típico para sistemas hospedados no Serviço de Aplicativo do Azure.

O caso mais comum é que ServiceId e ClusterId permaneçam fixos durante o tempo de vida do aplicativo e uma estratégia de implantação sem interrupção seja usada. Isso é típico para sistemas hospedados no Kubernetes e no Service Fabric.

Pontos de extremidade

siloBuilder.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)

Um silo do Orleans tem dois tipos típicos de configuração de ponto de extremidade:

  • Pontos de extremidade de silo para silo, usados para comunicação entre silos no mesmo cluster
  • Pontos de extremidade de cliente para silo (ou gateway), usados para comunicação entre clientes e silos no mesmo cluster

No exemplo, estamos usando o método auxiliar .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000) que define a porta usada para comunicação silo a silo como 11111 e a porta do gateway como 30000. Este método detectará qual interface escutar.

Esse método deve ser suficiente na maioria dos casos, mas você pode personalizá-lo ainda mais se precisar. Aqui está um exemplo de como usar um endereço IP externo com algum encaminhamento de porta:

siloBuilder.Configure<EndpointOptions>(options =>
{
    // Port to use for silo-to-silo
    options.SiloPort = 11111;
    // Port to use for the gateway
    options.GatewayPort = 30000;
    // IP Address to advertise in the cluster
    options.AdvertisedIPAddress = IPAddress.Parse("172.16.0.42");
    // The socket used for client-to-silo will bind to this endpoint
    options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Any, 40000);
    // The socket used by the gateway will bind to this endpoint
    options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Any, 50000);
})

Internamente, o silo escutará em 0.0.0.0:40000 e 0.0.0.0:50000, mas o valor publicado no provedor de associação será 172.16.0.42:11111 e 172.16.0.42:30000.

Partes do aplicativo

siloBuilder.ConfigureApplicationParts(
    parts => parts.AddApplicationPart(
        typeof(ValueGrain).Assembly)
        .WithReferences())

Embora esta etapa não seja tecnicamente necessária (se não estiver configurada, o Orleans verificará todos os assemblies na pasta atual), os desenvolvedores são incentivados a configurar isso. Esta etapa ajudará o Orleans a carregar assemblies e tipos de usuário. Esses conjuntos são chamados de Peças de Aplicação. Toda granularidade, interfaces de granularidade e serializadores são descobertos usando As Partes de Aplicativo.

As partes do aplicativo são configuradas usando IApplicationPartManager, que pode ser acessado usando o método de extensão ConfigureApplicationParts em IClientBuilder e ISiloHostBuilder. O método ConfigureApplicationParts aceita um delegado, Action<IApplicationPartManager>.

Os seguintes métodos de extensão em IApplicationPartManager são compatíveis com usos comuns:

Os assemblies adicionados pelos métodos acima podem ser complementados usando os seguintes métodos de extensão em seu tipo de retorno, IApplicationPartManagerWithAssemblies:

  • ApplicationPartManagerExtensions.WithReferences adiciona todas as montagens referenciadas das peças adicionadas. Isso carrega imediatamente quaisquer assemblies referenciados transitivamente. Erros de carregamento de assembly são ignorados.
  • ApplicationPartManagerCodeGenExtensions.WithCodeGeneration gera código de suporte para as peças adicionadas e o adiciona ao gerenciador de peças. Observe que isso exige que o pacote Microsoft.Orleans.OrleansCodeGenerator seja instalado e é comumente chamado de geração de código de tempo de execução.

A descoberta de tipo requer que as Partes do Aplicativo fornecidas incluam atributos específicos. Adicionar o pacote de geração de código em tempo de compilação (Microsoft.Orleans.CodeGenerator.MSBuild ou Microsoft.Orleans.OrleansCodeGenerator.Build) a cada projeto que contenha granularidade, interfaces de granularidade ou serializadores é a abordagem recomendada para garantir que esses atributos estejam presentes. A geração de código em tempo de compilação oferece suporte apenas a C#. Para F#, Visual Basic e outras linguagens .NET, o código pode ser gerado durante o tempo de configuração por meio do método WithCodeGeneration descrito acima. Mais informações sobre geração de código podem ser encontradas na seção correspondente.