更多常见问题请点击这里。
2020 年 11 月常见问题
1.【数据存储】某张表单个对象过大,导致请求速度较慢怎么办?
单个对象的数据过大,需要在业务层去优化代码,比如 data 是大数据字段:
或者考虑将 data 字段的数据做为「文件」保存,然后在表中通过 Pointer 关联起来。
2.【云引擎】云引擎部署期间用户使用会有影响吗?
正常情况下是没有影响的。在部署新版本或其他运维操作时,系统会让新旧版本的实例同时运行一段时间,再关闭旧版本的实例,让服务保持零中断。
3.【云引擎】与自建的 HashTable 相比较,LeanCache 有什么优势?
与自己在程序的全局作用域中维护一个 HashTable 相比,使用 LeanCache 的优势在于:
多实例之间的数据共享:云引擎支持多实例运行,自行维护的 HashTable 数据无法跨实例共享。
数据持久化存储:在程序重启或重新部署后数据不会丢失,Redis 会帮你完成数据持久化的工作。LeanCache 还会为你的 Redis 做热备,具有非常高的可靠性。
原子操作和性能:Redis 提供了常见的数据结构和大量原子操作,其文档中列出了每个操作符的时间复杂度,而自行实现的 HashTable 的性能则很大程度依赖于具体语言的实现。
2020 年 10 月常见问题
1.【数据存储】当数据量越来越大时,怎么加快查询速度?
与使用传统的数据库一样,查询优化主要靠索引实现。索引就像字典里的目录,能帮助你在海量的文字中更快速地查词。
原则:数据量少时,不建索引。多的时候请记住,建立索引后,写入时还需要更新索引,以此来换取更少的查询时间。所以,一般来说,写少读多就多建索引,写多读少就少建索引。
操作:进入 控制台 > 存储,选定一张表之后,点击右侧的 其他下拉菜单,然后选择 索引,然后根据你的查询需要建立好索引。
提示:
如果 Class 内数据很多,点击「创建」按钮后,控制台可能会显示「排队中」。这意味着索引创建操作已进入任务队列,会在集群闲时(通常是凌晨)自动进行。
数据表的默认四个字段 objectId
、ACL
、createdAt
、updatedAt
是自带索引的,但是在勾选时,可以作为联合索引来使用。
「唯一索引」选项指比如 uuid 等使用场景。勾选「唯一索引」但不勾选「允许缺失值」时,最多只能有一条不存在该字段的数据,否则数据就不唯一了。如果可能存在不止一条不存在该字段的数据,请同时勾选「允许缺失值」。
目前索引提供 3 种排序方案:正序、倒序和 2dsphere。其中 2dsphere 用于地理位置经纬度的数据(GeoPoint)。比如移动场景中一个常见的需求是查找附近的其他用户。由于存储服务支持双向遍历索引,因此单字段索引,正序和倒序是等价的,可随意选择。但联合索引的正序、倒序的组合需要根据业务需求选择。
下面以两个字段的联合索引为例详细说明正序、倒序的选择。我们假定创建 foo、bar 双字段联合索引时, foo 字段的索引选择正序,bar 字段的索引选择倒序。显而易见,foo 正序且 bar 倒序的查询能够利用索引。又因为支持双向遍历索引,所以上述查询的翻转形式 foo 倒序且 bar 正序也能利用索引。但是,foo、bar 同序(皆正序或皆倒序)的查询无法利用索引。同样是因为支持双向遍历索引的缘故,创建 foo 字段倒序、bar 字段正序的联合索引,效果是等价的。同理,foo、bar 字段同序的联合索引,能够被 foo、bar 同序的查询利用,不能被 foo、bar 异序的查询利用。三个或更多字段的联合索引以此类推。
2.【域名绑定】域名已经备案,在控制台绑定域名时却域名备案检查不通过
请先访问工信部网站试下能否查到域名备案信息,如果查询不到,需要等待工信部域名备案查询系统更新后再去控制台点「重试」。如果工信部网站可以查到而控制台域名备案检查却不通过,通常是因为 LeanCloud 使用的备案查询服务数据有延迟,请通过工单或邮件联系我们处理。
3.【数据存储】不通过短信验证能否强制修改 _User 表 mobilePhoneVerified 字段,使其设置为 true?
可以通过云引擎使用 master key 来修改 mobilePhoneVerified 的值。因为云引擎运行在可信的服务器端环境中,所以可以全局开启超级权限(Master Key),这样云端会跳过包括 ACL 和 Class 权限在内的检查,让你自由地操作所有云存储中的数据,当然这种方式也只允许调用一些仅供 Master Key 使用的 API。
2020 年 9 月常见问题
1.【数据存储】在 PC 端用手机号登录,在小程序上用微信登录,如何绑定到同一个账号上
从逻辑上,在 PC 端登录的账号,与在小程序中用微信登录的账号,他们没有任何可以联系在一起的地方。如果都是独立创建了两个账号,只能在业务层面进行绑定(也就是将一个账号的所有关联对象全都迁移到另一个账号,然后删除原账号)。
如果可以在业务上加一些限制,则可以避免上面这种「创建了两个独立的账号」的情况。比如,如果手机号是账号必须设置的信息,那么我们可以在以手机号作为关联项。具体的步骤如下,首先是 loginWithWeapp 并带上 failOnNotExist 参数,这样如果该微信关联的用户已经存在则照常登录,如果没有则会失败,此时跳转到使用手机号登录/注册的页面,让用户通过手机号登录或注册,成功之后再通过 associateWithWeapp 接口关联当前微信账号。
2.【短信】账号下有短信签名,新申请短信模板时,为什么仍提示需先创建对应签名?
短信的审核流程已经全面改版升级,提交短信签名时需要提供签名相关的资质文件,一些旧版的签名尚未提交过资质文件,这部分旧的签名虽然目前仍可以正常发送短信,但不能新建模板。
旧版签名需要补充资质文件重新提交一次审核。
3.【即时通信】如何检查好友的在线状态?
即时通讯支持 客户端上下线 Hook 通知。实现步骤是通过 hook 拿到 clientId
的在线状态,将这些状态存储到 LeanCache 中,客户端定期查询云函数来获得用户的在线状态。详细方案可参考文档:即时通讯中的在线状态查询。
2020 年 8 月常见问题
1.【即时通信】使用 REST API 发送实时通信消息收费吗?
使用 REST API 发送即时通信消息也是收费的。计费标准就是 API 调用费用标准(每万次 1.0 元)。
此项计费在控制台 > 财务 > 消费明细中对应扣费服务项目是:「数据存储(API 请求)」。
2.【数据存储】表数据变多后查询变慢,该怎么优化?
可以通过建索引加速查询。数据查询是很普通的操作,与传统关系型数据库一样,索引的优劣对于我们查询性能的影响非常大。 我们可以在控制台 > 存储 > 结构化数据的每个 Class 中,切换到「性能与索引」标签页,创建索引。
索引需要针对查询条件来做,过多的索引也会影响到写入效率。详情还可以参考:索引文档。
3.【云引擎】可以在云函数中未登录的情况下查询 _User 表吗?
在云函数里可以用 masterKey 跳过权限检查,未登录也可直接查询 _User 表。
因为云引擎运行在可信的服务器端环境中,所以你可以全局开启超级权限(Master Key),这样云端会跳过包括 ACL 和 Class 权限在内的检查,让你自由地操作所有云存储中的数据。具体细节可以参考文档: Master Key 和超级权限。
2020 年 7 月常见问题
1.【即时通信】为什么收不到离线消息的推送?
没有收到离线消息的推送,可以按照如下步骤检查:
参考 聊天消息没有收到 一节内容查看聊天消息是否有正常送达服务器;
检查接收者用户是否离线(控制台>即时通信>用户状态页面查询),接收者是否在 _Installation 表中有关联的设备记录;
参考 离线推送通知 一节内容,确认应用是否有配置默认的推送内容,这一步很重要,如果没有设置推送内容系统不会自动推送离线消息;
在控制台 > 推送 > 在线发送页面,使用在线推送实际发推送给目标设备查看推送是否出错,比如 iOS 证书不匹配,设备 Token 过期,设备 Token 和推送环境不匹配等
具体细节还可以参考文档:即时通信常见问题。
2.【云引擎】调用云函数报错:Application not Found
访问云引擎服务时,服务端返回错误「Application not found」或在云引擎日志中出现这个错误,可能有以下原因:
2020 年 6 月常见问题
1.【消息推送】如果同一个设备上有两个应用,如何推送到指定的应用?
_Installation 表记录了设备上生成的安装信息。可以在 _Installation 表新增一个字段来区分不同的应用。在推送消息的时候,如果选择推送全部用户,则两个应用都会收到推送。
如果想要针对某一个应用推送,可以参考 发送给特定的用户这个推送文档,只发送给指定的设备。
2.【云引擎】云引擎创建的新的分组,可以调试云函数吗?
云引擎默认会有一个用于处理云函数、Hook 和定时任务的分组,其他额外创建的分组将成为「拓展分组」,拓展分组不支持定义云函数(包括 Hook 函数和定时任务),只能通过绑定的域名提供网站托管服务。在创建了多个分组后,可以随时在云引擎的设置界面切换默认分组。
每个分组都有独立的预备环境用于测试代码、独立的域名供外部访问,每个分组的环境变量、代码仓库等设置也是独立的,可以单独对一个组部署代码。你可以按照 实例管理 一节中的介绍,在分组中创建和管理实例,如果组中没有实例就无法响应请求,如果组中有多个实例便可以提供负载均衡和高可用的能力。
2020 年 5 月常见问题
1.【消息推送】iOS 推送报错 「部分推送被 APNs 拒绝,拒绝原因是: BadDeviceToken」
这个报错是因为推送环境不正确,例如推送时通过 prod 参数设置推送给测试环境的设备(即"prod": "dev"
),则生产环境的设备无法收到推送。
同理,如果指定推送给生产环境的设备(即"prod": "prod"
),则测试环境的设备无法收到推送。
关于 iOS 的推送环境参考:推送环境。
2.【即时通信】如何实现聊天消息中的敏感词过滤?
对于开放聊天室来说,内容的审核和实时过滤是产品运营上的一个基本要求。我们即时通讯服务默认提供了敏感词过滤的功能,多人的 普通对话、聊天室和系统对话里面的消息都会进行实时过滤。 命中的敏感词将会被替换为 ***
。 消息内容实时过滤属于系统层面的修改消息,发送者会收到 MESSAGE_UPDATE
事件。
如果开发者有较为复杂的过滤需求,我们推荐使用 云引擎 Hook 函数 _messageReceived
来实现过滤,在 hook 中开发者对消息的内容有完全的控制力。
3.【云引擎】如何判断当前云引擎是预备环境还是生产环境?
默认情况,云引擎只有一个「生产环境」,对应的域名是 CCCCCCCCCCweb.example.com`(云引擎域名绑定指南参考:文档)。在生产环境中有一个「体验实例」来运行应用。
当生产环境的体验实例升级到「标准实例」后会有一个额外的「预备环境」,对应域名 stg-web.example.com
,两个环境所访问的都是同样的数据,你可以用预备环境测试你的云引擎代码,每次修改先部署到预备环境,测试通过后再发布到生产环境;如果你希望有一个独立数据源的测试环境,建议单独创建一个应用。
如果访问云引擎遇到「Application not Found」的错误,通常是因为对应的环境还没有部署代码。例如应用可能没有预备环境,或应用尚未发布代码到生产环境。
2020 年 4 月常见问题
1.【数据存储】如何提升标志位的查询效率?
当数据表中有很多布尔类型的数据时,可以考虑使用二进制存储提高查询效率。例如需要存储是否开启推送、是否静音、是否为会员等多个状态,可以这样表示:
111
:开启推送、静音、是会员
101
:开启推送、未静音、是会员
在 LeanCloud 存储为整型字段,操作这个字段的方法可以参考位运算的接口文档:REST API - 位运算。
2.【数据存储】应用内搜索的关键字查询, 查出来的结果是两月前的数据,最新数据查询不到怎么办?
这种情况可以在控制台尝试重建索引,索引创建完后会有邮件提醒。
一般来说当用户上传了新的词典,或者有批量删除过数据等情况都需要执行一次「重建索引」操作。当发现搜索与存储数据不一致时,也可以尝试重建索引来解决。
3.【即时通信】Android 和 iOS SDK是否需要本地化未读消息数的问题
对于未读通知的下发时机和数量,iOS 和 Java/Android 两个平台的 SDK 在内部处理上稍有差异:iOS SDK(Objective-C 和 Swift 都包括)在每次登录即时通讯云端的时候,都会获得云端下发的 大量 未读通知;而 Java/Android SDK 由于内部持久化缓存了通知的时间戳(能减轻服务端压力),所以登录即时通讯云端之后客户端只会收到上次通知时间戳之后发生了变化的 部分 未读数通知。
因此 Java SDK 的开发者需要在应用层缓存收到的未读数通知(同一个对话的未读数采用覆盖的方式来更新),而 iOS SDK 这里收到的 大量未读通知并不等于全量数据(云端追踪的有未读消息的对话数不超过 50 个) ,所以也是一样需要在应用层面缓存收到的未读计数结果,这样才能保证对话列表超过 50 个之后未读计数值的准确性。
2020 年 3月常见问题
1.【数据存储】如何解决数据一致性或事务需求?
LeanCloud 目前并不提供完整的事务功能,但提供了一些保证数据一致性的特性,可以解决大部分的一致性需求:
在单个对象的一次 save 操作中,对多个字段的更新操作是原子地完成的。
使用 increment(原子计数器)可以原子地更新数字字段。
唯一索引 可以保证在一个字段上有同样值的对象只有一个。
有条件更新对象 可以仅在满足某个查询条件时进行更新操作;在这个特性的基础上,你可以自己实现更加复杂的 两阶段提交。
在云引擎上还可以借助 LeanCache 来实现自定义的 排他锁。
关于这个话题我们还录制了一期公开课视频:在 LeanCloud 上解决数据一致性问题,其中有对上面这些特性的详细介绍,和解决常见场景的实例教程(包括实现两阶段提交)。
2. 【即时通信】即时通信如何获取在线用户列表以及用户的在线时长?
我们提供了 客户端上下线 Hook,开发者可以利用这两个 Hook 函数,结合云缓存来完成一组客户端实时状态查询的 endpoint。
具体实现步骤是通过 Hook 拿到 clientId 的在线状态,将这些状态存储到 LeanCache 中。客户端定期查询云函数来获得用户的在线状态。具体可以参考文档:即时通讯中的在线状态查询。
3. 【推送】离线推送通知服务里,_Installation 是如何与 _User 里的用户 id 关联的?
用户登录即时通信系统以后,服务器会将用户的 client id 保存在登录设备的 _Installation 表的 channels 字段里,从而完成关联。当用户离线,有离线消息需要推送时,服务端会去 _Installation 表内找到 channels 字段包含目标 client id 的设备来完成推送。
4. 【云引擎】如何访问云引擎预备环境中托管的网站?
需要在控制台手动绑定一个 stg-
开头的域名。stg-
开头的自定义域名(例如 stg-web.example.com
)会被自动地绑定到预备环境。
更多详情参考:域名绑定指南。
2020 年 2 月常见问题
1.【推送】iOS 推送如何正确保存 deviceToken?
iOS 系统重装、从备份恢复应用、在新设备上安装应用都会导致 device token 变化,因此 Apple 推荐 在应用每次启动时都去请求 APNs 的 device token,获取 token 后进行设置并保存 token。 除此以外,LeanCloud 后端会统计 installation 的更新时间(updatedAt
),据此清理长期未更新的 installation 数据。 所以我们建议开发者遵循 Apple 的推荐方式开发应用,以免有效 installation 数据被意外清理,以及因为 device token 过期无效而推送失败。
示例代码可以参考: 开发文档。
2.【云引擎】部署更新云引擎会导致服务中断吗?
服务不会中断。在代码部署时,系统会优先启动使用新版本代码的实例,待新实例通过了健康检查,系统修改路由将请求转发至新实例后,再关闭旧版本的实例,让服务保持零中断。
3.【云引擎】如何调整云引擎实例规格,什么样的配置是合理的?
为了防止实例因为资源使用超限而受到影响(特别是内存超限),我们建议:
2020 年 1 月常见问题
1.【域名证书】https 证书过期怎么更新?
如果是手动证书管理,可以在控制台 > 应用 > 设置 > 域名绑定页面找到对应域名下方的「更新证书」按钮,点击即可上传新的证书。
如果配置的自定义域名选择的是 ssl 自动管理,则无需更新证书,证书过期前系统会自动申请证书。
2.【推送】iOS 设备未收到推送,到控制台查看推送记录发现报错 invalidTokens, 是什么原因?
invalidTokens 的数量由以下两部分组成:
针对第一种情况,请检查 APNS 证书是否过期,并检查是否使用了正确的 证书类型。
3.【推送】iOS 推送如何区分使用的证书类型?
iOS 的推送环境有 测试 和 生产 两种。
我们支持上传两个环境的 iOS 推送证书,默认使用 生产证书 来发推送,可以通过设定 prod
属性来指定使用哪个环境证书。
更具体的细节可以参考这部分文档:iOS 测试和生产证书区分。