JSON-RPC? Faça o REST complicado


Estou certo de que o título causou uma reação saudável - "Bem, começou de novo ..." Mas deixe-me chamar sua atenção por 5 a 10 minutos, e tentarei não enganar as expectativas.


A estrutura do artigo será a seguinte: uma declaração estereotipada é tomada e a “natureza” do surgimento desse estereótipo é revelada. Espero que isso permita que você analise a escolha do paradigma de troca de dados em seus projetos sob um novo ângulo.


Para deixar claro o que é RPC, proponho considerar o padrão JSON-RPC 2.0 . Não há clareza com o REST. E não deveria ser. Tudo o que você precisa saber sobre o REST - é indistinguível do HTTP .


As solicitações de RPC são mais rápidas e eficientes porque permitem solicitações em lote.


O ponto é que, no RPC, é possível fazer uma chamada para vários procedimentos em uma solicitação. Por exemplo, crie um usuário, adicione um avatar a ele e, na mesma solicitação, assine-o sobre alguns tópicos. Apenas um pedido e quanto bom!


De fato, se você tiver apenas um nó de back-end, isso parecerá mais rápido com uma solicitação em lote. Como três solicitações REST exigirão três vezes mais recursos de um nó para estabelecer conexões.



Observe que a primeira solicitação no caso de REST deve retornar o ID do usuário para solicitações subsequentes. O que também afeta negativamente o resultado geral.


Mas essas infra-estruturas podem ser encontradas, talvez, em soluções internas e no Enterprise. Como último recurso, em pequenos projetos WEB. Porém, as soluções WEB completas, e também chamadas HighLoad, não devem ser construídas assim. Sua infraestrutura deve atender aos critérios de alta disponibilidade e carga de trabalho. E a imagem está mudando.



Verde indica os canais de atividade da infraestrutura no mesmo cenário. Observe como o RPC se comporta agora. A solicitação usa a infraestrutura apenas um ombro do balanceador para o back-end. Enquanto o REST ainda perde na primeira solicitação, compensa o tempo perdido usando toda a infraestrutura.


Basta digitar no script não dois pedidos de enriquecimento, mas, digamos, cinco ou dez ... e a resposta à pergunta "quem vence agora?" Torna-se óbvia.


Proponho olhar ainda mais amplo para o problema. O diagrama mostra como os canais de infraestrutura são usados, mas a infraestrutura não se limita aos canais. Um componente importante de uma infraestrutura muito carregada são caches. Vamos pegar algum artefato do usuário agora. Várias vezes. Diga 32 vezes.



Veja como a infraestrutura no RPC se "visivelmente recuperou" para atender às demandas de alta carga. O fato é que o REST usa toda a potência do protocolo HTTP, ao contrário do RPC. No diagrama acima, esse poder é realizado através do método de solicitação - GET.


Os métodos HTTP, entre outras coisas, têm estratégias de cache. Você pode conhecê-los na documentação HTTP . Para o RPC, as solicitações POST que não são consideradas idempotentes são usadas, ou seja, a repetição repetida das mesmas solicitações POST pode retornar resultados diferentes (por exemplo, após o envio de cada comentário, outra cópia desse comentário será exibida) ( fonte ).


Conseqüentemente, as RPCs não podem usar com eficiência os caches de infraestrutura. Isso leva ao fato de que você precisa "importar" caches de software. O diagrama mostra Redis nesta função. O cache flexível, por sua vez, requer que o desenvolvedor tenha uma camada de código adicional e alterações significativas na arquitetura.


Vamos agora calcular quantas solicitações "deram à luz" REST e RPC na infraestrutura em consideração?


InquéritosCaixa de entradabackendpara DBMSpara cache suave (Redis)TOTAL
REST1/32 *110 03/35
Rpc32.32.13196

[*] no melhor caso (se o cache local for usado) 1 solicitação (uma!), nas piores 32 solicitações recebidas.


Em comparação com o primeiro esquema, a diferença é impressionante. A vitória no REST agora é aparente. Mas eu proponho não parar por aí. A infraestrutura desenvolvida inclui CDN. Freqüentemente, ele também resolve o problema de combater ataques DDoS e DoS. Temos:



Aqui para RPC, tudo se torna muito deplorável. O RPC simplesmente não pode delegar trabalho com o carregamento da CDN. Só se pode confiar em sistemas para combater ataques.


É possível acabar com isso? E novamente, não. Os métodos HTTP, como mencionado acima, têm sua própria "mágica". E por boas razões, o método GET é totalmente usado na Internet. Observe que esse método é capaz de acessar parte do conteúdo, é capaz de definir condições que podem interpretar os elementos da infraestrutura antes de transferir o controle para o seu código etc. Tudo isso permite criar infraestruturas flexíveis e gerenciáveis ​​que podem digerir fluxos de solicitações realmente grandes. E no RPC, esse método ... é ignorado.


Então, por que o mito é tão persistente que as solicitações em lote (RPC) são mais rápidas? Pessoalmente, parece-me que a maioria dos projetos simplesmente não atinge esse nível de desenvolvimento quando o REST é capaz de mostrar sua força. Além disso, em pequenos projetos, é mais provável que ele mostre sua fraqueza.


A escolha de REST ou RPC não é uma escolha voluntária de um indivíduo no projeto. Essa escolha deve atender aos requisitos do projeto. Se o projeto puder extrair do REST tudo o que ele realmente puder e for realmente necessário, o REST será uma excelente opção.


Mas se, para obter todos os lucros do REST, você precisará contratar devops para dimensionar rapidamente a infraestrutura, administradores para gerenciar a infraestrutura, um arquiteto para projetar todas as camadas do serviço WEB ... e o projeto venderá três pacotes de margarina por dia ... iria parar no RPC desde esse protocolo é mais utilitário. Ele não exige um conhecimento profundo da operação de caches e infraestrutura, mas concentra o desenvolvedor em chamadas simples e compreensíveis para os procedimentos necessários. O negócio ficará satisfeito.


Solicitações de RPC são mais confiáveis ​​porque podem executar solicitações em lote em uma única transação


Essa propriedade do RPC é uma vantagem definitiva, pois fácil manter o banco de dados em um estado consistente. Mas com o REST, tudo é mais complicado. As solicitações podem chegar inconsistentemente em diferentes nós de back-end.


Essa “desvantagem” do REST é o outro lado das vantagens descritas acima - a capacidade de usar efetivamente todos os recursos de infraestrutura. Se a infra-estrutura é mal projetada, e ainda mais se a arquitetura do projeto e o banco de dados em particular são mal projetados, isso é realmente um grande problema.


Mas as solicitações em lote são tão confiáveis ​​quanto parecem? Vejamos o caso: crie um usuário, enriqueça seu perfil com alguma descrição e envie a ele um SMS com um segredo para concluir o registro. I.e. três chamadas em uma solicitação em lote.



Vamos considerar o esquema. Apresenta a infraestrutura com elementos de alta disponibilidade. Existem dois canais de comunicação independentes com gateways SMS. Mas ... o que vemos? Ao enviar SMS, ocorre o erro 503 - o serviço está temporariamente indisponível. Porque Se o envio do SMS for compactado em uma solicitação em lote, a solicitação inteira deverá ser revertida. Ações no DBMS são canceladas. O cliente recebe um erro.


A próxima tentativa é uma loteria. A solicitação vai para o mesmo nó novamente e retorna um erro, ou você tem sorte e ela será executada. Mas o principal é que pelo menos uma vez que nossa infraestrutura já funcionou em vão. Houve uma carga, mas nenhum lucro.


Bem, vamos imaginar que tensionamos (!) E pensamos na opção em que a solicitação poderia ser parcialmente concluída com êxito. E o restante, tentaremos cumprir novamente após algum intervalo de tempo (Qual? Decide a frente?). Mas a loteria permaneceu. Uma solicitação para enviar um SMS com uma probabilidade de 50/50 falhará novamente.


Concordo que, do lado do cliente, o serviço não parece tão confiável quanto gostaríamos ... mas e o REST?



O REST usa magia HTTP novamente, mas agora com códigos de resposta. Se ocorrer um erro 503 no gateway do SMS, o back-end transmitirá esse erro ao balanceador. O balanceador que recebe esse erro e sem interromper a conexão com o cliente envia a solicitação para outro nó que processa a solicitação com êxito. I.e. o cliente recebe o resultado esperado e a infraestrutura confirma sua alta classificação de "altamente acessível". O usuário está feliz.


E, novamente, isso não é tudo. O balanceador não recebeu apenas o código de resposta 503. É aconselhável fornecer esse código com o cabeçalho "Repetir após" ao responder. O cabeçalho deixa claro para o balanceador que você não deve perturbar esse nó nessa rota por um tempo especificado. E as seguintes solicitações de envio de SMS será enviado imediatamente para um nó que não apresenta problemas com o gateway do SMS.


Como podemos ver, a confiabilidade do JSON-RPC é superestimada. De fato, é mais fácil organizar a consistência do banco de dados. Mas a vítima, neste caso, será a confiabilidade do sistema como um todo.


A conclusão é amplamente semelhante à anterior. Quando a infraestrutura é simples, a obviedade do JSON-RPC é sem dúvida a sua vantagem. Se um projeto envolver alta disponibilidade com uma carga alta, o REST parecerá uma solução mais precisa, embora mais complexa.


Limite de entrada REST abaixo


Penso que a análise acima, desmistificando os estereótipos estabelecidos sobre o RPC, mostrou claramente que o limiar para entrar no REST é sem dúvida mais alto do que no RPC. Isso se deve à necessidade de um profundo entendimento do HTTP, bem como à necessidade de ter conhecimento suficiente sobre os elementos de infraestrutura existentes que podem e devem ser usados ​​em projetos WEB.


Então, por que muitas pessoas pensam que o REST será mais fácil? Minha opinião pessoal é que essa aparente simplicidade vem do REST se manifesta. I.e. O REST não é um protocolo, mas um conceito ... O REST não possui um padrão, existem algumas recomendações ... O REST não é mais complicado que o HTTP. A aparente liberdade e anarquia atraem "artistas livres".


Sem dúvida, o REST não é mais complicado que o HTTP. Mas o próprio HTTP é um protocolo bem projetado que foi provado por décadas. Se não houver um entendimento profundo do próprio HTTP, o REST não poderá ser julgado.


Mas sobre RPC - você pode. É o suficiente para atender a sua especificação. Então, você precisa de um JSON-RPC idiota ? Ou é REST astuto? Depende de você.


Espero sinceramente que não tenha perdido tempo em vão.

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


All Articles