本文记录了对 MOSN 的源码研究 - MOSN 的共享内存模型。
本文的内容基于 MOSN v0.9.0,commit id b2a239f5。
MOSN 用共享内存来存储 metrics 信息。MOSN 用 mmap 将文件映射到内存,在内存数组之上封装了一层关于 metrics 的存取逻辑,实现了 go-metrics 包的关于 metrics 的接口,通过这种方式组装出了一种基于共享内存的 metrics 实现供 MOSN 使用。
操作共享内存的方法主要在 pkg/shm/shm.go 文件下:
func Alloc(name string, size int) (*ShmSpan, error) {
...
return NewShmSpan(name, data), nil
}
func Free(span *ShmSpan) error {
Clear(span.name)
return syscall.Munmap(span.origin)
}
func Clear(name string) error {
return os.Remove(path(name))
}
都是围绕着 ShmSpan 结构体的几个操作方法。再来看 ShmSpan 结构体:
type ShmSpan struct {
origin []byte // mmap 返回的数组
name string // span 名, 创建时指定
data uintptr // 保存 mmap 内存段的首指针
offset int // span 已经使用的字节长度
size int // span 大小
}
Alloc 方法按照给定的 name 参数,在配置文件的目录下创建文件,并执行 sync.Mmap,其文件尺寸即 size 参数大小。Mmap 过后,将信息保存在 ShmSpan结构内返回。
本文记录了对 MOSN 的源码研究 - MOSN 的内存复用机制。
本文的内容基于 MOSN v0.9.0,commit id 1609ae14。
MOSN 在内存管理复用方面有 内存对象注册/管理 和 byte/io buffer 复用 两部分内容。MOSN 最新的 master 分支用了 mod 管理依赖,
发现后一部分也迁移到了 vendor 目录下,可单独使用。下面就分这两部分来讲述 MOSN 的内存复用机制。
简述一下两部分内容的机制,具体实现原理会在后面带上源码解析。
MOSN 在 go sync 包外,对 sync.Pool 对象进行了进一步封装,增加了管理和易用性。
MOSN 的 buffer 包提供了注册函数和统一的接口。将实现了接口的不同类型的 buffer 对象注册到 buffer 包, 在用到的使用通过 buffer 包导出的方法进行初始化和管理,增强了内存对象的管理。
而易用性方面,MOSN 封装了 bufferValue 对象,管理上面初始化出来的对象,并且将 bufferValue 对象也进行了池化管理。在这之上,封装出方法
NewBufferPoolContext 和 PoolContext,使内部根据 context 传值的场景更加易用。MOSN 里面在不同协程协作(比如连接被协程1 accept 后,
交由 worker 协程2 进行 IO)的过程,会将必要参数使用内部实现的 context with value 机制进行传递,
其中 buffer 传递的方法就是通过上述封装的方法进行传递的。
本文记录了对 MOSN 的源码研究 - MOSN 的插件机制, 以及如何创建自己的插件来扩展 MOSN。
本文的内容基于 MOSN v0.9.0。
使用过滤器模式来实现扩展是常见的设计模式,MOSN 也是使用了这种方式来构建可扩展性。
MOSN 把过滤器相关的代码放在了 pkg/filter 目录下:
➜ mosn git:(2c6f58c5) ✗ ll pkg/filter
total 24
drwxr-xr-x 8 mac staff 256 Feb 5 08:52 .
drwxr-xr-x 30 mac staff 960 Feb 5 08:52 ..
drwxr-xr-x 3 mac staff 96 Aug 28 22:37 accept
-rw-r--r-- 1 mac staff 2556 Feb 5 08:52 factory.go
-rw-r--r-- 1 mac staff 2813 Feb 5 08:52 factory_test.go
drwxr-xr-x 6 mac staff 192 Aug 28 22:37 network
drwxr-xr-x 7 mac staff 224 Aug 28 22:37 stream
-rw-r--r-- 1 mac staff 1248 Feb 5 08:52 types.go
➜ mosn git:(2c6f58c5) ✗
包括 accept 过程的 filter,network 处理过程的 filter,以及 stream 处理的 filter。其中 accept filters 目前暂不提供扩展(加载、运行写死在代码里面,如要扩展需要修改源码),
steram、network filters 是可以通过定义新包在 pkg/filter 目录下实现扩展。
本文记录了对 mosn 的源码研究,研究 mosn 是如何做到平滑重启的。
本文的内容基于 mosn v0.8.1。
我们先将被重启的 mosn 进程称为 旧 mosn,将重启并接管流量的进程成为 新 mosn。
mosn 没有使用重新读取 config 文件的方法来实现 reconfig,而是通过 unix socket 作为进程间通信,并将旧进程的监听 fd 通过 socket 传过去,新 mosn 接管 fd 并且重新读取 config,旧 mosn 进行 gracefully shutdown,以达到 reconfig 和平滑重启的功能。
我们先从一个启动着的 mosn 进程看起,看看它是如何被重启的。
mosn 的 reconfig 逻辑在 server 包的 reconfigure.go 内。
mosn 进程启动后,会创建一个叫 reconfig.sock 的 unix socket,创建一个协程,开始监听并往里面写入一个字节的内容,这时会出现写阻塞。一旦有另一个进程从 reconfig.sock 读取到这一个字节,旧 mosn 便开始 reconfig 逻辑。
当写阻塞结束,协程会尝试链接另一个 unix socket :listen.sock