服务开发说明

最近更新时间:2024-05-22 17:15:31

我的收藏
本文介绍开发云托管服务时需要了解的一些事项。

编程语言支持

您可以使用任何语言、任何框架编写服务,甚至直接使用现有的容器镜像。快速入门文档中提供了以多种主流语言编写的示例,但暂不在示例范围内的语言也均可支持。

代码要求

侦听 HTTP 请求

服务必须侦听 HTTP 请求,云托管暂不支持 tcp/udp/mqtt 等其他协议。

不支持 Docker Compose

云托管暂不支持 Docker Compose。

不支持 Windows

云托管暂不支持 Windows 操作系统的容器。

无状态服务

服务必须是无状态服务,不能依赖永久性本地状态。这是为了能够进行水平的自动扩缩容。
无状态服务(stateless service)指的是对单次请求的处理,不依赖其他请求。处理一次请求所需的全部信息必须都包含在这个请求里,或者可以从数据库、文件存储等外部获取,实例本身不存储任何信息。
有状态服务(stateful service)则相反,它会在自身保存一些数据,先后的请求是有关联的。

避免后台活动

代码中请不要在请求处理程序范围之外启动后台线程或例程,并确保在传送响应之前完成所有异步操作。强行运行后台线程可能会导致异常。例如一个 HTTP 服务,在收到一个接口后,直接调用 sh 命令,做系统层面的动作。如系统文件更新,指向,重启等,这都是不建议的,会引发不稳定导致回收。
再展开异步任务的例子来进一步说明:
1. 当服务最小实例为0(低成本模式),触发执行一个异步任务,时间达2小时。这个时间段中如果没有任何访问请求的话,半小时后会直接缩容到0,回收实例,异步任务会被终止。
2. 当服务负载出现高峰,触发了自动扩容,有2个甚至更多实例存在。这时候如果有异步任务2小时,但恰巧2小时内的流量访问又不足以一直支撑2个或多个容器提供服务,服务负载回落时,实例数减少。因为默认服务无状态,即每个实例都是完全等同的,缩容时无法指定具体销毁哪个容器,此时异步任务如果刚好在缩容的那个容器中,也会被终止。

异步任务处理

确实需要用云托管服务处理异步任务,且无法在传送响应之前完成所有异步操作的话,需要注意以下几点:
必须保证实例不会回收,意味着无法采用低成本模式,服务最小实例数不能设置为0;
可以约束任务,或者是通过守护请求来支撑住,避免任务受缩容影响;
可以通过放弃自动扩缩容能力,将服务最小和最大实例数都设置为同样的值(例如均设置为1,锁死服务无论如何只有1个实例),保障异步任务运行。

定时任务处理

确实需要用云托管服务处理定时任务,且无法在传送响应之前完成所有异步操作的话,需要注意以下几点:
必须保证实例不会回收,因为定时任务无法通过外部请求维持,意味着无法采用低成本模式,服务最小实例数不能设置为0;
必须放弃自动扩缩容能力,将服务最小和最大实例数都设置1,锁死服务无论如何只有1个实例,保障定时任务运行。

代码容器化

基于容器部署服务,您需要提供一个容器镜像,或者提供代码由云托管在线构建镜像。容器镜像是一种封装格式,其中包含您的代码、代码软件包、所需的全部二进制依赖项、要使用的操作系统以及运行服务所需的其他任何内容。因此,镜像一旦构建完成,以上所有信息就都被固化,云托管不会感知镜像具体内容,容器实例运行过程中镜像内容也不会变化。
说明:
如您需要修改任何内容,则需要重新构建镜像。
通常,您可以使用名为 Dockerfile 的文件来声明如何构建镜像。快速入门文档中提供的示例,也包含多种主流语言的 Dockerfile 参考。
说明:
Dockerfile 背景知识:查看 Dockerfile 官方文档 了解语法,并查看 编写 Dockerfile 的最佳做法 中的提示了解如何将这些语法整合在一起。
Dockerfile 通常从基础镜像(例如 FROM golang:1.11)开始。您可以在 Docker Hub 上找到由操作系统和语言作者维护的基础镜像。

谨慎使用依赖项

如果您使用具有依赖项库的动态语言,例如导入 Node.js 模块,那么在冷启动期间加载这些模块会增加延迟时间。 您可以通过以下方式缩短启动延迟时间:
最大限度地减少依赖项的数量和大小,以构建精简服务。
惰性加载不常用的代码(如果您所用的语言支持此方式)。
使用代码加载优化技术。

控制镜像大小

镜像较大会造成以下影响:
增加安全漏洞。
降低镜像的构建速度,增加构建时长,甚至引发构建超时。
降低服务的部署速度。
说明:
镜像的大小不会影响请求处理时间,但过大的镜像会消耗更多构建时间、部署时间,也会消耗更多资源,从而产生更多费用。
具体实现镜像优化,请参见 优化容器镜像