我们正在使用 spring boot 1.5.10
发布版本以及 mongodbrepository。
我们有大量数据,所以我们在服务器启动时使用 postconstruct 加载静态数据(select * from table)。
Api 响应大小约为 25MB,我们使用 gzip 对其进行压缩,因此大小变为 5MB。
我们有多个服务,每个服务都包含@PostConstruct
加载(select * from table)常用数据来准备 map 以提高性能。
我们正在从每个服务中的 findall db 查询准备 map
@PostCounstruct
在里面(){
列表 list = xyzRepository.findAll();
Map
当调用 findById/findAll/findByList(List employees> emps) 时,用户会从 map 得到快速响应
我们的数据库每个月都会刷新/更新。刷新数据库后,我们将重新启动 spring boot 应用程序。
如果数据库在一个月内发生任何数据库刷新(由于某些问题/延迟),我们将面临的问题,我们需要重新启动服务器以获取正确的数据而不是陈旧的数据。
我们在每个服务中都尝试了 @Cacheable
,但是第一个数据库命中花费了太多时间。(因为我们正在从表中选择 *)。
我们进行并行 ajax 调用以获取数据。 应用程序仪表板需要绘制大约 30MB(gzip 5mb)的数据,这很痛苦..
约 2000 名用户申请 20 项服务.. 每个服务调用以获取数据(有些服务正在从 postcounstruct 中初始化的 map 获取静态数据)
目前,我们每月都会在数据库刷新时重新启动服务器。
当出现意外的数据库刷新时,我们如何在不重启服务器的情况下获取最新数据?
--------[编辑-1]-----
赞成的答案建议在每项服务中存在的每张 map 中填充新/更新数据。
1.应用程序启动时间会很长,因为 map 将从数据库中填充。
2.在 Java map 中以某个时间间隔(每晚/隔天/每周)填充/维护数据的开销。
如果每个集合/表中以及每个月都会增加更多数据会怎么样。
需要对赞成的答案进行专家评审。
感谢阅读问题😊
最佳答案
可以引入一些接口(interface)
interface Refreshable {
void refresh();
}
所有在后期构造期间进行数据缓存的bean都应该实现它
@Component
public class SomeDataProvider implements Refreshable {
...
@Override void refresh() { /*here refresh data*/ }
@PostConstruct
public void postConstruct() {
...
refresh();
...
}
}
现在暴露了你可以在数据库改变时调用的 rest 端点
@RestControler
public class ForceRefresh {
@Autowired
private List<Refreshable> refreshables; // here Spring will inject all services which can be refreshed
@PostMapping
public void forceRefresh() {
// refresh concurrently using common thread pool
refreshables.stream().parallel().forEach(Refreshable::refresh);
}
}
或者,您可以实现夜间重新加载,而不是 REST 端点,请参阅 @@EnableScheduling
和 @Scheduled
的 Spring 文档。
附带说明 - 使用 @PostConstruct
进行加载不是最佳方法,因为 Spring 在单线程模式下加载 bean。更好地实现 ApplicationReadyEvent
监听器,注入(inject) Refreshable
的列表,如上例所示,并使用线程池异步加载数据(==利用服务器上多个 CPU 的全部能力和在 Mongo 上)。
关于java - Spring boot - 如何通过每月数据刷新来改善应用程序的 api 响应时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62720607/