组织微服务的有效交互

最近,微服务体系结构已受到欢迎。 基于它们的解决方案的性能和可伸缩性可能取决于微服务之间的交互方式。 该交互可以是同步的或异步的。 该材料(我们今天将向您提供翻译)讨论了微服务交互的同步方法。 即,我们将重点研究两种技术:HTTP / 1.1和gRPC。 第一种技术由标准HTTP调用表示。 第二种是基于Google高性能RPC框架的使用。 本文的作者建议查看使用HTTP / 1.1和gRPC实现微服务交互所需的代码,进行性能评估,并选择一种允许以最佳方式组织微服务之间的数据交换的技术。



正常应用


让我们从小处开始,创建一个包含两个可以相互交互的微服务的系统。 请注意,此处未使用群集模式。 这是我们的应用程序图。


典型应用架构

该应用程序包含以下组件:

  • 系统测试工具: jMeter
  • 服务A:一种微服务,它执行对服务B的请求并返回从服务B收到的响应。
  • 服务B(服务B):一种微服务,在其所有API使用了10毫秒的延迟后,它会发送静态JSON数据以响应请求。
  • 虚拟机(VM 1和VM 2):Amazon EC2 t2.xlarge实例。

▍HTTP/ 1.1


HTTP / 1.1是用于组织微服务交互的标准技术,在使用任何HTTP库(例如axiossuperagent)时使用该技术。

这是实现我们系统API的服务代码B:

server.route({  method: 'GET',  path: '/',  handler: async (request, h) => {    const response = await new Promise((resolve) => {      setTimeout(() => {        resolve({          id: 1,          name: 'Abhinav Dhasmana',          enjoys_coding: true,        });      }, 10);    });    return h.response(response);  }, }); 

以下是服务A的代码,该代码使用HTTP / 1.1访问服务B:

 server.route({ method: 'GET', path: '/', handler: async (request, h) => { try { const response = await Axios({ url: 'http://localhost:8001/', method: 'GET', }); return h.response(response.data); } catch (err) { throw Boom.clientTimeout(err); } }, }); 

通过运行这些微服务,我们可以利用jMeter进行性能测试。 我们将找出与50个用户(每个用户执行2000个请求)一起工作时系统的行为。 如下图所示,测量结果的中位数为37 ms。


使用HTTP / 1.1使用jMeter的普通模式系统的研究结果

RPCgRPC


默认情况下,gRPC使用协议缓冲区技术。 因此,使用gRPC,除了两个服务的代码外,我们还需要编写原型文件代码,该文件描述了系统模块之间的接口。

 syntax = "proto3"; service SampleDataService { rpc GetSampleData (Empty) returns (SampleData) {} } message SampleData { int32 id = 1; string name = 2; bool enjoys_coding = 3; } message Empty {} 

现在,由于现在我们计划使用gRPC,因此我们需要重写服务代码B:

 const grpc = require('grpc'); const proto = grpc.load('serviceB.proto'); const server = new grpc.Server(); const GetSampleData = (call, callback) => { setTimeout(() => {   callback(null, {     id: 1,     name: 'Abhinav Dhasmana',     enjoys_coding: true,   }); }, 10); }; server.addService(proto.SampleDataService.service, { GetSampleData, }); const port = process.env.PORT; console.log('port', port); server.bind(`0.0.0.0:${port}`, grpc.ServerCredentials.createInsecure()); server.start(); console.log('grpc server is running'); 

请注意此代码的一些功能:

  • 命令const server = new grpc.Server(); 我们创建一个grpc服务器。
  • server.addService(proto...命令server.addService(proto...我们将服务添加到服务器。
  • server.bind(`0.0.0.0:${port}...命令server.bind(`0.0.0.0:${port}...用于绑定端口和凭证。

现在,使用gRPC重写服务A:

 const protoPath = `${__dirname}/../serviceB/serviceB.proto`; const proto = grpc.load(protoPath); const client = new proto.SampleDataService('localhost:8001', grpc.credentials.createInsecure()); const getDataViagRPC = () => new Promise((resolve, reject) => { client.GetSampleData({}, (err, response) => {   if (!response.err) {     resolve(response);   } else {     reject(err);   } }); }); server.route({ method: 'GET', path: '/', handler: async (request, h) => {   const allResults = await getDataViagRPC();   return h.response(allResults); }, }); 

该代码的功能包括:

  • const client = new proto.SampleDataService...命令const client = new proto.SampleDataService...我们创建一个grpc客户端。
  • 使用client.GetSampleData({}...命令进行远程调用。

现在,让我们测试一下jMeter的功能。


使用jMeter使用gRPC的普通模式系统的研究结果

经过简单的计算,您可以发现使用gRPC的解决方案比使用HTTP / 1.1的解决方案快27%。

集群应用


这是与我们刚刚研究的应用程序类似的应用程序图,但是以集群模式工作。


集群模式应用架构

如果将此架构与先前考虑的架构进行比较,则可以注意到以下更改:

  • 有一个使用NGINX的负载均衡器(Load Balancer)。
  • 现在,服务B存在于在不同端口上侦听的三个实例中。

实际项目中通常使用类似的体系结构。

在新环境中探索HTTP / 1.1和gRPC。

▍HTTP/ 1.1


在集群环境中使用使用HTTP / 1.1的微服务时,无需更改其代码。 您只需要配置nginx来组织服务B流量的平衡,在这种情况下,您需要将/etc/nginx/sites-available/default文件转换为以下格式:

 upstream httpservers {  server ip_address:8001;  server ip_address:8002;  server ip_address:8003; } server {  listen 80;  location / {     proxy_pass http://httpservers;  } } 

现在,让我们运行已有的内容,并查看使用jMeter测试系统的结果。


使用jMeter使用HTTP / 1.1的基于集群的系统的研究结果

在这种情况下,中位数为41毫秒。

RPCgRPC


GRPC支持出现在nginx 1.13.10中 。 因此,我们需要最新版本的nginx,而通常的sudo apt-get install nginx命令不适合sudo apt-get install nginx

同样,在此我们不在集群模式下使用Node.js,因为在此模式下不支持 gRPC。

要安装最新版本的nginx,请使用以下命令序列:

 sudo apt-get install -y software-properties-common sudo add-apt-repository ppa:nginx/stable sudo apt-get update sudo apt-get install nginx 

另外,我们将需要SSL证书。 可以使用openSSL创建自签名证书:

 openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ -keyout localhost-privatekey.pem -out localhost-certificate.pem 

要使用gRPC,您需要编辑文件/ etc/nginx/sites-available/default

 upstream httpservers {  server ip_address:8001;  server ip_address:8002;  server ip_address:8003; } server {  listen 80;  location / {     proxy_pass http://httpservers;  } } 

现在,一切准备就绪,可以使用jMeter测试集群gRPC解决方案了。


使用jMeter使用gRPC的集群模式系统的结果

在这种情况下,中位数为28毫秒,与检查群集HTTP / 1.1解决方案时获得的相同指标相比,速度提高了31%。

总结


研究结果表明,使用gRPC的基于微服务的应用程序的生产率比使用HTTP / 1.1在微服务之间交换数据的类似应用程序高约30%。 本文讨论的项目的源代码可以在这里找到。

亲爱的读者们! 如果您正在开发微服务,请谈谈如何组织微服务之间的数据交换。

Source: https://habr.com/ru/post/zh-CN421579/


All Articles