gRPC-web现状及测试

本文主要介绍了gRPC-web现状及测试的简介、好不好用等相关内容。

gRPC是什么?

gRPC是谷歌开源的一款不那么快的基于原型缓冲区的RPC框架。

既然不那么快,为什么还要提它呢?相较于节俭,gRPC会慢一点,但是,本文的着眼点并不在于RPC吞吐量的极限值,也不是框架的通信时间减少几十几千纳秒,本文要介绍的是除GraphQL外,JSON RPC优化的另一个取向--gRPCweb。

众所周知,GraphQL着眼的优化点在于通过移交一部分查询的逻辑到客户端,从而减少了数据的交换量,而RPC则着眼于使用可压缩的二进制/文本协议,减少JSON文本传输带来的不必要的协议损失。本文着眼于此,对比gRPCweb当前的进展,对易用性,便捷性,成本方面进行了评价,结论虽然有些武断,但是仍然反映了当前gRPCweb仍然有待进一步发展的事实。

1gRPC web能给我们带来什么?

1.传输数据量减少,传输延迟降低

HTTP / 2天生具有头压缩等特性,解决了大量频繁的RPC交互通信带来的头部重复传输问题;使用二进制流或压缩文本传输,减少了一部分稀疏编码带来的字节空洞,提高了信息密度。传输速度更快,数据量更小,不仅降低成本,而且可以减少延迟。

2.可靠一致的API设计

客户端服务端使用相同的原文件进行接口定义,双方接口暴露完全相同,一致性更强,相较于传统的招摇接口管理,其数据结构更加直观精确,不再需要维护接口-URL间的复杂对应关系,API升级管理更加简单

3.对传输基础设施无感知的通信协议

节俭不能推出类似gRPCweb的方案的原因也正在于此.Thrift使用私有Tprotocol传输协议,与gRPC的HTTP / 2相比起来通用性大打折扣,Nginx的在最新的稳定版中已经提供了grpc_pass负载均衡支持,我们可以无痛使用原有的四层/七层负载均衡器提供大规模的调用支持

4.高效的序列化/反序列化支持

gRPC相较于JSON,拥有更高的序列化/反序列化效率,易于实现更高的吞吐性能

2gRPC web能不能用?好不好用?

话不多说,接下来我们就开始进行一套gRPCserver + envoy代理+ gRPCweb on TypeScript的echo通信测试,作为对比,笔者将实现一套同样功能的websocket链路,用以测试双方通信性能,比较这些功能的实现难度并评价两种“看似比较底层”的网络通讯协议。

gRPC web测试

首先定义一个我们的回声服务的原型:

syntax = "proto3";package chatman;
message ChatRequest {
   string messages = 1;
}
message ChatResponse {
   string messages = 1;
}
service Chat {    rpc chat (ChatRequest) returns (ChatResponse);
}

然后写服务器端代码,此处使用的Python实现:

生成服务器端的protobuf的文件,使用gRPC工具生成代码即可,然后我们引入grpcio和这些protobuf的库文件:

import grpcimport service_pb2,service_pb2_grpc
from concurrent.futures import ThreadPoolExecutorimport time


class ChatServicer(service_pb2_grpc.ChatServicer):
   def chat(self,request,context):        print(request.messages)
       return service_pb2.ChatResponse(messages="Server Received: %s" % request.messages)def server_start():
   server
= grpc.server(ThreadPoolExecutor(max_workers=5))
   service_pb2_grpc.add_ChatServicer_to_server(ChatServicer(),server)
   server.add_insecure_port('0.0.0.0:8800')
   server.start()
   time.sleep(3600*24)if __name__ == '__main__':
server_start()

我们先测试下HTTP / 2二进制流模式的gRPC:

Python的代码如下:

import grpcimport service_pb2_grpcimport service_pb2
channel = grpc.insecure_channel('0.0.0.0:8800')
stub = service_pb2_grpc.ChatStub(channel)
message = service_pb2.ChatRequest(messages="test message")
msg = stub.chat(message)
print(msg)

返回消息:“Server Received:test message”。测试成功,抓包结果如下:

bb

可以看到,两方使用“不安全“的HTTP协议交换了数据,通信成功完成。

接下来,我们使用gRPC的web实现相同功能。值得注意的一点是,目前gRPC幅还不能直接运行在浏览器上,因为浏览器尚未提供裸HTTP协议的接口,因此需要进行一层简单的封装,并通过代理剥去这层封装才能与真正的gRPC后端通信,这种通信方式被称为gRPC的Web文本。

同理,使用gRPC的工具生成打字稿文件,生成文件包含一个原始的JS库,一个描述文件以及一个TS客户端库,编写代码:

import { ChatRequest,ChatResponse } from './service_pb'import { ChatClient } from './ServiceServiceClientPb'const client1 = new ChatClient("http://127.0.0.1:8001",{},{});

let req = new ChatRequest()

req.setMessages("messages")

client1.chat(req,{},(err: any, res)=>{

   console.log(res);

});

在HTML中直接引用这个JS,并使用特使代理进行gRPC的Web文本到gRPC协议的转换,配置如下:

admin:
 access_log_path: /tmp/admin_access.log
 address:
   socket_address: { address: 127.0.0.1, port_value: 9901 }


static_resources:
 listeners:
 - name: listener_0
   address:
     socket_address: { address: 127.0.0.1, port_value: 8080 }
   filter_chains:
   - filters:
     - name: envoy.http_connection_manager
       config:
         codec_type: auto
         stat_prefix: ingress_http
         route_config:
           name: local_route
           virtual_hosts:
           - name: local_service
             domains: ["*"]
             routes:
             - match: { prefix: "/" }
               route:
                 cluster: echo_service
                 max_grpc_timeout: 0s
             cors:
               allow_origin:
               - "*"
               allow_methods: GET, PUT, DELETE, POST, OPTIONS
               allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
               max_age: "1728000"
               expose_headers: custom-header-1,grpc-status,grpc-message
               enabled: true
         http_filters:
         - name: envoy.grpc_web
         - name: envoy.cors
         - name: envoy.router
 clusters:
 - name: echo_service
   connect_timeout: 0.25s
   type: logical_dns
   http2_protocol_options: {}
   lb_policy: round_robin
hosts: [{ socket_address: { address: 127.0.0.1, port_value: 8800 }}]

现在进行测试,访问刚才的网页,可以看到通信情况:

bb

一看就知道是的base64编码,果断解码:

bb

果然不出所料,是一个封装在HTTP里的HTTP通讯

Web Socket的测试

接下来,使用的WebSocket进行对比:

编写服务端程序:

console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
   , wss = new WebSocketServer({port: 8010});
   wss.on('connection', function(ws) {
       ws.on('message', function(message) {
       console.log('Received: %s', message);
       ws.send('Server received: ' + message);
   });
});

使用节点启动后,在浏览器的控制台里连接并访问:

const ws_echo = new WebSocket("ws://127.0.0.1:8081/")
ws_echo.addEventListener('message', (event) => {
   console.log(event.data);
})
ws_echo.send("Hello!")

控制台返回服务器收到:您好!

通信完成,查看协议:

bb

可以看到,经过一次通信后,服务器直接返回升级升级连接的报头,随后双方使用的WebSocket进行通信,比起gRPC的协议,更加简易直白。

结论

在测试前我一直在思考,gRPCweb究竟是一个怎样的存在第一眼看到gRPCweb文本这个词,我的第一感觉是这个?

bb

在Gmail的邮箱里,充满了这种极其类似的protobuf的XHR请求,当看到需要使用专用代理进行转发的时候,我一度以为是这种高度压缩的文本协议正式出现在了通用的框架里,然而事实是,不论是gRPC-web还是gRPCweb-text,不论是易用性还是请求响应体长度,比起jon over brotli over websocket都仍然有很大的进步空间,要实现通过CDN分发js节省API服务器带宽的构思目前仍然需要自己造轮子,gRPCweb并不是银弹,至少目前不是。

bb

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31559359/viewspace-2637227/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/31559359/viewspace-2637227/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
grpc-server-spring-boot-starter是一个基于Spring Boot框架的gRPC服务器的启动器。gRPC(Google Remote Procedure Call)是一种高性能的远程过程调用框架,它使用Protocol Buffers作为接口定义语言,并支持多种编程语言。 grpc-server-spring-boot-starter提供了一系列简化配置和集成的功能,使得在Spring Boot应用中启动和配置gRPC服务器变得更加容易。它提供了自动装配的功能,可以根据应用的配置自动创建和启动gRPC服务器。用户只需要在配置文件中设置相应的参数,如服务器的端口号、TLS证书等,即可完成服务器的启动配置。 在使用grpc-server-spring-boot-starter时,用户可以方便地定义服务接口和实现类。通过使用gRPC的接口定义语言(protobuf)定义接口,并生成对应的Java代码。然后,用户只需要在实现类中实现相应的接口方法即可。 在服务器启动后,grpc-server-spring-boot-starter会根据定义的接口和实现类,自动创建相应的gRPC服务,并将其注册到服务器中。当客户端发起远程调用时,服务器会根据接口定义和方法参数,将请求转发给对应的实现类,并返回执行结果给客户端。 grpc-server-spring-boot-starter还支持对gRPC服务器进行拦截器的配置。拦截器可以在请求和响应的过程中拦截和修改消息,用于实现日志记录、鉴权、性能监控等功能。 总之,grpc-server-spring-boot-starter简化了在Spring Boot应用中使用gRPC的配置和集成过程,使得开发者可以更加便捷地构建和部署gRPC服务器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值