【问题标题】:Blocking successive SQL requests on the backend在后端阻止连续的 SQL 请求
【发布时间】:2018-04-12 21:01:22
【问题描述】:

上下文

我正在开发一个具有AngularJS 前端和Laravel 后端以及MySQL 作为数据库的应用程序。后端基本上作为 REST API 工作。

问题

在搜索页面工作时,我遇到了一个问题,当用户单击多个过滤器、在搜索文本字段中书写或快速翻阅页面时,会发送多个请求,因为搜索响应会自动更新,而无需一个搜索按钮,这会大大减慢响应时间。

所以我尝试通过在另一个请求被触发时取消请求来解决这个问题。 这是使用Restangular的代码:

this.refresh = function(filter) {
    if (abortGet){
        abortGet.resolve(); // cancel the previous call through timeout HttpConfig
    }

    abortGet = $q.defer();
    resource.rest = Service.withHttpConfig({timeout: abortGet.promise}).getList(filter);
    resource.rest.then(function(data) {
        ...
    });
};

问题是我认为请求仍然会到达后端,因此当请求的前端部分被取消时,数据库很慢。

我不希望应用程序感觉没有响应,因此我不希望在一段时间内阻止在前端发送的请求以确保用户完成查询。 p>

问题

  • 如果来自同一用户的连续请求到达,是否有办法在后端阻止对 MySQL 的请求?
  • 我认为这是高级搜索实施的典型问题,是否有多种策略可以解决?

【问题讨论】:

  • 您可以做的第一件事是对用户输入使用去抖动功能。
  • 我这样做了,但是,如果请求有点复杂、处理速度慢或者用户在选择选项时速度很慢,则会发送多个请求。我想我必须以某种方式在后端处理它。
  • 我会尝试使用 Redis 来缓存数据库结果。
  • @Camilo 感谢您的建议,我们已经使用 Redis 来缓存大多数非快速变化的数据。但是,我询问的数据变化很快。
  • 也许您可以在某些路线上设置rate limit

标签: mysql angularjs laravel rest


【解决方案1】:

后端

如果您的数据没有快速变化,一个好的解决方案可能是添加一个反向代理来缓存 Web 服务器上的渲染结果。

这样,如果重复请求相同的 URL,您的代理将从缓存中提供已呈现的文档。根据数据的性质,可以在不同的缓存保留下缓存不同的 URL 端点。

Nginx 内置了这些功能,并且 ha-proxy 和 Pound 也可能是不错的选择。

前端

另一种解决方案可能是在前端更智能一点,即将结果临时存储在内存或基于浏览器的数据库 IndexedDB 中。这将有助于解决两种典型情况:

  1. 如果用户反转过滤器小部件,则先前的结果将准备就绪。
  2. 如果用户缩小搜索范围,您可以通过过滤 IndexedDB 中的数据进行过滤。

【讨论】:

  • 感谢您的回答,我们已经在后端使用 Redis 为一些非快速变化的信息进行了缓存,但是,对于我询问的列表,它们快速变化并且它们每个包含大约 200k 条记录。 那么,在后端,您会考虑缓存整个列表吗?如果是这样的话,你会缓存所有现有过滤器的所有不同配置吗?
  • 对于 IndexedDB 解决方案,如果基于过滤器的当前显示列表是基于所选过滤器的数据库中整个记录列表的子集,那么我有一些不明白的地方。如果用户更改过滤器,我怎么知道当前子集中存在正确的信息,所以我不去数据库上搜索它?在所有情况下,除非我拥有 IndexedDB 中的所有记录,否则我无法确定。我错过了什么吗?
  • 您可以将来自更通用过滤器的结果保留在 IndexedDB 中,然后重新显示它以再次查询 API。 IndexedDB 的关键是您的过滤器设置。您还可以保留检索数据的时间戳。
  • 为什么要检索 20 万条记录?您应该使用分页或无限滚动,一次只能检索 500 条记录。
  • @MrWook 我已经在分页,但显示的结果可能会根据过滤器而变化。例如,如果我在没有任何过滤器的情况下缓存前 500 条记录,当用户添加过滤器时,我不确定过滤器的结果是否在这 500 条记录中,因此我必须使用当前过滤器再次进行完整搜索应用于数据库。稍后,如果他选择了另一个过滤器,我将不得不再次针对数据库重新执行整个请求。 你明白这个问题吗?除非您缓存整个数据集,否则缓存不起作用,因为您永远无法确定结果是否在缓存的子集中
猜你喜欢
  • 2018-01-28
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多