2019년 12월 6일 금요일

20191206 On Call


오늘은 자잘한 업무를 처리하느라 마이그레이션 작업을 진행하지 않으려고 한다.

MoM 진행하는 동안 업무일 기준으로 하루에 하나의 포스트를 작성하고자 하기 때문에 오늘은 회사의 제도 하나를 소개해보고자 한다. 마침 이번주에는 내가 On-Call이라 활동을 진행중이기도 하다.

LINE 서버 개발 부서들은 On-Call이라는 시스템을 가지고 있다.

On-Call 사전적인 의미를 찾아보면 다음과 같다.

If a worker such as a doctor is on call, he or she is available to work or make official visits at any time when needed:



간단하게 이야기해보면 필요한 상황에 바로 업무 대응을 있는 준비상태를 의미한다. 당직이나 당번이 이에 해당한다고 있고, 백엔드 개발자들이 주로 사용하는 의미는 업무시간 외에 서비스에 문제가 발생하거나 알람 등이 발생할 이를 먼저 판단하고 처리하는 역할 정도로 있을 같다.

그렇다면 팀에서는 어떻게 제도를 운영하고 있을까?

일단 한명이 1주일간 On-Call 진행한다. 그리고 아래의 사항들을 수행하고 있다.
  • 매일 아침 Server Daily Report 확인 하고 문제가 의심되는 로그를 분석해서 문제를 해결하거나 위임한다
  • 문자, 메일, 메신저, 슬랙으로 전달되는 시스템 WARN, ERROR, FATAL 로, 각종 알람을 확인하고 간단한 분석을 대화방에 공유한다
  • 날마다 쌓이는 다양한 로그들을 확인 로그의 레벨 조절하거나 메시지를 개선하는 등의 로그 개선 작업을 진행한다
  • 슬랙의 사내 문의 채널에 질문이 등록되면 먼저 확인해서 처리 혹은 위임한다

별로 역할이 조금씩은 다를 있겠지만 LINE 서버 개발 부서들은 대부분 비슷한 제도를 수행하고 있다고 있을 것이다.

다양한 업무를 하는 것으로 있겠지만, 핵심은 다음의 가지다.
  1. On-Call 기간 동안 다양한 경로로 시스템의 안정성을 모니터링
  2. 모니터링 결과 이상 신호가 감지되면 1 확인 처리 공유

24시간 서비스를 제공하는 메신저의 특성상 다양한 분서들이 모니터링을 진행하는데 서버 개발자들이 직접 봐야할 부분들을 서로의 시간을 나누어서 진행함으로써 나머지 인원들이 개발과 휴식에 집중할 있도록 한다고 있다.

문제를 파악하는 것과 그에 대한 1 조치를 취하기 위해서는 시스템의 전반을 이해하고 어떤 신호들이 존재하는지, 상황에 따른 대처 방법들은 어떤 것이 있는지를 알아야 한다. 따라서 팀에 합류한지 얼마 되지 않은 인원들은 기존 멤버와 함께 On-Call 진행하는 등의 과정을 통해서 적응에 필요한 시간을 가지고 있다.

On-Call 업무에 대한 회고를 정기적으로 진행하면서 효율성을 높이기 위한 방법들을 찾고 있으며, 만들어둔 On-Call 매뉴얼도 지속적으로 개선하고 있다.

20191205 Java11 마이그레이션 2일차


어제에 이이서 진행하는 프로젝트의 SDK 8에서 11으로 마이그레이션 하는 작업을 진행중이다.

어제 실패하는 testcase 수정하기 시작했고 하나씩 수정을 진행하고 있다.

오늘 수정한 첫번째 케이스는 내부적으로 사용하는 LanguageUtils라는 클래스의 Unittest인데, 자바의 Locale 활용해서 en-US 등의 문자열을 로케일 정보 등으로 변환하는 작업을 돕는 역할을 하는 클래스이다. 사용할 locale 문자열이 표준에 맞지 않은 경우들이 있기 때문에 이를 해결하는 휴리스틱한 코드들이 있고 이에 대한 테스트 케이스도 존재하는데 자바의 버전이 올라가면서 Locale 클래스에서 지원하는 언어나 국가들이 많아지게 되어 없는 Locale 이라고 생각하고 테스트 케이스를 만들었던 것들이 실패하게 것이다.

예를 들어 ka라는 언어 코드를 가진 Locale 8버전에는 없었으나 11버전에는 추가되어서 없을 경우를 가정한 테스트가 깨지는 등의 문제가 있었다.

테스트케이스 수정은 간단하게 진행할 있었다. 존재하지 않는 코드들을 찾아서 원래의 의도에 맞게 테스트를 통과할 있도록 수정했다.


나머지 테스트케이스들에는 문제가 없었기 때문에 여기까지 작업한 내용을 기반으로 Pull Request 만들어서 등록했다. 앞으로 필요한 작업은 베타 서버 한대에 배포해서 동작을 장기적으로 확인하는 일과 다른 모듈들도 제대로 동작하는지 검증하는 일이다.

2019년 12월 4일 수요일

20191204 Java11으로 가는 길


Java11으로 가는

사내에서 Java8에서 11으로 업그레이드 성능 향상에 대해 공유된 적이 있다. 유의미한 수준의 성능 개선을 확인할 있었다. 동안 Java 업그레이드 관련해서 언젠가 해야하겠다는 정도만 생각하고 있었는데, 실행해야겠다고 생각하는 계기가 되었다.

무엇보다 차세대 LTS 버전이 존재하는데 계속 이전 세대의 JDK 유지하고 있으면 유지보수에도 불리하기 때문에 업그레이드가 필요하다는게 팀원들 대부분의 의견이기도 했다.

Oracle Java SE Su ort Roadma 
Release 
6 
7 
9 (non-LTS) 
10 (non-LTS) 
It (LTS) 
12 (non-LTS) 
13 (non-LTS) 
GA Date 
December 
2006 
July 2011 
March 2014 
September 
2017 
March 2018 
September 
2018 
March 2019 
September 
2019" • 
Extended Support 
Premier Support Until 
December 2015 
July 2019 
March 2022 
March 2018 
September 2018 
September 2023 
September 2019 
March 2020 
Until 
December 2018 
July 2022 
March 2025 
Not Available 
Not Available 
September 2026 
Not Available 
Not Available 
Sustaining 
su 
Indefinite 
Indefinite 
Indefinite 
Indefinite 
Indefinite 
Indefinite 
Indefinite 
Indefinite


작업을 시작하기에 앞서 사내의 사례를 찾아봤는데, LINE Shop 케이스가 먼저 보였다



1 전에 작업 자바 유저 그룹에서 발표까지 내용이 있었고, 사내의 위키에는 자세한 내용들도 있어서 좋은 참고 자료가 되었다. 라인 메신저에 관련된 백엔드 대부분이 비슷한 인프라를 사용하고 있고 내부 구조도 거의 동일하기 때문에 shop 케이스는 우리에게도 수정 없이 적용할 있을 것이라 판단했다.

일단 간단하게 마이그레이션 작업을 측정하기 위해서 다음의 사항을 진행해보기로 한다.
  1. 메인 개발 장비인 IMac 업무 대응에 사용해야 하므로 Macbook Pro JDK11 설치한다
  2. 실패할 경우를 고려해서  SDKMAN으로 설치를 진행
  3. 로컬에서 프로젝트를 빌드할 있도록 작업
  4. unittest 모두 성공할 있도록 작업
  5. Integration Test 모두 성공할 있도록 작업
  6. 프로젝트가 정상적으로 기동하도록 작업
  7. E2E 테스트가 모두 성공할 있도록 작업

일단 위의 내용들이 모두 성공하면 마이그레이션이 가능하다고 판단할 있다고 생각한다. 이후 필요한 작업들은 마이그레이션 계획을 수립해서 팀에 공유하고 Beta -> Staging -> Release 환경으로 차근차근 진행하는 것이 필요하다고 생각한다.


첫날에 진행한 작업은 다음과 같다.

JDK11 설치 개발환경 세팅

먼저 맥북에 JDK11 설치했다. SDKMAN 이전에 설치해두었기 때문에 `sdk use` 명령으로 11 기본으로 사용하도록 하였고, IntelliJ에서 프로젝트 기본 SDK 11 사용하도록 수정했다.

컴파일 문제 해결

컴파일 과정에서 먼저 확인된 문제가 @Resource 어노테이션의 클래스를 찾을 없다는 문제였다. 해결방법을 찾아보니 dependency 추가해줘야 한다는 것을 있었다.

javax.annotation:javax.annotation-api

위의 dependency gradle 적당히 넣어주고 문제는 해결 있었다.

Unittest 문제 해결

Unittest 실행해보니 열개 조금 넘는 실패가 있었다. 첫번째로 문제를 확인한 것은 powerMock에서 에러가 발생하는 것이었는데 bytecode 조작에 사용되는 ASM 6.x 버전을 JDK11에서 지원하지 않아서 발생하는 것이었다. 해결책은 두가지가 있는데, 첫번째는 ASM7 사용하도록 하는 것이고 두번째는  powerMock을 제거하는 것이다.

예전부터 powerMock 필요한 상황은 아니라고 생각하고 있었기 때문에 이번 기회에 Mockito JUnit 기능들을 사용해서 powerMock 대치하기로 결정하였다.


향후 진행 과정을 여기에 하나씩 정리해볼 계획이다.




Man of Month를 마치며

벌써 2020년 1월 14일이다. 19년의 마지막 달에 Man of Month라는 팀의 제도를 시작한다고 했었는데, 12월이 지나고 그 다음 달도 거의 절반이 흐른 것이다. MoM을 시작하면서 하겠다고 계획했던 것들도 실제 한 것들과 비교해보니...