백엔드 개발자의 진로

일의 범위

백엔드 개발자는 현업에서 실제 무슨 일을 하고 어떤 일을 할 수 있나요?

'백엔드 개발자'가 담당하는 일은 범위가 넓습니다. 사용자에게 보이는 웹 어플리케이션 개발뿐만 아니라 데이터 분석을 위한 엔지니어링, 분산파일시스템이나 DBMS와 같은 제품을 만드는 개발자들도 백엔드 개발자라 불리기도 합니다. '웹 프런트엔드 개발자', '모바일앱(iOS/Android) 개발자' 에 비하면 그 대상이나 하는 일이 상대적으로 모호합니다. 어플리케이션을 개발하는 백엔드 개발자는 프로젝트에 따라서는 서버관리, DB관리, 프런트엔드 개발까지 모두 담당하기도 합니다. 현대 야구가 발전하면서 선발/중간/마무리 투수가 구별된 것처럼 이전에는 백엔드 개발자가 다 하던 일이 분업화된 영역도 있습니다.

이렇듯 백엔드 개발자는 폭넓은 기술을 접할 수 있는 역할을 수행합니다. SE(System engineer), FE(Front End) 등 인접한 분야의 개발자와 소통할 기회가 많습니다. 그리고 접한 분야 중 한 분야에 대한 전문성을 키울 수 있는 기회를 만나기도 쉽습니다. 예를 들면 담당하는 서비스의 통계 모듈 개발로 시작해서 대용량 데이터를 다루는 데이터 엔지니어로 성장하는 경우입니다.

특화된 분야의 전문가로 성장하더라도 어플리케이션을 잘 개발하는 능력은 중요합니다. 다른 개발자가 사용하는 플랫폼이나 라이브러리의 개발도 어플리케이션 개발의 특성을 이해해야 적용하기가 편리한 인터페이스를 설계할 수 있습니다. 대용량 데이터 분석이나 처리를 담당하는 개발자라도 업무 효율화를 위해 모니터링, 관리 도구를 만들어야 할 때도 있습니다. 그래서 깊이 있는 전문분야와 함께 어플리케이션 개발 능력을 갖춘다면 더욱 유능한 개발자가 될 수 있습니다. 남은 질문에 대한 대답들은 백엔드 어플리케이션 개발 분야에 초점을 맞춰서 드리고자 합니다.

보람과 고충

백엔드 개발을 할 때 가장 어려운 점과 백엔드 개발을 하면서 느낀 매력은 무엇인가요?

개발 프로젝트 팀을 음악 밴드에 비유하자면, 인프라 담당자와 백엔드 개발자는 드럼이나 베이스 기타와, 프런트엔드 개발자는 보컬이나 퍼스트 기타와 비슷하게 느껴집니다. 무대에서 주목받고 찬사를 받기 쉬운 쪽은 보컬이지만 베이스와 드럼이 안정적으로 뒷받침하지 못하면 좋은 공연이 나올 수 없습니다.

백엔드 개발자는 시스템을 안정적이고 효율적으로 만들 때 보람을 느낍니다. 사용자가 갑자기 몰려와도 에러 없이 서버 프로그램이 실행될 때, 성능을 획기적으로 개선했을 때, 모듈의 구조를 개선해서 코드를 많이 줄였을 때가 그런 경우입니다. 문제가 생기지 않을 때에는 겉으로 잘 드러나지 않는 영역일 수도 있습니다. 내면적인 부분까지 완성도를 추구하는 사람이 백엔드 개발을 하기에 더욱 적합합니다.

서버 프로그램은 24시간 실행된다는 점이 백엔드 개발자들에게는 고충이기도 합니다. 긴급한 상황에 대비하기 위해서 노트북 컴퓨터를 항상 가지고 다니는 사람이 많습니다. 회식자리에서도 노트북을 켜고 장애 상황에 대응하는 경우도 있습니다. 그런 부담을 줄이기 위해서 규모가 큰 서비스에서는 당번(oncall)을 정해서 통상적인 휴식 시간대에는 돌아가면서 대응을 하기도 합니다.

향후 전망

다양한 도구와 프레임워크가 개발되고 있는 상황에서 백엔드 개발자의 미래는 어떻게 될지 백엔드 개발에 어떤 비전이 있다고 생각하시나요?

새로운 도구와 프레임워크로 인해 개발자의 수요나 가치가 하락하지 않을까 하는 우려도 있습니다. 하지만 현장에서 느껴지는 바로는 우리가 해야할 과제가 늘어가는 속도에 비하면 도구 등에 의한 생산성 증가 속도는 오히려 느리다고 느껴집니다. 새로운 시스템에 대한 수요와 유지 보수할 기존의 시스템도 늘어만 간다는 느낌입니다. 혁신에 투자할 수 있는 여력을 가진 사회라면 S/W개발자에 대한 투자는 계속 증가할 것이라고 전망합니다. 새로운 도구/프레임워크는 기존의 문제를 해결하고 개선하기 위해 나온 것입니다. 기존의 기술을 쓰면서 깊이 있는 고민을 한 사람이라면 새로운 도구에 더 빨리 적응하고 응용할 수 있을 것입니다. 따라서 새로운 도구와 프레임워크들도 기존의 개발자에게 더 큰 기회가 될 수도 있습니다.

다만 개발 분야에 따라서는 흥망성쇄가 엇갈릴 수도 있습니다. 예를 들면 이전에는 Flash기반의 UI개발에 대한 수요가 많았습니다. 하지만 HTML 내부에서 화려한 UI를 구현할 수 있도록 기술환경이 변화되면서 이전만큼 Flash 개발자를 찾지 않게 되었습니다. 모바일에서 Symbian OS를 바탕으로 개발을 했던 분들 익숙했던 개발플랫폼이 저물어가는 모습을 지켜봐야 했습니다.

지금까지는 개발자에 대한 수요가 계속 늘었기에, 개발분야를 바꿀 수 있는 기회도 많았습니다. 기존 기술을 깊이 있게 이해한 분들은 새로운 환경에서도 뛰어난 개발자로 정착하는 모습을 많이 봤습니다. Flash에서 사용하는 ActionScript를 잘 쓸 수 있었던 개발자들이 웹FE개발자로 전환하는 경우는 많습니다. Android 초창기에는 같은 Java 언어를 썼던 서버개발자보다 FE개발자 출신 분들이 훨씬 빠르게 적응한다는 이야기를 들었었습니다. UI에 대한 패턴, 프로그래밍 모델들은 기존에 FE 개발을 하신 분들에게 익숙한 것이었기 때문입니다.

기존에 있던 개발 분야들도 깊게 발전하면서 이전에 없던 전담자가 생기고 있습니다. 하지만 한번 맡은 분야를 끝까지 담당한다는 보장은 없습니다. 실무에서는 갑자기 새로운 업무가 필요해졌을 때 사람이 채용될 때까지 기다릴 수도 없습니다. 그래서 새로운 개발분야에 적응할 수 있는 역량은 키워두는 것이 좋습니다. 지금 하는 업무와 연관성이 있는 분야에 관심이 있다면 그런 준비가 자연스럽게 이루어질 수 있습니다.

백엔드 개발은 여러 분야와 연결되기에 그런 면에서 무난한 선택입니다. 포용하는 분야가 많고, 이론과 실무경험이 잘 조화될 수 있기 때문입니다. RDB, TCP/IP, OS, 통계 등의 바탕이 되는 지식들은 몇십 년 전부터 축적되면서 발전된 것들입니다. 그래서 실무에 들어가기 전에 학교에서부터 준비할 수 있는 지식이 많기도 합니다.

머신러닝이나 빅데이터 기술의 발달이 백엔드 개발에 어떤 영향을 미칠 것으로 예상되나요?

해당 분야들은 급격한 수요 증가로 인해 여러 방면으로 전문가를 수혈하고 있습니다. AI같은 분야는 학교에서 이론적으로 준비가 된 분들이 회사에 들어오는 경우가 많아 보입니다. 기존에 백엔드 개발을 하시던 분이 해당 서비스의 필요해 의해 해당 분야의 전문가로 성장한 경우도 있습니다. 예를 들어 어떤 서비스의 추천 모듈을 1~2명이 개발하다가 고도화를 위해 전담 팀을 따로 분리한 경우도 있습니다.

백엔드 개발을 하다가 데이터 분석, 모델링 업무에 참여하는 경우도 더 늘어날 것 같습니다. 이론적인 바탕이 튼튼하더라도 특정 분야에 의미있는 분석/모델링을 하기 위해서는 그 도메인을 이해하는 것이 중요합니다. 서비스를 개발하면서 사용자의 특성을 이해한 개발자가 이론적인 깊이까지 갖춘다면 가치가 더 높아질 수 있습니다.

직접적으로 분석/모델링을 수행하지 않더라도 많은 백엔드 개발자는 이를 뒷받침하는 개발을 하게 될 것입니다. 예를 들면 깊이 있는 데이터 분석을 위해서는 데이터를 단순히 RDB같은 하나의 저장소에 쌓아두는 것만으로는 부족합니다. 이전에는 그냥 버렸던 로그성 데이터들도 어떻게 활용할 수 있을지 분석하기 좋게 저장을 할지 고민을 더 하게 되었습니다. 데이터를 다른 저장소로 옮기는 일도 용량이 클 때는 쉬운 일이 아닙니다. 무엇보다 해당하는 서비스가 많은 사용자와 데이터를 받을 정도로 운영되어야 머신러닝 같은 고급기법으로 분석할 만큼 많은 데이터가 쌓일 것입니다. 넓게 보면 대용량의 서비스를 개발하는 백엔드 개발자는 AI/빅데이터와 시대의 과제와 맞닿아 있습니다.

다른 분야로의 확장

백엔드 개발이라는 포지션에서 다른 영역(경영, 기획 등)에 관여하는 게 현실적으로 가능한지

프로젝트에 따라서는 서비스/제품의 기획 단계에서 개발자의 의견이 많이 반영됩니다. 개발자가 사용하는 플랫폼을 만들 때에는 더욱 그러합니다. 개발업무를 개선하기 위해 만드는 자동화 도구들, 모니터링 도구들도 큰 방향성을 잡는 사람은 개발자일 수 밖에 없습니다. 비개발자들이 사용하는 서비스들도 최근 들어서도 개발자의 의견이 많이 반영되고 있다고 느낍니다. 특히 구체적인 데이터 구조를 고려하는 백엔드 개발자가 초기에 의견을 주면 효율적인 방향으로 기획이 이루어질 가능성이 높아집니다. 기획자, UX설계자 역할을 하시는 분들 중에서도 개발자 출신들이 있기도 합니다.

'경영'의 영역에 관여하는 것은 개발 조직에서 조직장이 하는 역할입니다. 어떤 일에 어느 정도의 투자를 하고, 사람을 얼마나 채용할지, 어떻게 보상을 할 건지가 모두 경영적인 판단이라고 할 수 있습니다. 개발자 중 일부는 그런 역할을 하는 사람이 될 수도 있습니다. 하지만 그런 일이 모든 사람의 적성에 맞는 일은 아닙니다. 조직장은 기술뿐만 아니라 사람 사이의 일에 관심을 깊이 가져야 잘 할 수 있는 일이라고 생각합니다. 뛰어난 개발자가 사람 사이의 문제를 잘 해결할 수 있으리라는 보장은 없습니다. 기술을 깊이 파고 널리 쓰이는 프로그램을 만들고 지식을 잘 전파하는 일에서 행복을 더 느끼는 개발자들이 더 많을 것 같습니다. 그런 일로도 긍정적인 영향력을 크게 미친다면 조직 내에서 중요한 존재로 대우받을 것입니다.

백엔드 개발에 필요한 지식

백엔드 개발을 하려면 어떤 지식이 중요하고 무엇을 기본적으로 알아야 할까요? 백엔드 개발 전문가는 어떤 언어, 툴, 주제를 공부하고 개발하나요? 프로젝트 스킬셋을 결정하는데 고려되는 부분들은 어떤 것들이 있나요?

백엔드 개발에서 중요하다고 생각되는 지식이 무엇인지에 대해서 많은 분들이 질문해 주셨습니다. 저는 주로 JVM과 Linux를 바탕으로 한 환경에서 서버 모듈 개발을 했습니다. 그래서 앞으로 이어지는 이야기에서 여러 기술 생태계를 다양하게 담지는 못했다는 점을 감안해 주셨으면 합니다. 웹 서버를 개발할 때는 아래와 같은 요소들이 우선 떠오릅니다.

  • 웹 생태계의 스펙
    • HTML, HTTP(1.1 , HTTP/2)
  • 기본 SDK, 라이브러리/프레임워크 이해와 활용
  • 클라이언트를 위한 API 설계
  • 서버/컴퍼넌트/객체 간의 역할 분담/의존성/통신 방법 설계
  • 저장소 활용
    • DBMS 설계
    • Cache 적용
      • Global/Local cache 적용범위, 라이프 싸이클, 솔루션 선택
    • 파일 저장 정책/솔루션 선택 활용
  • 검색엔진 연동 방식 결정
  • 빌드 도구
    • Maven/Gradle
  • 배포 전략
  • 성능 테스트/프로파일링/튜닝
    • JVM 레벨의 튜닝 (GC 옵션 등)
      • 웹 서버(Nginx,Tomcat)등의 설정/튜닝
    • OS 설정의 주요 값 확인
  • 인접 기술에 대한 이해
    • DBMS, Front End 등
  • 서버 개발자에만 해당하지는 않는 항목
    • 테스트 코드 작성/리팩토링 기법
    • 버전 관리 전략
      • branch 정책 등

개발자 한 명이 위에 언급한 모든 요소를 깊이 잘 알아야 프로젝트에 참여할 수 있어야한다는 의미는 아닙니다. 팀을 이룬 개발자들의 지식들이 합쳐져서 구현 방식과 정책이 결정됩니다.

프로젝트의 스킬셋을 정할 때에도 보통 구성원 중 적어도 한명은 경험이 있는 기술들을 택합니다. 사용자가 많은 서비스라면 프로그램이 돌아가는 만드는 것만이 목적이 아니기 때문에 기술의 선택에 더 조심스러워집니다. 운영환경에서의 모니터링과 문제해결까지 팀 구성원이 할 수 있는 기술을 선택합니다. 내부의 소수만 사용하는 관리 도구를 만들 때는 상대적으로 부담 없이 팀원 모두가 처음 쓰는 기술을 적용하기도 합니다. 새로운 기술은 위험성이 적은 서비스에 적용해서 경험을 키운 이후에 큰 서비스에 적용을 합니다.

데이터베이스

데이터베이스를 어디까지 알아야하나요?? 데이터베이스를 어떻게 활용하는 것이 효율적인가요? 쿼리를 어떻게 만들고 튜닝해야할까요?

사용자의 요청량과 저장 용량이 많은 서비스에서는 하나의 저장소만을 쓰지는 않습니다. 네이버의 서비스에서도 MySQL, CUBRID, Redis, Memchaced, HBase, MonoDB, Elasticsearch 등 다양한 저장소를 활용하고 있습니다. 네이버와 라인에서 Arcus, Elasticsearch, Cassandra, Redis, HBase와 같은 다양한 저장소가 쓰인 사례는 아래 글을 참고하실 수 있습니다.

다양한 저장소가 쓰이는 시대에도 RDB(관계형 데이터베이스)는 여전히 가장 우선시되는 저장소입니다. 그래서 RDB를 잘 다루는 능력은 백엔드 개발자의 핵심 역량 중 하나입니다. 개발을 하는 도중에도 쿼리의 호출 횟수나 실행 계획이 비효율적이지 않은지 확인하는 습관이 필요합니다. 운영 중에도 느린 쿼리를 모니터링하고 DBA와 협업하여 성능 개선을 하는 작업을 실무개발자들은 꾸준히 하고 있습니다. ORM같은 추상화된 프레임워크를 써서 직접 SQL을 작성하지 않는 경우에도 그런 작업들은 더욱 중요합니다.

대용량 서비스들을 보면 DB 쿼리를 만드는 스타일이 과거와는 달라졌습니다. 과거에는 서버 간의 네트워크 호출 비용을 줄이기 위해 굉장히 많은 테이블을 한번에 조인하는 긴 SQL을 만드는 경우가 많았습니다. 하지만 요즘은 복잡한 JOIN은 가급적 피하는 경향이 생겼습니다. 데이터를 조회하는 SQL이 단순할수록 데이터를 다른 저장소에 캐시하거나 분산해서 저장하기가 쉬워집니다. 대용량을 저장하는 UGC 서비스에서는 RDB 테이블 사이의 JOIN은 최대한 제약을 하고 어플리케이션 레벨에서 여러 저장소의 연관된 데이터를 조합하기도 합니다.

Stored prodecure도 가급적 사용하지 않는 경우가 많습니다. DB안에서 실행되는 Stored procedure는 급하게 개발된 서비스에서는 많이 사용되었습니다. 네트워크 호출비용이 없어서 성능에 이득이 있고, DB안에 저장되니 배포절차가 단순했기 때문입니다. 그러나 길게 작성된 Stored prodecure는 만들었던 사람도 수정하기 힘든 경우가 많습니다. 데이터와 독립적으로 로직을 테스트하기도 어렵습니다. 별다른 배포절차가 없으니 버전관리가 제대로 되지 않는 경우가 많았습니다. 그리고 데이터의 연산에 DB서버의 CPU 자원을 소모함으로서 서비스가 커가면서 DB에 병목이 될수 있는 가능성을 더 키울 수 있습니다. 이런 이유로 초기에 Stored procedure로 개발했던 로직을 어플리케이션 단으로 빼는 작업이 서비스가 성장하는 과정에서 흔하게 일어납니다.

DB서버 1대로 트래픽이나 저장량이 감당이 안 될 때, 이떻게 이를 분산할지도 항상 어려운 과제입니다. 성능 향상을 위해서 Local cache, Global cache를 동원하기도 합니다. 어느 정도 복제지연(Replication replay)이 그다지 민감하지 않은 서비스에서는 쓰기 작업은 Master 노드로, 읽기작업은 복제되는 Master의 데이터를 복제한 여러 대의 Slave로 DB를 구성하기도 합니다. 총 저장되는 용량이 많을 때에는 여러 개의 DB인스턴스에 이를 나누어서 저장하기도 합니다. 이를 샤딩이라고 부르는데 Sharding Platform에서 자세한 개념을 참조하실 수 있습니다. SpiderMySQL fabric와 같은 솔루션으로 샤딩을 할 수 있고 네이버 내부에서는 이런 용도로 자체 개발한 Nbase-T라는 저장플랫폼을 쓰고 있습니다. 샤딩의 기준이 되는 키가 명확하면 나누어서 저장하기가 상대적으로 쉽습니다. 개인화 서비스의 경우에는 사용자의 ID별로 샤드키를 잡으면 자연스럽습니다. 그런데 샤드키를 어떤 것으로 잡아야 할지 명확히 확신이 서지 않는 서비스가 있을 수 있고, 중간에 샤드키를 바꾸는 비용은 굉장히 큽니다. 어떤 솔루션을 쓰든 RDB는 사용량이 늘어났을 때 분산하는 비용이 비쌉니다. 그래서 성장할 가능성이 큰 서비스라면 RDB의 자원을 아껴서 쓸 필요가 있습니다.

개발툴

Jenkins, AWS 등 Backend에 도움이 되는 도구를 배웠지만 도구를 배운다는 게 과연 실력을 키우는 것인지는 의문입니다.

개발도구를 잘 활용하는 능력은 생산성과 직결되기에 중요합니다. 그런데 개발도구를 '배워야'하는 개발자보다는 스스로 익힐 수 있고, 적절한 도구를 선택할 수 있는 개발자가 현장에서는 필요합니다. 특정 개발도구를 익혔다는 사실은 단기적으로는 실력이라고 할 수 있습니다. 새로운 도구가 나왔을 때도 적응할 수 있는 학습력/적응력/판단력이 본질이고 이것이 누적되어 실력이 됩니다.

개인적으로는 아래와 같이 개발자의 수준을 분류하고 싶습니다.

  • 레벨0: 이미 쓰고 있는 개발도구의 사용법을 알려주거나 가이드 문서를 줘도 잘 못 씀
  • 레벨1: 알려주거나 같은 팀에서 만든 가이드 문서에 있는 만큼만 쓸 수 있음
  • 레벨2
    • 개발도구의 공식 레퍼런스를 보고 사용법을 스스로 익힐 수 있음
    • 자신이 경험한 사용법을 문서화해서 팀 내에 전파할 수 있음
  • 레벨3
    • 여러 개발도구를 비교 분석해서 상황에 적합한 도구를 선택할 수 있음
    • 공식 레퍼런스 문서에서 부족한 부분을 수정해서 기여할 수 있음
  • 레벨4
    • 개발도구의 문제를 소스 코드를 수정해서 Fork/패치해서 사용할 수 있음

신입사원이라도 레벨2 정도는 함께 일할 개발자에게 기대를 하게 됩니다.

병렬처리

병렬처리를 어떻게 도입하면 좋은가요?

Servlet기반의 Java웹서버들은 기본적으로 사용자의 요청을 병렬적으로 처리합니다. 그래서 객체가 멀티스레드에서 공유되는 것인지, 아닌지를 의식하는 일은 중요합니다. 클래스의 멤버변수에는 항상 멀티스레드에서 접근해도 안전한(Thread-safe)한 변수만 두면 된다는 단순한 규칙만으로도 많은 문제를 예방할 수 있습니다. 그런데 Local cache를 적용할 때는 멀티스레드에서 공유된 객체가 쉽게 눈에 안 띌 수도 있습니다. 그래서 Cache대상의 객체는 Immutable하게 유지하는 것이 안전합니다. 직접 Cache 모듈을 만드는 경우 위험한 버그가 생기는 경우가 많습니다. 하나의 메모리 누수를 잡기까지 도 그런 사례입니다.

사용자 요청을 처리하는 스레드 외에도 별도의 스레드 풀로 실행해야 할 작업이 종종 생기기도 합니다. 예를 들면 사용자에게 주는 응답에 영향을 주지는 않지만 실행시간이 길어질 수도 있는 update 구문을 DB에 실행하는 작업같은 것입니다. 그런 경우 Java에서는 ExecutorsThreadPoolExecutor에 있는 많은 옵션들이 정교한 제어를 하는데 도움이 됩니다. new Thread()로 직접 스레드를 생성하는 방식은 JDK5 이후로는 권장하지 않습니다.

보안

다양한 보안 위협 상황에 어떻게 대처해야 하나요?

널리 알려면 XSS, CSRF, SQL Injection 공격에 대해서 대처하는 방법은 모든 개발자가 알고 있어야 합니다. 실무에서 일하다보면 의존하는 라이브러리에서 발견된 보안 취약점에 대처한 경우가 많았습니다. 보통 버전업을 하거나 회사 내에서 자체적인 패치를 하기도 했습니다. 보안 취약점이 자주 발견되는 Struts2 같은 프레임웍들은 신경써서 대처하기 위해 주요 변경을 알리는 메일링 그룹에 가입하기도 했습니다.

테스트

테스트가 얼마나 중요하다고 생각하는지 궁금합니다. 실제 서비스에서는 테스트 코드를 어떻게, 어느 정도로 짜는가요?

많은 사람이 협업해서 개발하고 지속적으로 개선해나갈 소프트웨어라면 테스트 코드를 작성하는 일은 더욱 중요합니다. 테스트 코드를 작성하는 능력도 백엔드 개발자의 핵심역량 중 하나이기도 합니다. FE개발이 분업화되고 서비스간의 API 호출이 많아지면서 최근 백엔드 개발자의 업무는 API 서버 개발에 더 집중되고 있습니다. 따라서 최종적으로 UI와 통합하기 전에 개발한 API를 스스로 테스트해야 할 필요성이 더 커졌습니다. 오류를 있다는 제보를 다른 개발자로부터 받아서 수정 후 재배포하고 다시 알리는 비용은 스스로 오류를 발견했을 때보다 굉장히 크기 때문입니다. HTTP API에 대한 테스트는 작성하기도 쉽고 작성했을 때의 이득도 큽니다. 최근 진행 중인 프로젝트에서는 Rest-assured 와 Spring MVC Test Integration 을 이용해서 HTTP API를 통합 테스트 하고 있습니다. 라이브러리나 개발플랫폼을 개발하는 경우에도 테스트 코드는 중요합니다. 수천 대의 서버에 배포되는 라이브러리에서 사소한 수정을 해서 배포한 적이 있었는데, 최대한 모든 경로를 상상해서 테스트 코드를 작성할 수 밖에 없었습니다. 라이브러리 배포 후 이를 적용한 서비스에서 오류가 발생했을 경우 재배포하는 과정이 비용도 크고 신뢰를 잃게하는 요인이 되기 때문입니다.

'시간이 없어서 테스트를 못 만들었다’는 말은 '나는 테스트 코드를 만드는데 시간이 많이 걸린다’는 말과 동일합니다. 해당 언어에 대한 숙련도가 떨어지는 사람일수록 테스트 코드를 작성하는데 부담을 크게 느끼는 경우도 많이 봤습니다. 능숙해질수록 테스트 작성 시간은 줄어들어 테스트에 투자한 대비 이득이 커집니다. 가끔 테스트를 작성할 때 이 테스트 덕분에 어느 시점에 실제적인 이득이 있을지 나누어 생각할 때가 있습니다. 예를 들면 아래와 같습니다.

  • 유지보수 기간의 생산성을 높여주고 새로 프로젝트에 투입될 사람에게도 이득을 주는 테스트
  • 프로젝트 오픈 일정 직전까지의 코드 변경과 버그 발견에 도움을 주는 테스트
  • 오늘 당장 프로그램을 목표한 곳까지 작성하는 일을 더 빨리 마치게 해주는 테스트

테스트 코드를 작성하다 보면 실제로 당장 할 일을 더 마치게 빠르게 해주는 테스트도 만나게 됩니다. 복잡하게 얽힌 프로그램을 개발할 때는 최종적인 UI를 통해서 수동으로 테스트하기 전에 부분적으로 잘라서 테스트하는 것이 버그를 쉽게, 빨리 잡는데 도움이 됩니다. 예를 들어 일주일 걸려서 만든 프로그램을 마지막 날에 한번에 테스트한다면 디버깅에 훨씬 시간이 많이 걸릴 것입니다. 몇 달 간 진행하는 프로젝트에서 단 한 줄의 테스트 코드도 안 짜는 분이 있다면 당신의 지금 능력으로도 그 방식이 오늘 일을 가장 빨리 마치는 방법이 아닐 것 같다고 말씀드리고 싶습니다. 그리고 테스트를 적극적으로 짜다보면 오늘 하루를 넘어서서 더 큰 이득을 주는 테스트를 만들어서 다른 사람의 생산성에도 긍정적인 영향을 미칠 수 있을 것입니다.

실제로 테스트로 인한 긍정적인 경험을 쌓아가다 보면 더 넓은 범위와 다양한 기법으로 테스트 코드를 작성하는데 동기유발이 됩니다. 제 개인적인 경험을 돌아보면, 점진적으로 테스트 코드를 작성하는 범위를 늘려가는 방식이 도움이 되었습니다. 처음에는 테스트가 쉬운 Utilty 클래스에 대한 테스트부터 작성했습니다. 전에도 간단한 유틸리티에 대한 테스트는 main메서드 안에서 하기도 했는데, 그런 코드를 JUnit 안으로 옮기니 반복해서 실행하고 결과를 확인하기에 훨씬 편해졌습니다. 그 이후에는 Spring framework의 통합테스트 기능을 이용한 테스트를 작성하기 시작했습니다. 특히 테스트 코드에서 DB에 입력한 데이터를 자동으로 롤백시키는 기능이 DB와 연동된 테스트를 할 때 유용했었습니다. 이후에 더 정교한 테스트를 하려다 보니 테스트용 객체를 만드는 프레임워크인 Mockito를 사용하게 되었습니다. 테스트 코드를 먼저 작성하는 기법도 사용할 수 있게 되었습니다. 저는 실무에서 테스트코드를 작성하기 시작한 후부터 6개월정도가 지나서야 Mockito와 같은 라이브러리의 필요성을 느끼게 되었었습니다. 처음으로 시도한 프레임워크는 EasyMock이었는데, 그 당시에는 프레임워크 제목처럼 전혀 Easy하게 느껴지지 않았습니다. 근래에는 프레임워크의 발달로 이전보다는 테스트 코드를 작성하기도 쉬운 구조로 모듈을 구성하기도 쉽고 테스트 코드 작성 자체도 훨씬 편해졌습니다. 따라서 이제는 대부분 제가 겪었던 단계적인 과정을 훨씬 더 빠르게 경험하실 수 있으실 것이라 예상합니다.

자료구조/알고리즘

학교에서 배운 알고리즘, 자료구조를 어떻게 실무에서 적용하나요? 실무에서는 기본적인 알고리즘을 직접 구현하지는 않습니다. 이미 기본적인 SDK나 많이 사용되는 라이브러리 솔루션에서 자주 쓰이는 자료구조, 알고리즘은 구현이 되어 있기 때문입니다. 하지만 그러한 이미 구현된 솔루션을 잘 선택하고 활용하기 위해서는 그 바탕이 되는 지식이 중요합니다.

JDK의 Collection framework의 소스를 볼 때에도 기본적인 자료구조에 대한 이해가 필요합니다. Java HashMap은 어떻게 동작하는가?와 같은 깊이 있는 분석도 그런 배경지식을 바탕으로 하고 있습니다. 대용량 데이터를 어떻게 저장하고 탐색할지를 결정할 때도 자료구조는 중요합니다. LINE 소셜 네트워크 서비스의 아키텍처SSD는 소프트웨어 아키텍처를 어떻게 바꾸고 있는가? 의 기사에서 B-Tree, B+Tree를 어떻게 활용했는지도 참고할 수 있습니다. 이미지 처리처럼, 특화된 분야의 알고리즘이 실무에서 응용되는 경우도 있습니다. PHOLAR의 흔들림 보정 원리가 그 예입니다.

개발 프레임워크

백엔드 개발 프레임워크의 트렌드는 어떤가요?

제가 주로 관심을 가지는 JVM 생태계에서는 계속 Spring/Netty 기반의 프레임워크들이 꾸준한 발전을 하고 있다고 느껴집니다. 제 주변에 있는 여러 개발팀에서는 고부하 처리를 위한 서버에는 Netty를 바탕으로 UI개발과 직접 호출되는 API 서버나 HTML까지 그리는 서버 개발에는 Spring 계열이 많이 쓰이고 있습니다.

비동기 I/O를 활용하는 서버 개발이 최근 몇 년 동안 서버개발자들 사이에서는 많은 관심을 끌고 있습니다. Java 생태계에서는 보통의 웹어플리케이션을 개발하는데까지는 비동기방식의 개발이 확산되지는 못했습니다. 여러가지 이유가 있겠는데, 비동기 개발 자체가 가지는 진입장벽과 기술적인 난이도가 있기도 합니다. RDB를 호출하는 어플리케이션이 대부분인데 이를 뒷받침해야 할 비동기 JDBC 스펙의 구현체가 공식적으로 나오지 않은 탓도 있습니다. 최근 나온 Spring 5에서 비동기 IO개발을 지원하는 Webflux 모듈도 주목을 받고 있습니다.

모든 서버 어플리케이션이 비동기로 개발되어야 할 필요는 없다고 생각합니다. 그러나 트래픽이 많아서 동기/쓰레드 기반으로는 자원을 효율적으로 쓸 수 없는 시스템에서는 택할만한 선택지입니다. 네이버에서 고부하를 처리하는 플랫폼의 서버는 Netty/Vert.x 위에서 비동기 방식으로 개발된 것이 많습니다. 대용량 세션을 위한 로드밸런서 도 그 예입니다.

Serverless

Serverless 아키텍처에 대해 궁금합니다.

Serverless라는 용어가 자극적이기에 널리 퍼졌다는 생각도 듭니다. 주로 BaaS와 FaaS에 의존하는 아키텍처를 Severless라고 주로 부릅니다. AWS의 람다나 네이버 클래우드 플랫폼의 Cloud Functions에 Servleless 아키텍처를 지원하는 플랫폼입니다. 요즘은 그 의미를 더 넓게도 쓰고 있습니다. 폭넓게는 어플리케이션 코드를 작성하는 개발자가 서버관리를 신경쓰지 않는 구조나 역할분담을 해당 어플리케이션 입장에서는 'Serverless'라고 부르기도 합니다. 외부로 공유하는 글에 Serverless 라는 용어를 쓰게 된다면 마틴파울러의 블로그에 올라온 https://martinfowler.com/bliki/Serverless.html 와 같은 글을 읽어볼 만합니다.

Serverless와 같이 인프라 환경이 고도로 자동화/추상화된 환경에서는 이제 전통적인 어플리케이션에서 했던 JVM, 커널 파라미터, 웹 서버 튜닝이 이제 필수 지식이 아니라고 생각할 수도 있습니다. 그러나 인프라의 기반 구조를 잘 이해하면 추상화된 서비스도 잘 쓸 수 있게 될 여지도 있습니다. 네이버와 같은 회사에서는 내부적으로 BaaS, FaaS를 만들기도 하기 때문에 그런 프로젝트에 참여하는 개발자들에게는 최종 사용자 격인 개발자들보다 숨겨진 레이어에 대한 지식이 더 필요하기도 합니다.

실무에서 하는 고민

이 단락은 구체적인 질문은 없었더라도 실무에서 반복적으로 하는 고민들을 떠오르는 대로 정리해봤습니다.

용어의 범위

협업하는 사람들 사이에서 용어의 정의가 명확하지 않다면 갈등이 생기기 쉽습니다. 익숙하게 쓰고 있는 용어일지라도 그 정의에 대해서 한번도 찾아본 적이 없다면 원래의 의미를 잘못 이해했을 가능성이 높습니다. 책이나 인터넷 동영상에서도 정밀하지 못한 용어를 쓰는 경우가 꽤 많습니다. 때로는 용어의 정의 자체가 논쟁적인 경우도 있습니다. 그런 경우 어떤 논란이 있는지 이해를 한다면 그 용어를 피하거나 합의점을 찾아가는데 도움이 됩니다.

HTTP 프로토콜 위에서 JSON혹은 XML의 형식으로 통신하는 API를 폭넓게 REST API라고 부르는 경우가 많습니다. 그런데 현업에서 많은 이들이 REST라고 부르는 API들은 창시자인 Roy Fielding의 기준으로는 REST가 아닙니다. 대표적으로 상태가 Hyper link를 통해 전이되어야 한다는 HATEOAS를 대부분의 API를 충족시키지 않습니다. 이에 대해서는 그런 REST API로 괜찮은가를 참조하실 수 있습니다. REST API의 범위에 대한 논란을 피하고 싶다면 HTTP API 혹은 Web API라고 칭하는 것이 무난합니다.

테스트 코드를 작성하는 일을 통칭해서 TDD (Test Driven Develop)라고 부르는 사람도 있습니다. 이미 운영서버에서 잘 돌아가는 코드에 테스트 코드를 추가하면서 커밋로그에 'TDD 코드 추가'라고 적어놓은 경우도 본 적이 있습니다. 그러나 TDD의 개념을 정리한 Kent Beck이 'Test Driven Development: By Example' 책에서 보여준 기법은 테스트 작성, 테스트를 통과하는 코드 작성, 리팩토링의 싸이클을 거치는 것입니다. 테스트가 없던 레거시 코드의 버그를 고치거나 리팩토링 하기 전에 테스트를 추가하는 것도 TDD의 싸이클의 일부일 수도 있습니다. 그렇지 않은 경우에 뒤늦게 테스트를 추가하는 작업은 TDD라고 부르기보다는 '테스트 코드를 작성한다.'라는 표현이 무난합니다.

비슷하게 JUnit으로 작성하는 코드를 모두 '단위 테스트'라고 부르는 사람도 있습니다. JUnit의 이름으로 인해 생긴 오해입니다. JUnit으로는 다양한 범위의 테스트 코드를 작성할 수 있습니다. 예를 들면 스프링 프레임워크의 레퍼런스 메뉴얼에서도 단위 테스팅(Unit-testing)과 통합 테스팅(Integration-testing)이 구분되어 있습니다. 해당 메뉴얼의 단위 테스팅에 대한 설명에서는 아래와 같이 설명을 덧붙이고 있습니다.

진정한 단위 테스트는 실행시점에 구성되어야할 기반요소가 없기 때문에 대체로 굉장히 빠르게 실행된다. (True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up.) https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#unit-testing

Spring 레퍼런스 메뉴얼의 통합 테스팅 절에서 설명하는 기법들도 JUnit을 쓰고 있습니다. 이를 봐서도 JUnit으로 만든 테스트 코드를 모두 '단위 테스트’라고 칭하는 것은 정교하지 못한 분류이고, 혼동의 소지가 있습니다.

VO (Value Object)라는 패턴 이름도 실무에서 혼란스럽게 쓰이고 있습니다. getter/setter만 있는, 값을 실어나르는 VO라고 칭하는 사람이 있는데 이는 DTO로 칭하는 것이 혼란의 여지가 적습니다. Core J2EE Patterns 라는 책의 초판에서 그 의미로 VO가 정의되어 있었지만, 혼동의 여지가 있어서 2판부터는 TO(Transfer Object)로 바뀌었었습니다. 아래 자료들에서 VO와 TO의 정의를 확인할 수 있습니다.

위의 자료들에 따르면 Value Object는 값에 의해 동등성이 판단되는 객체입니다. Getter/Setter만 가진 객체를 VO라고 생각한다면 ORM이나 DDD(Domain Driven Development)의 맥락에서 나오는 VO 용어를 접할 때 혼란이 올 것입니다. Java의 스펙 제안 문서인 JEP 169: Value Objects에도 VO는 getter/setter만 가진 객체를 의미하지 않습니다.

이렇듯 새로운 용어를 접할 때 엄밀한 정의를 검색해 보는 습관을 들인다면 위의 사례들과 같은 혼란에 더 잘 대처할 수 있습니다. 그 용어를 만든 사람이 한국인이 아니라면, 영어 자료를 구글로 검색해보는 것을 추천합니다.

더불어 내가 속한 회사에만 쓰이는 용어와 업계에서 범용적으로 쓰이는 용어도 구분할 줄 알아야합니다. 특히 큰 회사에 다니시는 분들이 회사 내에서만 통용되는 어를 회사밖에서도 쓰는 경우가 종종 보입니다. 예를 들면 네이버에서는 품질향상을 위한 활동을 QP(Quality Practice)라는 용어로 칭했었습니다. 어떤 분들은 이 용어를 QA처럼 외부에서도 쓰이는 것으로 생각하고 사용하시는 경우를 봤었습니다.

클라이언트와 백엔드의 역할분담

이전에는 JSP와 같이 HTML를 서버사이드에서 생성하는 기술이 주로 쓰였습니다. 화면 전체를 다시 그릴 필요가 없는 요청은 Ajax로 처리했지만, 서버 렌더링에 보조적으로 쓰이는 경향이 강했습니다. 하지만 요즘은 React.js나 Vue.js와 같은 프레임워크가 널리 쓰이면서 클라이언트 사이드에서 HTML을 생성하는 비중이 높아지고 있습니다. https://d2.naver.com 도 React를 이용해서 전적으로 클라이언트 사이드인 웹브라우저에서 HTML을 그리고 있습니다. 선택지가 더 생김으로 인해서 어플리케이션이나 페이지의 특성에 따라서 어느 방식이 적합할지 이전보다 더 많이 고민하게 되었습니다. 사용자가 페이지에 처음에 진입할 때는 서버에서, 그 이후로는 클라이언트에서 HTML을 그리는 Universal Rendering도 최근 많이 시도되고 있습니다.

HTML 렌더링을 어디에서 할지는 개발자 간의 역할분담에도 영향을 미칩니다. 100% 클라이언트 사이드 렌더링을 하는 구조는 서버 개발자가 HTTP API 개발에만 전념할 수 있다는 장점이 있습니다. 반면 전문 Front End 개발자의 작업이 더 많아지는 부담도 생깁니다. 제가 속한 조직에서는 백엔드 개발자들도 React.js나 Vue.js를 이용한 UI개발자 참여함으로써 그런 단점을 보완하고 있습니다.

클라이언트를 위한 API 설계

앞서 언급한 REST 스타일의 일부를 차용하더라도 HTTP API의 설계의 많은 부분은 매번 프로젝트마다 고민해야할 점이 많습니다. 예를 들면 단순 CRUD(입력/조회/수정/삭제) API는 각각 POST/GET/PUT/DELELE의 HTTP 메서드로 연결시키더라도 이를 벗어난 기능들은 어떻게 설계해야할지 명확하지 않은 경우가 많습니다. 페이징 처리를 할 때나 복잡한 검색조건이 있을 때의 파라미터 표현방식에서도 서비스마다 다르게 정의하고 있습니다. 그리고 API에서 선택적으로 반환할 속성과 아닐 속성을 지정하는 방식도 다양합니다. 아래의 스펙들이 보다 구체적인 API 설계안들을 제안하기는 합니다. 그러나 아직 어떤 상세한 스펙이 지배적으로 많이 쓰이고 있지는 않은 상황입니다.

클라이언트 사이드에서 UI 렌더링을 하는 경우가 늘어나면서도 HTTP API를 더 다양하고 정교하게 사용하고자 하는 필요성이 늘었습니다. 이러한 흐름 속에서 Facebook에서는 GraphQL을 내 놓았고, Github에서도 이를 도입하는 등 점점 확산되고 있는 추세입니다. 현시점에서 기존의 소위 REST 스타일과 유사한 틀에서 나름대로의 관례를 정립해서 최선을 추구할지, GraphQL을 도입할지도 고민되는 선택 중의 하나입니다.

시스템을 어떻게 자를것인가

시스템을 만들 때 많은 고민들은 결국 '구성요소 간의 역할과 책임을 어떻게 나눌 것인가'로 표현할 수 있습니다. 적게는 메서드, 클래스, 패키지 사이의 분담을, 크게는 jar로 배포되는 모듈이나 API로 통신을 하는 컴퍼넌트를 나누고 통신을 하는 방법을 고민을 하게 됩니다. 그리고 소프트웨어가 나누어진 경계에 맞추어 사람이 담당하는 업무의 범위나 협업 방식이 정해집니다. 그런 구조가 잘 잘라져 있어야 많은 사람들이 동시에 협업하면서 소프트웨어를 개발할 수 있습니다.

최근 MSA(Micro Service Architecture)라는 구조가 각광을 받으면서 서버에 배포 가능한 모듈의 단위를 이전보다 작게 가져가는 경향이 나타나고 있습니다. 많은 개발자가 동시에 협업하면서 개발하는데 MSA가 장점이 있기 떄문입니다. 이전에는 MSA와 같은 구조로 서비스를 만드는 것이 비용이 더 컸었습니다. 서버/네트워크를 더 많이 사용해야 하고, 서버/구성요소마다 설정하는 시간이 더 들어가고 문제가 생겼을 때 모니터링과 추적을 하는 것도 중간에 원격호출이 없을 때보다는 쉽지 않았습니다. 그러나 요즘에는 인프라시스템, 모니터링, 프레임워크의 발전으로 과거보다는 작게 단위로 서비스를 쪼개는 비용이 내려갔습니다. 그렇지만 서비스 간의 경계를 어떻게 잘라야 할지는 여전히 어려운 일이고, 적절히 잘라지지 않은 경계를 나중에 바꾸는 일도 비용이 큽니다.

네이버의 서비스들은 상호 연관되어 있고 다양한 조직의 많은 개발자들이 협업으로 만들고 있습니다. 네이버의 첫화면에 들어가는 구성요소만 해도 다양한 조직이 담당하는 모듈들을 거치고 있습니다. MSA라는 용어가 나오기 전이었지만, 그리고 최근의 경향보다는 서비스의 단위가 큰 경우가 많았겠지만 MSA가 이루고자 했던 장점들은 네이버에서 오랫동안 실용적으로 추구되어 왔다고 느껴집니다.

네이버의 백엔드 개발

개발,배포 방식

실무에서 어떻게 협업을 하고 개발, 배포를 하나요? 개발팀이나 프로젝트의 성격에 따라서 일하는 방식은 다양합니다. 제가 참여하는 프로젝트 중 하나의 예를 들면 아래와 같습니다.

  • 주 1회 배포
    • 월요일 쯤에 회의로 이번 주 배포 범위를 확정. 목/금요일에 주로 배포
    • 치명적인 버그에 대한 Hot fix는 주1회 주기에 상관없이 배포
    • 최대한 무정지 배포
  • 버전 관리/ 코드 리뷰
    • master에서 추가할 기능별로 feature branch(topic branch)를 따고 주로 master를 목표로 PR(pull request) 요청
    • Github의 마일스톤으로 버전을 입력하고 PR마다 매핑
    • 한번에 반영하기 힘든 기능이나 큰 단계의 버전업은 별도의 feature branch로 merge하기도 함
    • 리뷰를 충분히 받았는지는 PR을 올린 사람이 판단하여 merge
    • 배포일이 다가오는데 기능 오류가 없는 것으로 검증된 branch는 일단 merge후 사후 리뷰를 하기도 함
  • DB 스키마 관리
    • 개발환경에서는 Liquibase 로 관리
    • 운영환경에는 Liquibase에서 생성된 SQL을 사내 스키마 관리 시스템을 통해서 요청
  • 테스트
    • PR를 올리면 CI서버에서 빌드 실행. API 서버의 테스트 코드와 FE코드에 검사도구인 Eslint의 검증을 통과해야 merge 가능
    • 현재는 서버 모듈만 테스트 코드 작성
      • 통합 테스트: JUnit + Rest assured + (Spring MVC Test framework 또는 Embeded Tomat 활용) 이용
      • 단위 테스트: JUnit + Mockito 활용
      • 특별히 의식하지는 않았는데 Line coverage 는 74% 정도
    • Docker를 이용한 테스트 환경 활용
      • 마크업 등 UI변경을 확인해야 하는 경우는 PR에 'Docker build'라는 라벨을 붙임
      • 그러면 docker 이미지가 만들어져서 사내 docker 이미지 배포용 cluster에 해당 branch를 확인할 수 있도록 배포가 됨
      • docker로 배포된 서버에서 어느 정도 테스트 후 merge
    • 주1회 배포전 QA시간을 따로 잡고 개발팀 전체가 함께 테스트. (전담 QA가 없는 프로젝트인 경우)
    • 테스트 시나리오는 그 주 변경된 기능과 영향받는 기능 위주로 작성
    • 큰 기능 추가, 전체적인 코드 변경 시점에는
      • 스테이징 서버에서 1~2주 정도 개발팀이 미리 운영 데이터로 시스템을 써보기도 함
        • 전체 기능에 대한 테스트 시나리오를 다 수행해보기도 함

인프라 기술 활용

네이버에서 클라우드 컴퓨팅 기술(IaaS, PaaS, SaaS)을 어떻게 활용하고 있는지 알고 싶습니다. 네이버 서버 개발팀과 IT Operations팀 간의 소통 방식과 코드 배포 방법, 또 모니터링 툴들에 대해서 알고 싶습니다

네이버 내부에서 가상 서버(VM)를 관리하는 방식은 IaaS에 가깝습니다. 개발망에서는 특별한 결재없이 개발자 누구나 직접 가상서버(VM)를 생성할 수 있습니다. 운영망에서는 예산 승인 절차 등을 거쳐서 SE에게 요청해서 VM 서버를 생성합니다. 물리서버도 필요하다면 사용 신청을 할 수 있는데, 가상서버에 비해서는 신청 절차에 시간이 더 걸립니다. 최근에는 Docker container를 이용해 더 운영효율성을 높이려는 시도도 진행되고 있습니다. 이에 대해서는 아래 자료들을 참조하실 수 있습니다.

사내에 많이 쓰이는 플랫폼은 조직마다 직접 설치하고 운영할 필요가 없도록 PaaS 형태로 제공되고 있습니다. 로그수집시스템 Nelo, 어플리케이션 성능 측정 도구인 Pinpoint, 성능테스트 도구인 nGrinder, 분산메모리 저장소인 NbaseARC이 그 대표적인 예입니다. 많이 쓰이는 오픈소스 솔루션도 PaaS화하여 운영하는 사례가 늘어가고 있습니다.

최종 사용자가 바로 서비스를 사용하는, 네이버 메일, 캘린더, 클라우드(NDrive) 등이 SaaS의 예라고 생각합니다. 네이버 내부의 IaaS/PaaS/SaaS 기술들은 Naver Cloud Platform ( https://www.ncloud.com/ )을 통해서 외부에도 제공되고 있습니다.

코드 배포는 내부적으로 만든 배포 솔루션을 사용하고 있고, 개발자 누구나 서버에 몇번의 클릭으로 서버에 배포할 수 있습니다. 개발 환경에서는 코드 Push나 Pull request가 올라오는 이벤트 등과 연결시켜서 자동으로 배포하기도 합니다. 운영환경에 배포하는 작업은 개발팀의 내/외부와 긴밀한 협의를 거쳐서 시점이 정해집니다. 배포 일정에 맞춰서 코드 리뷰, 소스 합치기, 테스트, 의존하는 다른 서비스에 공지하는 작업 등이 사전에 이뤄져야하기 때문입니다.

모니터링 도구는 여러가지를 복합적으로 사용하고 있습니다. 장비별 주요 자원 사용량, 네트워크, 어플리케이션 성능, 로그 수집 분석 등 모니터링 툴마다 특화된 영역이 다르기 때문입니다. 장애에 대한 모니터링을 하는 시스템은 빌드배포 시스템, 각종 모니터링 시스템과도 연동되어 있습니다.

네이버 내부에 정확히 'IT operation팀'이라는 용어는 쓰이고 있지는 않습니다. Nginx, Tomcat, JVM과 같은 솔루션의 설치와 설정 변경은 개발팀에서 직접하고 있습니다. 운영서버 VM의 생성, OS패치 등의 작업, 인프라 구성 등에 대한 컨설팅을 서비스마다 지정된 SE분들이 해주십니다. 개발DB의 설치와 스키마 변경은 개발팀에서 자율적으로 하고, 운영 DB에 대한 중요한 작업은 전담 DBA에게 요청합니다. 오랫동안 서비스를 개발,운영하면서 실용적인 프로세스가 정착되었다고 느껴집니다.

마치며

개발과 요리가 비슷한 면이 있다는 생각이 들 때가 있습니다. 몇 명이 먹을 요리를 정해진 레시피를 보고 혼자 만드는 일은 어렵지 않습니다. 그런데 많은 사람을 위한 음식을 여러 사람이 함께 준비하는 일은 차원이 다른 일입니다. 예전에 친척 분의 집에 방문했다가 샌드위치 500인분을 만드는 과정에 한두시간정도 참여한 적이 있습니다. 재료가 얼마나 필요할지 예측해서 구하고, 일하는 방식과 담당자를 정하고, 작업 시간을 계획하는 것 등 하나하나가 수월해 보이지 않았고, 그 중 하나만 어긋나도 샌드위치는 예상대로 만들어지지 않을 것 같았습니다. 그 일을 겪은 이후로 저는 큰 식당이나 결혼식 피로연에 갈 때마다 그 음식들을 준비하신 분들이 정말 대단하다고 느낍니다.

일단 실행은 되는 백엔드 프로그램을 만드는 일은 쉽습니다. 요즘은 특히 인터넷에 많은 재료와 레시피가 있기에 더욱 그러합니다. 그러나 협업하기에 좋은 방식으로, 성능과 안정성까지 고려한 백엔드 프로그램을 만드는 개발은 쉽지 않습니다. 그리고 모니터링과 데이터 수집,분석 등 사용자의 눈에 보이지 않는 영역들도 실무에서는 많은 비중을 차지합니다. 데이터나 사용자가 적었을 때에는 효율적이었던 구현 방식이 시스템이 성장하면서 문제의 근원지가 되기도 합니다.

블로그 이미지

낭만가을

,