详解如何使用Golang扩展Envoy

 更新时间:2023年06月11日 16:40:47   作者:豆浆大叔  
这篇文章主要为大家介绍了详解如何使用Golang扩展Envoy实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、背景

主要介绍用 Golang 扩展 Envoy 的极速开发体验

MoE(MOSN on Envoy)是 MOSN 团队提出的技术架构,经过近两年的发展,在蚂蚁内部已经得到了很好的验证;并且去年我们也将底层的 Envoy Go 七层扩展贡献了 Envoy 官方,MOSN 也初步支持了使用 Envoy 作为网络底座的能力。

借此准备写一系列的文章,逐一介绍这里面的技术。本文作为开篇,将重点介绍 MoE 中的基础技术,Envoy Go 扩展。

二、FAQ

开始前,先给大家解答下几个基本的问题:

1、MoE 与 Envoy Go 扩展有什么区别?

A:MoE 是技术架构,Envoy Go 扩展是连接 MOSN 和 Envoy 的基础技术。

2、Envoy Go 扩展,与用 Go 来编译 Wasm 有什么区别?

A:Envoy Go 支持 Go 语言的所有特性,包括 Goroutine;Go Wasm 则只能使用少量的 Go 语言特性,尤其是没有 Goroutine 的支持。

3、Go 是静态链接到 Envoy 么?

A:不是的,Go 扩展编译成为 so,Envoy 动态加载 so,不需要重新编译 Envoy

4、Envoy Go 支持流式处理么?

A:支持的。

由于 Go 扩展提供的是底层的 API,非常的灵活,使用上相对会稍微复杂一些;如果只想简单的使用,可以使用 MOSN 的 filter,后面我们也会介绍。

三、需求

我们先实现一个小需求,来实际体会一下:

对请求需要进行验签,大致是从 URI 上的某些参数,以及私钥计算一个 token,然后和 header 中的 token 进行对比,对不上就返回 403。

很简单的需求,仅仅作为示例,主要是体验一下过程。🧸

四、代码实现

完整的代码可以看 envoy-go-filter-example[1] 这个仓库,这里摘录最核心的两个函数:

const secretKey = "secret"
func verify(header api.RequestHeaderMap) (bool, string) {
    token, ok := header.Get("token")
    if ok {
        return false, "missing token"
    }
    path, _ := header.Get(":path")
    hash := md5.Sum([]byte(path + secretKey))
    if hex.EncodeToString(hash[:]) != token {
        return false, "invalid token"
    }
    return true, ""
}
func (f *filter) DecodeHeaders(header api.RequestHeaderMap, endStream bool) api.StatusType {
    if ok, msg := verify(header); !ok {
        f.callbacks.SendLocalReply(403, msg, map[string]string{}, 0, "bad-request")
        return api.LocalReply
    }
    return api.Continue
}

DecodeHeaders 是扩展 filter 必须实现的方法,我们就是在这个阶段对请求 header 进行校验。

verify 是校验函数,这里的 RequestHeaderMap 是 Go 扩展提供的 interface,我们可以通过它来读写 header,其他都是常见的 Go 代码写法。

五、编译

编译很简单,与常见的 Go 编译一样,这里我们使用 Golang 官方的 docker 镜像来编译:

docker run --rm -v `pwd`:/go/src/go-filter -w /go/src/go-filter \
-e GOPROXY=https://goproxy.cn \
golang:1.19 \
go build -v -o libgolang.so -buildmode=c-shared .

Go 编译还是很快的,只需要几秒钟,当前目录下,就会产生一个 libgolang.so 的文件。反观 Envoy 的编译速度,一次全量编译动辄几十分钟,或者上小时的,这幸福感提升了不止一个档次。🥰

六、运行

我们可以使用 Envoy 官方提供的镜像来运行,如下示例:

docker run --rm -v `pwd`/envoy.yaml:/etc/envoy/envoy.yaml \
        -v `pwd`/libgolang.so:/etc/envoy/libgolang.so \
        -p 10000:10000 \
        envoyproxy/envoy:contrib-dev \
        envoy -c /etc/envoy/envoy.yaml

只需要把上一步编译的 libgolang.so 和 envoy.yaml 挂载进去就可以了。

值得一提的是,我们需要在 envoy.yaml 配置中启用 Go 扩展,具体是这段配置:

http_filters:
  - name: envoy.filters.http.golang
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
      library_id: example
      library_path: /etc/envoy/libgolang.so
      plugin_name: example-1

跑起来之后,我们测试一下:

$ curl 'http://localhost:10000/'
missing token
$ curl -s 'http://localhost:10000/' -H 'token: c64319d06364528120a9f96af62ea83d' -I
HTTP/1.1 200 OK

符合期望,是不是很简单呢?👀

七、后续

什么?这个示例太简单?

是的,这里主要是体验下开发流程,下篇我们将再介绍更高级的玩法:

Go 接受来自 Envoy 侧的配置、异步 Goroutine,以及与 Istio 配合的用法。

|相关链接|

[1]envoy-go-filter-example 仓库:https://github.com/doujiang24/envoy-go-filter-example/tree/master/example-1

以上就是详解如何使用Golang扩展Envoy的详细内容,更多关于Golang扩展Envoy的资料请关注脚本之家其它相关文章!

相关文章

  • golang 实现Location跳转方式

    golang 实现Location跳转方式

    这篇文章主要介绍了golang 实现Location跳转方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • intelliJ idea安装go开发环境并搭建go项目(打包)全过程

    intelliJ idea安装go开发环境并搭建go项目(打包)全过程

    最近在配置idea开发go语言时碰到很多问题,所以这里给大家总结下,这篇文章主要给大家介绍了关于intelliJ idea安装go开发环境并搭建go项目(打包)的相关资料,需要的朋友可以参考下
    2023-10-10
  • go+redis实现消息队列发布与订阅的详细过程

    go+redis实现消息队列发布与订阅的详细过程

    这篇文章主要介绍了go+redis实现消息队列发布与订阅,redis做消息队列的缺点:没有持久化,一旦消息没有人消费,积累到一定程度后就会丢失,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • golang文件读取-按指定BUFF大小读取方式

    golang文件读取-按指定BUFF大小读取方式

    这篇文章主要介绍了golang文件读取-按指定BUFF大小读取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 简单聊聊Go语言中空结构体和空字符串的特殊之处

    简单聊聊Go语言中空结构体和空字符串的特殊之处

    在日常的编程过程中,大家应该经常能遇到各种”空“吧,比如空指针、空结构体、空字符串等,本文就以 Go 语言为例,一起来看看空结构体和空字符串在 Go 语言中的特殊之处吧
    2024-03-03
  • Go语言题解LeetCode455分发饼干示例详解

    Go语言题解LeetCode455分发饼干示例详解

    这篇文章主要为大家介绍了Go语言题解LeetCode455分发饼干示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Golang sync包中errgroup的使用详解

    Golang sync包中errgroup的使用详解

    Go 语言为我们提供了丰富的并发原语,且大多数都位于 sync 包下,今天我们来探讨一下该库下的原语之一:errgroup,感兴趣的小伙伴可以了解一下
    2023-05-05
  • golang实现大文件读取的代码示例

    golang实现大文件读取的代码示例

    在实际工作,我们需要读取大数据文件,文件可能上G百G,所以我们不可能一次性的读取到内存,接下来本文给大家介绍了golang实现大文件读取的示例,需要的朋友可以参考下
    2024-04-04
  • Go语言定时器Timer和Ticker的使用与区别

    Go语言定时器Timer和Ticker的使用与区别

    在Go语言中内置的有两个定时器,Timer和Ticker,本文主要介绍了Go语言定时器Timer和Ticker的使用与区别,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • Golang中深拷贝与浅拷贝详解

    Golang中深拷贝与浅拷贝详解

    这篇文章主要为大家详细介绍一下Golang深拷贝和浅拷贝,文中有详细的代码示例供大家参考,需要的可以参考一下
    2023-05-05

最新评论