Brant Burnett é um Especialista em CouchbaseEle é um dos maiores especialistas em desenvolvimento de software, arquiteto de sistemas e desenvolvedor .Net com experiência em desenvolvimento de pilha completa para desktop e web. Nos últimos 12 anos, ele trabalhou na CenterEdge Software, uma empresa de software de entretenimento familiar com sede em Roxboro, NC. Brant tem experiência no desenvolvimento de aplicativos para todos os segmentos de seu pacote de software. Nos últimos quatro anos, ele trabalhou para fazer a transição da infraestrutura de nuvem da empresa de uma plataforma Microsoft SQL para uma plataforma Couchbase NoSQL pura. Com seu trabalho na CenterEdge, Brant pôde se concentrar na criação de soluções de software sérias para empresas divertidas.

Com o lançamento do Couchbase .NET SDK 2.4.0O Couchbase agora tem suporte oficial para .NET Core. Isso abre um vasto mundo novo para o .NET Couchbase desenvolvedores. Em particular, agora podemos usar Docker para gerenciar facilmente nossos aplicativos e aprimorar o processo de implantação, algo que antes era reservado a aplicativos como Java e Node.js.

Em Software CenterEdgeCom o lançamento do ASP.NET Core, estamos nos movendo rapidamente para transformar nossos aplicativos monolíticos do ASP.NET em microsserviços do ASP.NET Core baseados no Docker. Estamos muito empolgados com as novas possibilidades que ele oferece e com as melhorias na robustez e na facilidade de implementação de nossos aplicativos. Esperamos que esta visão geral das abordagens que estamos usando para fazer essa transição ajude outras pessoas a seguir o exemplo.

Configuração e ambientes

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

No CenterEdge, definimos os ambientes do .NET Core para significar 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 é necessário 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 na nuvem
  • Produção - Tanto o ambiente de pré-produção (para testes finais antes da implementação) quanto o ambiente de produção final. Esses ambientes geralmente são iguais ao Staging, mas com um registro mais leve por padrão.

Portanto, nosso arquivo básico appsettings.json geralmente se parece com isto:

{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Padrão": "Debug",
"Sistema": "Informações",
"Microsoft": "Informações",
"Couchbase": "Debug"
}
},
"Couchbase": {
"Buckets": [
{
"Name" (Nome): "my-bucket"
}
]
}
}

A configuração acima usa localhost para o Couchbase Server por padrão, já que não temos nenhum URL de servidor especificado. Em seguida, criaremos Configurações do aplicativo.Staging.json e/ou Configurações do aplicativo.Production.json assim:

{
"Logging": {
"LogLevel": {
"Padrão": "Informações",
"Couchbase": "Informações"
}
}
"CouchbaseServiceDiscovery": "_couchbase._tcp.services.local"
}

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

Injeção de dependência

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

Para dar suporte a isso, usamos o Couchbase.Extensions.DependencyInjection para preencher a lacuna entre os objetos de balde do SDK do Couchbase e o sistema de injeção de dependência. O Couchbase é registrado durante o ConfigureServices no Inicialização passando a seção de configuração mencionada acima. Também adicionamos algum código de desligamento para fechar as conexões quando o aplicativo Web estiver saindo.

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

.AddCouchbase(Configuration.GetSection("Couchbase"))

.AddCouchbaseBucket("my-bucket");

Se (!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 está mostrando a inicialização padrão do aplicativo aqui

// …

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

Você pode acessar qualquer bucket em qualquer controlador injetando IBucketProvider por meio do construtor. No entanto, você pode observar que o exemplo acima também faz uma chamada para AddCouchbaseBucket("my-bucket").

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

interface pública IMyBucketProvider : INamedBucketProvider
{
}

E, em seguida, injetá-lo em um controlador ou serviço de lógica comercial. Ele sempre fornecerá o mesmo bucket, com base na configuração que você forneceu durante o ConfigureServices.

classe pública HomeController : Controlador
{
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 meu balde AS Extent");

Se (!result.Success)
{
lançar nova Exceção("Erro do Couchbase", 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 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. Há muitas soluções para a descoberta de serviços, mas no CenterEdge decidimos manter uma solução simples por enquanto, DNS SRV registros.

Para dar suporte a isso, usamos o Couchbase.Extensions.DnsDiscovery pacote. Esse pacote encontrará registros SRV de DNS que listam os nós do 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 tem a lista de nós do Couchbase. O conjunto de registros do Route 53 tem a seguinte aparência:

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 inicialização, você deve ter notado a seguinte seção:

Se (!Environment.IsDevelopment())
{
services.AddCouchbaseDnsDiscovery(Configuration["CouchbaseServiceDiscovery"]);
}

Isso substituirá todos os servidores passados por meio da configuração pelos servidores encontrados ao procurar o registro SRV do DNS. Também fornecemos o nome DNS por meio da configuração, o que facilita a substituição, se necessário. Especificamente, não usamos essa extensão em nosso ambiente de desenvolvimento, onde estamos usando localhost para acessar o cluster do Couchbase.

Isso é legal, mas e o Docker?

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

Primeiro, há algumas etapas preparatórias que você precisará concluir em seu computador de desenvolvimento:

  1. Certifique-se de que você tenha Hyper-V ativado no Windows
  2. Instalar Docker para Windows
  3. Configurar um Drive compartilhado no Docker para a unidade em que seu aplicativo reside
  4. Instalar Ferramentas do Visual Studio para o Docker
  5. Certifique-se de que o Docker esteja iniciado (você pode configurar o Docker para iniciar automaticamente no login)

Agora, você está pronto para começar. Basta clicar com o botão direito do mouse em seu projeto no Visual Studio e ir para Add > Docker Support. 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 eu gostaria de destacar é Dockerfile:

DE microsoft/aspnetcore:1.0.1
ENTRYPOINT ["dotnet", "TestApp.dll"]
Fonte ARG=.
WORKDIR /app
EXPOSE 80
COPY $source .

Há duas linhas importantes nesse arquivo que talvez você precise modificar:

DE microsoft/aspnetcore:1.0.1

Você deve alterar essa linha se estiver usando uma versão diferente do .NET Core, como 1.0.3 ou 1.1.0. A tag de versão nessa linha deve corresponder à versão do .NET Core usada em seu arquivo project.json.

ENTRYPOINT ["dotnet", "TestApp.dll"]

Se você renomear o projeto, ele produzirá um nome de arquivo de DLL diferente. Altere essa linha para fazer referência ao nome de arquivo DLL correto.

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

Nossa configuração para o ambiente de desenvolvimento está tentando acessar "localhost" para acessar o Couchbase Server. Essa abordagem funciona bem se o aplicativo estiver sendo executado no IIS Express. No entanto, dentro de um contêiner do Docker, "localhost" não aponta mais para o seu computador de desenvolvimento. Em vez disso, ele se refere ao contêiner isolado do Docker, da mesma forma que faria em uma máquina virtual.

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

versão: '2'

serviços:
testapp:
imagem: user/testapp${TAG}
construir:
contexto: .
dockerfile: Dockerfile
portos:
– “80”
ambiente:
- Couchbase:Servidores:0=http://$COMPUTERNAME:8091/

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

Agora você está pronto para testar no Docker. Basta alterar o menu suspenso Executar na barra de ferramentas do Visual Studio para Docker em vez de IIS Express antes de iniciar seu aplicativo. Ele ainda oferece suporte à depuração e mostra os registros na janela Debug.

Se você quiser ficar realmente sofisticado, também pode ajustar docker-compose.yml para fazer coisas como iniciar contêineres adicionais necessários, substituir outras configurações por meio de variáveis de ambiente e muito mais. Por exemplo, no CenterEdge, usamos essa abordagem para iniciar microsserviços adicionais que são dependências do aplicativo que está sendo desenvolvido.

Implantação

Sua abordagem exata de implantação varia de acordo com sua plataforma Docker. Por exemplo, o CenterEdge usa o Amazon AWS, portanto, faremos a implantação usando Serviço de contêiner do EC2. Independentemente da plataforma escolhida, você precisará criar uma imagem do Docker a partir do seu aplicativo e publicá-la em um registro de contêineres do Docker.

No CenterEdge, adicionamos isso ao nosso processo de integração contínua, mas aqui está um resumo das etapas envolvidas:

  1. Execute "dotnet publish path/to/your/app -c Release" para publicar seu aplicativo. Por padrão, ele será publicado em "bin/Release/netcoreapp1.0/publish", mas isso pode ser controlado com o parâmetro "-o some/path". Para o .NET Core 1.1, será netcoreapp1.1 em vez de netcoreapp1.0 por padrão.
  2. Execute "docker build -t myappname path/to/your/app/bin/Release/netcoreapp1.0/publish" para criar uma imagem do Docker. Ela será marcada como "myappname".
  3. Execute "docker tag myappname yourdockerregistry/myappname:sometag" para marcar a imagem do Docker para o seu registro do Docker. Substitua "yourdockerregistry" pelo caminho para o seu registro do Docker. Para o Docker Hub, esse é apenas o seu nome de usuário. Substitua "sometag" pela tag que você deseja usar, como "latest" ou "1.0.5".
  4. Execute "docker push yourdockerregistry/myappname:sometag" para enviar a imagem para o registro de contêineres do Docker. Isso pressupõe que você já tenha usado o "docker login" para se autenticar no seu registro.

Com relação ao controle de versão, no CenterEdge usamos a numeração de versão no estilo NuGet para nossos microsserviços. Por exemplo, "1.1.0" ou "2.0.5-beta002". Esse número de versão é a tag que usamos em nosso registro de contêineres do Docker. Também seguimos SemVerIsso significa que os incrementos em diferentes partes do número têm significados específicos. Se incrementarmos o primeiro dígito, isso significa que a API tem mudanças significativas e não é totalmente compatível com as versões anteriores. O incremento do segundo dígito indica novos recursos significativos. O terceiro dígito é incrementado para correções de bugs.

Conclusão

Esperamos que agora você tenha as ferramentas básicas necessárias para fazer a transição de seus aplicativos .NET usando o Couchbase para o .NET Core e o Docker. Achamos que a transição foi divertida e empolgante. Embora o ASP.NET Core tenha mudado algumas abordagens e outras coisas tenham sido preteridas, a plataforma geral parece muito mais limpa e fácil de usar. E tenho certeza de que ainda mais coisas excelentes estão por vir no futuro.

Autor

Postado por Laura Czajkowski, gerente da comunidade de desenvolvedores, Couchbase

Laura Czajkowski é a Snr. Developer Community Manager da Couchbase, supervisionando a comunidade. Ela é responsável pelo nosso boletim informativo mensal para desenvolvedores.

Deixar uma resposta