Skip to content

Commit 83b4f1c

Browse files
Create index.md (#1167)
Co-authored-by: Marco <[email protected]>
1 parent edac702 commit 83b4f1c

File tree

1 file changed

+151
-0
lines changed
  • content/zh/blog/moe-series (1)|how-to-extend-envoy-with-golang

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: "MoE 系列(一)|如何使用 Golang 扩展 Envoy"
3+
authorlink: "https://github.com/sofastack"
4+
description: "MoE 系列(一)|如何使用 Golang 扩展 Envoy"
5+
categories: "SOFAStack"
6+
tags: ["SOFAStack"]
7+
date: 2023-03-28T15:00:00+08:00
8+
cover: "https://mdn.alipayobjects.com/huamei_soxoym/afts/img/A*fPOiTJsdpxMAAAAAAAAAAAAADrGAAQ/original"
9+
10+
---
11+
12+
*本文作为 MoE 系列第一篇,主要介绍用 Golang 扩展 Envoy 的极速开发体验。*
13+
14+
**一、背景**
15+
16+
MoE*(MOSN on Envoy)*是 MOSN 团队提出的技术架构,经过近两年的发展,在蚂蚁内部已经得到了很好的验证;并且去年我们也将底层的 Envoy Go 七层扩展贡献了 Envoy 官方,MOSN 也初步支持了使用 Envoy 作为网络底座的能力。
17+
18+
借此准备写一系列的文章,逐一介绍这里面的技术。本文作为开篇,将重点介绍 MoE 中的基础技术,Envoy Go 扩展。
19+
20+
**二、FAQ**
21+
22+
开始前,先给大家解答下几个基本的问题:
23+
24+
> **1、MoE 与 Envoy Go 扩展有什么区别?**
25+
26+
A:MoE 是技术架构,Envoy Go 扩展是连接 MOSN 和 Envoy 的基础技术。
27+
28+
> **2、Envoy Go 扩展,与用 Go 来编译 Wasm 有什么区别?**
29+
30+
A:Envoy Go 支持 Go 语言的所有特性,包括 Goroutine;Go Wasm 则只能使用少量的 Go 语言特性,尤其是没有 Goroutine 的支持。
31+
32+
> **3、Go 是静态链接到 Envoy 么?**
33+
34+
A:不是的,Go 扩展编译成为 so,Envoy 动态加载 so,不需要重新编译 Envoy
35+
36+
> **4、Envoy Go 支持流式处理么?**
37+
38+
A:支持的。
39+
40+
由于 Go 扩展提供的是底层的 API,非常的灵活,使用上相对会稍微复杂一些;如果只想简单的使用,可以使用 MOSN 的 filter,后面我们也会介绍。
41+
42+
**三、需求**
43+
44+
我们先实现一个小需求,来实际体会一下:
45+
46+
对请求需要进行验签,大致是从 URI 上的某些参数,以及私钥计算一个 token,然后和 header 中的 token 进行对比,对不上就返回 403。
47+
48+
很简单的需求,仅仅作为示例,主要是体验一下过程。
49+
50+
**四、代码实现**
51+
52+
完整的代码可以看 envoy-go-filter-example[1] 这个仓库,这里摘录最核心的两个函数:
53+
54+
```bash
55+
const secretKey = "secret"
56+
57+
func verify(header api.RequestHeaderMap) (bool, string) {
58+
token, ok := header.Get("token")
59+
if ok {
60+
return false, "missing token"
61+
}
62+
63+
path, _ := header.Get(":path")
64+
hash := md5.Sum([]byte(path + secretKey))
65+
if hex.EncodeToString(hash[:]) != token {
66+
return false, "invalid token"
67+
}
68+
return true, ""
69+
}
70+
71+
func (f *filter) DecodeHeaders(header api.RequestHeaderMap, endStream bool) api.StatusType {
72+
if ok, msg := verify(header); !ok {
73+
f.callbacks.SendLocalReply(403, msg, map[string]string{}, 0, "bad-request")
74+
return api.LocalReply
75+
}
76+
return api.Continue
77+
}
78+
```
79+
80+
`DecodeHeaders` 是扩展 `filter` 必须实现的方法,我们就是在这个阶段对请求 `header` 进行校验。
81+
82+
`verify` 是校验函数,这里的 `RequestHeaderMap` 是 Go 扩展提供的 `interface`,我们可以通过它来读写 header,其他都是常见的 Go 代码写法。
83+
84+
**五、编译**
85+
86+
编译很简单,与常见的 Go 编译一样,这里我们使用 Golang 官方的 docker 镜像来编译:
87+
88+
```bash
89+
docker run --rm -v `pwd`:/go/src/go-filter -w /go/src/go-filter \
90+
-e GOPROXY=https://goproxy.cn \
91+
golang:1.19 \
92+
go build -v -o libgolang.so -buildmode=c-shared .
93+
```
94+
95+
Go 编译还是很快的,只需要几秒钟,当前目录下,就会产生一个 libgolang.so 的文件。反观 Envoy 的编译速度,一次全量编译动辄几十分钟,或者上小时的,这幸福感提升了不止一个档次。🥰
96+
97+
**六、运行**
98+
99+
我们可以使用 Envoy 官方提供的镜像来运行,如下示例:
100+
101+
```bash
102+
docker run --rm -v `pwd`/envoy.yaml:/etc/envoy/envoy.yaml \
103+
-v `pwd`/libgolang.so:/etc/envoy/libgolang.so \
104+
-p 10000:10000 \
105+
envoyproxy/envoy:contrib-dev \
106+
envoy -c /etc/envoy/envoy.yaml
107+
```
108+
109+
只需要把上一步编译的 `libgolang.so``envoy.yaml` 挂载进去就可以了。
110+
111+
值得一提的是,我们需要在 envoy.yaml 配置中启用 Go 扩展,具体是这段配置:
112+
113+
```bash
114+
http_filters:
115+
- name: envoy.filters.http.golang
116+
typed_config:
117+
"@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
118+
library_id: example
119+
library_path: /etc/envoy/libgolang.so
120+
plugin_name: example-1
121+
```
122+
123+
跑起来之后,我们测试一下:
124+
125+
```bash
126+
$ curl 'http://localhost:10000/'
127+
missing token
128+
$ curl -s 'http://localhost:10000/' -H 'token: c64319d06364528120a9f96af62ea83d' -I
129+
HTTP/1.1 200 OK
130+
```
131+
132+
符合期望,是不是很简单呢?
133+
134+
**七、后续**
135+
136+
什么?这个示例太简单?
137+
138+
是的,这里主要是体验下开发流程,下篇我们将再介绍更高级的玩法:
139+
140+
**Go 接受来自 Envoy 侧的配置、异步 Goroutine,以及与 Istio 配合的用法。**
141+
142+
**|相关链接|**
143+
144+
[1]envoy-go-filter-example 仓库:
145+
146+
[*https://github.com/doujiang24/envoy-go-filter-example/tree/master/example-1*](https://github.com/doujiang24/envoy-go-filter-example/tree/master/example-1)
147+
148+
**了解更多…**
149+
150+
**MOSN Star 一下✨:**
151+
[*https://github.com/mosn/mosn*](https://github.com/mosn/mosn)

0 commit comments

Comments
 (0)