A opção de funcionalidade é uma ferramenta que permite alternar da funcionalidade antiga para a nova sem reconstruir o aplicativo e liberá-lo novamente. É implementado adicionando um operador condicional (
if
) ao código, o que possibilita controlar o comportamento do programa, simplesmente alterando o valor desejado no arquivo de configuração ou no banco de dados. Se você já editou as configurações em um arquivo ini, estará familiarizado com esta tecnologia.
Indo mais fundo, você pode encontrar um grande número de opções diferentes para os switches e os novos recursos que eles fornecem. Isso levanta muitas questões. Onde colocar a configuração? Mas e se ficar indisponível? Talvez você possa escrever uma estrutura simples para trabalhar com os switches? Talvez seja melhor usar uma solução pronta? Isso serve tanto para o monólito quanto para os microsserviços?
Este material contém informações básicas sobre opções de funcionalidade no contexto de desenvolvimento na plataforma .NET. A primeira parte contém informações gerais sobre os comutadores; eles são bastante independentes da implementação específica e podem ser úteis para profissionais que trabalham com uma variedade de plataformas. A segunda parte discute ferramentas modernas específicas que facilitam o uso de switches ao desenvolver para o .NET.
Tentei escrever um artigo que o ajudasse a decidir se implementaria opções de funcionalidade no seu caso específico e, se necessário, como. Até agora, em nosso departamento, os switches são usados apenas para solucionar problemas específicos. Por exemplo, nosso aplicativo geralmente precisa solicitar informações legais e contábeis de um catálogo, que pode ser apresentado de duas formas: um catálogo completo remoto e sua cópia parcial local. Nas configurações do aplicativo, os usuários podem escolher com que tipo de diretório o aplicativo deve trabalhar no momento. Os planos incluem a introdução de switches como uma infraestrutura comum para todo o projeto. Com base nisso, processos semelhantes aos descritos acima serão construídos.
Visão geral do comutador de funcionalidade
O que é isso
Em termos simples, o significado das opções é o seguinte. O contratado avança em nosso código, representando a lógica da área de assunto, e se depara com uma declaração condicional. Nesta declaração, o contratado pergunta se algum código condicional precisa ser executado em algum registro que sabe quando e sob que circunstâncias a funcionalidade de interesse deve funcionar.
Como resultado, o executor percorre uma ramificação ou outra e, em um caso degenerado, a outra ramificação está simplesmente vazia. No caso mais simples, o comutador assume um dos dois valores ("ativado" e "desativado") sob o controle da pessoa responsável que mantém o registro. E você pode criar algo mais complicado, por exemplo, incluir funcionalidade apenas para usuários específicos ou para usuários de determinados países ou em um determinado momento.
O registro de funcionalidade pode assumir uma variedade de formas. O ponto é quando você pode gerenciar esse registro sem parar o aplicativo ou reimplementá-lo. Por exemplo, os comutadores podem ser armazenados em um arquivo, em um banco de dados ou ter um serviço de rede separado com comutadores. Abaixo da operação dos comutadores é considerado em mais detalhes.
Isso é relevante?
Em seu
artigo, o criador do
featureflag.tech afirma que os switches se tornam uma prática padrão no desenvolvimento de software. Há cada vez mais materiais sobre switches: artigos teóricos, histórias sobre a prática de implementar switches, relatórios em conferências. Incluí links para os materiais mais interessantes no texto deste artigo; Todos os links são coletados na seção
"Conclusão" .
Eu diria que o crescimento da popularidade dos switches é facilitado pela estabilização e padronização em algumas áreas da tecnologia da informação. Na "empresa sangrenta" aparece cada vez mais ilhas de estabilidade. Um aumento no número de métricas no desenvolvimento, automação da montagem, inspeção e entrega do aplicativo leva ao fato de que os processos de desenvolvimento se tornam mais transparentes e gerenciáveis. Como resultado, os requisitos para um novo nível estão começando a ser apresentados para a criação de software. Um desses requisitos é o desejo de disseminar no tempo os momentos de publicação do aplicativo e a inclusão de novas funcionalidades, implementadas pelos comutadores. Os recursos da indústria já amadureceram para atender a essa demanda industrial.
Quanto às ferramentas que ajudam a trabalhar com comutadores, existem muitas, e muitas, para uma variedade de plataformas. Provavelmente, a aparência de um grande número de ferramentas é explicada pela simplicidade com a qual você pode implementar os recursos básicos dos comutadores. Mas a adição de pães mais complexos e "saborosos" pode exigir custos de mão-de-obra significativos, muitos projetos de código aberto que implementam opções de funcionalidade param de se desenvolver e receber suporte. No entanto, um número significativo de projetos, pagos e gratuitos, permanece à tona. Os mais interessantes (do ponto de vista do .NET) são descritos na
segunda parte do artigo .
Um pouco mais
Este artigo possui um bom diagrama que ilustra a operação dos comutadores; Convido você a se familiarizar com isso.
Começamos nossa consideração do circuito com código. Deixe no nosso exemplo uma nova funcionalidade - verificando a correção do preenchimento do documento. Garantimos que o documento seja verificado apenas se essa funcionalidade estiver ativada. Vamos fazer um ponto de comutação:
var document = GetDocument(); if (feature.IsEnabled("Feature #123. Document validation")) { Validate(document); }
Nesse caso, o
feature
é uma referência à infraestrutura que ajuda nosso aplicativo a se comunicar com o roteador e o registro de funcionalidade. Usando essa infraestrutura, descobrimos se é necessário verificar o documento e, em caso afirmativo, verifique-o.
O roteador usa as informações disponíveis: o nome da funcionalidade que passamos como argumento e o que podemos extrair das classes estáticas que ele sabe para determinar se a funcionalidade solicitada deve funcionar nesse caso. O roteador descobre como os comutadores no registro estão configurados. Se o registro estiver indisponível, você deverá usar os dados armazenados em cache anteriormente ou recorrer a alguma outra estratégia para esse caso. Você também pode imaginar um roteador que receba explicitamente informações adicionais (o contexto) através dos argumentos do método que o ajuda a decidir se deseja ativar a funcionalidade no momento.
O pessoal responsável configura os comutadores da maneira selecionada. Na opção mais agradável, eles acessam o site que representa o registro dos comutadores e clicam nos comutadores selecionados com o mouse.
Portanto, no sentido de artefatos, o sistema de comutação consiste em duas partes. Por um lado, essa é uma infraestrutura para um programador descobrir se a funcionalidade deve funcionar nesse caso e executar diretamente a ramificação de código apropriada. Por outro lado, é um mecanismo que permite a um funcionário responsável escolher qual funcionalidade ativar e qual desativar. Em casos degenerados (quando o registro é costurado no código, veja abaixo), os dois artefatos podem coincidir e o programador pode controlar a funcionalidade de ligar e desligar.
Possíveis requisitos de sistema do switch
Como você pode ver, o sistema de comutação pode ser uma coisa bastante complicada. Listamos os requisitos básicos que podem ser impostos a esse sistema.
- A dependência da funcionalidade on e off de diferentes parâmetros. Exemplos de parâmetros: usuário (função, identificador, localização geográfica), hora (luz do dia ou escuridão, dias úteis ou dias da semana, períodos específicos), ambiente (para desenvolvimento, teste, operação industrial).
- Coleta de estatísticas de uso ao analisar processos do domínio: qual usuário em que condições viu ou não viu a funcionalidade, quantas vezes ele usou a nova funcionalidade.
- Uma auditoria do que está acontecendo com os próprios switches: quem os pressiona, quando, o que muda.
- Fornecer uma escolha flexível entre a funcionalidade do registro local e remoto ou algumas estratégias, caso o registro remoto não esteja disponível.
- Configuração do acesso ao sistema de comutação para diferentes categorias de funcionários, tanto no cliente quanto na empresa contratada: especialistas técnicos, especialistas na área de assunto e também os próprios usuários do aplicativo.
Obviamente, não é necessário se esforçar para satisfazer todos esses requisitos. Em muitos casos, alguns requisitos, pelo contrário, podem ser indesejáveis. Quanto mais requisitos você precisa cumprir, obviamente mais oneroso é o desenvolvimento de seu próprio sistema de comutação. Isso significa que, em algum momento após a introdução dos comutadores, o suporte do seu próprio sistema se tornará inútil e é hora de tomar uma solução pronta.
Árvore tecnológica
Resumimos as informações consideradas sobre as opções de funcionalidade, recorrendo à metáfora da
árvore tecnológica dos videogames. Vamos imaginar os comutadores como uma tecnologia que permite à empresa implantar novas funcionalidades sem estar ligada aos momentos de montagem e implantação do aplicativo. Essa tecnologia tem um custo conhecido (o custo de manutenção dos ciclos de vida dos comutadores e do registro) e os pré-requisitos para implementação: uma metodologia de desenvolvimento flexível e integração contínua. Obviamente, a integração contínua não é um pré-requisito, mas torna os switches muito mais eficientes e permite a entrega contínua do aplicativo. Além disso, a “pesquisa” dos switches “abre” outras tecnologias - testes A / B e lançamentos de canários. Eles serão discutidos abaixo.

Onde o registro de funcionalidade pode estar localizado
Considere várias opções para colocar o registro de funcionalidade, colocando-os em crescente complexidade de implementação.
- Costure a configuração diretamente no código, por exemplo, comente o código desnecessário e remova o comentário do código necessário ou use as diretivas de compilação condicional. Obviamente, essa opção elimina a essência da introdução de switches, porque com ela você precisará recompilar e implantar o aplicativo para ver a nova funcionalidade. Duas dificuldades também devem ser observadas. Em primeiro lugar, com essa abordagem, um funcionário que inclui funcionalidade exigirá habilidades técnicas adicionais: editar o código fonte e a capacidade de trabalhar com o sistema de controle de versão (SLE). Deus sabe que habilidades, é claro, mas o mais provável é que os próprios programadores tenham que incluir funcionalidades. Em segundo lugar, a funcionalidade será a mesma em todos os nós em que esta versão do aplicativo foi publicada - para escolher entre a funcionalidade antiga e a nova, será necessário um balanceador e vários nós com o aplicativo.
- Coloque a configuração no ambiente do aplicativo, por exemplo, em variáveis de ambiente. Essa opção parece um pouco extravagante, porque está repleta de aparência de dependências excessivas no tempo de execução ou no sistema operacional.
- Use arquivos de configuração, que são um local bastante padrão para armazenar as configurações do aplicativo. A desvantagem dessa opção será a necessidade de manter os arquivos de configuração separadamente ao lado de cada instância do aplicativo. Essa desvantagem é inerente à versão anterior.
- Mantenha uma tabela no banco de dados que descreve as opções de funcionalidade. Instâncias de aplicativos baterão nesse banco de dados para verificar se a funcionalidade que lhes interessa funciona. Nesta opção, o registro é centralizado (diferente da versão anterior), mas permite incluir funcionalidades separadamente para cada nó, se isso for suportado pela infraestrutura de switch selecionada.
- Aumente o serviço de rede ao qual as instâncias do aplicativo acessarão através do protocolo de rede selecionado. Se na versão anterior significava que os comutadores provavelmente serão armazenados junto com as entidades da área de assunto e, portanto, o custo de pesquisa dos comutadores será previsível, então aqui teremos acesso adicional pela rede. O custo de manipulação adicional e a possibilidade de negação de serviço são sérios inconvenientes dessa opção, mas, é claro, o armazenamento em cache não é proibido. E para falhas, você deve fornecer um comportamento padrão.
Recomendações
Em relação ao uso de comutadores, as seguintes recomendações gerais podem ser feitas.
O ponto de comutação e a lógica não precisam estar juntos . No exemplo mais simples, após a declaração condicional, na qual interrogamos o estado de uma opção específica, o código implementa imediatamente a funcionalidade incluída. Isso não é muito conveniente, porque adiciona dependências redundantes à lógica: conhecimento sobre a infraestrutura dos comutadores e o nome de uma funcionalidade específica do registro. Na prática, isso complica o processo de teste e remoção do comutador quando ele se torna desnecessário.
Defina o ponto de comutação mais alto . Desenvolvimento do parágrafo anterior. Os pontos nos quais a infraestrutura do switch é acessada devem ser excluídos da lógica da área de assunto até a última oportunidade possível, ou seja, "empurrá-los" para mais perto do local em que a solicitação foi recebida. Assim, reduzimos a dependência de módulos individuais em switches, simplificamos os processos de suporte e testes.
Use estratégias em vez de instruções condicionais . Se o switch permanecer por muito tempo, o operador condicional poderá ser aprimorado para uma estratégia e isolar explicitamente a lógica comutável em algo seguido e testado separadamente.
Não agrupe comutadores . Você não deve formar dependências entre os comutadores, agrupá-los e montá-los em hierarquias. Isso tornará mais fácil manter o código com novas funcionalidades e o ciclo de vida dos próprios switches.
Consolide pontos de comutação para uma funcionalidade . Pode acontecer que o comportamento de vários blocos de programas ao mesmo tempo dependa da mesma opção. Se o desenvolvimento estiver mal coordenado, os pontos de comutação podem ser duplicados em locais diferentes, e isso leva a testes e suporte mais caros. Se você é disciplinado a tentar empurrar os pontos de comutação para a entrada do aplicativo, essa recomendação - não espalhe pontos por todo o sistema - geralmente é executada automaticamente.
As principais categorias de switches
Considere a classificação do comutador fornecida
neste artigo . É baseado em quanto tempo o switch "vive" e com que frequência seu estado muda. A atribuição de um comutador a uma classe específica ajuda a determinar como usar o comutador no código e como armazenar o estado do comutador.
Interruptores de liberaçãoEsta é a visão principal dos switches. Eles permitem que você concentre o desenvolvimento em uma filial principal, que, além disso, é lançada regularmente em operação comercial. Em vez de desenvolver em uma ramificação separada e injetá-la na ramificação principal para liberar a versão desejada, introduzimos um ponto de alternância no código, que oculta a funcionalidade que ainda não está pronta para os usuários. Quando prontos, os switches iniciam uma nova funcionalidade.
Essas opções permanecem por vários dias ou semanas - enquanto o desenvolvimento e a implementação de novas funcionalidades estão em andamento. Quando a funcionalidade foi testada e considerada adequada, o comutador e o ponto de comutação no código podem ser removidos. O estado do comutador geralmente muda quando uma nova versão é lançada ou quando a configuração do aplicativo é alterada. É permitido armazenar essa opção no arquivo de configuração. Há uma alta probabilidade de que o ponto de comutação para a nova funcionalidade seja o único; faz sentido não cavar e colocá-lo na forma de uma declaração condicional convencional.
Switches de experiênciaPara executar em novas funcionalidades, são usados switches que duram de vários dias a vários meses. Durante o experimento, você pode monitorar como os usuários percebem as mudanças e como o comportamento delas muda. É desejável que o estado do comutador possa mudar muito dinamicamente a cada solicitação. Algum armazenamento centralizado, como um banco de dados ou serviço de rede, é mais provável que seja adequado aqui.
Se o experimento se encaixar em um número previsível de problemas, o ponto de comutação também pode ser emitido na forma de uma declaração condicional.Comutadores técnicos Os comutadorestécnicos ajudam a gerenciar as partes da infraestrutura de um aplicativo que afetam seu desempenho geral. Eles podem ser úteis quando lançamos uma atualização cujo impacto no desempenho é difícil de avaliar. Nesse caso, seria bom ter uma "opção" que desabilite instantaneamente novas funcionalidades se descobrir que seu uso leva a conseqüências desastrosas.Provavelmente, esses comutadores permanecerão por várias semanas ou mais e mudarão de estado quando a configuração do aplicativo mudar ou com mais frequência. A criticidade da função que esses comutadores implementam sugere que eles precisam usar um serviço de rede ou pelo menos um banco de dados. Você precisa começar para garantir que, no código, os pontos de comutação para a mesma funcionalidade não estejam espalhados em lugares diferentes.Switches para controle de acessoOutra oportunidade óbvia de usar switches é fornecer acesso a novas funcionalidades apenas para alguns usuários. Isso pode ser necessário tanto para a versão canary (quando novas funcionalidades gradualmente abrangem mais e mais usuários) quanto para criar seções privadas nas quais apenas usuários privilegiados têm acesso.Parece que essas opções permanecem muito tempo (talvez contanto que o próprio aplicativo) e possam mudar de estado a cada nova solicitação. Um serviço de rede para armazenar switches também é adequado aqui. É recomendável usar algum tipo de mecanismo centralizado para escolher entre a funcionalidade antiga e a nova e não espalhar instruções condicionais por todo o código.,
A introdução de opções de funcionalidade não apenas possui vantagens óbvias, para as quais tudo é iniciado normalmente (diversidade no momento da publicação do aplicativo e ativação de novas funcionalidades, reduzindo o número de filiais em moeda forte), mas também pode simplificar alguns processos paralelos. Listamos-os e depois consideramos alguns com mais detalhes.Teste A / B. Comparação do comportamento dos usuários usando as versões nova e antiga.Questões canárias. Aumento gradual no número de usuários com acesso a novas funcionalidades.Lançamentos azul esverdeado. Envie solicitações usando o balanceador para o servidor com a versão antiga ou para o servidor com a nova versão.Funcionalidade extrema planejada.A inclusão de funcionalidade por um curto período de tempo, por exemplo, durante a promoção.Inclusão simultânea de funcionalidades em vários locais. A inclusão de funcionalidade ao mesmo tempo, tanto no site quanto no aplicativo móvel. Ou a inclusão da funcionalidade simultaneamente em diferentes módulos do mesmo aplicativo.Grandes mudanças na infraestrutura. Por exemplo, a transição para outra maneira de armazenar dados.Testando coisas novas pelos usuários. Fornecendo aos usuários a capacidade de ativar e desativar a nova funcionalidade, personalizando o aplicativo por si mesmos.Teste A / BVamos dar uma rápida olhada no que é o teste A / B. Ao preparar o teste A / B, são formuladas algumas propriedades mensuráveis do sistema de informações ou do comportamento do usuário. Exemplos dessa propriedade: 1) a duração de um processo específico na área de assunto, 2) o número relativo de usuários que acessaram uma página específica, 3) o número de recursos que o aplicativo utiliza. Além disso, é feita uma suposição de como o valor dessa propriedade será alterado quando a nova funcionalidade for incluída. Os usuários obterão uma resposta mais rápida? Eles vão comprar mais? O aplicativo comerá menos?Em seguida, durante o teste A / B, para um grupo, a nova funcionalidade é ativada e, para o outro, permanece desativada. As suposições feitas durante a preparação são verificadas e, com base nos resultados, conclui-se se a nova funcionalidade fornece algo bom e não leva a algo ruim. Às vezes, os usuários são divididos em três grupos, em dois dos quais a funcionalidade permanece antiga. Se os resultados dos dois grupos de controle forem muito diferentes, todo o teste conterá algum tipo de erro, tornando as conclusões baseadas neste teste não confiáveis.As opções de funcionalidade facilitam a divisão dos usuários em grupos e o gerenciamento deles. Para cada grupo, você pode habilitar e desabilitar a nova funcionalidade sem aguardar a próxima versão do aplicativo. Isso reduz o tempo necessário para verificar suposições e concluir todo o ciclo de teste A / B. Muitas empresas procuram estabelecer a verificação de várias suposições por semana.Você pode aprender mais sobre esse método neste artigo , aqui e aqui em "Habré", e definitivamente vale a pena dar uma olhada no relatório "Alternâncias de recursos ou Como rolar recursos sem liberação" , que revela algumas sutilezas interessantes dos testes A / B com comutadores de funcionalidade.Questões sobre canários e azul esverdeadoO que o canário tem a ver com isso? Canários eram usados na indústria de mineração: os mineiros levavam canários em uma gaiola quando desciam em uma mina, onde se suspeitava de uma alta concentração de gases explosivos. As canárias gostam muito de ar puro e muito antes que as pessoas comecem a sentir impurezas prejudiciais e perigosas. Se o canário parar de cantar, desligar ou morrer, as pessoas precisam evacuar urgentemente até que exploda. Aqui aqui você pode ler mais sobre isso (em Inglês).Daqui, como eu a entendo, veio a expressão "testemunho do canário". Se você mora em um estado que segue uma política doméstica repressiva (ou seja, em qualquer), poderá um dia descobrir que foi instruído não apenas a transferir os dados pessoais de seus usuários para departamentos autorizados, mas também a não dizer a ninguém que você eles foram entregues, não que você tenha recebido esse pedido. Obviamente, você não poderá sair, mas, em alguns casos, pode enviar regularmente mensagens desse tipo aos seus usuários: "No mês passado, não recebemos pedidos para divulgar seus dados pessoais". É assim que você canta, canta como um canário e, quando você recebe um pedido para fornecer dados pessoais, cala a boca. Assim, você cumpre os requisitos das autoridades e fornece aos usuários motivos para serem cautelosos.E há questões canárias. Aqui a metáfora funciona assim: quando uma pequena parte dos usuários fica doente, "evacuamos" com urgência - desativamos uma nova funcionalidade que fez com que os usuários ficassem doentes e não deixassem que atingisse todos os usuários (não deixem "empurrão"). Para fazer isso, você deve poder estender a nova funcionalidade para diferentes grupos. Aqui você pode fazer sem interruptores. Por exemplo, temos um balanceador e dois nós para redirecionar solicitações. Em um nó, implantamos uma versão estável e, no segundo, uma versão experimental contendo novas funcionalidades. Por padrão, todas as solicitações são enviadas ao nó com a versão estável e, com a ajuda do balanceador, começamos a enviar algumas solicitações ao nó com a versão experimental.Mas com a opção, você pode obter mais flexibilidade na forma como as novas funcionalidades se estendem aos usuários. No switch, você pode combinar diferentes parâmetros das solicitações recebidas e fornecer aos funcionários responsáveis uma interface gráfica conveniente para gerenciar o problema do canário. Em geral, o processo permanece o mesmo: incluímos novas funcionalidades para um pequeno grupo de usuários, por exemplo, 1%. Depois disso, monitoramos o estado do aplicativo, como os usuários que trabalham com a nova funcionalidade se comportam e fazemos uma previsão sobre o que acontecerá quando o estendermos a um número maior de usuários. Abrangendo gradualmente mais e mais usuários com novas funcionalidades, podemos testar e ajustar nossas hipóteses. Se percebermos tendências negativas,então a nova funcionalidade pode ser facilmente desabilitada.Durante a versão azul esverdeado, dois servidores são usados, provisoriamente chamados azul e verde. Assumimos que antes do lançamento, o balanceador envia todas as solicitações para o servidor verde. Durante o lançamento, uma nova versão do aplicativo é implantada em um servidor azul, onde o balanceador também começa a enviar solicitações. Se a nova versão do aplicativo contiver erros, voltaremos ao servidor verde.A versão básica da versão azul esverdeada sugere que os usuários trabalhem com todas as novas funcionalidades incluídas na nova versão ou não com nenhuma. E com o uso de comutadores, torna-se possível durante o lançamento enviar solicitações ao servidor azul com a nova versão, para a qual os comutadores de todas as novas funcionalidades estão desativados. Depois disso, você pode incorporar gradualmente a nova funcionalidade em partes.Você pode ver que as opções de funcionalidade permitem combinar os benefícios de versões canárias e verde-azuladas. Normalmente, durante uma liberação azul esverdeada, existem dois nós claramente separados nas versões antiga e nova do aplicativo e, com a ajuda do balanceador, redirecionamos todas as solicitações de uma só vez para um ou outro nó. E com os comutadores, podemos redirecionar solicitações para o nó com a nova versão, mas com a nova funcionalidade desativada e, em seguida, ativá-lo gradualmente, como durante o lançamento do canary.Um pouco mais de detalhes sobre as questões canárias - no artigo correspondente no site da Fowler ou em "Habré", por exemplo aqui . Sobre lançamentos azul esverdeado - em um artigo de revisão. E o uso de comutadores de função em versões azul-verde pode ser encontrado aqui .Alterando a maneira como os dados são armazenadosPor um longo tempo, enquanto estudava técnicas de programação como abstração e desenvolvimento de interfaces, encontrei muitas vezes a seguinte recomendação: tente não vincular seu programa a um método específico de armazenamento de dados, por exemplo, a um banco de dados específico, porque no futuro Pode ser necessário alterar o método de armazenamento. Enfiei-o no bigode e fiz como solicitado. Desde então, no entanto, as razões pelas quais eu compartilho a lógica do domínio e o método de armazenamento foram alteradas e, pelo contrário, fiquei cético quanto à possibilidade de alterar o banco de dados em um produto comercial.E enquanto preparava esse material, aprendi sobre os caras que garantemque muitas empresas praticam a alteração de bancos de dados em produtos operados industrialmente. Além disso, a alteração do banco de dados é supostamente completamente indolor, se você usar as opções de funcionalidade. É claro que o artigo mencionado foi escrito por pessoas interessadas (o site é suportado pelo fabricante de uma ferramenta comercial para gerenciar switches), mas não será demais considerar a estratégia de mudar para outro banco de dados que eles propuseram.Descreva brevemente a estratégia da seguinte maneira. O processo começa a partir do momento em que nosso aplicativo trabalha com um banco de dados (antigo). Usando as opções de funcionalidade, forçamos sequencialmente nosso aplicativo a gravar primeiro dados em um novo banco de dados e, a seguir, ler os dados do novo banco de dados. Ao mesmo tempo, a interação com o banco de dados antigo é preservada: nós dois escrevemos e lemos nos dois bancos de dados!Se o registro for mais ou menos claro, a leitura deverá ser esclarecida. Quando um aplicativo precisa de dados, ele os lê nos dois bancos de dados. Esses dois pontos de leitura estão sempre próximos um do outro, para que, após a leitura, você possa comparar os dados recebidos e verificar sua consistência. Após a estabilização do aplicativo (quando os dois bancos de dados começam a retornar os mesmos dados de maneira estável), o aplicativo é desconectado do banco de dados antigo e os comutadores são excluídos.Uma descrição detalhada da estratégia para mudar para um novo banco de dados usando o MongoDB e o DynamoDB como exemplo.MongoDB DynamoDB. DynamoDB: ( ) MongoDB. — , , , — . (DynamoDB).
, MongoDB, — DynamoDB. , DynamoDB ( MongoDB). , DynamoDB .

DynamoDB , MongoDB. - MongoDB. , . , («» «»), . - DynamoDB . , , . — .
MongoDB, DynamoDB. , , , , , , . - , , MongoDB, , . , , , . , .
, . , , DynamoDB. MongoDB, .
. , , , DynamoDB , MongoDB , DynamoDB 100 %. , .
Inclusão simultânea de funcionalidades em diferentes plataformasO relatório já mencionado “Alterna entre recursos ou como implantar recursos sem liberação” falou sobre o requisito de habilitar novas funcionalidades ao mesmo tempo (minuto por minuto!), Tanto no site quanto no aplicativo móvel. E então você também pode precisar desativá-lo da mesma maneira.Não é fácil cumprir esse requisito, pois é muito difícil sincronizar o fornecimento de novas versões para diferentes plataformas. Se os servidores com o site estiverem sob seu controle, você ainda poderá adivinhar alguma coisa (e esperar que, desta vez, a entrega funcione como um relógio), a loja de aplicativos móveis poderá alterar a política de atualização das atualizações conforme desejar. De qualquer forma, a atualização do aplicativo é um processo longo, que inclui a verificação do aplicativo publicado pela própria loja. Além disso, você não deve esperar que o próprio aplicativo móvel solicite regularmente atualizações de sua API e as instale "dentro" de si. Esta loja, como eu a entendo, também está sob a cuidadosa supervisão do proprietário da plataforma - certamente haverá problemas com a execução de código arbitrário.Mas as opções ajudam a atender aos requisitos da inclusão simultânea de funcionalidades em condições em que você não pode controlar completamente a entrega do aplicativo. Obviamente, a entrega ainda deve ser garantida até a inclusão esperada. Esse método provavelmente será útil durante períodos de promoções temporárias, como a Black Friday.Uma situação semelhante existe com vários módulos de um sistema. Se eles forem publicados separadamente e ao mesmo tempo participarem do suporte a um processo da área de assunto, as opções permitirão que você faça alterações coordenadas nesse processo ao lado de vários módulos.Ferramentas de alternância no .NET
As ferramentas para trabalhar com comutadores podem ser divididas em três grupos. Em primeiro lugar, esses são produtos pesados universais (combinações), que geralmente incluem um serviço de rede que funciona com um provedor e um conjunto de bibliotecas que permitem a comunicação com esse serviço para diferentes linguagens de programação. Quase sempre, você precisa pagar (e muito) pelo uso desses produtos. Em segundo lugar, esses são projetos que são serviços de rede que devem ser executados em seus computadores e que os clientes podem acessar por meio da API REST. Dos projetos deste grupo (por uma questão de brevidade, os chamaremos de servidores), apenas aqueles que possuem uma API bem documentada ou um cliente oficial do .NET entraram na visão geral. Em terceiro lugar, essas bibliotecas são simples (em relação aos dois grupos anteriores) para .NET.Eles sugerem armazenar o registro de funcionalidade em arquivos de configuração ou acessar um registro remoto que não faz parte desses projetos pela rede.Um leitor atento perceberá que há outro grupo de ferramentas de software que não se enquadram na revisão. Estes são produtos que podem ser usados como um repositório de configuração para um sistema distribuído. Os representantes conhecidos desses produtos incluem o Apache ZooKeeper , Consul e etcd , e nos comentários deste artigo eles também mencionam o Spring Cloud Config Server, que pode ser facilmente amigo do .NET. De fato, em seus recursos básicos, os switches são muito semelhantes aos repositórios de configuração; portanto, essas ferramentas podem ser usadas como ponto de partida para criar sua própria infraestrutura de switches. No entanto, devido ao fato de que o objetivo dos comutadores de funcionalidade tem certas especificidades, com o desenvolvimento da cultura de comutadores no projeto, as desvantagens dos repositórios de configuração universal começarão a ser sentidas. Por esse motivo, produtos similares não são mais discutidos.Ceifeiras
LaunchDarklyParece que este é o produto mais excitado e "furioso" no campo das opções de funcionalidade. Fica-se com a sensação de que, neste produto, cabem quase tudo o que só vem à mente quando se fala em interruptores. Isso se aplica aos recursos da própria plataforma, à variedade de clientes disponíveis e aos tipos de integração com várias ferramentas, como Jira e Visual Studio Code. Tudo está documentado em grandes detalhes e com exemplos. A ferramenta, é claro, é paga, mas durante o período de avaliação de 30 dias pode ser usada gratuitamente.A Catamorphic Co., fabricante deste produto, também está patrocinando um site de referência para troca de recursos .Microsoft.FeatureManagementDesenvolvimento da Microsoft para .NET Core, que pode ser usado de duas maneiras principais: primeiro, como uma biblioteca cliente que permite trabalhar com comutadores e armazenar seu estado em um arquivo de configuração e, em segundo lugar, como uma combinação, que inclui um local centralizado além desta biblioteca para gerenciar comutadores no Azure. A ferramenta parece basear-se na infraestrutura mais geral da Configuração de Aplicativos do Azure, para a qual existe uma API documentada .A biblioteca do cliente oferece possibilidades interessantes de integração com o ASP.NET Core, por exemplo, filtros adicionais nas ações dos controladores e visualização condicional de uma exibição, dependendo do estado dos comutadores.Nos comentários deste artigo, eles sugerem que você se familiarize com as séries úteis de notas.Microsoft.FeatureManagementDistribuiçãoO site parece bom, mas quando você tenta obter informações específicas, os problemas começam. Por exemplo, é indicado que o produto possui muitos recursos interessantes para auditar interruptores, monitorar o uso da funcionalidade e conduzir experimentos. Mas, ao mesmo tempo, os fabricantes não divulgam políticas de preços (fica claro que há uma avaliação gratuita de 14 dias) e mantêm uma documentação bastante bruta de sua API REST. A documentação para bibliotecas cliente, no entanto, está em ordem. O sistema suporta o armazenamento de switches em arquivos de configuração.OptimizelyEm geral, o Optimizely é algum tipo de plataforma interessante para coletar análises e conduzir experimentos. O sistema possui uma parte de lançamentos gratuita .fornecendo recursos básicos de switch. Está escrito que, além de oferecer suporte à segmentação ("implementando" a funcionalidade para determinados grupos de usuários), essa parte gratuita suporta um número infinito de comutadores e projetos. Além disso, quantos funcionários você desejar podem usar este sistema. Vale ressaltar que o custo de muitos outros produtos é determinado precisamente por essas características quantitativas. Quanto custa mudar para uma plataforma totalmente funcional é um segredo.Trem-balaEsta plataforma parece bem simples. Ele não possui recursos especiais, como a coleta de análises - apenas os principais recursos dos comutadores. Quando você coloca a plataforma em seus próprios servidores, pode usá-la gratuitamente.SplitOutra plataforma que é tímida em seus preços. Dos "chips" adicionais oferece integração com algumas outras ferramentas de desenvolvimento e suporte para a realização de experimentos (teste A / B).ConfigCatE aqui está um produto com um site divertido, onde há gatos. Parece provocador. No entanto, suspeita-se que a documentação da API REST não esteja publicada nela. Com o cliente no .NET, está tudo bem. A propósito, existe um plano gratuito.MogglesUm projeto de código aberto que inclui um servidor com um site para gerenciar switches e um cliente. Para iniciar o servidor, o SQL Server é necessário. Parece bem maduro.Servidores
DesencadearUm projeto de código aberto bastante maduro que envolve a hospedagem de um sistema nos servidores da empresa. Inclui um site simples de gerenciamento de switches. Existem ferramentas simples integradas para explicar o uso da funcionalidade. A instalação é bastante simples; PostgreSQL necessário.Não existe uma biblioteca oficial do cliente .NET, mas várias já foram criadas. Além disso, graças à API documentada, em teoria, você pode criar sua própria biblioteca.Sinalizadores de recursos do GitlabO GitLab construiu seu sistema de comutação em cima do Unleash, para que as mesmas bibliotecas clientes sejam usadas para interagir com o GitLab e para o Unleash. É diferente do Unleash em si, pois você precisa cavar menos com a instalação (exceto a instalação do próprio GitLab), mas precisa pagar: opções de funcionalidade estão disponíveis a partir dos planos do GitLab Premium (se o GitLab for executado em seus próprios servidores) e do GitLab Silver (se o GitLab é executado nos servidores do provedor).API de sinalizadores de recursos no GoEste projeto de código aberto é um serviço com uma API (um pouco documentada) através da qual você pode gerenciar comutadores. Aparentemente, não há interface gráfica. Escrito em Go; usa bancos de dados internos e um servidor de rede; portanto, a configuração, a julgar pelas instruções, é trivial. Fornece recursos de segmentação rudimentares. Última edição no repositório: 20 de fevereiro de 2019.BandieraTambém um projeto aberto. Serviço com API e GUI. Escrito em Ruby; requer o MySQL ou PostgreSQL para funcionar, ou pode ser instalado no Docker. Existem clientes para Ruby, Node, Scala, PHP, mas não para .NET. Suporta um conjunto bastante variado de tipos de comutadores.FlagrOutro projeto de código aberto no Go. Instalado no Docker. Existe uma interface gráfica, além de clientes para Ruby, Go, JavaScript, Python. Oferece ferramentas simples integradas para contabilizar o uso da funcionalidade e experimentação. Cada switch pode ser configurado com flexibilidade e equipado com sua própria configuração.Bibliotecas cliente
Há um grande número de bibliotecas para .NET que fornecem os recursos básicos dos comutadores. Mas a maioria deles está em um estado abandonado. Uma rápida revisão mostrou que, em 2019, apenas dois projetos tiveram edições nos repositórios. Encontrei mais dois projetos interessantes nos links dos comentários deste artigo. Todos eles são apresentados abaixo.EsquioO projeto mais interessante, bem documentado e funcional de seu grupo. O mecanismo de armazenamento interno é um arquivo de configuração ou um EF Core. Ele se integra um pouco ao ASP.NET Core (como Microsoft.FeatureManagement); a documentação diz que o uso do Azure pode simplificar a configuração do switch.RecursosEle pode solicitar o estado do comutador do arquivo de configuração e remotamente (é configurado usando classes de espaço FeatureSwitch.Strategies
). No kit, existe uma estrutura de site simples que permite gerenciar switches. Não está claro se é possível fazer uma opção mais complexa do que ligar / desligar.Toggle.NetA biblioteca mais simples para trabalhar com switches, que armazena em um arquivo de texto. Aparentemente, ele suporta apenas chaves liga / desliga. Biblioteca clienteRimDev.FeatureFlagspara o ASP.NET Core. Além de permitir o uso de comutadores de funcionalidade, ele gera, juntamente com o site principal do projeto, uma página adicional na qual os comutadores podem ser controlados. O mecanismo de armazenamento de configuração interno é o SQL Server.( ) .
«» .
. , , .
. , , , .
. , A/B-.
. .
. .
Conclusão
Parece que em muitas empresas já se tornou prática comum o uso de switches para abranger os momentos do lançamento da versão e a inclusão de novas funcionalidades. Além disso, as opções ajudam a reduzir o grau de insanidade ao mesclar ramificações em um sistema de controle de versão. Além disso, eles abrem caminho para técnicas populares, como problemas com canários e testes A / B.Para trabalhar com switches, foi criado tanto software, pago quanto gratuito, que qualquer empresa pode escolher a ferramenta que preferir.Como resultado, listarei os recursos das opções de funcionalidade e voluntariamente (como de costume) as dividirei em vantagens e desvantagens.Os benefícios
- , — , , .
- , . , .
- , . , , , , .
- , . . , «» .
- , . , . , .
- . , . : , . , , .
- . , , . : , , , , . : ( ), .
- . ? , ? . , , . ? ? : , .
- — , . , . : (); ( ); .
- — , . : (); «/».
- , . : ; (, ).
- . , ? : , , , ( ).
( )
( Medium)
( HighLoad++)
- ( )
- («»)
(«»)
(«»)
- ( Featureflags.io)
( Featureflags.io)
Microsoft ( )
( )
( Smithsonian)
(«»)