뭐요

업무정리, 그리고 서버 장애 회고 본문

Activity/Smart Olive

업무정리, 그리고 서버 장애 회고

욕심만 많은 사람 2023. 5. 27. 16:46

현장실습 종료까지 실근무일이 정확히 14일 남았다..!

3월에 입사하고나서, 월차를 안쓰고 모아놨는데 앞으로 퇴사까지 주에 한 번씩 쉴 수 있게 되었다. 사실 특별한 이유가 있어서 월차를 안쓰고 모아놓은 것은 아니다. 다만 월차의 맛을 알아버리면 평일 내내 쉬고싶다는 생각을 할까봐 안썼는데 지금 생각하니 정말 잘한 선택이다.

현장실습을 하면서 네이버 공채, 우테캠, 카카오브레인 패스파인더에 지원했는데 매번 코딩테스트에서 벽을 느꼈다. 역시 무슨 일이든 미리미리 준비하면 좋은 거 같다..^^ 꾸준히 준비했다면 더 많은 기회를 잡을 수 있었겠지만 이미 지나가버린 일에 대한 후회는 접어두고 열심히 PS 해야겠다.

회사를 다니면서 공부하기가 여간 쉬운 것이 아니라는 말을 체감하는 요즘이다. 퇴근하면 약간의 보상심리가 작용해서 쉬어도 되지 않을까 라는 생각을 한다.. 하하. 또 출퇴근 시간 동안 지하철에서 사람들 사이에 낑겨 오면 체력적으로도 힘들어서 밥 먹고 앉으면 눈이 감긴다.

그치만 PS, 개인 프로젝트에 투자할 시간을 확보하기 위해선 쉴 수가 없다. 오늘도 월차쓰고 집 앞 카페에 와서 공부하는데 이게 썩 나쁘진 않은 걸 보니 전공 하나는 잘 선택했다고 느낀다.

빈도수가 잦아진 DB 서버 과부하


근무중인 당사의 서비스는 3개의 웹 서버가 존재해서 L4를 통해 로드밸런싱을 한다. 또한 DB 서버는 2개가 존재하는데 Master/Slave로 이중화 해서 사용중이다.

전자식권의 특성상 식사시간 대에 사용자 트래픽이 몰릴 수밖에 없는데, 최근 한달간 2번이나 서버가 다운되었다. 지금까지 2~3달에 한번 발생한 현상이라고 하는데 그럴 때마다 단순히 아파치를 내리고 톰캣을 restart 했다고 한다(……… 왜 해결책을 찾으려는 노력을 안하는지 의문이다…!).

DBA가 따로 없었기도 하고 사실상 백엔드 개발은 나 혼자 하고 있기 때문에 해결할 사람이 나밖에 없었다. 그렇다고 현장실습생인 나에게 해결할거라는 기대는 하지 않는 모습이 나를 더 자극했다. 꼭 해결하고 싶어서 이리저리 원인을 분석했다.

원인을 분석하기 전에 상황부터 정리했는데 다음의 두 가지 단서가 존재했다.

  1. 11시 37분부터 CPU 사용량 급증
  1. 11시 37분부터 Disk I/O read 급증

특정 기능이 장애인 경우

갑작스럽게 CPU 사용량이 급증한 건 특정 기능에서 반복적으로 서버에 부하를 주는 것이 아닐까 생각했다. 매번 트래픽이 몰리는 점심시간, 저녁시간에 장애 현상이 발생했다고 하니 먼저 사용자 앱 서버와 식수 센싱기 서버 모듈의 로그를 뒤져보았다.

장애가 발생한 시간에 거의 모든 로그에 다음의 Error 문구를 확인할 수 있었다.

### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Too many connections

해당 로그를 통해 왜 Disk I/O read가 급증했는 지 알 수 있었다. 이제 DB 서버에 문제가 있다는 사실을 확인했으니 어느정도 갈피를 잡은 느낌을 받았다. 하지만 서비스의 규모가 매우 컸기 때문에 사용자 앱 모듈과 식수 센싱기 모듈로 의심 범위를 한정한다 해도, 어디에서 장애가 발생했는지 알아 내기엔 모래사장에서 바늘찾기 라는 말이 참 잘어울렸다. 이렇게 주먹구구식으로 찾는 방법은 시간 낭비라고 생각해서 다른 방법을 찾아보았다.

지인 찬스

급박했기에 고민할 충분한 시간이 없었다. 스트리밍 관련 스타트업에서 백엔드 개발자로 열심히 성장 중인 학교 선배한테 도움을 구했다.

위 대화에서 어느정도 힌트를 얻었다. DB 서버에서 connection이 과도하게 일어났기 때문에 처리가 될때까지 해당 connection이 wait 상태에 있었고 wait 상태인 동안 쓰레드를 잡고 있었으니 CPU 사용량이 급증했음을 알 수 있었다.

(아직 근본적인 해결 방법을 찾진 못했다..)

connection은 왜 꽉찼을까

  1. max-connection 설정

DB 서버에 설정되어 있는 max-connection을 확인했다.

아키텍처든 코드든 퀄리티적으로 마음에 드는 구석 하나 없었기 때문에 솔직히 default value로 설정되어있을 줄 알았는데 다행히 그건 아니었다. max-connection이 300으로 설정 되어있었는데, 다음의 reference를 참고하여 max-connection을 늘렸다. https://releem.com/docs/mysql-performance-tuning/max_connections

(하지만 max-connection을 늘리는 것은 근본적인 원인 해결이 아니라 임시 방편의 해결책이다.)

  1. slow query

DB에 데이터가 점점 쌓이면서 원래도 느리던 query들이 더 느려지지 않았나 의심했다. slow query를 찾아야겠다고 생각했다.

병목현상을 야기하는 slow query 찾기

자 이제 병목현상을 찾아볼까?

구글링을 해보니 mysql에서 slow query에 대한 로그만 따로 남길 수 있도록 옵션을 지정할 수 있음을 알게됐다. 당연히 설정이 되어있겠지?! 하며 호기롭게 설정을 확인했지만 해당 옵션이 OFF 였다..!

하하.. 그래서 직접 쿼리 응답 시간이 8초 이상인 경우 로그를 기록하도록 설정해두었고, 다음번에 한번 더 장애가 발생해서야 slow query log를 확인할 수 있었다.

고작 이것 때문에..?

결론부터 말하면 INDEX 설정이 안되어있었다.

slow query log를 확인하고 나서 쉽게 원인을 알게 되니 너무너무너무 허무했다. 사용자가 식사 결제를 할 때 본인의 바코드를 검색하는데 이 때 바코드에 INDEX 설정이 되어있지 않았기 때문에 약 10초 이상 걸렸다. 다음은 문제의 query이다.

SELECT T.ticketCode
FROM HIS_EMP_POINT H
JOIN TBL_EMP_TICKET T
ON H.ticketId = T.ticketId
WHERE H.barcode = '000029570033011136311'
AND H.historyType = 'USE'
ORDER BY T.ticketCode DESC LIMIT 1;

단순히 바코드에 INDEX를 생성해주니 10초 이상 걸리는 query가 1초만에 끝났다.

칼럼 하나에 INDEX 생성을 안해줬다고 이런 문제가 생겼다니 놀라웠다. 간단한 문제여서 금방 해결해 다행이긴 하지만 한편으로는 너무 아쉽다. 이렇게 빙빙 돌아올 문제가 아니었는데 지금까지 이거 하나 때문에 자사 서비스는 막심한 손해를 봤을 것이다.

해결하면 엄청 뿌듯하고 후련할 줄 알았는데 아쉬운 마음에 기분이 썩 좋진 않았다. 회사에 충분한 백엔드 인력이 있었으면 훨씬 더 빠르게 해결할 수 있었을 것이다.

또한 추후에 개인 프로젝트에서 만든 서비스를 배포하게 되면 데이터독 같은 모니터링 툴로 꼭 관리해주는 것이 좋겠음을 느꼈다.

직원 조회 불가능


*** 담당자가 직원 포인트 충전을 위해 직원 목록을 조회하면 아무 것도 안뜬다고 합니다. CM -> 충전관리 -> 포인트 충전/사용하기 담당자 : *** 매니저(010-????-????)

위의 내용으로 CS가 들어왔다. 사실 사소한 CS여서 정리할 것도 없지만 깔끔하게 잘 답변해서 기록한다!

CS 답변

James님 해당 CS건의 원인은 다음과 같습니다.

  • 관리자는 특정 부서를 관리합니다.
  • 관리자는 본인이 관리하는 부서 내의 직원만 포인트를 충전시킬 수 있습니다.

FLOW

  1. 관리자 *** 님은 26개의 부서(마케팅본부, 임상실 등등)를 관리합니다.
  1. 찾고자 하는 직원 ??? 님의 부서는 마케팅1팀 입니다.
  1. *** 님은 마케팅1팀을 관리하지 않습니다.
  1. 관리자 *** 님 계정으로는 ??? 님을 포인트 충전/사용하기 페이지에서 조회가 불가능합니다.

따라서 *** 님이 관리하는 부서에 마케팅1팀을 추가해야만 조회가 가능합니다.

'Activity > Smart Olive' 카테고리의 다른 글

현장실습 마지막 회고, 후기  (2) 2023.07.18
업무 정리 및 회고 (5)  (0) 2023.04.16
업무 정리 및 회고 (4)  (0) 2023.04.02
업무 정리 및 회고 (3)  (0) 2023.03.17
업무 정리 및 회고 (2)  (0) 2023.03.11