Adicione uma API JSON muito rápida ao nosso aplicativo.

Todos os nossos microsserviços, independentemente de como eles se comunicam, fornecem um tipo de interface de pulsação para que o sistema de monitoramento possa a qualquer momento descobrir como é; como o estado geral de saúde e algumas particularidades específicas, digamos, somas de verificação para os dados internos com os quais estão lidando. Não se trata do transporte principal: aqui, o RabbitMQ e o Redis bem.


E às vezes faz sentido fornecer uma interface simples ( HTTP ) para exportar dados relevantes. Pensando nessa direção também, a longo prazo, quero me livrar completamente do Redis em favor de uma solução interna para armazenar pares de valores-chave, como fizemos com sucesso exatamente há dois anos com o PubSub .


Portanto, em vez de reinventar as bicicletas com cada novo microsserviço, decidi criar uma biblioteca de plug-ins que poderia resolver esse problema não sofisticado de fornecer dados arbitrários de qualquer aplicativo com código zero (exceto três linhas em config.exs ). Seja um simples batimento cardíaco ( HTTP 200 OK ) ou uma longa lista de taxas de câmbio atuais.


A solução é baseada neste tweet de Dave Thomas .


Servidor API JSON no peso da caneta


O Camarero é uma solução pronta para uso para adicionar algumas funções da API JSON a um aplicativo existente ou mesmo para implementar uma API JSON não tão confusa do zero quando soluções mais complexas (leia-se pesadas) são indesejáveis. A figura abaixo mostra como, em um caso típico, podemos conectá-lo e usá-lo.


Laços Camarero


A biblioteca não foi de forma alguma projetada para se tornar um substituto para soluções completas, como a Phoenix. De jeito nenhum, não. Esse é apenas um exemplo, quando o microsserviço precisa apenas expor algumas APIs da API HTTP. A Camarero , em alguns casos, pode ser um bom candidato para substituir o Redis ou qualquer outra reserva de valores-chave (também em seu grupo de peso). A principal diferença desse tipo de solução da Web é que essa biblioteca é realmente rápida.


Aqui estão os tempos de resposta HTTP para retornar um valor de chave de uma tabela de hash com um milhão de chaves.


Pesquisa de armazenamento de valor-chave de 1 milhão: 10μs ±


Sim, não há captura. O tempo de resposta HTTP para uma solicitação via kv-storage com um milhão de valores é de várias dezenas de microssegundos no pior dos casos.


Detalhes da implementação


Supõe-se que o Camarero se conecte a um aplicativo em execução simplesmente ativando a biblioteca e três linhas no arquivo de configuração. Ele processa as rotas configuradas, delegando a execução aos módulos manipuladores designados. A configuração mais simples pode ser assim:


 config :camarero, carta: [Camarero.Carta.Heartbeat], root: "api/v1" 

Isso é tudo e, portanto, provavelmente está claro: /api/v1 é a raiz do servidor da Web, uma rota de heartbeat (configurada na parte interna do módulo, por padrão, o nome sem prefixo) - com o manipulador Camarero.Carta.Heartbeat . Os manipuladores também podem ser adicionados dinamicamente em tempo de execução usando chamadas para Camarero.Catering.route! .


Manipuladores


Um manipulador é um módulo que implementa o comportamento Camarero.Plato . Consiste em métodos padrão de manipulação de repositório CRUD . Para uso como manipulador de solicitações HTTP recebidas, qualquer módulo que implemente esse comportamento é adequado.


Há um ajuste ainda mais refinado: o comportamento Camarero.Tapas , que gerencia o CRUD dentro de cada contêiner Camarero.Plato , para um par de chave / valor. Normalmente, você não precisa se aprofundar muito ao usar a biblioteca.


A implementação padrão usa o mapa %{} como um contêiner e parece bastante compacta:


 defmodule Camarero.Carta.Heartbeat do use Camarero.Plato end 

Este é um módulo de Heartbeat puro e não envernizado, incluído na biblioteca por padrão. Usos menos triviais são descritos na documentação .


Ajuste fino


Sem exceção, todos os métodos de ambas as implementações padrão ( Camarero.Tapas e Camarero.Plato ) são facilmente redefinidos. Por exemplo, para usar uma rota personalizada para um módulo, bem como um contêiner personalizado, você pode fazer o seguinte:


 defmodule Camarero.Carta.Heartbeat do use Camarero.Plato, container: %MyStructWithAccessBehaviour{} @impl true def plato_route(), do: "internal/heartbeat" end 

Configuração do servidor da Web


O Camarero precisa de um servidor Cowboy2 e do CowboyPlug para funcionar . Aqui está uma configuração típica do Cowboy2 em config.exs :


 config :camarero, cowboy: [port: 4043, scheme: :https, options: []] 

O que Camarero não reivindica


Esta biblioteca de forma alguma alega competir com soluções complexas. Ele não está nele e, quase certamente, nunca haverá autorização ou autenticação, ou seja, nós o usamos apenas para serviços dentro de uma nuvem privada.


Todos os módulos de processamento são gerados, portanto, exceto a sobrecarga da interface, nenhum ajuste adicional é possível. Isso também é feito deliberadamente.


Mas é mais rápido do que qualquer análogo em todos os benchmarks .


fonte


Tenha uma boa resposta rápida!

Source: https://habr.com/ru/post/pt485120/


All Articles