简体   繁体   English

Spring Boot:设计一个缓存定时数据的服务

[英]Spring Boot: Design a service that caches timed data

I am developing a service using Spring Boot (with Java) and I have the following requirement: The service (when invoked) must generate a timed UUID associated with a string that I pass as input to the service.我正在使用 Spring Boot(使用 Java)开发一项服务,我有以下要求:该服务(在调用时)必须生成一个与我作为输入传递给该服务的字符串关联的定时 UUID For example, if I invoke the service like this (with a Http GET):例如,如果我像这样调用服务(使用 Http GET):

http://localhost:8080/myService?param=example http://localhost:8080/myService?param=example

The service returns me a UUID like 55bcbfce-8984-4f1d-8435-f9548baf8cb5.该服务返回一个 UUID,如 55bcbfce-8984-4f1d-8435-f9548baf8cb5。 The fact is that I want to implement a caching system that stores (for a limited time, like 5 seconds) this UUID along with the passed string example .事实上,我想实现一个缓存系统来存储(在有限的时间内,比如 5 秒)这个 UUID 以及传递的字符串example

So, a "table" stored in the application would be such a thing like this:因此,存储在应用程序中的“表”将是这样的:

UUID UUID param参数 duration期间
55bcbfce-8984-4f1d-8435-f9548baf8cb5 55bcbfce-8984-4f1d-8435-f9548baf8cb5 example 3sec 3秒
07ef2e6e-e6a1-45e7-b6a6-51dfab49f782 07ef2e6e-e6a1-45e7-b6a6-51dfab49f782 example2 2sec 2秒

Like this, a second service I call by passing it a UUID as input, like this:像这样,我通过将 UUID 作为输入传递给它来调用第二个服务,如下所示:

http://localhost:8080/mySecondService?UUID=55bcbfce-8984-4f1d-8435-f9548baf8cb5 http://localhost:8080/mySecondService?UUID=55bcbfce-8984-4f1d-8435-f9548baf8cb5

It could return me ( if invoked in the right time ) the param associated with the UUID 55bcbfce-8984-4f1d-8435-f9548baf8cb5, that is example .它可以返回给我(如果在正确的时间调用)与 UUID 55bcbfce-8984-4f1d-8435-f9548baf8cb5 关联的param ,即example If the time is up, then the second service returns an error.如果时间到了,则第二个服务返回错误。

My question is: is there an easy way to implement this WITHOUT USING A DB , but using just a small caching system (the memory will be shared between the two services?), I am new to both Spring Boot and caching.我的问题是:有没有一种简单的方法可以在不使用数据库的情况下实现这一点,而只使用一个小型缓存系统(memory 将在两个服务之间共享?),我对 Spring 引导和缓存都是新手。 and have never used cache before.并且以前从未使用过缓存。 I simply cannot use a DB in this situation.在这种情况下我根本无法使用数据库。

I suppose you have a DTO like this:我想你有这样的 DTO:

public record ResultDTO(String param, int seconds) {
}

You can use @Cacheable annotation that handles automatically the cache by configuring a CacheManager .您可以使用@Cacheable注释通过配置CacheManager自动处理缓存。 You can follow this tutorial .您可以按照本教程进行操作。 At the end the method will something like this:最后,该方法将是这样的:

@Cacheable("params")
public ResultDTO getByUUID(String UUID) {
    // your logic to retrieve the object
}

The code inside getByUUID is executed if the element having UUID input is not in the cache.如果具有UUID输入的元素不在缓存中,则执行getByUUID中的代码。

You can use a in memory cache implementation.您可以使用 memory 缓存实现。 A cache stores some data temporarily and typically has a feature that automatically removes data (expires) after some time duration.缓存临时存储一些数据,通常具有在一段时间后自动删除数据(过期)的功能。

Here is an example with cache2k :这是cache2k的示例:

    Cache<String, String> cache =
      Cache2kBuilder.of(String.class, String.class)
        .entryCapacity(5000)
        .expireAfterWrite(5, TimeUnit.SECONDS)
        .build();

    String myService(String param) {
      String uuid = generateUuid();
      cache.put(uuid, param);
    }

    String mySecondService(String uuid) {
      String param = cache.get(uuid);
      if (param == null) {
          // error
      }
      return param;
    }

With the code above the expiry is not happening exactly after 5 seconds but may lag around a second depending on system activity.使用上面的代码,过期不会在 5 秒后准确发生,但可能会延迟大约一秒,具体取决于系统活动。 If you want the item to be visible no more than 5 seconds, use this instead of expireAfterWrite :如果您希望该项目的可见时间不超过 5 秒,请使用它而不是expireAfterWrite

  .expiryPolicy((key, value, startTime, currentEntry) ->
    Expiry.toSharpTime(startTime + TimeUnit.SECONDS.toMillis(5)))

Make sure to make the entry capacity high enough, because otherwise the cache will evict data was not used recently.确保条目容量足够大,否则缓存会驱逐最近未使用的数据。

Do not use @Cacheable of Spring. It would only fit for mySecondService and not for the population of the cache.不要使用@Cacheable的 @Cacheable。它只适合mySecondService而不是缓存的数量。 So don't mix different API concepts.所以不要混用不同的 API 概念。

The approach is basically the same with other cache implementations.该方法与其他缓存实现基本相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM