Spring 启动反应式缓存
Spring boot Reactive caching
在我的应用程序中,我正在使用 spring webflux,并且我正在使用 webclient 从某些第 3 方 API 检索详细信息。现在,我想将第一次 webClient 响应存储在内存缓存中,以便第二次我可以直接从缓存中获得这些响应。
我正在尝试在内存缓存机制和“caffine”中使用 Spring 引导。但是 none 正在按预期工作。
application.yml:
spring:
cache:
cache-names: employee
caffiene:
spec: maximumSize=200, expireAfterAccess=5m
EmployeeApplication.java:
@SpringBootApplication
@EnableCaching
public class EmployeeApplication{
public static void main(String[] args){
}
}
EmployeeController.java:
它有一个休息端点 employee/all
,可以从第 3 方 Api 获取所有员工。
EmployeeService.java:
@Service
@Slf4j
public class EmployeeService{
@Autowired
private WebClient webClient;
@Autowired
private CacheManager cacheManager;
@Cacheable("employee")
public Mono<List<Employee>> getAllEmployee(){
log.info("inside employee service {}");
return webClient.get()
.uri("/employees/")
.retrieve()
.bodyToMono(Employee.class);
}
}
虽然我已经配置了缓存名称,但是当我第二次点击 url 时,它正在调用服务方法。需要使用什么缓存机制来缓存 Mono 响应?请提出建议。
有几种缓存反应式发布者的选项。
- 使用反应式
cache
API 缓存 Mono
定义的持续时间
employeeService.getAllEmployee()
.cache(Duration.ofMinutes(60))
.flatMap(employees -> {
// process data
})
- 使用来自
reactor-extra
的 CacheMono
的外部缓存(Guava、Caffeine)。如果您需要根据不同的输入缓存结果(例如多租户环境),此选项更适合
这是 Guava 的示例,但您可以将其改编为 CacheManager
Cache<String, List<Employee>> cache = CacheBuilder.newBuilder()
.expireAfterWrite(cacheTtl)
.build();
Mono<List<Employee>> getEmployee(String tenant) {
return CacheMono.lookup(key -> Mono.justOrEmpty(cache.getIfPresent(key)).map(Signal::next), tenant)
.onCacheMissResume(() -> employeeService.getAllEmployee(tenant))
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> cache.put(key, value))
)
);
}
在我的应用程序中,我正在使用 spring webflux,并且我正在使用 webclient 从某些第 3 方 API 检索详细信息。现在,我想将第一次 webClient 响应存储在内存缓存中,以便第二次我可以直接从缓存中获得这些响应。 我正在尝试在内存缓存机制和“caffine”中使用 Spring 引导。但是 none 正在按预期工作。 application.yml:
spring:
cache:
cache-names: employee
caffiene:
spec: maximumSize=200, expireAfterAccess=5m
EmployeeApplication.java:
@SpringBootApplication
@EnableCaching
public class EmployeeApplication{
public static void main(String[] args){
}
}
EmployeeController.java:
它有一个休息端点 employee/all
,可以从第 3 方 Api 获取所有员工。
EmployeeService.java:
@Service
@Slf4j
public class EmployeeService{
@Autowired
private WebClient webClient;
@Autowired
private CacheManager cacheManager;
@Cacheable("employee")
public Mono<List<Employee>> getAllEmployee(){
log.info("inside employee service {}");
return webClient.get()
.uri("/employees/")
.retrieve()
.bodyToMono(Employee.class);
}
}
虽然我已经配置了缓存名称,但是当我第二次点击 url 时,它正在调用服务方法。需要使用什么缓存机制来缓存 Mono 响应?请提出建议。
有几种缓存反应式发布者的选项。
- 使用反应式
cache
API 缓存Mono
定义的持续时间
employeeService.getAllEmployee()
.cache(Duration.ofMinutes(60))
.flatMap(employees -> {
// process data
})
- 使用来自
reactor-extra
的CacheMono
的外部缓存(Guava、Caffeine)。如果您需要根据不同的输入缓存结果(例如多租户环境),此选项更适合
这是 Guava 的示例,但您可以将其改编为 CacheManager
Cache<String, List<Employee>> cache = CacheBuilder.newBuilder()
.expireAfterWrite(cacheTtl)
.build();
Mono<List<Employee>> getEmployee(String tenant) {
return CacheMono.lookup(key -> Mono.justOrEmpty(cache.getIfPresent(key)).map(Signal::next), tenant)
.onCacheMissResume(() -> employeeService.getAllEmployee(tenant))
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> cache.put(key, value))
)
);
}