ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何用 C++ 实现 Arrow Flight 服务并处理 RPC 错误

如何用 C++ 实现 Arrow Flight 服务并处理 RPC 错误 如何用 C 实现 Arrow Flight 服务并处理 RPC 错误【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow如果你的任务是让一个 C 程序对外提供 Arrow Flight RPC 服务并在调用失败时返回带 Flight 错误码的状态而不是泛泛的失败信息那么 Apache Arrow 官方文档给出的路径是继承arrow::flight::FlightServerBase并覆写 RPC 方法用arrow::flight::MakeFlightError构造 Flight 专属错误码再通过Init/Serve把服务跑起来。本文基于仓库中的 docs/source/cpp/flight.rst、docs/source/format/Flight.rst 和示例 cpp/examples/arrow/flight_grpc_example.cc 整理。前提条件你的工程需要包含arrow/flight/api.h与arrow/api.h并链接 Arrow Flight 库。仓库示例 flight_grpc_example.cc 的头部注释还特别提醒如果同时动态链接 gRPC 和 Protobuf应用侧与 Flight 侧的链接方式必须一致且版本相同否则程序可能崩溃或静默损坏数据。第一步继承 FlightServerBase 并覆写 RPC 方法Arrow Flight 服务端必须继承arrow::flight::FlightServerBase通过覆写该类上的 RPC 方法来实现具体功能。每个 RPC 方法接收一个arrow::flight::ServerCallContext携带本次调用的公共参数返回一个arrow::Status表示成功或失败需要返回数据的方法额外使用出参。以ListFlights为例官方文档给出的写法是class MyFlightServer : public FlightServerBase { Status ListFlights(const ServerCallContext context, const Criteria* criteria, std::unique_ptrFlightListing* listings) override { std::vectorFlightInfo flights ...; *listings std::unique_ptrFlightListing(new SimpleFlightListing(flights)); return Status::OK(); } };这里的SimpleFlightListing是 Flight 提供的辅助类用一个std::vectorFlightInfo就能构造ListFlights的出参不需要自己实现FlightListing接口。如果你的 RPC 需要返回失败不要直接返回Status::Invalid(...)改用arrow::flight::MakeFlightError返回 Flight 专属错误码见下文。第二步初始化并启动服务启动流程固定为四步构造Location指定监听地址 → 调用Init启动服务非阻塞→ 调用SetShutdownOnSignals注册中断信号 → 调用Serve阻塞直到服务停止。官方文档给出的代码std::unique_ptrarrow::flight::FlightServerBase server; // Initialize server arrow::flight::Location location; // Listen to all interfaces on a free port ARROW_CHECK_OK(arrow::flight::Location::ForGrpcTcp(0.0.0.0, 0, location)); arrow::flight::FlightServerOptions options(location); // Start the server ARROW_CHECK_OK(server-Init(options)); // Exit with a clean error code (0) on SIGTERM ARROW_CHECK_OK(server-SetShutdownOnSignals({SIGTERM})); std::cout Server listening on localhost: server-port() std::endl; ARROW_CHECK_OK(server-Serve());两点需要注意ForGrpcTcp(0.0.0.0, 0)中的端口0表示让系统分配空闲端口。实际端口在Init之后通过server-port()取得上面std::cout打印的Server listening on localhost:端口就是文档给出的启动确认方式。要监听固定端口时参考 flight_grpc_example.cc它用 gflags 定义-port参数并以flight::Location::ForGrpcTcp(0.0.0.0, FLAGS_port)构造监听地址未指定端口时直接退出。SetShutdownOnSignals({SIGTERM})的文档说明是收到 SIGTERM 时以干净的错误码0退出。如果后续要在同一端口上额外注册 gRPC 服务或做自定义拦截可以通过FlightServerOptions::builder_hook拿到底层grpc::ServerBuilder*flight_grpc_example.cc展示了完整写法。第三步用 MakeFlightError 返回 Flight 错误码RPC 方法失败时文档明确要求用arrow::flight::MakeFlightError返回 Flight-specific 错误码而不是普通的 ArrowStatus。其声明在 cpp/src/arrow/flight/types.hStatus MakeFlightError(FlightStatusCode code, std::string message, ...);Flight 协议定义了如下错误码集合来自 docs/source/format/Flight.rst 的 Error Handling 章节Error Code含义UNKNOWN未知错误无其他错误码适用时的默认值INTERNAL服务实现内部发生错误INVALID_ARGUMENT客户端传入了非法参数TIMED_OUT操作超时或超过 deadlineNOT_FOUND请求的资源action、数据流不存在ALREADY_EXISTS资源已存在CANCELLED操作被取消客户端或服务器UNAUTHENTICATED客户端未认证UNAUTHORIZED客户端已认证但没有执行该操作的权限UNIMPLEMENTED该 RPC 未实现UNAVAILABLE服务不可用客户端可能因连接问题发出需要留意文档中的一条实现差异说明C 中Unimplemented是一个通用 Arrow 错误状态而在 Java 中它是 Flight 专属异常。仓库中cpp/src/arrow/flight/下的测试代码如 test_flight_server.cc展示了典型用法例如return MakeFlightError(FlightStatusCode::Internal, Could not cast array);认证失败则返回MakeFlightError(FlightStatusCode::Unauthenticated, Invalid token)。在服务端处理长耗时 RPC 时还需要手动轮询ServerCallContext::is_cancelled()检查客户端是否已取消调用若已取消则中断当前处理——服务器侧对取消没有自动处理超时则不需要额外代码。第四步用 FlightClient 验证服务服务端跑起来后用客户端调用验证。文档说明每个客户端 RPC 方法返回arrow::Result请求成功时包含结果对象流式调用会返回 reader/writer 对象最终状态要等流结束才能确定。连接方式// 通过 FlightClient::Connect 连接 Flight 服务 // 每次 RPC 返回 arrow::Result需检查 .status()带超时与取消控制的完整调用形态见 flight_grpc_example.cc 同文档的 Best practices 章节C 侧写法// 设置单次调用超时 FlightCallOptions options; options.timeout TimeoutDuration{0.2}; Status status client-GetFlightInfo(options, FlightDescriptor{}).status(); // 关闭僵死的调用在调用建立时记录 stop token StopSource stop_source; FlightCallOptions call_options; call_options.stop_token stop_source.token(); stop_source.RequestStop(Status::Cancelled(StopSource)); flight_client-DoAction(call_options, {});验证要点如果status非 OK检查其中的 Flight 错误码是否是你服务端用MakeFlightError发出的那个客户端超时调用会落到TIMED_OUT/CANCELLED这类错误码上。限制与排查要点gRPC 可能延迟报告连接错误gRPC 可能直到真正发起调用才报告连接错误。因此客户端创建后应发起一个 dummy RPC 来确认连接可用而不是假设Connect成功即连通。长连接意外断开的排查用netstat监控打开连接数若远多于客户端数量可能导致问题设置环境变量GRPC_VERBOSITYinfo GRPC_TRACEhttp可在两侧打印初始头部和消息发送情况用于判断连接是否真正建立。不要对 Flight 客户端做 round-robin 负载均衡每个客户端会到每个服务器保持连接连接数会超预期并耗尽服务器资源。认证与 TLS文档明确警告未启用 TLS 时握手认证是不安全的。启用 TLS 时在FlightServerBase::Init提供证书和密钥对客户端侧用Location::ForGrpcTls构造 Location。客户端应复用创建和关闭客户端在两侧都有 setup/teardown 开销客户端是线程安全的多个线程可共享同一个实例。协议层的完整消息定义Flight.proto可在 format/Flight.proto 查看C 侧所有 client/server 类型的 API 列表在 docs/source/cpp/api/flight 指向的 API 文档中。【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表