微服务设计原则——高性能

2024-08-25 13:11:07 浏览数 (4)

1.分页查询

页宜小不宜大

对于查询 API 来说,当查询结果集包含成千上万条记录时,返回所有结果是一个挑战,它给服务器、客户端和网络带来了不必要的压力,于是便有了分页接口。

在设计分页接口时,页大小需要设置上限。这是因为如果没有上限,客户端可以请求任意大的页大小,从而可能导致服务器性能问题,例如一次请求返回过多数据,导致服务器响应变慢,网络传输时间变长,甚至可能引起系统崩溃等问题。

为了防止这种情况的发生,通常会在设计分页接口时设置一个最大页大小限制。当客户端请求的页大小超过最大限制时,应该向客户端返回一个错误提示,告知客户端页大小超过最大限制,建议客户端减小页大小,以保证服务器和客户端的正常运行。

那么页大小设为多少合适呢?

常见的页大小有 10,20,50,100,500 和 1000。如何选择页大小,我们应该在满足特定业务场景需求下,宜小不宜大。

太大的页,主要有以下几个问题:

  • 影响用户体验。页太大,加载会比较慢,用户等待时间会比较长。
  • 影响接口性能。页太大,会增加数据的拉取编解码耗时,降低接口性能。
  • 浪费带宽。很多场景下,用户在浏览的过程中,不会看完一页中的所有数据,返回太大的页是一种浪费。
  • 扩展性差。随着业务的发展,接口在页大小不变的情况下,返回的页数据可能会越来越大,导致接口性能越来越差,最终拖垮接口。

页大小多少合适,没有标准答案,需要根据具体的业务场景来定。但是要坚持一点,页宜小不宜大。如果页大小能用 10 便可满足业务需求,就不要用 20,更不要用 50。

浅分页使用偏移量,深分页使用游标

通常我们通过偏移量(OFFSET 和 LIMIT)或游标(NEXT_ID 和 LIMIT)实现分页。

基于偏移是最常见的分页接口设计,其原理是通过页号和页大小指定某一分页的数据。

代码语言:javascript复制
// 请求
{
  "page": 2,
  "count": 10
}
// 响应
{
  "data": [],
  "total": 100
}

优点:简单易懂,易于实现。支持分页跳转,支持向前翻页。

缺点:

  • 不适用于大数据量的深分页场景。因为当 OFFSET 值较大时,性能会下降,因为数据库需要扫描和跳过大量记录。
  • 不适用动态数据:偏移量方案对数据变动支持也差,数据的插入或删除可能会导致数据重复或跳过,比如用户在查看第 10 页内容,此时第 1 页一条数据被删除,此时整个列表会往迁移,这会导致第 11 页跳过了 1 条数据。

基于游标(cursor)的分页方式适用于动态数据场景,一般使用唯一标识符(如主键)或时间戳作为分页的游标,基于上一个分页的最后一条记录来查询下一页数据。

代码语言:javascript复制
// 请求
{
  "next_id": "11",
  "count": 10
}
// 响应
{
  "data": [],
  "next_id": "21",
}

深分页使用游标查询时,每次分页查询都多查询一个元素作为 Next Cursor 使用,同时可以用来判断是否有剩余数据。

游标分页方案优点就是性能好,对数据变动也有较好支持,不会因为数据的插入或删除导致数据重复或跳过。

缺点是不能像偏移量方案可以任意跳转指定页,往前翻页也需要特别处理。

索引优化

确保分页查询使用了合适的索引来提高查询性能,尤其是在处理大数据量时。

1 人点赞