반면, 상용 서비스에서 통합 테스트 환경은 네이버 뉴스에서의 javadoc을 이용한 Functional Test 정도인 듯 하다. (소문에 따르면 지금은 사라졌다고 들었다).
http://d2.naver.com/helloworld/87523
지금 회사에 와서 서비스 개발하면서 가장 큰 수확은 바로 Spec By Example( 통합 테스트 환경)이었다. 수십 개의 컴포넌트가 유기적으로 동작하기 위한 테스트 환경이 Jenkins + Rspec을 기반으로 이미 구축되어 있었다.
(혹시,,
Rspec을 잘 모른다면, https://semaphoreci.com/community/tutorials/getting-started-with-rspec를 읽으면 좋은 시작점이 될 것이다.
Jenkins + RSpec 연동을 위해서는 https://sephinrothcn.wordpress.com/2014/04/24/run-rspec-with-jenkins/을 참조하면 좋을 것 같다)
(참고로 Rspec 말고도 최근에는 여러 Spec By Example 프레임워크가 나오고 있다.)
Ruby를 전혀 몰랐지만, Rspec을 통한 테스트 환경이 얼마나 서비스를 강력하게 만드는지 깨닫게 되었다.
격리된 환경에서 수십 개의 컴포넌트(자바 서버, MariaDB, Redis, ES, Mongo 등등......)에 수천 개의 시나리오 테스트가 동작하는 구조로 튼튼한(robust)할 수 있었다.
- 최대한 상용 환경과 비슷하다.
- 리눅스, Mac OS에서 잘 동작한다.
- 인수 인계 문서가 필요없다. 시나리오 코드가 결국 어떻게 동작되는지를 설명한다.
- 코드 리팩토링하더라도 Spec 이 깨지는 일을 찾아내 문제를 빨리 해결할 수 있다.
- API를 기반으로 하기 때문에 스토리지를 변경하는 마이그레이션(Migration)을 쉽게 할 수 있다.
- 버전 별 API가 진행된다.
- 운영을 하지만, Spec이 있기 때문에
- Continuous Deployment의 근간, Continous
이외에 수 많은 장점이 있었다.
수천 개의 테스트를 시퀀셜(sequencial)로 진행될 때 가상 장비에서 50분이 넘어가기 시작했다. 이를 위해 병렬로 테스트를 진행하려 했지만, Rspec의 이슈가 아니라 수 천개의 테스트를 돌리다보니 서비스의 제약 사항을 넘지 못해 병렬로 진행하는 것은 실패했다.
중형 장비를 사용해 50분의 소요시간을 20분대로 줄였다.
이후, 시간이 흘러 Spec By Example 코드가 많아지면서 중형 장비가 다시 57분이 되었다.
이를 해결하기 위해 여러 개발자와 함께 Docker와 Redis를 준비했다.그래서 8~9분 대로 줄어들도록 진행했고, Continuous Delivery(테스트가 성공되면 자동 개발 서버 배포)를 진행시켰다. 만족도는 좋았다!!!
Devops의 시간을 절약했다!!
이제 그 얘기를 진행한다.
보통 Continuous Integration, Continuous Delivery, Continous Deployment의 근간은 Spec By Example이라고 생각한다. 그리고, 절제된 아키텍처가 필요했다.
Docker를 활용했지만, Docker의 이미지에 모든 것을 넣지 않았다. 변경이 자주 될만한 컴포넌트와 변경이 자주 안될만한 컴포넌트로 나눴다.
변경이 자주 되지 않은 이미지를 Docker 이미지로 만들었다. 무척 큰 용량의 이미지가 생성된다.
- Docker 이미지를 생성한다
- Docker 이미지를 registry에 업로드한다.
- Docker 이미지를 테스트 중형 서버에 배포된다.
Jenkins에서 Job이 돌면서 Docker에 추가될 부분을 추가하고 여러 중장비에 Docker 이미지를 잘 사용할 수 있도록 했다.(정확히 말하면 병목 지점을 최대한 병렬화했다)
- 소스 커밋이 되면, Jenkins job 실행한다. (multijob + multijob)
- Job 실행시 docker 이미지를 사용해서 여러 데몬을 띄워 최대한의 성능을 낸다.
- 결과를 취합한다. (rspec + redis)
(주의할 사항은 Docker가 메모리 사용량이 높기 때문에 메모리에 대한 관리가 특별히 필요하다)
- 수천 개의 테스트를 모두 통과(정상)하면 개발 서버에 자동으로 배포한다. - Continuous Delivery
그리고, 여러 대의 중장비에 수십 개의 테스트 환경으로 분할할 때는 제대로 만든 분배 알고리즘이 만들었고, 잘 동작했다.
이를 기반으로 QA없이 테스트를 진행하고 빠른 Spec By Example을 통해 배포 시간을 최대한 줄였다.
배운점 :
1. 병목부분을 정확하게 아는 것이 중요하다.
2. Docker, RSpec, Jenkin가 무엇인지 아는 것은 쉽지만, 제대로 아는 것은 쉽지 않다.
Docker를 무조건 이미지로 만들고 다운로드하는 것은 Continuous Integration에 적합치 않을 수 있다.
효율적인 구조로 만드는 개선 노력이 필요하다.
3. Docker를 여러 대의 중장비에 수십 개의 테스트 환경(Spec By Example)으로 동작시킬 때는
중장비를 사용하는 것이 좋다.
소감 : 외국의 모델을 따라하는 게 아니라, 세계에 없는 우리 만의 모델을 만들었다는 점에서 기분이 좋았고, DevOps 사례로 남을 듯 하다.
다음 시도 : 일부러 프레임워크를 쓰지 않았다. robust한 환경을 위해 Mesos + Marathon 대신 Google의 Kubernetes를 적용해서 반-자동화를 테스트해보고 적용할 예정이다.