🆘 문제

<aside> ⚠️ PinPoint calltree 메서드별 분석 결과 지나치가 응답시간이 긴 트랜잭션의 경우, HikariCP의 ‘getConnection()’ 메서드에서 대부분의 응답시간이 소요됨을 확인했습니다.

</aside>

Untitled


👁‍🗨 분석

GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

<aside> 💡 서버에서 DB로 쿼리를 보낼 때 커넥션을 취득하는 과정에서 병목현상이 발생한다고 판단했습니다.

</aside>


🌟 시도

1. 토큰으로 유저정보를 조회할 때 로컬 캐시를 적용.

@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

  private final UserRepository userRepository;

  //  토큰에 있는 email로 유저 정보 조회
  @Override
  @Cacheable(cacheNames = "localCache", key = "#email")
  public UserDetails loadUserByUsername(String email) {
    User user = userRepository.findByEmail(email).orElseThrow(
        () -> new CustomException(ExceptionType.NOT_FOUND_USER_EXCEPTION)
    );
    return new UserDetailsImpl(user, user.getEmail());
  }
}

// -------------------------------------------------------------------
@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

@Bean
  public CacheManager localCacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager("localCache");
    cacheManager.setCaffeine(Caffeine.newBuilder()
        .expireAfterWrite(1, TimeUnit.HOURS)
        .maximumSize(200));
    return cacheManager;
  }

  @Bean
  public CacheManager redisCacheManager() {
    RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
        .fromConnectionFactory(redisConnectionFactory());
    return builder.build();
  }

  @Primary
  @Bean
  @Override
  public CacheManager cacheManager() {
    return new CompositeCacheManager(localCacheManager(), redisCacheManager());
  }

2. Hikari maximumPoolSize와 RDS MySQL max_connections 설정을 조절해 적절한 수의 커넥션 풀을 생성.