云引擎常见问题
云引擎功能
云引擎都支持哪些语言?
目前支持 Node.js、Python、Java、PHP、.NET、Go 运行环境,也支持基于 Node.js 的 Web 前端项目,详见 云引擎服务总览。
如果你还需要其他运行环境的支持,欢迎向我们反馈。
云引擎支持托管纯静态网站吗?
支持,请看 云引擎 Web 前端应用运行环境。
云引擎支持 HTTPS 吗?
支持,在绑定自定义域名时可以上传 SSL 证书或自动管理证书。
绑定自定义域名时还可以配置「强制 HTTPS」来实现自动跳转。
部署更新云引擎会导致服务中断吗?
服务不会中断。在代码部署时,系统会优先启动使用新版本代码的实例,待新实例通过了健康检查,系统修改路由将请求转发至新实例后,再关闭旧版本的实例,让服务保持零中断。
云引擎和云函数是什么关系?
云引擎是一个托管后端服务的平台,适用于所有的 Web 后端应用,对于程序内部的逻辑没有侵入。
在此基础上,开发者可以选择在程序内接入云引擎的 SDK,来使用云函数和 Hook 等功能,云函数与 数据存储 服务有深度的整合,对于已经在使用数据存储服务的开发会非常方便。
不接入云引擎 SDK 也可以使用云函数以外的所有功能,云引擎也提供了业界广泛使用的 Redis、MongoDB 和 Elasticsearch 供开发者存储数据。
云函数
云函数有哪些限制?
云函数是 TDS 提供的一个 相对受限 的自定义服务器端逻辑的功能,和我们的 SDK 有比较 深度的集成。我们将云函数设计为一种类似 RPC 的机制,在云函数中你只能关注参数和结果,而不能自定义超时时间、HTTP method、URL,不能读取和设置 Header。
如果希望更加自由地使用这些 HTTP 的语义化功能,或者希望使用第三方的框架提供标准的 RESTful API,请在你的应用中自行来处理 HTTP 请求而不是使用云函数。
云函数可以同时存在于多个分组么?
云引擎会自动将一个应用下的云函数请求转发到正确的分组,因此你可以同时在多个分组下使用云函数。
项目部署成功了,但云函数和 Hook 不可用?
为了支持云引擎的云函数和 Hook 功能,云引擎的管理程序会使用 /1.1/functions/_ops/metadatas
这个 URL 和 SDK 交互,请确保将这个 URL 交给 SDK 处理。
默认情况下,云引擎会尝试从 /1.1/functions/_ops/metadatas
获取云函数和 Hook 的元信息,如果失败,则云函数和 Hook 功能不可用,但不会中断部署。
如果希望在获取元信息失败后中断部署,可以在 leanengine.yaml
文件中指定 functionsMode
为 strict
。
如果应用不使用云函数和 Hook 功能,那么你可以:
- 在
leanengine.yaml
中不指定functionsMode
,同时/1.1/functions/_ops/metadatas
返回一个 HTTP404
表示不使用云函数和 Hook 相关的功能; - 或者在
leanengine.yaml
中指定functionsMode
为disabled
。注意,这种情况下,即使应用代码中定义了云函数和 Hook,Hook 也不会生效,云函数调用(通过 SDK 发起远程调用或通过 REST API 向 API 域名发起云函数调用)有可能因为被转发到错误的云引擎分组而失败。
部署中断,提示有同名云函数怎么办?
云引擎支持多个分组。
如果当前部署代码中部分云函数与其他组的同名,默认情况会提示错误并中断部署,防止意外重复定义云函数。
我们建议你移除不需要的云函数,毕竟重复定义的云函数并不易于理解和维护。
不过,你也可以通过在每次部署时额外指定 --overwrite-functions
参数强制替换其他组云函数的实现。
为什么 Class Hook 没有被运行?
首先确认一下 Hook 被调用的时机是否与你的理解一致:
beforeSave
:对象保存或创建之前afterSave
:对象保存或创建之后beforeUpdate
:对象更新之前afterUpdate
:对象更新之后beforeDelete
:对象删除之前afterDelete
:对象删除之后onVerified
:用户通过邮箱或手机验证后onLogin
:用户在进行登录操作时(become(sessionToken)
不是登录操作,因此不会调用onLogin
)
还需注意在本地进行云引擎调试时,运行的会是线上预备环境的 Hook,如果没有预备环境则不会运行。
然后检查 Hook 函数是否被执行过:
可以先在 Hook 函数的入口打印一行日志,然后进行操作,再到云引擎日志中检查该行日志是否被打印出来,如果没有看到日志原因可能包括:
- 代码没有被部署到正确的应用
- 代码没有被部署到生产环境(或没有部署成功)
- Hook 的类名不正确
如果日志已打出,则继续检查函数是否成功,检查控制台上是否有错误信息被打印出。如果是 before 类 Hook,需要保证 Hook 函数在 15 秒内结束,否则会被系统认为超时。
after 类 Hook 超时时间为 3 秒,如果你的体验实例已经休眠,很可能因为启动时间过长无法收到 after 类 Hook,建议升级到云引擎的标准实例避免休眠。
可以在云函数中未登录的情况下查询 _User 表吗?
在云函数里可以用 masterKey 跳过权限检查,未登录也可直接查询 _User 表。
因为云引擎运行在可信的服务器端环境中,所以你可以全局开启超级权限(Master Key
),这样云端会跳过包括 ACL 和 Class 权限在内的检查,让你自由地操作所有云存储中的数据。具体细节可以参考 云引擎 SDK 使用指南 § 使用超级权限。
部署
多次部署同一个项目时镜像大小为什么差别那么大?
云引擎底层有一套缓存机制以加速构建过程,所以部署时显示的「存储镜像到仓库」后面的大小表示本次构建新产生的数据,可用于评估是否利用到了缓存,不代表整个项目的大小。
部署时长时间卡在「正在下载和安装依赖」怎么办?
这个步骤对应在云端调用各个语言的包管理器(npm
、pip
、composer
、maven
)安装依赖的过程,我们有一个依赖缓存机制来加速这个安装过程,但缓存可能会因为很多原因失效(比如修改了依赖列表),在缓存失效时会比平时慢很多,请耐心等待。如果你在 leanengine.yaml
中指定了系统依赖也会在这个步骤中安装,因此请不要添加未用到的依赖。
对于 Node.js 建议检查是否在 package-lock.json
或 yarn.lock
中指定了较慢的源。
部署到多个实例时,部分实例失败需要重新部署吗?
同一环境(预备/生产)下有多个实例时,云引擎会同时在所有实例上部署项目。如因偶然因素部分实例部署不成功,会在几分钟后自动尝试再次部署,无需手动重新部署。
云引擎实例部署后控制台多次显示「部署中」是怎么回事?
控制台显示的「部署中」状态泛指所有运维操作,例如唤醒休眠实例、服务器偶发故障引起的重新部署,不只是用户主动进行的部署。
云引擎的健康检查是什么?
云引擎的管理系统会每隔几分钟检查所有实例的工作状态(通过 HTTP 检查,详见具体运行环境文档的「健康检查」小节), 如果实例无法正确响应的话,管理系统会触发一次重新部署,并在控制台上打印类似下面的日志:
健康检查失败:web1 检测到 Error connect ECONNREFUSED 10.19.30.220:51797
如果一周内发生一两次属正常现象(有可能是我们的服务器出现偶发的故障,因为会立刻重新部署,对服务影响很小),如果频繁发生可能是你的程序资源不足,或存在其他问题(运行一段时间后不再响应 HTTP 请求),需结合具体情况来分析。
实例启动失败: 无法访问应用的 Web 端口(Error: connect ECONNREFUSED),请确保程序在 30 秒内正确地启动了 HTTP 服务
云引擎在部署过程中会检测应用的 3000 端口是否提供了 HTTP 服务,所以请保证应用至少暴露了 3000 端口。
限制和费用
云引擎的请求有哪些限制?
云引擎的负载均衡组件限制了请求不能超过 100 MB(包括直接上传文件到云引擎)、请求处理不得超过 60 秒,WebSocket 60 秒无数据会被断开连接。
国内节点未绑定独立 IP 的云引擎默认为纯静态站点优化。请求会先经过边缘节点,再视缓存命中情况回源到负载均衡组件,最后到达你的应用。 边缘节点额外限制了请求不能超过 60 MB、请求处理不得超过 10 秒,另外边缘节点不支持 WebSocket 请求和 HTTP PATCH 方法,也不支持获取客户端 IP。 因此,如果你在国内节点云引擎托管动态网站,我们建议你绑定独立 IP,使用独立入口,不经过边缘节点,自然也就没有上述限制。
每个应用最多有几个实例?
每个应用最多拥有 12 个实例,如果需要更多资源请通过工单联系我们的技术支持。
云引擎如何收费?
云引擎中如果有云服务的存储等 API 调用,按数据存储收费策略照常收费。
云引擎的标准实例、LeanDB 实例、回源流量、加速流量都会产生费用,详见官网的价格方案页面。
流量如何计费?
每个云引擎实例每天有 1 G 免费额度,超出部分价格可以在价格页面查看。
一个应用下的流量额度会合并计算,即每天的免费额度为 max(n, 1)
GB,其中 n
为该应用所有云引擎分组下的标准实例总数。
云引擎不适合分发大文件之类的场景,有此需求的开发者可以使用文件服务。
在开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 云引擎 > 管理部署 > 云引擎分组 > 统计 > 流量可以查看最近流量统计。
如果更改了实例规格或数量,当天的云引擎费用如何收取?
云引擎资源使用量按 当天最大的实例数量 计算,次日凌晨从账户余额中扣费,假设某天从 0 点至 24 点之间:
- 应用本来有 4 个 standard-512 的实例;
- 发现资源数量不足,将实例规格调整到了 standard-1024;
- 发现资源过多,减少到 2 个实例。
则当天费用按照 standard-1024 的价格乘上 4 个实例计算。
Hook 函数算 API 请求次数吗,afterUpdate 执行一次算 1 次请求次数吗?
AfterUpdate 是在云引擎内执行的,执行 afterUpdate 不算 API 请求,自然也不计入 API 请求数。如果 afterUpdate 里发起了 API 请求,那么照常计算 API 请求数(和客户端请求 API 一样)。
最佳实践
云引擎如何上传文件?
托管在云引擎的网站可以使用相应 SDK 提供的接口上传文件。 不过,一般情况下建议在客户端 SDK 上传文件,而不是通过云引擎中转,以免增加不必要的云引擎流量。
在云引擎使用文件上传,报错 failed to upload file to qiniu bcz current file has not data stream。
LCFile 内部会使用一个本地缓存(需要先有一个本地目录)来先保存二进制数据,然后再把它上传到文件存储服务里。在云引擎里面应该会因为权限不足的原因无法创建这样的缓存目录或文件,导致出现 failed to upload file to qiniu bcz current file has not data stream
这样的错误。
我们不建议在云引擎使用文件服务,有几个原因:
- 上面提到的权限问题,导致云引擎里无法创建缓存目录和临时文件;
- 所有文件数据都先到服务端,然后再调用 API 推到文件存储服务商那里,这会导致效率很低,并且用户需要支付的网络成本很高(云引擎也需要付超出标准的流量费用的)。
建议在客户端使用 SDK 上传文件,之后把结果(例如文件的 object id 或者 url)再给到服务端(就是云引擎代码)。在客户端上传,会使用文件存储服务商的 CDN 链路(就近上传),用户的体验会更快,并且还可以节省云引擎流量成本。
定时任务应该在预备环境还是生产环境执行?
系统赠送的预备环境体验实例会自动休眠,可能干扰定时任务的执行,因此一般建议在预备环境测试定时任务,在生产环境正式执行定时任务。 如果定时任务 CPU、内存占用非常高,担心影响生产环境的网站托管功能或其他云函数访问,那么可以在预备环境购买标准实例,并在预备环境执行定时任务。
如何判断当前云引擎是预备环境还是生产环境?
默认情况,云引擎只有一个「生产环境」,对应的域名是 web.example.com。在生产环境中有一个「体验实例」来运行应用。
当生产环境的体验实例升级到「标准实例」后会有一个额外的「预备环境」,对应域名 stg-web.example.com,两个环境所访问的都是同样的数据,你可以用预备环境测试你的云引擎代码,每次修改先部署到预备环境,测试通过后再发布到生产环境;如果你希望有一个独立数据源的测试环境,建议单独创建一个应用。
另外,stg-web.example.com 域名是需要在控制台自行绑定的。
如何访问云引擎预备环境中托管的网站?
需要在控制台手动绑定一个 stg-
开头的域名。stg-
开头的自定义域名(例如 stg-web.example.com)会被自动地绑定到预备环境。
云引擎可以绑定裸域名吗?
如果希望绑定裸域名,请添加直接指向独立 IP 的 A 记录。
疑难问题
Application not found 错误
访问云引擎服务时,服务端返回错误「Application not found」或在云引擎日志中出现这个错误,可能有以下原因:
- 调用错了环境。最常见的情况是,免费的体验实例是没有预备环境,开发者却主动设置去调用预备环境。
- 云引擎自定义域名填错了,比如微信回调地址。
- 因为免费版(体验版)的云引擎是有休眠的,休眠期间被调用会出现这个错误。建议升级到标准实例以保证实例一直运行。
云引擎响应时间增加怎么办
响应时间的增加有很多种原因:可能因为只是单纯的请求处理的数据更加复杂导致耗时变长;也有可能是因为请求量过高实例的处理能力不足从而导致响应时间增加。 建议分析当前的代码并参考 CPU、内存占用量找出瓶颈,确定是否需要调高实例规格或增加实例数量。 如果需要定位具体是哪些 API 或云函数响应较慢,可以下载访问日志分析。
在线上无法读取到项目中的文件怎么办?
建议先检查文件大小写是否正确,线上的文件系统是区分大小写的,而 Windows 和 macOS 通常不区分大小写。
云引擎会重复提交请求吗?
云引擎的负载均衡对于幂等的请求(GET、PUT),在 HTTP 层面出错或超时的情况下是会重试的,建议使用正确的谓词(例如 POST)避免此类重试。
云引擎的 AccessToken 在哪里?
具体位置在:部署 > 命令行部署 > 生成新的 AccessToken,如下图: