2021년 회고 및 새해 다짐

2020년 회고 밎 새해 다짐 포스팅을 올린지 벌써 1년이 지났는데요,

밀린 업무를 처리하느라 눈코뜰새 없던 2021년 이었던것 같습니다. 중간중간 번아웃이 올 뻔한적도 있었지만 어찌어찌 극복하여 올 한 해도 잘 마무리 한 것 같습니다.

체감상으로는 시간이 몇 달 정도 밖에 지나지 않은 것 같은데 나이를 먹어갈 수록 시간이 정말 빨리 자나간다는 것을 몸소 체험하고 있는 요즘입니다.

각설하고, 작년에는 올해 Morden PHP 도입을 소망했었는데, 올해 얼마나 목표를 달성했을까요?

 

우선, Morden PHP 도입은 성공적이었습니다. 2021년 6월부터 라라벨 프레임워크 기반 백엔드 API를 설계하여 8월부터 실 서비스에 적용하기 시작했습니다.

오래된 서비스에 라라벨을 적용하는 작업은 쉽지 않았습니다. 라라벨은 기존 쿠키 방식의 세션을 사용하지 않기 때문에 레거시 세션을 연동하는 드라이버를 개발해야 했으며, 인증 드라이버 역시 라라벨의 것을 이용할 수 없어 그누보드용 인증 드라이버를 개발하여야 했습니다. 이 과정에서 에반스님이 올려주신 gnu-migration 프로젝트를 많이 참고하였습니다. (이 자리를 빌어 에반스님께 감사드립니다)

이후 주문서, 장바구니, 상품 등 주요 기능을 하나씩 라라벨 API로 이전하였습니다. 그리고 신규로 프로젝트의 대부분은 라라벨 기반 API에서 진행하였습니다.

그 결과 2021년 12월 현재 회사 서비스의 약 10% 비즈니스 로직이 Morden PHP로 구현이 되었습니다.

10% 정도라면 매우 적은 수치일 수 있겠지만, 오랜 기간 동안 유지보수가 이루어지던 서비스였고 대부분 Model 1의 낡은 코드에 기반한 서비스를 이정도로 개선했다는 것만으로 놀라운 성과라고 생각합니다.

 

대부분의 개발자는 낡은 레거시 코드를 유지보수하기 싫어합니다. 레거시 코드 기반으로 신기능을 추가하고, 유지보수를 한다는 것은 개발자 입장에서 괴로운 일이고 커리어에도 도움이 되지 않는 일입니다. 개발자 커뮤니티에는 새로 출근한 회사가 10년이 넘은 레거시 코드로 운영되는 모습을 보고 3일만에 추노했다는 도시전설(?)까지 있을 정도니 말 다한 셈입니다.

하지만, 개발자가 항상 신기술만 다루며 일을 할 수 있을까요? 아무리 최신 프레임워크와 패러다임을 이용하여 서비스를 만들었다고 해도 그 서비스로 뚜렷한 성과나 매출을 기대하기 힘들다면 기술이 아무런 소용이 없는 일입니다. 레거시 코드로 10년 이상 유지가 되었다는 것은 그 서비스의 업력과 실적이 그만큼 탄탄하다는 반증입니다.

이 글을 보시는 개발자분들께서도 레거시를 만난다면 회피하기보다는 기회를 봐서 과감하게 환경을 바꾸어 보라고 말씀을 드리고 싶습니다. 길가에 떨어진 쓰레기를 치우는 시민의식이 있다면 거리가 늘 깨끗해지듯이, 레거시를 맞닥뜨리게 되면 과감하게 개선하는 문화가 자리잡는다면 개발자들이 일하기 좀 더 편해지지 않을까요?

 

아무튼, 2022년부터는 새로운 API에 더 많은 기능을 추가하고 기존 레거시에 구현되어 있던 기능들도 마이그레이션이 진행될 예정입니다. 그렇게 된다면 저희 회사에 새로운 인원이 합류하였을 때 백엔드 구조를 이해할 필요 없이 가져다 쓰기만 하면 되기 때문에 업무 효율이 극대화되게 됩니다. 앱 개발자는 백엔드 기술에 대한 이해 필요 없이 앱 개발에만 집중할 수 있으며, 프론트엔드 개발자는 PHP나 SQL을 할 줄 몰라도 디자이너가 작업한 멋진 디자인을 프론트 기술을 활용하여 빠르게 실서비스에 적용할 수 있습니다.

탄탄한 기초 위에 멋진 건물이 지어질 수 있듯이, API가 탄탄한 기초 역할을 하여 저희 회사가 멋진 플랫폼 기업으로 성장할 수 있는 기반이 되기를 소망합니다.

Laravel API 고도화 레거시

대용량 스토리지 서버 이전 작업

 

회사가 운영하고 있는 서비스에 많은 기능들이 추가되고 이용 고객들이 날로 늘어나다 보니 서버 업그레이드에 대한 소요가 지속적으로 제기되었습니다.

기존에 운영하고 있던 스토리지 서버도 훌륭한 스펙을 갖추고 있었지만 상기의 문제들로 점점 한계에 부딪혔습니다.

그래서 몇 달 전쯤 새로운 스토리지 서버를 추가적으로 도입하였고, 이전까지 성공적으로 마무리하였습니다.

회사 보안상 자세하게 밝힐 수는 없지만 대략적인 과정을 블로그를 통해 공유하고자 합니다. ^^

 

먼저 기존에 운영하고 있던 스토리지 서버는 다음과 같은 문제를 내포하고 있었습니다.

 

  • 디스크 I/O 과부하
  • 디스크 공간 부족
  • 비SSD (하드디스크 드라이브)
  • OS 지원 중단

 

회사가 운영중인 서비스에는 상품 판매를 위한 이미지, 사이즈별 썸네일, 첨부파일 등 자잘한 파일이 수십TB를 이루고 있었습니다.

그리고 모든 서버가 해당 스토리지에 연결되어 하루에도 수십GB 분량의 파일을 썼다, 지웠다 등의 작업이 발생하고 있는 상황이었습니다.

그 상황에서 대용량 SSD가 탑재된 신규 스토리지로 이전 작업을 해야 하는데, 요구조건은 아래와 같습니다.

 

  • 서버 이전 도중 서비스 부하를 최소한으로 한다.
  • 서버 이전 도중 서비스 중단이 없도록 한다.


서버 이전을 위해 실제로 서비스중인 서버를 종료하고 수 시간에 걸쳐 데이터를 신규 서버로 복사하고 서버를 부팅하는 방식으로 작업을 진행한다면, 이는 서비스의 중단으로 이어지고 곧 매출에 부정적인 영향을 미칠 수밖에 없습니다.

따라서, 대규모 서비스에서 서버를 업그레이드하거나 이전하는 작업은 무중단 작업이 필수불가결한 부분일 수밖에 없습니다.

 

절차는 아래와 같습니다.

 

1. 먼저, 기존 서버에 동작하고 있던 Batch Job이 있다면 먼저 내리도록 합니다.

기존 스토리지 서버에는 더 이상 필요가 없어진 파일을 자동으로 삭제하거나, 자동으로 백업하는 batch job이 있었습니다. 이러한 부분이 있다면 사전에 중단하여 신규 서버 이전 도중 데이터 불일치가 발생할 여지를 최소화 하도록 합니다.

 

2. 신규 서버로 전체 복제를 1회 실시합니다.

1차적으로 기존 스토리지에 있던 파일을 신규 스토리지 서버로 복사합니다. 복사는 리눅스의 rsync를 사용하였습니다.

$ rsync -aPvz --delete --bwlimit=4096 /복제할소스 사용자명@신규서버주소:/복제할목적지

bwlimit 옵션을 주면 일정 대역폭 이내에서 파일을 전송하게 됩니다. 기존 스토리지가 하드디스크 드라이브였기 때문에 부하를 최소화하기 위함입니다.

만약 rsync 복제가 실패한다면 873번 포트가 허용되어 있는지 확인하고, 차단되어 있다면 이를 허용해주도록 합니다.

$ firewall-cmd --permanent --zone=dmz --add-port 873/tcp
$ firewall-cmd --reload

 

3. 신규 서버로 증분 / 실시간 동기화를 실시합니다.

rsync로 파일 전체 복제를 1차적으로 마무리 하였더라도 기존 스토리지에는 지속적으로 파일 쓰기/삭제가 발생하고 있기 때문에 결과적으로 기존 스토리지와 신규 스토리지의 데이터는 달라질 수밖에 없습니다.

불일치한 데이터를 맞추기 위해 lsyncd를 활용할 것입니다.

 

lsyncd는 우리가 흔히 사용하는 원드라이브, 구글드라이브 등의 동기화 프로그램을 PC에 설치하면 PC의 내용을 클라우드 서버로 자동을 전송하는 것처럼 양 서버간의 불일치한 데이터를 동기화 시켜주는 강력한 도구입니다.

lsyncd는 양방향/단방향 동기화가 가능하며, 여기서는 단방향 동기화 설정을 하여 서버 이전작업을 진행할 것입니다.

 

먼저 기존 스토리지 서버에 lsyncd가 설치되어 있지 않다면 면저 설치해 주도록 합니다. (기존 스토리지 서버가 동기화 서버가 될 것입니다)

$ yum install lsyncd

 그리고 /etc/lsyncd.conf 설정파일을 편집하여 아래와 같이 설정해줍니다.

...
sync {
   default.rsync,
   delete=true,     # 원본(소스) 파일이 삭제될 경우 목적지 서버의 파일도 함께 삭제됩니다.
   source="복제할소스디렉토리",
   target="복제할타겟디렉토리::타겟서버rsync공유이름",
   exclude={"제외할디렉토리"},
   rsync = {
    archive = true,
    compress = false,
    whole_file = false
   },
   delay=0
}

 그리고 lsyncd 서비스를 시작해 줍니다.

$ systemctl start lsyncd

동기화 서버 설정이 끝났다면 동기화 클라이언트 (복제 대상 목적지) 설정을 할 차례입니다.

신규 스토리지 서버에서  /etc/rsyncd.conf 를 아래와 같이 설정합니다.

...
[rsync공유이름]
# destination directory
path = /공유할디렉토리
# Hosts you allow to copy (specify source Host)
hosts allow = 허용할IP
use chroot = yes
uid = root
gid = root
read only = false

설정이 완료 되었다면 서비스를 기동합니다.

$ systemctl start rsyncd

이제 lsyncd는 기존 스토리지 서버의 파일과 신규 스토리지 서버의 파일을 서로 비교하여 불일치한 부분만 자동으로 동기화 할 것입니다.

동기화 진행 상황은 로그파일 /var/log/lsyncd.log 에서 확인할 수 있습니다.

(최초에는 양 서버간 불일치 파일을 확인하기 때문에 시간이 오래 걸립니다)

 

4. 동기화가 맞추어지면, 신규 스토리지 서버로 최종 변경합니다.

3번까지 진행했다면 대부분의 이전 작업은 마무리 된 것입니다.

이제 가장 서비스 이용량이 적은 시간대 (주로 새벽)에 서비스를 잠시 내리고 (1분 이내) mount point 등 기존 서버에 연결되어 있던 경로를 신규 서버로 맞추어주면 되겠습니다.

이 때, 각 서버들의 서비스 설정파일, 서비스 코드 내 경로를 콘솔이나 에디터로 미리 변경해놓고 동시다발적으로 배포 및 서비스 재기동을 실시하여 다운타임을 최소화 할 수 있도록 합니다.

그리고 기존 서버에 동작하고 있던 Batch job도 신규 서버에 맞게 수정하여 다시 등록하면 되겠습니다.

 

이상으로 대용량 스토리지 서버 이전 작업에 필요한 사항을 간략하게나마 적어 보았습니다.

대부분 위와 같은 시나리오대로 진행하면 되지만, 실무에서는 예기치 못한 상황이 언제든지 발생할 수 있습니다.

예를 들면 이전한 서버가 예상대로 동작하지 않는 경우가 있을 수 있는데, 이를 대비해서 언제든지 이전을 중단하고 기존 서버로 복구할 수 있는 절차도 마련해 두시는 것을 권장합니다.

 

물론 작업에 필요한 사항은 보고서, 계획서로 정리하여 사전에 충분한 검토를 거친 후 시행하는 것이 좋겠습니다.

감사합니다.

서버이전 리눅스 무중단

2020년 회고 밎 새해 다짐

참으로 오래간만에 포스팅을 하게 되었습니다.

눈 감았다 떠보니 2021년이 되어 있을 정도로 정신없이 일했던 것 같습니다.

 

전 직장에서는 보안장비에 올라가는 관리자 화면을 개발했습니다.

제품의 특성상 회사의 핵심적인 업무가 아니었기 때문에 웹 개발자로서 성장의 한계를 체감하였습니다.

신기술 도입에도 인색하여 변변한 사내 업무관리 시스템이나 버전 관리 시스템 조차도 없어서

이메일과 공유폴더로 업무를 관리하다 보니 업무 효율도 시대에 뒤떨어지는 부분이 많았습니다.

 

반면에 현재 다니는 회사에서는 Notion으로 모든 프로젝트와 일정, 문서를 관리하고 있습니다.

참고: 스타트업, 더 좋은 문서도구가 필요해요! Notion을 만나다. | by seapy | 당근마켓 팀블로그 | Medium

 

기존에는 Jira+Confluence 로 협업시스템이 구성되어 있었습니다만, 최근 업데이트 이후 전체적으로 굼뜨고 무거워지는 문제가 생겼습니다.

그 바람에 대체할 솔루션을 찾고 있던 도중 Trello를 알게 되었고, 잠시 Trello로 일정관리를 하다 이번에 최종적으로 Notion에 안착하였습니다.

협업 툴을 변경하자는 제안을 대표님께서 혼쾌히 수락해주시고, 동료들도 새로운 도구를 익히는데 불편함을 감수해 준 덕분입니다.

 

회사가 운영하고 있는 서비스에도 많은 기능들이 추가되었습니다.

그 중 주요한 것을 뽑자면 아래와 같습니다.

  • 해외 수출을 위한 검역신청관리기능
  • 1:1 상품문의 기능 (like 네이버 톡톡상담)
  • 서비스내 상품광고기능 (키워드광고 등)
  • 이벤트 로깅 시스템
  • 상품후기 시스템 개선 (포토후기 등)
  • 상품 추천시스템 개발
  • 신규상품 등록 키워드 알림기능
  • HTML5 기반 상품 이미지 업로더 도입

 

뿐만 아니라, 서비스 아키텍처 구성에도 큰 변화가 있었습니다.

  • 더 많은 부분에 Redis 캐시 도입
  • 서버 증설 및 PC/모바일 웹서버 분리
  • MySQL 신규 Replication 서버 구성
  • 이미지 서버 증설 및 무중단 데이터 이전
  • 비동기 방식 상품이미지 업로드 시스템 도입

 

2019년과 2020년은 실무에서 좌충우돌하는 성장의 기간이였다면,

2021년에는 그동안 계획했던 Modern PHP의 도입, CI/CD 등 서비스/개발프로세스 고도화의 한 해가 되기를 소망합니다.

회고