Утечка ресурсов обнаружена при использовании Spring-Data-Redis на литейном облаке - PullRequest
2 голосов
/ 16 апреля 2019

Мы разрабатываем сервис весенней загрузки, который предлагает api rest (spring-webflux) и отправляет данные через RabbitMQ (spring-rabbit). Служба развернута на облачном литейном заводе, и мы используем spring-boot в версии 2.1.4. Мы добавили spring-boot-starter-data-redis, чтобы использовать redis для кэширования некоторых данных, и получили следующую ошибку:

[io.netty.util.ResourceLeakDetector] [] LEAK: HashedWheelTimer.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 
Created at:
    io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:284)
    io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:217)
    io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:196)
    io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:178)
    io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:162)
    io.lettuce.core.resource.DefaultClientResources.<init>(DefaultClientResources.java:169)
    io.lettuce.core.resource.DefaultClientResources$Builder.build(DefaultClientResources.java:532)
    io.lettuce.core.resource.DefaultClientResources.create(DefaultClientResources.java:233)
    io.lettuce.core.AbstractRedisClient.<init>(AbstractRedisClient.java:98)
    io.lettuce.core.RedisClient.<init>(RedisClient.java:87)
    io.lettuce.core.RedisClient.create(RedisClient.java:124)
    org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.lambda$createClient$7(LettuceConnectionFactory.java:971)
    java.base/java.util.Optional.orElseGet(Unknown Source)
    org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.createClient(LettuceConnectionFactory.java:971)
    org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.afterPropertiesSet(LettuceConnectionFactory.java:273)
    org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator.create(RedisConnectionFactoryCreator.java:88)
    org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator.create(RedisConnectionFactoryCreator.java:31)
    org.springframework.cloud.Cloud.getServiceConnector(Cloud.java:288)
    org.springframework.cloud.Cloud.getSingletonServiceConnector(Cloud.java:202)
    org.springframework.cloud.config.java.CloudServiceConnectionFactory.redisConnectionFactory(CloudServiceConnectionFactory.java:260)
    org.springframework.cloud.config.java.CloudServiceConnectionFactory.redisConnectionFactory(CloudServiceConnectionFactory.java:242)
    ...

Эта ошибка возникает только тогда, когда мы запускаем службу на литейном облаке, если мы запускаем ее локально, мы не получаем никакой ошибки.

Мы не делаем никакой конфигурации фабрики соединений или stringRedisTemplate на нашей стороне и используем только stringRedisTemplate, который настраивается с помощью Spring-Autoconfiguration. Мы используем следующую конфигурацию для redis на облачном литейном производстве:

@Configuration
@Profile( "cloud" )
public class CloudSpecificConfig extends AbstractCloudConfig {

   @Bean
   public RedisConnectionFactory redisConnectionFactory() {
      return connectionFactory().redisConnectionFactory();
   }
}

А вот так мы используем шаблон

@Component
@RequiredArgsConstructor
public final class RequestUtil {

   private final StringRedisTemplate myRedisTemplate;

   public String cacheId(String id, String value) {
      myRedisTemplate.opsForValue().set( id, value );

   }
}

Это наши весенние зависимости:

<properties>
  <spring-boot-version>2.1.4.RELEASE</spring-boot-version>
</properties>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-webflux</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-configuration-processor</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-sleuth</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-cloud-connectors</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-amqp</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
     <version>${spring-boot-version}</version>
  </dependency>

Мы смущены с нашей стороны, так как мы не делали никаких конкретных настроек на нашей стороне. Нам кажется, что с облачной конфигурацией пружины что-то не так. Мы делаем что-то не так? Нужно ли что-то настраивать по-другому? Это ошибка?

1 Ответ

0 голосов
/ 22 мая 2019

Это то, что я должен был сделать

Я посмотрю, смогу ли я найти более элегантный способ

@Bean(destroyMethod = "shutdown")
public DefaultClientResources lettuceClientResources() {
    return DefaultClientResources.create();
}

@SuppressWarnings("unused")
@Bean
public RedisConnectionFactory redisConnectionFactory(DefaultClientResources dependency) {
    return connectionFactory().redisConnectionFactory("redis-pcf-service");
}
...