【分享一个工具】通过定义proto3来自动生成多进程模式的插件代码
  ZvAhkxhPQwyp 2023年11月02日 76 0
Go

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


我在多进程插件框架 hashicorp/go-plugin 的基础上,使用 protoreflect 来解析 proto3 语法的IDL文件,通过命令行工具自动生成多进程框架的 callee 和 caller 代码。
项目的地址请看:https://github.com/ahfuzhang/go-plugin/tree/main/examples/code_generator
并且已经提了PR到官方。

golang自身的plugin还非常的弱,主要有这些限制:

  • 其插件的编译环境必须与宿主进程的编译环境完全一致
  • 插件可以动态加载,但是无法动态卸载

hashicorp公司(他们更出名的产品是terra-form)开源的go-plugin使用了多进程的模式来实现插件,宿主进程创建子进程,然后通过unix套接字来通讯。
虽然跨进程来通讯有一定的损耗,但对于计算的场景还是OK的,反之用于通讯则不太适合。
hashicorp/go-plugin有这样一些不错的特性:

  • 提供了多进程插件化运行的框架,可以以多种方式写caller端和callee端。
  • 可以动态的加载插件(创建进程)、卸载插件(退出子进程)
  • 因为是跨进程的通讯,所以子进程的稳定性不影响宿主进程;其所有的操作系统资源都是与主进程隔离的
  • 官方甚至提供了一个用python实现子进程的例子
    • 如果用go + lua的方式来写插件,相信可以做到用lua来实现动态跨进程执行的效果
    • 基于这个框架可以很容易写出一个FAAS(Function as-a Service)框架来
  • 提供了日志、加密、通讯等其他支撑性的功能

最后再介绍我实现的这个小工具:如果基于grpc的风格来写插件,其中还是要实现一部分对grpc接口的封装,如果每次写插件都要写这些重复代码,未免有点太繁琐了。所以可以在proto3中定义好service,并通过extension的语法来定义插件名字。具体的步骤已经写在了文档里,大致是:

  • 通过*.proto文件来定义请求格式、响应格式、服务接口;
    • 通过plugin_name这个extension来定义服务对应的插件名字,如果不写,则插件名字就是服务名。
  • 通过protoc来把*.proto变成xx.pb.go的golang代码
  • 通过gen_code命令行来读取*.proto, 生成插件需要的xx.plugin.go文件
    • 同时生成callee目录,生成插件对应的代码。然后在todo的位置填写代码
    • 生成callee_test.go文件,可以拷贝到宿主进程中,用于加载插件。

再补充一点,如果需要把一堆基本类型构成的[]interface{}数组的数据在插件之间传递,我写的上一个工具可以解决这个场景:如何在proto3中用上golang对应的interface{}类型,以及这个工具:Serilizer

Have fun, 希望对你有用。 😃

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  uGYzDadp0Cs7   2024年04月18日   58   0   0 Go
  hyrB1Ag4eVs8   2024年04月15日   38   0   0 Go
  YFCZjJLTjJgW   17天前   21   0   0 Go
  uGYzDadp0Cs7   2024年04月16日   94   0   0 Go
ZvAhkxhPQwyp