
后端微服务API设计【免费下载链接】thriftApache Thrift项目地址https://gitcode.com/gh_mirrors/thrift2/thrift点击查看免费下载本文围绕 Apache Thrift 仓库中 tutorial/ocaml/README.md 的实战流程展开完整讲解如何基于 tutorial/tutorial.thrift 生成 OCaml 源码、通过 OASIS 构建出客户端与服务端两个可执行文件并配合仓库中 CalcClient.ml 与 CalcServer.ml 的源码剖析说明 OCaml 生成代码的形态与运行时组件。读完本文你将能够独立完成一次「OCaml 版本 Thrift 教程示例」的生成、编译、运行全流程并理解其中的底层原理。前置条件OCaml 运行时库本示例假定你已经构建并安装了 Thrift 的 OCaml 运行时库即libthrift-ocaml。该库位于仓库的 lib/ocaml 目录包含以下核心模块Thrift—— 抽象基类、异常与通用函数运行时的心脏见 Thrift.mlTBinaryProtocol—— 二进制协议实现见 TBinaryProtocol.mlTSocket—— 阻塞 Socket 传输实现见 TSocket.mlTFramedTransport、TChannelTransport—— 其他传输实现TServer、TSimpleServer、TThreadedServer、TServerSocket—— 服务端抽象与两种典型服务器实现运行时库本身也通过 OASIS 描述构建其元数据见 lib/ocaml/_oasis库的 Findlib 名称是thrift依赖threads因为TThreadedServer需要 OCaml 系统线程库。在编译教程示例之前请先确认该库已成功安装且能被 ocamlfind 找到。第一步生成 Thrift 的 OCaml 源码与大多数语言示例不同OCaml 示例不会把生成的代码预先提交到仓库。这是 OASIS 构建工具的局限所致生成代码必须放在示例目录中才能被构建系统拾取。因此你需要手动运行编译器thrift -r --gen ocaml ../tutorial.thrift命令含义拆解thrift是 Apache Thrift 的 IDL 编译器可执行文件要求已安装到系统路径例如/usr/local/bin-rrecurse表示递归生成依赖的 include 文件。tutorial.thrift中有一行include shared.thrift见 tutorial/tutorial.thrift-r会一并处理该被包含的 tutorial/shared.thrift生成SharedService、SharedStruct等模块--gen ocaml指定目标语言为 OCaml../tutorial.thrift是相对于当前目录即tutorial/ocaml/的 IDL 文件路径。执行后会在当前目录生成gen-ocaml/目录其中包含Calculator、Tutorial_types、Shared_types、SharedService、Tutorial_consts、Shared_consts等模块——这正是 tutorial/ocaml/_oasis 中Library tutorial_thrift一节所列举的Modules。也就是说这些生成模块会被打包成本地库tutorial_thrift供客户端与服务端共同链接。生成的 OCaml 代码长什么样依据 lib/ocaml/README.md 中的说明可以预判生成代码的形态struct被转成类字段全部是option类型且初始为None。写入序列化是类的方法而读取反序列化由独立函数完成OCaml 没有静态类。类的类型名为t所在模块与 struct 同名。例如Workstruct 对应Work模块字段通过w#grab_num1取字段与w#set_num1设字段这样的方法访问enum被放入独立模块并生成to_i/of_i两个转换函数把 OCaml 变体类型转成 int / 从 int 转回变体。例如Operation.ADD对应整数 1Operation.to_i w#grab_op用于取回枚举的整数值typedef直接展开为 OCaml 类型别名如typedef i64 UserId变成type userid Int64.texception与 struct 相同但额外生成异常类型E of t用于raise (Xception.E (...))与with Xception.E e - ...模式匹配list映射为 OCaml 原生listmap / set都映射为Hashtbl.t其中 set 的值类型为boolservice生成三类构件——client类以输入输出协议为参数、processor类以 handler 为参数、iface抽象类handler 需继承它。需要注意与其他语言实现不同OCaml 的client并不实现iface因为iface方法必须接受option参数以应对客户端未发送全部参数的情况。第二步用 OASIS 配置并编译生成源码后依次执行oasis setup makeoasis setup读取 tutorial/ocaml/_oasis据此生成setup.ml、Makefile等 OASIS 构建文件。该文件声明了Library tutorial_thrift位于gen-ocaml路径Findlib 名tutorial_thrift依赖threads, thriftExecutable CalcClient主文件CalcClient.mlCompiledObject: bestExecutable CalcServer主文件CalcServer.mlCompiledObject: bestBuildDepends均包含thrift, tutorial_thrift, threads即运行时库、生成代码库与线程库三者缺一不可。make完成实际编译与链接。CompiledObject: best的含义是让 OCaml 构建系统自动选择最优目标格式。因此最终会产出两个可执行文件CalcServer.byte 或 CalcServer.native CalcClient.byte 或 CalcClient.native其中type只能是byte或native具体取决于你的 OCaml 安装是否支持原生代码编译ocamlopt可用则倾向native否则回退为byte。第三步运行服务端与客户端与 C 教程示例的玩法一致先在后台启动服务端再运行客户端./CalcServer.native # 或 ./CalcServer.byte ./CalcClient.native # 或 ./CalcClient.byte服务端默认监听127.0.0.1:9090见 CalcServer.ml 中let port 9090。客户端连接同一地址端口后依次发起一系列 RPC 调用并打印结果正常运行会看到类似输出ping() 112 InvalidOperation: Cannot divide by 0 15-105 Check log: 5其中InvalidOperation: Cannot divide by 0不是错误而是客户端主动捕获服务端抛出的异常并打印的预期行为用于演示 Thrift 的异常传播机制。源码级解读客户端如何调用 RPCCalcClient.ml 的核心是connect与doclient两个函数let connect ~host port let tx new TSocket.t host port in let proto new TBinaryProtocol.t tx in let calc new Calculator.client proto proto in tx#opn; { trans tx ; proto proto; calc calc }这段代码清晰地展示了 OCaml 运行时的分层组装模式传输Transport→ 协议Protocol→ 服务客户端Client。TSocket.t负责底层 TCP 连接其实现见 TSocket.ml通过Unix.open_connection建立连接并提供opn/close/read/write/flush方法TBinaryProtocol.t把 OCaml 值编码为二进制字节流见 TBinaryProtocol.ml注意其消息头带版本号version_1 0x80010000l读到不匹配版本会抛出BAD_VERSIONCalculator.client则由编译器从service Calculator生成其构造参数是两个协议对象一个用于发送请求、一个用于接收响应此处复用同一个。doclient依次演示了 Thrift 的几种典型交互void 方法cli.calc#ping无参数无返回值带参返回cli.calc#add (Int32.of_int 1) (Int32.of_int 1)注意 OCaml 的i32映射为Int32.tstruct 参数与异常捕获构造Work对象w设置op Operation.DIVIDE、num2 0调用calculate由于除零服务端抛出InvalidOperation客户端用with InvalidOperation io - ... io#grab_why捕获并打印原因再次调用并查日志getStruct从服务端内存日志中取回SharedStruct打印grab_value优雅关闭最后cli.trans#close关闭连接若传输层出错则由with Transport.E (_,what) - ...统一兜底。源码级解读服务端如何实现与调度CalcServer.ml 由两部分组成。一是 handler 实现。class calc_handler继承Calculator.iface生成代码提供的抽象接口必须实现ping、add、calculate、zip、getStruct全部方法。其中calculate是重点| Operation.DIVIDE - if w#grab_num2 Int32.zero then let io new invalidOperation in io#set_whatOp (Operation.to_i w#grab_op) ; io#set_why Cannot divide by 0 ; raise (InvalidOperation io) else Int32.div w#grab_num1 w#grab_num2这里演示了 Thrift 异常的完整用法创建异常对象invalidOperation、填充字段whatOp存操作码、why存错误说明、最后raise (InvalidOperation io)抛给 RPC 框架。服务端同时维护了一个Hashtbl作为日志calculate每次把结果封装成sharedStruct存进去供getStruct按logid查询——对应 IDL 中calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch)的设计。二是服务器组装。doserver演示了完整的服务端分层let proc new Calculator.processor h in let pf new TBinaryProtocol.factory in let server new TThreadedServer.t proc (new TServerSocket.t port) (new Transport.factory) pf pf in server#serveCalculator.processor生成代码负责把协议层的消息分发给 handlerTThreadedServer是线程池式服务器——其 实现 为每个接入连接创建一个系统线程在线程内循环调用pf#process ip op处理消息。TServerSocket.t port是监听套接字Transport.factory为每个连接创建传输对象两个TBinaryProtocol.factory分别为每个线程创建输入、输出协议。这一组装顺序对应TServer.t抽象类的五个构造参数processor、server transport、transport factory、input protocol factory、output protocol factory见 TServer.ml。构建注意事项与常见问题thrift编译器版本生成的代码会随编译器版本变化请使用与运行时库匹配的 Thrift 版本避免 ABI 不一致OASIS 与 ocamlfindoasis setup与make需要环境中装有 OASIS 工具链和 ocamlfind且thriftFindlib 包名必须已注册-r不可省略教程 IDL 依赖shared.thrift缺少-r会导致 include 文件未生成、编译期找不到SharedService/Shared_types模块端口占用服务端固定监听 9090若端口被占用需先释放或修改 CalcServer.ml 中的port与 CalcClient.ml 中的连接端口保持一致预期异常输出客户端打印InvalidOperation属正常演示流程并非运行失败。延伸阅读IDL 定义本示例的服务、struct、枚举与异常均定义在 tutorial/tutorial.thrift其中Calculator extends shared.SharedService演示了服务继承oneway void zip()演示了一向fire-and-forget方法运行时库实现lib/ocaml/src 下的各模块尤其 TServer.ml 与 TThreadedServer.ml 对比了串行与并发两种服务模型生成代码规范lib/ocaml/README.md 详细说明了 struct、enum、exception、list、map/set、service 在 OCaml 中的映射规则其他语言对照同一份 IDL 还被用于 tutorial/cpp、tutorial/py、tutorial/java 等示例可用于对比不同语言生成的客户端/服务端代码风格。赞分享后端微服务API设计【免费下载链接】thriftApache Thrift项目地址https://gitcode.com/gh_mirrors/thrift2/thrift点击查看免费下载相关推荐gRPC-Go Hello World 快速入门运行你的第一个 gRPC 服务gRPC Go Hello World 快速入门运行你的第一个 gRPC 服务 本文以 gRPC Go 仓库中的 helloworld 示例 example后端微服务API设计Apache Thrift OCaml 教程从 IDL 到 Calc 客户端/服务器的完整构建与运行指南Apache Thrift OCaml 教程从 IDL 到 Calc 客户端/服务器的完整构建与运行指南 本篇技术指南围绕 Apache Thrift 仓库中后端RPC框架序列化代码生成Apache Thrift 官方教程实战从 .thrift IDL 到多语言客户端/服务器Apache Thrift 官方教程实战从 .thrift IDL 到多语言客户端/服务器 本教程是 Apache Thrift 仓库中 tutorial/后端RPC框架序列化代码生成上一篇Omi错误处理机制组件异常捕获与优雅降级方案下一篇Omi服务端渲染探索提升首屏加载速度的实施方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考