Caddy 源码分析 启动流程与Event事件通知
Caddy 源码分析 启动流程与Event事件通知
介绍
Caddy 整个软件可以说是由不同的 插件 堆砌起来的。自己本身仅提供 Plugin 的注册运行逻辑和 Server 的监听服务功能。
学习 caddy 的源码,实际上是学习 如何构建一个松耦合的抽象 Plugin 设计,即模块化插拔的做法。
所以我们的源码阅读,围绕 Caddy 为 Plugin 提供的基础设施,和 Plugin 自身逻辑。
下面我们从第一步,启动流程开始阅读。 之后的路径应该是 Caddyfile 的解析,解析出的 配置文件如何消费,配置完成的服务器如何服务。
main.go
├── caddy # caddy主目录
│ ├── caddymain
│ │ ├── run.go # 运行文件
│ │ └── run_test.go
│ ├── main.go # 主文件
│ └── main_test.go
其中run.go 上篇笔记中已经分析 Caddy 源码分析 run.go
main.go
var run = caddymain.Run // replaced for tests
func main() {
run()
}
通过改变 run 变量的值来方便测试,可以学习一下。
启动流程
启动 caddy 的流程
caddyfileLoader 加载 caddyfile 配置 --> 生成 Input 信息 Context --> 生成 Server
caddyfile 示例
Instans 是运行操作的 Server 实例,可以看到几个主要的操作都是在他身上
Server 两种监听模式 TCP UDP
启动服务器
发送 StartupEvent
// Executes Startup events 注册开始事件钩子(即插件相关启动都在此处注册 很多魔改框架都是改动的这里)
caddy.EmitEvent(caddy.StartupEvent, nil)
读取配置文件
caddyfileinput, err := caddy.LoadCaddyfile(serverType)
启动
instance, err := caddy.Start(caddyfileinput)
发送 InstanceStartupEvent
caddy.EmitEvent(caddy.InstanceStartupEvent, instance)
Start()
// Start your engines
instance, err := caddy.Start(caddyfileinput)
if err != nil {
mustLogFatalf("%v", err)
}
这里除了 Instance 之外还有两个新名词
Controller(控制器):它是用来帮助 Directives(指令) 设置它自身的,通过读取 Token,这里的 Directives 实际上对应的就是上文所说的 caddyfile 中的配置文件选项。
这一点请参照 Caddy(三)中 Loader 下的 excuteDirective 理解。
Token :是 caddy 自己的 词法分析器 解析 caddyfile 配置文件出的选项的标记。
这一点请Caddy(三)中 Loader 中的 Parser 理解