在这里我对GoFast的主要设计思路做一些概要介绍。

框架核心流程

源代码开始的地方:gofast/fst/fst.go

image-20210104141018413

说明:以后我们也把这些后台WebServer叫做Application,简称App。

CreateServer

每个应用都要从这里开始,在这里我们定义了一个配置结构AppConfig,将来所有的配置参数都放在这里面,配置传入之后我们要做一些默认值的设置。

我为根路径单独定义了一个结构HomeSite,其实他就是根节点分组(Root RouterGroup),将来所有的路由分组和路由项都是他的子孙节点。关键是很多特殊的功能呢都需要在HomeSite上设置,比如NoRoute、NoMethod的处理函数等。

  • 和其它很多框架不一样,我特意将App和HomeRouter的概念拆分开,而不是合二为一,想让这个框架结构更清晰。资源监测、数据库连接、定时任务等属于App的范畴;而设置程序的路由规则、处理HTTP请求等属于Site的范畴。

初始化MethodTrees。和有些框架将所有不同种类的Method请求处理放入一颗路由树种的做法不一样。我们将不同的Method对应的路由和处理函数构建成不同的路由树,主要是性能的考虑,以后专门研究这个话题。

SetRouter

使用者在这一步规划自己的路由和相应的处理函数。本框架最大的特点之一就在这里,可以随意的对路由分组(比如想要做权限控制和版本控制),并对任意的分组和具体路由项定制请求全生命周期的处理函数。

此功能非常灵活,这种特性的功能可能会造成内存占用过大;为此我专门设计了一套内存占用极小的数据结构。

ReadyToListen

端口监听正式启动之前,我们需要做很多特殊的操作。

  • 如果使用者没有定义特殊情况的处理函数,我们会设置一个默认值。
  • 在这里可以打印后台构建的路由树,主要用于开发设计阶段的调试,将来考虑加入打印实际的路由项。
  • 核心:用数组这种数据结构,重建整颗路由树。
  • 执行App级别的一些事件处理函数。

在此之前我们就构建了整颗Radix路由树,为了进一步减小内核大小,尽可能提高CPU的缓存命中率,较少页面切换;我设计了一套新数据结构,主要思想是:压缩字节,数组连续存储。

Listen

到这里就可以启动监听,接受请求了。框架依赖标准库net包,底层得知客户请求之后做基本的上下文处理工作,然后通过一个个goroutine交给我们编写的fst.ServeHTTP来处理。

(未完待续…)