FitPass 트러블 슈팅

김규현·2025년 6월 27일
0

문제 상황. 1

검색 기능에서 데이터를 찾는 방법으로 쿼리문을 작성을 했을 때 다른 방법들도 있다는 것을 알게 되어서 @Query, QueryDSL, QueryMethod 등등 방법이 있는 것을 알게 되어서 다른 방법으로 작성을 생각 하던 중 QueryMethod를 사용을 해보자는 생각으로 코드를 작성 막연하게 모든게 변경이 가능 할 것 이라는 생각으로 시작.

문제 분석


@Query("SELECT g FROM Gym g WHERE g.name LIKE %:keyword% AND g.deletedAt IS NULL")
Page<Gym> findByGymName(@Param("keyword") String keyword, Pageable pageable);

@Query("SELECT p FROM Post p WHERE p.gym.id = :gymId AND p.postType = :postType ORDER BY p.createdAt DESC")
List<Post> findByGymIdAndPostType(@Param("gymId")Long gymId, @Param("postType") PostType postType);

@Query("SELECT p FROM Post p WHERE p.postStatus <> 'DELETED' AND (p.title LIKE %:keyword% OR p.content LIKE %:keyword%)")
Page<Post> searchByTitleOrContent(@Param("keyword") String keyword, Pageable pageable);

여기서 첫번째 Query어노테이션과 두번째는 비교적 간단하고 해서 변경하는데 큰 어려움이 없었는데 세번째 Query어노테이션에서 변경이 가능하다고 생각을 하고 찾아 보던중에 문제가 발생

해결 방안

QueryMethod는 제한적인 것들이 많다는 것을 알게 되었고 여기서는 postStatus <> 'DELETED 라는 조건은 QueryMethod로 표현이 불가능.

쿼리 메소드로 최대한 표현을 할 수 있는 정도는

Page<Post> findByPostStatusNotAndTitleContainingOrContentContaining(PostStatus postStatus, String keyword1, String keyword2, Pageable pageable);

까지는 작성이 가능 하다.

하지만 이렇게 된다면 AND (...) 형태가 아닌 A AND (B OR C)로 해석이되서

PostStuatus가 아닌 경우이면서, 제목이나 내용 하나라도 키워드 포함인 모든 결과가 나오게 되어서 원래의도인 삭제되지 않은 게시글 중에 제목 또는 내용중에 keyword가 포함된 글을 검색 해야하는데 QueryMethod로 작성 하게되면 내용에 keyword가 포함된 게시글은 postStatusDELETED여도 포함될 수 있다.

그렇게 해서 모든 것을 바꿀 수 없어서 기존의 @Query를 사용해서 문제점을 해결 하는 방법을 선택 하게 되었다.

문제 상황. 2

예약 시스템 Reservation 에서 동일 한 자원 에 대한 여러 사용자가 동시에 예약을 시도하는 경우, 데이터 정합성이 깨지는 문제가 발생 하여서, 이를 해결 하기 위해서 DB구조를 Master-Replica 으로 구성하고, Redisson 기반 분산 락을 적용 하려고 기획

문제 분석

Replica.cnf

[mysqld]
log_bin = mysql-bin
server_id = 11
relay_log = /var/lib/mysql/mysql-relay-bin
log_slave_updates = 1
read_only = 1
default_authentication_plugin=mysql_native_password

이렇게 작성을 하여두었는데 Replica DB에서 봤을때 서버 아이디가 정상적으로 들어가지 않는 부분이 발생 read_Only 옵션이 있어서 였는지 확인 server_id 가 Master DB의 값과 같은 문제가 발생 강제로 값을 변경하고 DB를 껐다 켜지 않는 방법으로 해결하였다 근본적인 문제를 해결 했다기보다는 이해를 제대로 하지못해서 임시 방편으로 수정하는 방법을 선택했다.

이후에도

Slave_IO_Running : YES

Slave_SQL_Running : YES

DB 동기화에는 성공 했지만 MasterDB에 있던 값들이 ReplicaDB에 내용이 없다던지 작성을 해도 들어가지 않는 문제들이 있었다. 이 부분은 아직 정확히 Master, Replica DB분산을 이해 못한 문제에서 생긴문제였다.

해결 방안

공부를 하던중 아직은 Master-Replica의 사용 점을 정확히 이해하지못하고 구조를 이해하지못하여 추후에 조금 더 Master-Replica의 필요성과 사용법을 숙지 후 적용 계획

문제 상황. 3

prometheus + grfana 를 사용 하려던 중 연결 하는 부분은 어렵지 않게 성공을 했었는데 작동을 시킬려고 했을때 부분에 문제가 생겼었다. 연결이 잘 되었다고 생각했었는데 생각지 못한 부분에서 문제가 발생.

문제 분석

databases:
  my-db:
    dsn:

metrics:
  user_total:
    type: gauge
    description: Total number of users

queries:
  user_count_query:
    interval: 30
    databases: [my-db]
    metrics: [user_total]
    sql: |
      SELECT COUNT(*) as user_total FROM users

config.yml 파일을 만들어서 기본적인 쿼리를 넣어서 테스트 해볼려고 했는데 처음 연결 후에 prometheus를 봤을 때 user_total 이라는 쿼리가 없어서 연결 부분에서 잘못 되었다는 것을 인지

해결 방안

처음으로는 디렉토리 구조 volumes를 잘못 입력.

GRAFANA-PROMETHEUS-RDBMS/
├── grafana/
│   └── provisioning/
│       └── datasources/
│           └── datasource.yml
├── prometheus/
│   └── prometheus.yml
└── query-exporter/
    └── config.yml
volumes:
      - ./GRAFANA-PROMETHEUS-RDBMS/query-exporter/config.yml:/etc/query-exporter/config.yml 

이렇게 작성을 했어야 하는 부분을

volumes:
      - ./query-exporter/config.yml:/etc/query-exporter/config.yml 

이렇게 작성해서 제대로 찾지 못하는 부분이 발생하여 위에 처럼 수정을 하고 나서 다른 부분에서 작동오류가 발생 volumes 설정에 어려움이 있어서 다시 확인을 했을 때 위 처럼 작성해야 된다는 것을 다시 인지하게 됨

2025-06-24 09:11:14 [error    ] database error                 database=my-db                                                                                                                                                                 
query-exporter-dev  | Traceback (most recent call last):
query-exporter-dev  |   File "/virtualenv/lib/python3.13/site-packages/query_exporter/db.py", line 482, in connect                                                                                                                                                  
query-exporter-dev  |     await self._conn.open()                                                                                                                                                                                                                   
query-exporter-dev  |   File "/virtualenv/lib/python3.13/site-packages/query_exporter/db.py", line 346, in open                                                                                                                                                     
query-exporter-dev  |     self._create_worker()                                                                                                                                                                                                                     
query-exporter-dev  |     ~~~~~~~~~~~~~~~~~~~^^                                                                                                                                                                                                                     
query-exporter-dev  |   File "/virtualenv/lib/python3.13/site-packages/query_exporter/db.py", line 378, in _create_worker                                                                                                                                           
query-exporter-dev  |     assert not self._worker
query-exporter-dev  |            ^^^^^^^^^^^^^^^^                                                                                                                                                                                                                   
query-exporter-dev  | AssertionError

이러한 DB에 연결하지 못하는 상황 발생 이 부분은 연결 시점의 문제가 있어서


container_name: mysql-dev
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${DB_PASSWORD}" ]
      timeout: 20s
      retries: 10
      interval: 10s
      start_period: 40s
--------------------------------------------------------------------------------------------------
image: adonato/query-exporter     
    depends_on:
      mysql:
        condition: service_healthy

Docker Compose의 컨테이너 실행 순서만 제어할 뿐, 네트워크 연결이 완전히 준비되었는지 혹은 MySQL이 쿼리가 가능한 상태인지 보장을 하지 않음 따라서 정상적으로 DB가 준비되었는지 확인 후 실행 할 수 있도록 대기 로직을 추가해서 해결

0개의 댓글