在REST API Java Spring Boot

时间:2018-03-05 15:58:26

标签: mysql spring performance hibernate spring-boot

我们正在使用以下技术设计API Rest:

  • spring-boot 1.5.7
  • 弹簧数据JPA
  • MySQL 5.5.59

它是一个带有spring-boot的Java REST API设计,并通过mysql-connector连接到MySQL数据库。存储库中的大多数查询都是以JPA Query方式编写的。 为了编译它,我们使用maven并将它部署在运行在tomcat服务器上的fatjar中。

事实上,对于一个用户来说,其中的几个表和资源可能非常大。因此,当使用高偏移量进行GET请求时,我们可以处理慢速查询。

我们尝试了几种解决方案:

  • 为mysql连接设置tomcat参数
  • 使用hikari但没有可用的参数来杀死慢查询
  • 在glassfish5服务器中部署其余的api,但是spring数据jpa查询会抛出一个execption(无法提取结果集),所以这是一个问题。

此外,很多人会说我"使用分页并检查请求中的偏移量#34;。事实是我们正在使用它,但类 PageRequest 有一个棘手的行为。实际上,API为您提供此类的资源具有以下形式:

{
  "content": {},
  "links": [
    {
      "href": "string",
      "rel": "string",
      "templated": true
    }
  ],
  "page": {
    "number": 0,
    "size": 0,
    "totalElements": 0,
    "totalPages": 0
  }
}

正如您所看到的,您有一个带有 totalElements 字段的对象。如果一个用户的表中有很多条目,则会出现此问题。因为spring数据会做一个" SELECT COUNT(*)"拥有此 totalElements 信息。分页不是解决方案,因为我们已经有了这个问题。

因此,我们要求您提供的是最佳实践,也许是使用spring-boot处理和删除Restful API设计中的慢查询的解决方案。

谢谢!

2 个答案:

答案 0 :(得分:1)

关于分页,请看一下这个答案:Way to disable count query from PageRequest for getting total pages?

基本上返回List而不是Page。这当然不会给你总数,所以你需要以不同的方式处理这种情况。它可能需要为下一页提供一个额外的查询,它将返回一个空列表,但您将在每个页面上保存计数。

如果您因某种原因仍然需要总数,则必须进行计算。

关于您的评论&#34;由您的数据库引起的慢查询&#34;:不是生成慢查询的数据库。您和您的代码会生成慢查询。除了杀死正在运行的查询之外,您可能还有解决问题的方法,但是您需要提供有关数据库的更多信息:结构,记录数,确切的查询问题,适当的索引等等。也许您可以引入缓存?< / p>

如果你仍然坚持要杀死查询,你可以在CompletableFuture中运行并等待超时完成:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

答案 1 :(得分:0)

经过大量的研究,我只是通过重点阅读tomcat数据源文档找到了解决问题的方法。我找到了我在application.yml中设置的jdbc拦截器,如下所示:

jdbc-interceptors: QueryTimeoutInterceptor(queryTimeout=20);SlowQueryReport(threshold=20000,logFailed=true)

所以这就是我想要的,例如,如果我的查询超过20秒就会抛出异常并将其杀掉!

非常感谢您的帮助!

相关问题