[Release] develop 을 운영에 반영한다 - 관리자 페이지 개편, 배포 전 새 컨테이너 확인, 모니터링 알림, 훈장과 미션 문구 - #344
Merged
Merged
Conversation
- ci-prod 는 수동 실행이 아니라 main push 로 바로 배포를 시작하고, 이 워크플로를 기다리지 않는다 - 그래서 배포를 막는 것은 PR 단계이고, main 과 develop 의 branch protection 이 격리 환경 테스트를 required check 로 건다
[Chore] 격리 환경 테스트를 통과해야 main 과 develop 에 머지되게 한다
- ono-alerts.yml 규칙 7개는 평가되고 있었지만 prometheus.prod.yml 에 alerting 설정이 없어서 어디로도 가지 않았다. Alertmanager 를 붙이고 앱 에러 알림과 같은 DISCORD_WEBHOOK_URL 로 보낸다. 웹훅 주소는 설정 파일에 적지 않으려고 컨테이너가 뜰 때 환경변수를 파일로 옮겨 webhook_url_file 로 읽는다 - Redis 와 RabbitMQ 는 떠 있는데 수집을 안 해서 Dependency 대시보드 패널 4개가 항상 비어 있었다. redis-exporter 를 추가하고, RabbitMQ 는 이미지에 내장된 rabbitmq_prometheus 의 detailed 엔드포인트에서 큐별 적체와 컨슈머 수를 가져온다. 합계만 보면 큐 하나의 컨슈머가 죽어도 티가 안 나기 때문이다 - 5xx 비율은 단위가 0~1 인데 경고 기준이 5 라서 에러율이 100% 여도 초록이었고, 평균 응답시간은 기준이 5ms 라 평소에도 빨강이었다. 기준을 고치고 평균 대신 p50 을 둔다 - Server/Process Memory 패널은 JVM 이 내보내지 않는 process_resident_memory_bytes 를 그려서 실제로는 mysql-exporter 메모리를 보여주고 있었다. JVM 메모리로 바꾸고, CPU 도 호스트 전체가 아닌 앱 프로세스 기준으로 바꾼다 - 하루 요청의 96% 가 스캐너라 요청 지표를 /api 로 한정하고, 행동 지표에서는 security_rejected, not_found, unmapped_request 를 뺀다. 트래픽이 적어 5분 창은 너무 튀기 때문에 1시간 창으로 보고 p99 는 뺐다 - 외부 API 성공률은 호출이 없으면 0% 빨강으로 보였다. 호출이 없을 때는 값을 비우고 호출 없음으로 표시한다 - promtail 이 Loki 자기 로그를 수집해서 하루 로그의 97% 를 차지하고 있었다. 수집 대상에서 빼고 Alertmanager 로그를 넣는다 - 배포와 모니터링 재시작 워크플로에 새 컨테이너를 추가하고, restart-monitoring 의 .env.prod 에 빠져 있던 DISCORD_WEBHOOK_URL 을 넣는다 Closes #335
[Chore] 모니터링 알림을 디스코드로 연결하고 대시보드의 빈 패널과 틀린 값을 고친다
- read 부터 서버에 저장된 적 없는 refresh token 으로 토큰 갱신 경로가 1002 로 답하는지 본다. 서버는 저장 전에 끝나서 쓰기가 없다 - full 에서 이미지 업로드 URL 발급과 오답노트 등록, 조회, 삭제, 404 를 확인한다. X-App-Version 헤더로 XP 적립을 막는다 - 흔적이 남는 GET(presigned URL)은 full 에서만 재시도 없이 보내고, refresh 는 확인용 토큰만 허용한다 - nginx 전환 직전에 새 컨테이너를 확인하는 pre_switch_check.sh 를 추가한다 (actuator health 후 새 포트로 read) - 자체 테스트 42개에서 64개, README 와 smoke-test.yml 의 서명 키 설명을 실제 설정에 맞게 고친다
- healthy 확인과 nginx 전환 사이에서 pre_switch_check.sh 를 부르고, 실패하면 새 컨테이너를 이름으로 지우고 배포를 끝낸다 - 새 컨테이너가 남으면 다음 배포가 현재 색을 잘못 읽을 수 있어서, 지우지 못하면 에러로 남긴다 - 배포를 끝내지 못하면 prod-latest 를 이전 색이 돌리던 이미지로 되돌린다 - 돌고 있던 앱이 없던 복구 배포는 확인이 실패해도 경고만 하고 전환한다 - refresh 서명 키는 서버와 같은지 아직 확인되지 않아 전환 전 확인에는 넘기지 않는다
[Feat] 스모크 테스트가 토큰 갱신과 오답노트 등록을 보고, prod 배포가 nginx 전환 전에 새 컨테이너를 확인한다
- 평균 응답시간은 분모를 clamp_min(…, 1e-9) 에서 > 0 으로 바꾼다. 앱이 재시작되면 같은 라벨의 요청 수는 그대로인데 시간 합만 늘어나는 경우가 있어서, 요청 수 증가량 0 을 1e-9 로 바꿔 나누면 1,250만 ms 같은 값이 나왔다. 이제 그 URI 는 값을 비운다 - 외부 API 성공률은 호출이 없을 때 "최근 1시간 호출 없음" 이 임계값 기준색(빨강) 위에 떴다. null 매핑으로 회색을 준다 - Redis 히트율은 인증 요청마다 로그아웃 토큰과 탈퇴 사용자 블랙리스트를 조회하고 두 키 모두 대부분 없는 것이 정상이라 5% 안팎이 평소 값이다. 경고색을 없애고 패널 설명에 이유를 적는다 Closes #338
[Chore] 대시보드 평균 응답시간, 외부 API 성공률, Redis 히트율 패널의 값과 색을 고친다
- 로그인 성공 시 세션 유휴 만료를 24시간으로 늘린다 (설정이 없어 톰캣 기본값 30분이 적용되고 있었다) - 로그인 유지 쿠키를 붙여 배포로 컨테이너가 바뀌어도 24시간 동안 다시 로그인하지 않는다 - logoutUrl 에 전체 URL 이 들어가 어떤 요청과도 맞지 않던 설정을 경로로 고친다 - 로그인이 풀린 채 관리자 화면을 열면 JSON 401 대신 로그인 화면으로 보낸다 - 관리자 화면의 유저 삭제 엔드포인트를 없앤다
- 온보딩 페이지의 브랜드 초록(#1cba1a)과 회색 바탕 위 흰 카드 구성으로 공통 스타일을 만든다 - 사이드바, 페이지 이동, 탭 밑줄, 숫자 카운트업, 화면 전환 효과를 공통 조각과 스크립트로 둔다 - 페이지 링크가 지금 걸린 필터를 유지하도록 AdminPager 를 추가한다 - 공지는 실사용자 전원에게 뜨므로 걸기 전과 내리기 전에 한 번 더 확인받는다
- 유저 목록에 검색과 가입 경로 필터, 정렬 7종을 넣고 상세를 치장, 업적, 미션, 스터디룸까지 탭 7개로 나눈다 - 복습 기록을 mission_log 대신 problem_solve 기준으로 바꾸고 복습노트 상세 화면을 추가한다 - 오답노트와 복습 기록, 복습노트 목록에 날짜와 유저, 상태 필터를 넣는다 - 스터디룸 상세에 챌린지, 공유 문제와 댓글, 피드, 주간 리포트를 추가한다 - 미션, 업적, 치장 현황 화면을 새로 만든다 - 통계를 사용자, 학습, AI 분석, 성장, 스터디룸으로 나누고 재방문율과 고착도, 직전 기간 비교를 넣는다 - 날짜별 표의 숫자를 누르면 그날 목록으로 이동한다 - 권한 테스트에 새 엔드포인트와 공지 엔드포인트를 넣는다
- 그리드 안 두 번째 카드에만 위 여백이 붙어 나란한 박스 높이가 어긋나던 규칙을 고친다 - 화면이 뜬 뒤 카드를 투명하게 되돌리던 등장 효과와 숫자 카운트업을 없애 이동할 때 깜빡이지 않게 한다 - 탭과 세그먼트를 화면이 그려지기 전에 붙이고, 페이지 전환은 브라우저 기본 교차 전환만 짧게 쓴다 - 로고를 OnO 전체 브랜드색으로 칠한다 - 데스크톱은 사이드바를 접고 펼 수 있고 상태를 기억한다. 모바일은 상단 메뉴로 여닫는 서랍으로 바꾼다 - 미션 달성률을 시작한 유저 대비 달성으로 이름을 바꾸고 계산 기준을 적는다
- 출시 때 섞인 게스트와 스모크 테스트용 게스트가 지표를 부풀려서 모든 집계 쿼리에 같은 조건을 붙인다 - 조건은 AdminSqlFilters 한 곳에 두고 통계, 홈, 유저, 학습 기록, 스터디룸, 성장 집계에 적용한다 - 목록의 행과 상세 화면은 그대로 두고, 게스트 수와 비율 지표는 없앤다 - 게스트가 만든 데이터가 집계에서 빠지는지 영역별 테스트를 추가한다
- 관리자 컨트롤러의 인자 없는 LocalDate.now() 를 Asia/Seoul 기준으로 바꾼다 (PersistenceRulesTest 위반) - 로그인 없이 관리자 화면을 열면 로그인 화면으로 보내는 동작을 AuthApiTest 에 반영하고, 화면이 아닌 요청은 401 인지 따로 확인한다
[Feat] 관리자 페이지 개편 (디자인, 로그인 유지, 데이터 조회, 통계)
- 훈장 설명 12개를 숫자로 바꾸고 말투를 담백하게 고친다. 새벽반과 올빼미는 판정 시간(SolveScan 의 05~08시, 00~03시)을 설명에 적는다 - 미션 제목 6개는 V47 마이그레이션의 UPDATE 로 바꾼다. V30, V33 을 고치면 이미 적용된 환경에서 Flyway 체크섬이 어긋난다 - 테스트 시드가 V47 까지 읽게 하고, 옛 문구를 비교하던 테스트를 새 문구로 맞춘다 Closes #341
…copy [Chore] 훈장 설명과 미션 제목의 한글 수를 숫자로 바꾼다
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✔️ 연관 이슈
develop 에 쌓인 PR 6개를 운영에 반영합니다. 연결된 이슈(#332, #333, #335, #338, #340, #341)는 모두 닫혀 있습니다.
📝 작업 내용
read를 먼저 돌립니다. 실패하면 새 컨테이너만 내리고 이전 버전이 계속 받습니다.👤 사용자 영향
🔌 API 호환성
앱이 부르는
/api/**는 응답 문자열 값만 바뀌고 필드는 그대로입니다. 바뀐 엔드포인트는 관리자 화면(/admin/**,/login)뿐입니다.🗄️ DB migration
없음
있음: V47 하나입니다.
V47
use_digits_in_mission_titles:mission_definition의title6행을UPDATE ... WHERE code = ...로 바꿉니다. 스키마 변경은 없고 code, 목표값, 보상은 그대로라 진행도에는 영향이 없습니다.🔐 인증/권한
관리자 세션 만료가 30분에서 24시간으로 늘고 로그인 유지 쿠키가 생깁니다(#342). 관리자 엔드포인트 인가 테스트는 새 동작에 맞춰 고쳐져 있습니다.
✅ 검증 결과
979fb1b) 기준 GitHub CI격리 환경 테스트가 통과했습니다.CI Build & Deploy Dev성공).🚀 배포 리스크
deploy-prod.yml(수동 배포)이 우회로입니다. 맥미니 러너에서는 아직 돌려 보지 않았고, python3 3.9 이상이 없으면 스모크만 건너뛰고 경고를 남깁니다.↩️ 롤백/대응 방법
prod-latest를 이전 이미지로 되돌리게 해 두었습니다.UPDATE하는 마이그레이션을 새로 올리면 됩니다. 문구만 다른 거라 급하게 되돌릴 일은 없을 것 같습니다.Restart Monitoring Stack워크플로를 돌리면 됩니다.JWT_REFRESH_TOKEN_SECRET과APPLICATION_PROD안의jwt.refreshToken.secret이 같은 값인지 확인해 주세요. 다르면 배포 뒤 스모크가1001로 실패하고 매시 알림이 울립니다(배포는 막히지 않습니다).