
1.2.2 Nuclio的架构设计
Nuclio试图描述并抽象出所有事件信息,当事件发生时(例如,将消息记录写入Kafka时、发起一个HTTP请求时、计时器到期时等)能够将事件信息发送给一段代码逻辑来处理。为了实现这个目标,Nuclio希望用户可以(至少)提供关于什么可以触发一个事件并且在发生此类事件时应该由哪一段代码逻辑来进行处理的详细信息。用户可以通过命令行工具(nuctl)、REST API或者一个可视化的Web端应用程序来描述。Nuclio的架构如图1-2所示。
Nuclio获取信息(通常称为函数处理程序(Handler)和函数配置(Configuration))并发送给构建器(包含在用户仪表盘(DashBoard)中)。构建器将制作函数的容器镜像,其中包含用户提供的函数处理程序及一个可以在接收到事件后执行该函数处理程序的函数处理器(Processor)。然后,构建器将该容器镜像发布到容器镜像仓库中,容器镜像仓库可以是DockerHub等开源仓库也可以是私有镜像仓库。在开发、生产中建议使用私有仓库,这样函数构建运行速度会加快(私有镜像仓库的镜像上传和下载速度会比公网快很多)。一旦发布完成,这个函数的容器镜像就可以被部署了。

图1-2 Nuclio的架构
控制器将从函数的配置中生成编排平台所需的特定配置文件。例如,如果是部署在Kubernetes集群中,控制器将会读取配置文件中的副本数量、自动缩容时间、函数需要的CPU和GPU数量等参数,并将它们转化为Kubernetes的资源配置(例如,Deployment、Service、Ingress等)。
Kubernetes将会从已经发布的容器镜像中启动容器并执行它们,并将函数的配置文件传递到容器中。这些容器的入口点(Entrypoint)就是“处理器”,它负责读取配置文件、监听事件触发器(例如,连接到Kafka、监听HTTP端口等),当事件发生时,读取事件并调用用户的函数处理程序。处理器还负责很多其他的事情,包括处理指标、编码响应及崩溃等。
一旦构建并部署到Kubernetes这样的编排平台中,Nuclio函数(即处理器)就可以处理事件,并根据性能指标、发送日志等进行扩缩容,所有这些都不需要任何外部实体的帮助。部署完成后就可以关闭Nuclio的仪表盘和控制器了,Nuclio函数依然可以完成运行和伸缩容。
但是,缩容为零的能力单单依靠函数自身是无法完成的。相反地,一旦缩容为零,当一个新的事件到达时,Nuclio函数无法完成自己的扩容操作。为此,Nuclio有一个扩缩容服务,它解决了将函数缩容为零,以及从零开始扩容的问题。
缩容为零(AutoScaler)服务定时从Kubernetes中查询指标数据,以决定服务是否进行缩放。决定的依据来源于用户事先的配置,如在10min中没有请求到达,服务就会缩容为零。查询的间隔时间也是由用户指定的。
DLX(Dead Letter Exchange,死信交换)是当请求首次到达系统时,它会创建一个缓冲区,并结合函数的实际情况更改函数的状态,然后交由控制器将副本设置为大于零的值,完成从零开始的扩容功能。当服务就绪后,修改对应函数Service(Service是Kubernets中的一个概念,它是将运行在一个或一组Pod上的网络应用程序公开为网络服务的方法)中的选择器,将流量路由回函数服务,这样再次请求就会路由到对应的函数。后续监控会采集服务指标,以供AutoScaler服务进行决策。