.NET

Couchbase Encontra o .Net Core e o Docker

Brant Burnett é um Especialista em Couchbase, arquiteto de sistemas e desenvolvedor .Net com experiência em desenvolvimento full stack para desktop e web. Nos últimos 12 anos, ele trabalhou na CenterEdge Software, uma empresa de software para entretenimento familiar sediada em Roxboro, NC. Brant tem experiência no desenvolvimento de aplicações para todos os segmentos de seu conjunto de softwares. Nos últimos 4 anos, ele trabalhou na transição da infraestrutura de nuvem da empresa de uma plataforma Microsoft SQL para uma plataforma puramente Couchbase NoSQL. Por meio de seu trabalho na CenterEdge, Brant pôde se concentrar na criação de soluções de software sérias para negócios divertidos.

Com o lançamento do Couchbase .NET SDK 2.4.0, o Couchbase agora tem suporte oficial para .NET Core. Isto abre um novo e vasto mundo para o .NET Couchbase desenvolvedores. Em particular, agora podemos usar Docker para gerenciar facilmente nossas aplicações e melhorar nosso processo de implantação, algo antes reservado para tecnologias como Java e Node.js.

Em CenterEdge Software, estamos nos movendo rapidamente para dividir nossas aplicações monolíticas em ASP.NET em microsserviços ASP.NET Core baseados em Docker. Estamos muito entusiasmados com as novas possibilidades que isso proporciona e com as melhorias na robustez e na facilidade de implantação da nossa aplicação. Esperamos que esta visão geral das abordagens que estamos usando para fazer essa transição ajude outros a seguirem o mesmo caminho.

Configuração e Ambientes

Na maioria dos aplicativos ASP.NET Core, a configuração é baseada em definições lidas a partir de appsettings.json arquivo na raiz do seu projeto. Essas configurações são então substituídas por configurações específicas de ambiente (como appsettings.Development.json). Essas configurações podem então ser substituídas por sua vez por variáveis de ambiente presentes quando o aplicativo é iniciado.

Na CenterEdge, nós definimos os ambientes do .NET Core para significarem coisas específicas em relação aos nossos ambientes do mundo real. Observe que você também pode adicionar seus próprios nomes de ambiente, não precisa usar os padrões, mas os padrões funcionaram para nós.

  • Desenvolvimento – Desenvolvimento em máquina local usando o Visual Studio. A configuração aponta para o Couchbase Server na máquina local, etc.
  • Staging – Ambientes de teste em nuvem
  • Produção – Tanto o ambiente de pré-produção (para testes finais antes da implantação) quanto o ambiente de produção final. Esses ambientes são geralmente iguais aos de Staging, mas com registro de logs mais leve por padrão.

Portanto, nosso appsettings.json base geralmente se parece com isto:

{
“Registro”:
“IncludeScopes”: false,
“LogLevel”: {
“Default”: “Debug”,
“Sistema”: “Informação”,
“Microsoft”: “Informação”,
“Couchbase”: “Depurar”
}
},
“Couchbase”:
“Buckets”: [
{
“Name”: “my-bucket”
}
]
}
}

A configuração acima usa o localhost para o Servidor Couchbase por padrão, já que não temos URLs de servidores especificadas. Em seguida, criaremos appsettings.Staging.json e/ou appsettings.Production.json assim:

{
“Registro”:
“LogLevel”: {
“Padrão”: “Informação”,
“Couchbase”: “Informação”
}
}
“CouchbaseServiceDiscovery”: “_couchbase._tcp.services.local”
}

Isso reduz nossos níveis de log para algo mais razoável e também possui uma configuração para descoberta de serviços (discutida mais tarde).

Injeção de Dependência

O ASP.NET Core usa muitas técnicas que são diferentes do modelo tradicional do ASP.NET, o que significa que a integração do Couchbase em aplicativos .NET Core é um pouco diferente. Em particular, o ASP.NET Core foi construído desde o início para funcionar com injeção de dependência.

Para apoiar isso, usamos o Couchbase.Extensions.DependencyInjection pacote para preencher a lacuna entre os objetos de bucket do SDK do Couchbase e o sistema de injeção de dependência. O Couchbase é registrado durante ConfigurarServiços no Startup turma, passando a seção de configuração acima. Também adicionamos código de encerramento para fechar as conexões quando a aplicação web estiver sendo encerrada.

public void ConfigureServices(IServiceCollection services)
{
// Registrar o Couchbase com a seção de configuração
serviços

.AddCouchbase(Configuration.GetSection(“Couchbase”))

.AddCouchbaseBucket(“my-bucket”);;

if (!Environment.IsDevelopment())
{
services.AddCouchbaseDnsDiscovery(Configuration[“CouchbaseServiceDiscovery”]);
}

services.AddMvc();
// Registre outros serviços aqui
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env,

ILoggerFactory loggerFactory,
IApplicationLifetime applicationLifetime
{
// ...

// Não estou mostrando a inicialização padrão do aplicativo aqui

// ...

// Quando o aplicativo for interrompido, encerre graciosamente as conexões do Couchbase
applicationLifetime.ApplicationStopped.Register(() =>
{
app.ApplicationServices.GetRequiredService().Close();;
});
}

Você pode acessar qualquer bucket em qualquer controller injetando IBucketProvider através do construtor. No entanto, você pode notar que o exemplo acima também faz uma chamada para AddCouchbaseBucket(“my-bucket”).

Este método permite registrar uma interface vazia herdada de INamedBucketProvider:

public interface IMyBucketProvider : INamedBucketProvider
{
}

E então injete-o em um controlador ou serviço de lógica de negócios. Ele sempre fornecerá o mesmo bucket, com base na configuração que você forneceu durante ConfigurarServiços.

public class HomeController : Controller
{
private readonly IMyBucketProvider _bucketProvider;

public HomeController(IMyBucketProvider bucketProvider)
{
_bucketProvider = bucketProvider;
}

public IActionResult Index()
{
var bucket = _bucketProvider.GetBucket();

var result =
await bucket.QueryAsync(
“SELECT Extent.* FROM `my-bucket` AS Extent;

if (!result.Success)
{
throw new Exception(“Couchbase Error”, result.Exception);
}

return View(result.Rows);
}
}

Descoberta de Serviços

Ao trabalhar com microsserviços, a descoberta de serviços é um problema comum. Cada ambiente em que você executa tende a ter serviços diferentes em pontos de extremidade diferentes. O Couchbase é um desses serviços, que pode existir em um endereço diferente em cada ambiente. Existem muitas soluções para descoberta de serviços, mas na CenterEdge decidimos nos ater a uma solução simples por enquanto, DNS SRV registros.

Para apoiar isso, usamos o Couchbase.Extensions.DnsDiscovery pacote. Este pacote encontrará registros DNS SRV que listam os nós no cluster. Para dar suporte a isso, criamos um domínio DNS privado no AWS Route 53 chamado “services.local” e criamos um conjunto de registros SRV chamado “_couchbase._tcp.services.local” que possui a lista de nós do Couchbase. O conjunto de registros do Route 53 se parece com isto:

10 10 8091 couchbasedata1.int.dev.centeredgeonline.com
10 10 8091 couchbasedata2.int.dev.centeredgeonline.com
10 10 8091 couchbasedata3.int.dev.centeredgeonline.com

No exemplo acima para ConfigureServices na classe startup, você pode ter notado a seguinte seção:

if (!Environment.IsDevelopment())
{
services.AddCouchbaseDnsDiscovery(Configuration[“CouchbaseServiceDiscovery”]);
}

Isso substituirá quaisquer servidores passados por configuração pelos servidores encontrados através da consulta ao registro SRV de DNS. Nós também fornecemos o nome DNS via configuração, tornando fácil substituí-lo, se necessário. Especificamente, nós não usamos esta extensão em nosso ambiente de Desenvolvimento, onde estamos usando localhost para acessar o cluster do Couchbase.

Isso é legal, e quanto ao Docker?

Até agora, tudo o que fizemos é aplicável ao ASP.NET Core em geral, e não necessariamente específico para o Docker. Então, como passamos de uma aplicação geral para uma que é executada em um contêiner Docker?

Primeiro, há algumas etapas preparatórias que você precisará concluir em sua máquina de desenvolvimento:

  1. Certifique-se de que você tem Hyper-V ativado no Windows
  2. Instalar Docker para Windows
  3. Configurar um Unidade Compartilhada no Docker para a unidade onde sua aplicação reside
  4. Instalar Visual Studio Tools para Docker
  5. Certifique-se de que o Docker esteja iniciado (você pode configurar o Docker para iniciar automaticamente ao fazer login)

Agora você está pronto para começar. Basta clicar com o botão direito no seu projeto no Visual Studio e ir em Adicionar > Suporte ao Docker. Isso adiciona os arquivos necessários ao seu projeto.

add docker support 3
Adicionar Suporte ao Docker

Embora vários arquivos tenham sido adicionados, há alguns que são particularmente importantes. O primeiro arquivo que gostaria de destacar é Dockerfile:

FROM microsoft/aspnetcore:1.0.1
ENTRYPOINT [“dotnet”, “TestApp.dll”]
ARG source=.
WORKDIR /app
EXPOSE 80
COPY $source .

Há duas linhas principais neste arquivo que você talvez precise modificar:

FROM microsoft/aspnetcore:1.0.1

Você deve alterar esta linha se estiver usando uma versão diferente do .NET Core, como 1.0.3 ou 1.1.0. A marca de versão nesta linha deve corresponder à versão do .NET Core usada no seu arquivo project.json.

ENTRYPOINT [“dotnet”, “TestApp.dll”]

Se você renomear seu projeto, ele gerará um arquivo DLL com um nome diferente. Altere esta linha para fazer referência ao nome correto do arquivo DLL.

O próximo arquivo é docker-compose.yml. Este arquivo, junto com alguns arquivos relacionados, controla a natureza dos contêineres Docker iniciados quando você clica em Executar. Precisaremos fazer uma alteração em docker-compose.yml para fazer a conexão com o Couchbase Server funcionar.

Nossa configuração para o ambiente de Desenvolvimento está tentando acessar “localhost” para acessar o Couchbase Server. Essa abordagem funciona bem se a aplicação estiver sendo executada no IIS Express. No entanto, dentro de um contêiner Docker, “localhost” não aponta mais para o seu computador de desenvolvimento. Em vez disso, ele se refere ao contêiner Docker isolado, assim como faria dentro de uma máquina virtual.

Para corrigir isso, precisamos adicionar uma seção de ambiente a docker-compose.yml para usar o nome do seu computador em vez de “localhost”:

versão: ‘2’

serviços:
testapp:
imagem: user/testapp${TAG}
compilação
contexto.
dockerfile: Dockerfile
portas
– “80”
ambiente
– Couchbase:Servidores:0=https://$COMPUTERNAME:8091/

Basta adicionar as últimas duas linhas acima ao seu arquivo. O Docker Compose substituirá automaticamente $-NOME DO COMPUTADOR com o nome do seu computador, o que é útil ao compartilhar o aplicativo com sua equipe por meio de controle de versão.

Agora você está pronto para testar no Docker. Basta alterar a lista suspensa Executar na barra de ferramentas do Visual Studio para Docker em vez de IIS Express antes de iniciar seu aplicativo. Ele até oferece suporte à depuração e exibe logs na janela Depurar.

If you want to get really fancy, you can also tweak docker-compose.yml to do things like launch additional required containers, override other settings via environment variables, and more. For example, at CenterEdge we use this approach to launch additional microservices that are dependencies of the application being developed.

Implantação

Your exact deployment approach will vary depending on your Docker platform. For example, CenterEdge uses Amazon AWS, so we’ll deploy using EC2 Container Service. Regardless of your platform of choice, you’ll need to make a Docker image from your application and publish it to a Docker container registry.

At CenterEdge we’ve added this to our continuous integration process, but here’s a summary of the steps involved:

  1. Run “dotnet publish path/to/your/app -c Release” to publish your application. This will publish to “bin/Release/netcoreapp1.0/publish” by default, but this can be controlled with the “-o some/path” parameter. For .NET Core 1.1, it will be netcoreapp1.1 instead of netcoreapp1.0 by default.
  2. Run “docker build -t myappname path/to/your/app/bin/Release/netcoreapp1.0/publish” to build a Docker image. It will be tagged as “myappname”.
  3. Run “docker tag myappname yourdockerregistry/myappname:sometag” to tag the Docker image for your Docker registry. Substitute “yourdockerregistry” with the path to your Docker registry. For Docker Hub, this is just your username. Substitute “sometag” with tag you want to use, such as “latest” or “1.0.5”.
  4. Run “docker push yourdockerregistry/myappname:sometag” to push the image to your Docker container registry. This assumes that you’ve already used “docker login” to authenticate with your registry.

Regarding versioning, at CenterEdge we use NuGet-style version numbering for our microservices. For example, “1.1.0” or “2.0.5-beta002”. This version number is the tag we use in our Docker container registry. We also follow SemVer, meaning that increments to different parts of the number have specific meanings. If we increment the first digit, it means the API has breaking changes and is not fully backwards compatible. Incrementing the second digit indicates significant new features. The third digit is incremented for bug fixes.

Conclusão

Hopefully, you now have the basic tools you’ll need to transition your .NET applications using Couchbase to .NET Core and Docker. We’ve found the transition to be fun and exciting.  While ASP.NET Core has changed some approaches and other things have been deprecated, the overall platform feels much cleaner and easier to use. And I’m sure even more great things are coming in the future.

Compartilhe este artigo

Autor

Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She’s responsible for our monthly developer newsletter.

Deixe um comentário

Pronto para começar com o Couchbase Capella?

Começar a construir

Confira nosso portal para desenvolvedores para explorar o NoSQL, navegar por recursos e começar com tutoriais.

Use o Capella free

Coloque a mão na massa com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Quer saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.