使用 Rust 构建 gRPC 微服务

前言 当前越来越多的公司基于 Google gRPC 通信框架来构建微服务体系,比较流行的是使用 Go/Java/C++ 这样的主流编程语言来编写服务端,我们今天来尝试使用 Rust 语言来实现一个 gRPC 服务端/客户端。 打开官方文档可以看到目前 Rust 并不在 gRPC 官方支持的语言列表中: Supported languages C# C++ Dart Go Java Kotlin Node Objective-C PHP Python Ruby 不过不用担心这个问题。我们知道只要某个语言兼容了基于 C/C++ 编写的 gRPC 的核心库 ,那么该语言就可以完美支持 gRPC。目前 Rust 可以实现 gRPC 的主流 crate 如下: tonic grpc-rs grpc-rust 以上三种任选其一都可以,只是 grpc-rs/grpc-rust 当前还处于开发状态,我们在这里使用 tonic 包。 构建程序 首先检查你的 Rust 版本: $ rustc --version rustc 1.61.0 (fe5b13d68 2022-05-18) tonic 适用于 1.56 及以上,如果低于这个版本,你应该先更新你的 Rust 编译器: $ rustup update stable 确保你已经提前安装了 protobuf:...

2022-05-30 · 3 min · L

gRPC Connection reset by peer 问题

前提 因产品需求,需用 PHP(v7.0.12)调用 k8s 集群中 gRPC([email protected])服务。 问题 经过 dev 环境测试,当 php-fpm 启动后第一次调用或者距离上次调用时间 20 分钟后左右,再次请求 gRPC 微服务接口,就会返回 Connection reset by peer 错误,说明 gRPC 服务端或者客户端主动关闭连接了。继续发起请求到服务端,又恢复正常。 思考 经查阅相关资料,发现问题可能出现在 k8s 集群的 kube-proxy 模式上。当前 k8s 环境 (dev) 下的 kube-proxy 为 ipvs 模式,服务端与客户端之间通信如下: 把上图 client 看成是 apsopen-inside 服务 pod,Backend pod(1~3) 看成 gRPC 服务,可以看出它们之间的交互路径: ---> gRPC server pod1 gRPC-client ---> ipvs ---> gRPC server pod3 ---> gRPC server pod3 我们知道gRPC是基于HTTP/2协议的,gRPC的client和server在交互时会建立多条连接,为了性能,这些连接都是长连接并且是一直保活的。这段环境中不管是客户端服务还是 gRPC 服务都被调度到各个相同配置信息的 Kubernetes 节点上,这些 k8s 节点的 keep-alive 是一致的,如果出现连接主动关闭的问题,因为从 client 到 server 经历了一层 ipvs,所以最大的可能就是 ipvs 出将连接主动断开,而 client 端还不知情。 搜索 ipvs timeout 关键字找到了下面相关的链接:...

2019-07-22 · 1 min · L

gRPC error code

RPC.response.status.code HTTP RPC Description 0 - OK 200 OK Not an error; returned on success. 1 - CANCELLED 499 Client Closed Request The operation was cancelled, typically by the caller. 2 - UNKNOWN 500 Internal Server Error Unknown error. For example, this error may be returned when a Status value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error....

2019-06-12 · 4 min · L