本文记录了对 MOSN 的源码研究 - MOSN 的共享内存模型。 本文的内容基于 MOSN v0.9.0,commit id b2a239f5。 机制 MOSN 用共享内存来存储 metrics 信息。MOSN 用 mmap 将文件映射到内存,在内存数组之上封装了一层关于 metrics 的存取逻辑,实现了 go-metrics 包的关于 metrics 的接口,通过这种方式组装出了一种基于共享内存的 metrics 实现供 MOSN 使用。 创建共享内存:Mmap 操作共享内存的方法主要在 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.
本文记录了对 MOSN 的源码研究 - MOSN 的内存复用机制。 本文的内容基于 MOSN v0.9.0,commit id 1609ae14。 MOSN 在内存管理复用方面有 内存对象注册/管理 和 byte/io buffer 复用 两部分内容。MOSN 最新的 master 分支用了 mod 管理依赖, 发现后一部分也迁移到了 vendor 目录下,可单独使用。下面就分这两部分来讲述 MOSN 的内存复用机制。 机制 简述一下两部分内容的机制,具体实现原理会在后面带上源码解析。 1. 内存对象注册/管理 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.
本文记录了对 mosn 的源码研究,研究 mosn 是如何做到平滑重启的。 本文的内容基于 mosn v0.8.1。 我们先将被重启的 mosn 进程称为 旧 mosn,将重启并接管流量的进程成为 新 mosn。 1. 机制 mosn 没有使用重新读取 config 文件的方法来实现 reconfig,而是通过 unix socket 作为进程间通信,并将旧进程的监听 fd 通过 socket 传过去,新 mosn 接管 fd 并且重新读取 config,旧 mosn 进行 gracefully shutdown,以达到 reconfig 和平滑重启的功能。 2. 旧mosn 我们先从一个启动着的 mosn 进程看起,看看它是如何被重启的。 mosn 的 reconfig 逻辑在 server 包的 reconfigure.go 内。 mosn 进程启动后,会创建一个叫 reconfig.sock 的 unix socket,创建一个协程,开始监听并往里面写入一个字节的内容,这时会出现写阻塞。一旦有另一个进程从 reconfig.sock 读取到这一个字节,旧 mosn 便开始 reconfig 逻辑。 reconfig 逻辑: 当写阻塞结束,协程会尝试链接另一个 unix socket :listen.