使用 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. 3 - INVALID_ARGUMENT 400 Bad Request The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name). 4 - DEADLINE_EXCEEDED 504 Gateway Timeout The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long enough for the deadline to expire. 5 - NOT_FOUND 404 Not Found Some requested entity (e.g., file or directory) was not found.Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist,NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used. 6 - ALREADY_EXISTS 409 Conflict The entity that a client attempted to create (e.g., file or directory) already exists. 7 - PERMISSION_DENIED 403 Forbidden The caller does not have permission to execute the specified operation. PERMISSION_DENIED must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED instead for those errors). PERMISSION_DENIED must not be used if the caller can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions. 8 - RESOURCE_EXHAUSTED 429 Too Many Requests Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. 9 - FAILED_PRECONDITION 400 Bad Request The operation was rejected because the system is not in a state required for the operation’s execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc.Service implementors can use the following guidelines to decide between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call. (b) Use ABORTED if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until the system state has been explicitly fixed. E.g., if an “rmdir” fails because the directory is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless the files are deleted from the directory. 10 - ABORTED 409 Conflict The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort.See the guidelines above for deciding between FAILED_PRECONDITION,ABORTED, and UNAVAILABLE. 11 - OUT_OF_RANGE 400 Bad Request The operation was attempted past the valid range. E.g., seeking or reading past end-of-file.Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from an offset past the current file size.There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) when it applies so that callers who are iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are done. 12 - UNIMPLEMENTED 501 Not Implemented The operation is not implemented or is not supported/enabled in this service. 13 - INTERNAL 500 Internal Server Error Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. 14 - UNAVAILABLE 503 Service Unavailable The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff.See the guidelines above for deciding between FAILED_PRECONDITION,ABORTED, and UNAVAILABLE. 15 - DATA_LOSS 500 Internal Server Error Unrecoverable data loss or corruption. 16 - UNAUTHENTICATED 401 Unauthorized The request does not have valid authentication credentials for the peration.

2019-06-12 · 4 min · L