如何使用 Spring Boot 为每个请求范围构建线程安全的内存缓存

How to build a thread safe in-memory cache per request scope with Spring Boot

我想在 Spring 引导应用程序中实现线程安全的内存缓存。基本上,每次收到请求时,我都需要从远程客户端请求信息,同时将响应保存在内存中,以便可以在流程的多个阶段通过我当前的请求重新使用它。我一直在浏览不同的方式,想找到最适合我的情况的想法

  1. 使用 ThreadLocal 保存我的上下文,因为 ThreadLocal 保持每个 request/thread 的上下文。但是,我 researched 并且觉得这种方法可能已经过时(主要在 2018 年之前讨论过,并且可能会导致 GC 泄漏问题(例如:如果在当前请求期间发生异常,而 ThreadLocal 内容没有机会 clear/evict)

  2. 使用 Google Guava 缓存,这是我目前的方法,它似乎工作正常,但我觉得它可能根据我的要求被过度使用,因为我的缓存主要是请求范围的。此外,我必须设置一个大容量,以防我的请求线程超过缓存容量,这可能会导致缓存内容被错误地失效(例如:如果缓存容量为 10,而我有 15 个请求,但是,前 10 个服务并存储到缓存中但未完成,其余 5 个请求可能会替换一些缓存内容,导致前几个缓存内容无效)

  3. 定义一个组件 class 并发 hashmap - 不幸的是,这个组件可能无法在多线程请求中工作并且难以管理容量。 (例如,我同时有 3 个具有相同身份密钥的请求 A、B 和 C,理想情况下,我只希望请求 A 进行内部调用,而请求 B 和 C 将从缓存中获取。但是,如果我的由 A 触发的内部调用需要时间,而 B 和 C 已经到达缓存位置,我看到 B 和 C 也进行了 2 个额外的内部调用)

有经验的也请不吝赐教,万分感谢!

我相信您可以尝试将 spring 缓存与带有范围 request_scope 和 sync=true 注释的自定义缓存管理器一起使用。这应该可以满足您的所有要求。