Apache Pulsar 之 Go Function

作者 | 冉小龙

审校 | Anonymitaet

编辑 | Susan

阅读本文需要约 8 分钟。

image

- 导读 -

在学习如何编写、部署 Go Function 之前,先向大家介绍一下 Go Function 的实现思路。

一篇文章了解 Pulsar Functions 中我们提到,Function 作为 Pulsar 的计算层,其实现思路主要有如下两种:

  • SDK

  • Plugin

之前介绍的 Java FunctionPython Function 使用 Plugin 的形式实现,本篇介绍的 Go Function 却使用 SDK 的形式提供给用户使用。为什么我们不与 Java Function 和 Python Function 采用相同的形式却要在 Go Function 中另辟蹊径,以 SDK 的形式提供给用户使用呢?

Go Function 使用 SDK 的原因

1

Go 不支持动态反射。这是语言层面本身的问题,Go 是一门静态类型的语言,虽然支持了反射的功能,但反射的支持相对较弱,不支持动态反射的功能。

这一点与 Java 和 Python 不同,Python 是动态类型的语言,动态加载本身就是它的强项所在。Java 虽然是静态类型的语言,但支持 ClassLoader 可以实现类似动态反射的功能。

所以在 Go 中我们没办法直接将用户的代码逻辑动态加载到 Pulsar Functions 中来执行。

2

Go Plugin 不成熟。Go 1.8 官方实现了 Go Plugin,支持动态加载的特性,但是并不成熟,在调研过程中发现的主要问题如下:

  • 如果注入了一些非法模块,会带来一定的安全隐患,如何防范它们?

  • 给系统带来一些不稳定因素。如果模块出现问题,则会导致服务崩溃。

  • 它给版本管理带来了一定的困难,特别是在微服务场景下,相同的服务,加载了不同的插件,如何做版本的管理?

  • 社区相对不成熟。

基于以上考量,我们使用了 SDK 的形式来做 Go Function 的实现。

编写 Go Function

Go Function 使用 SDK 实现,将 Function 的接口以 SDK 的形式对外暴露给用户,在使用 Go Function 之前需要 import "github.com/apache/pulsar/pulsar-function-go/pf",使用方式具体如下:

import (
"context"
"fmt"

"github.com/apache/pulsar/pulsar-function-go/pf"

)

func HandleRequest(ctx context.Context, input []byte) error {
fmt.Println(string(input) + "!")
return nil
}

func main() {
pf.Start(HandleRequest)
}

在上述示例代码中,将输入的 input 加 ! 后打印,第一个参数为一个 context 对象,当用户编写的 Function 需要与 Go Function 进行交互时,可以加入该参数,使用示例如下:

if fc, ok := pf.FromContext(ctx); ok {
fmt.Printf("function ID is:%s, ", fc.GetFuncID())
fmt.Printf("function version is:%s\n", fc.GetFuncVersion())
}

在 main() 中,用户只需要将编写的 Function name 注册到 Start() 中,需要注意的是,Start() 中只能接收一个函数的名字。Go Function 会根据接收到的 Function name 利用 Go 的反射来验证用户实现的参数列表和返回值列表是否正确。

为了方便验证,需要规定用户输入的参数列表与返回值列表具体为什么,Go Function 目前支持如下形式的函数样例:

func ()
func () error
func (input) error
func () (output, error)
func (input) (output, error)
func (context.Context) error
func (context.Context, input) error
func (context.Context) (output, error)
func (context.Context, input) (output, error)

在一切准备就绪之后,Go Function 会启动 channel 来源源不断地接收从 inputs topic 中传入的数据。需要说明的是,用户无需关心该 channel 关闭的时机,因为在 Function 的使用场景下,一旦启动就会源源不断的来处理输入的数据,用户可以使用 Ctrl+C 来终止整个程序的运行,或者可以通过参数 killAfterIdleMs 来配置该 Function 运行的时长,单位为毫秒。

部署 Go Function

Go Function 的实现依赖于 pulsar-client-go,在运行 Go Function 之前,需要保证 pulsar-client-go 正确安装,具体安装参考 pulsar-client-go 安装。

pulsar-client-go:

https://pulsar.apache.org/docs/en/client-libraries-go/

Go Function 的实现形式虽然同 Java FunctionPython Function 不同,但是为了降低用户的部署成本,对外暴露给用户的部署方式是相同的,具体操作如下:

  1. 启动 Pulsar。

  2. 编译 Go Function。

$ go build [your function file name].go

3\. 启动 Go Function。

./bin/pulsar-admin functions localrun/create
--go [your go function path]
--inputs [input topics]
--output [output topic]
--tenant [default:public]
--namespace [default:default]
--name [custom unique go function name]

注意:

  • 与 Java Function 和 Python Function 不同的是,在 Go Function 中,用户无需指定 classname。

  • 在 Java Function 中,--jar 上传的是打包好的 jar 文件;在 Python Function 中 --py 所上传的是 python 文件;无论哪种形式,上传的都属于 user code。而 Go Function 中 --go 所上传的是一份编译好的可执行文件,其中包含了 user code 和 Function 本身的代码。

Go Function 目前不支持的功能如下:

  • Schema,目前 input 和 output 只允许为 []byte

  • Metrics

  • Secrets

  • Authentication & Authorization

更多关于 Pulsar 的技术干货和产品动态,请关注 StreamNative 微信公众号。

下一场 Pulsar meetup 于 6/29 在深圳举办,欢迎来现场了解 Pulsar。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容