10년전 C++로 개발을 시작했을때는 내가 필요한것을 모두 작성해야 했었다.

현재는 내가 필요한것이 어딘가에 오픈소스이든 상용소스인든지 어딘가에 존재한다.

기억을 더듬어(년도는 추정치) 필자가 실제 개발에 활용했던 코드샘플을 통해 개발의 변천사를 알아보자

1기 - OOP : 2007

#include <iostream>

struct Node{

    Node* prev;
    Node* next;

    void* data;
};

struct List{
    Node* head;
};

List* createList(){

    Node* head = new Node;
    head->prev = head;
    head->next = head;
    head->data = 0;

    List* list = new List;
    list->head = head;

    return list;
}

void insertNodeAfter(Node* node, void* data){
    
    Node* before = node;
    Node* after = node->next;

    Node* newNode = new Node;
    newNode->data = data;
    newNode->next = after;
    newNode->prev = before;

    after->prev = newNode;
    before->next = newNode;
}

void removeNode(Node* node, bool deleteData){

    Node* before = node->prev;
    Node* after = node->next;

    before->next = after;
    after->prev = before;

    if (deleteData)
        delete node->data;
    delete node;
}
............................................
// 이하생략 이만큼의 코드로도 리스트가 제대로 작동하지않는다.
// 또한 스레드 세이프하기위해서 더 신경쓰야할 부분도있다.

c에서 c++로 전환 되면서 객체지향이란 컨셉이 대동하기 시작한다.  하지만 성능이 항상 중요했고, c++을 사용하지만

oop를 활용하지 못했고... List가 얼마나 빠른지? 자료구조에 신경을 쓰던때이다. 

개발자의 컴퓨터 메모리가 1기가 안되던 시절로, List를 빠르게 하기위해 OOP로 설계하는것은 사치이던 시절이 있었다.


그리고 몇년이 흘러,이러한것을 작성할 필요없는(자료구죠) stl이 등장하였고-  stlport라는 c++비공식 라이브러리였으며 표준에 채택되기 까지는 더 많은 시간이 필요했음

자주 사용되는 자료구조를 구현이아닌 이용을 할수 있는  신기방기한 녀석이 등장하였다. 우수한 개발자들의 역량이 자료구조 설계에 있었으며

이때 등장한 STL을 반가울리 없었으며, STL 과 성능 벤치마크까지 해서 자신의 자료구조의 성능을 증명하거나, 마지막까지 고수하였지만  

이 녀석의 등장으로 곧 템플릿+제네릭 프로그램이 유행을하였으며 프라이빗한 자료구조는 몽땅 대체되기 시작하였다. 

자료구조를 아주 잘 작성하는 개발자의 시대가 끝났다란것을 의미하기도 한다. (  제네릭을 제공하는 라이브러리 전문개발자로,높은곳에 존재한다.   )

물론 이러한 개발자가 도메인개발까지 잘할수 있다란것은 별개의 문제이다.

템플릿의 등장과함께 본격적인 OOP시대가 개막된다.


부록: 이시절 서버 오토스케일링 시스템

위와같은 코드를 활용하여, 사용자의 수에따라 자동으로 서버가 증감하는 오토스케일링은 물론

서버 무중단 업데이트( 진행중인 게임상태를 트랜스퍼하고 유지한체 서버업데이트)가 가능하였습니다.

이 시절 스케일(in/out)이라는 용어의 개념조차 확립이 되기 전의 시절이며

현시대에는 도커와 연동되는 몇가지 CI/CD 통해 이러한것을 쉽게 할수 있지만 , 순수웹과 게임의 무중단 업데이트 기술은 수준이 다른분야입니다.

위키피디아 기재 : 미국에서는 Poker가 스포츠로 분류되며 Cereus Poker로 북미 Top3 에 드는 시스템이였습니다. ( 대용량 트래픽을 처리했다란 의미)

1.5기 제네릭 프로그래밍 : 2008

#include <algorithm>
#include <iostream>
#include <list>
 
int main()
{
    // Create a list containing integers
    std::list<int> l = { 7, 5, 16, 8 };
 
    // Add an integer to the front of the list
    l.push_front(25);
    // Add an integer to the back of the list
    l.push_back(13);
 
    // Insert an integer before 16 by searching
    auto it = std::find(l.begin(), l.end(), 16);
    if (it != l.end()) {
        l.insert(it, 42);
    }
 
    // Iterate and print values of the list
    for (int n : l) {
        std::cout << n << '\n';
    }
}

위와같이 자료구조를 컨테이너화하는 제네릭컨셉은 java,c#을 포함하여 여러가지 언어에서 공통적으로 이용할수 있다.

c++은 java가 탄생하기전에 이미 위와같은 컨셉이 적용되고 실험되었으며 OOP의 역사는 c++을 중심으로 보는것이 이해가 쉽다.

템플릿 프로그래밍과 함께 다음 개발자의 노력은 OOP의 능력을 극대로 사용하는 디자인 패턴으로 이어진다.

하지만 템플릿과 프라이빗한 패턴적용은 서비스 코드에서 가독성의 문제와 디버깅문제를 격게 되며

MVC,싱글톤,팩토리패턴등  유용한 패턴들은 프레임워크에 자연스레 녹여들면서 구현보다는 사용하고 활용하는쪽으로 변화하면서

디자인 패턴을 극단적으로 생산하는것을 프레임워크가 잡아주게 된다.

MVC템플릿이 프레임워크 레벨에서 자동생성되거나 잘 갖추어진 의존성 주입방식을 활용하는것이 대표적인 예이다. 


부록: 모니터링

모니터링을 직접 개발하여, CPU/패킷량/메모리/디스크등 실시간 측정하였으며

장애발생시 메일자동발송 하기도 하였습니다. 요즘은 이러한것을 직접 개발하지 않고

다양한 APM 시스템을 이용할수 있습니다.


2기  : 멀티스레드 작성의 몰락과 비동기 프로그래밍 : 2012


하드웨어의 발전과 함께 단일노드에서 멀티스레드를 통한 대용량처리가 주류를 이루었으며

IOCP SOCK에서 절정을 이루었습니다. 이때 고급 개발자의 역량은 단일노드 만명동시처리를

멀티스레드의 작성을 통해 하던 시기 였습니다.

하지만 무어의 법칙에의해 하드웨어 성능의 비약적 발전은 종료되게되며, 공짜점심이 끝났다라고 표현합니다.

인터넷의 발전과함께 사용자가 늘어남과 동시에 사용자한명이 소모하는 트래픽이 늘어나게 되었으며

더이상 단일노드 멀티스레드 최적화를 통해 트래픽 커버를 할수 없게됩니다.

분산처리를 위해 복잡한 멀티스레드 개발방식은  단순화가 필요했으며 , asyn 라는 비동기 프로그래밍이

시작되었습니다.   


콜백헬이라는 몸살을 겪으며 함수형이 함께 도입되며 Future 와 Promice라는

컨셉으로 완결이 되는것으로 보이며 곧바로 함수형시대가 열리게 됩니다.


참고:

Future and Promise


부록: 모니터링

모니터링/로깅등 직접개발했던 것을 관리되는 서비스로 전환하던 시기이며

OpenNMS(모니터링),Splunk(로깅)등을 연동하여 APM이 도입되던 시기입니다.

3기  : 람다와 함께 함수형 프로그래밍의 등장 : 2015


이제는 람다 + 함수형과 결합을 하여 불변하지 않는 리스트 객체를 이용하여

집계 통계등을 신기방기한 방식으로 간단한 코드로 표현이 가능 해졌습니다.

이것은 복잡한 비동기 처리 개발방법이 필요없어지게 되었고, 알아서 멀티코어를 활용하여

다중 동시 처리를 해준다.

아래코드는 C#이며, JAVA 8 Stream에서도 비슷하게 작성할수가 있다.

List<Person> persons = new List<Person>()
{
    new Person { PersonId = 1, car = "Ferrari" },
    new Person { PersonId = 1, car = "BMW" },
    new Person { PersonId = 2, car = "Audi"}
};


List<Result> results2 = persons
    .GroupBy(p => p.PersonId, 
             (k, c) => new Result()
                     {
                         PersonId = k,
                         Cars = c.Select(cs => cs.car).ToList()
                     }
            ).ToList();


스칼라의 WordCount는 함수형 프로그래밍을 통해 데이터의 집계처리를 단순화한 좋은 예이다.

https://spark.apache.org/examples.html


최근 핫한 스칼라/언랭/파이썬 등에서 위와같은 컨셉이  나왔고 그것을 이용하는것만이 모던한 개발 이라는 정의는 하지말자

템플릿/람다/제네릭/함수형 그 컨셉이 메니지드 언어에 존재하지도 았을때-예를 들면 자바 4혹은 닷넷 프레임웍 2.0 이하시절

이미 오래전, 10년도 더 전에 C++에서 시도 되었고  Boost(https://www.boost.org/)로 집약이 되어있다.


다만 오랫동안 사용된 언어의 형태를 유지한채, 새로운 컨셉이 적용되니 혼용하는 방식에대한 이질성이 발생하게되었으며

다시 작성되어진 언어에서는 과감한 버젼업을 통해 비교적, 평셔널,람다등을  우선적으로 고려하게 되었으며

때로는 컴파일이아닌 스크립트언어의 장점까지 살리면서 우아하고 쉽게 사용할수 있게 제공되면서 유행하기 시작하였습니다.

여기서 유행은 기존 개발방식이 대체되었다란 의미가 아니고, 이러한 개발방식에 장점이 있는부분 예를들면 데이터분석/인프라관리

개발이 폭발적으로 수요가 생겨났고 파이썬/Spark(Scala) 가 메이져 언어가 하지못하는 틈새에 진입하고 탄력을 받기 시작했다란것입니다.


만약 함수형+스트리밍(리액티브)을 모두 잘 활용할수 있는 방식으로 개발을 하고 싶다고하면

Scala + Playframework를 추천해봅니다.

Scala언어는 내가아는한 언어의 장점이외에 Spark를 통해 함수형언어의 장점을 빅데이터를 처리하는곳에 유행시켰고

Akka라는 분산 메시지처리를 가지고 있으며,  또한 내가 아는 어떠한 웹프레임워크보다 성능을 위한 디테일한 스레풀설정이 가능했기때문이다.

이것은 기존 C++고성능 처리를 JVM이 어떻게 할것이냐에대한 오랜 고민끝에 결정한 프레임워크였으며 자바 네티의 고성능 IO컨셉이

충분히 커버하리라는 판단을 하였기때문입니다. 

그리고 이것은 Akka Http라는 녀석으로 이어진다. 


하지만, 왜 ?웹서비스시장에 이러한것이 주류가 되지 못하고 , Spring Boot의 점유율이 높은가? 를 분석해볼 필요가 있다.

왜 스프링에 두꺼운 사용자층이 이탈하지않고 머무는지에 대해 질문을 던질 필요가 있다. 단순하게 JAVA여서는 아닌것같다.

오픈스택의 단점이 무엇인가? 유용한 오픈소스를 발견하고 추가하고,조합이 되었을때 의존성 문제를 파악해야 한다.

오픈소스를 제약할 어떠한 단체가 없기때문이다. 조합에 따른 책임은  그것을 사용하는 사용자가 전담해야하는부분이다.

그리고 그러한 문제는 빌드타임에 발생하는것이아니고 런타임에 발생할수 있기때문에 골치아픈 문제가 될수도 있다.

하지만 그러한 조합의 안정성을 검증하고 웹스택에 안정적으로 사용할수 있게끔 그룹화를 시켜주는 똑똑한 단체가 있고 프레임워크를 내놓았다고하면

이야기가 달라진다. Spring Boot은 정확하게 웹에서 쓸만한 오픈스택을 테스트되고 안정적인 버젼만을 조합하여 그것을 쉽게 사용할수 있는 방법을

프레임워크를 통해 단일화시키고 제공해주기때문이다,또한 Boot를 통한 웹서비스의 경량화에도 신경쓰고 있기때문이며 최근 마이크로서비스의 요구사항과도 맞아 떨어진다.

WAS에 벚어나려는 시도가 최근 모던웹의 공통 관심사이고 , MS역시 정신을 차리고 윈도우 서버를 과감히 포기하면서 닷넷코어를 밀고 있는 이유도 동일하며

Spring Boot 의 성공한 전략을 따라가고 있다라고 볼수있다. ( Java 8부터는 Future및 Stream을 포함하여 쓸만한 언어스펙을 가지고 있기때문에 이제는 큰 단점이 되지 못한다.)


부록 : 데브옵스의 분리

이제 서버 개발자가 모니터링/배포자동화등을 직접 구축 하는것에서 분리되는 개발패턴인 데스옵스가 등장하기 시작하였으며

우리의 개발팀도 이러한것에서 도움을 받고 조금더 아키텍처 적인 부분에 집중을 할수 있게되었습니다.

시스팀의 단일지점 포인트는 항상 존재합니다. 이것을 어떻게 분산처리 할것인가? 는 단순하게

스케일 아웃이 되는 자동화된 시스템을 이용하는것으로 해결되지 않습니다.

멀티스레딩 프로그래밍이 사라지고 있다고 스케일업을 하지 말아야되는것은 아닙니다.


4기  : 1~3기의 장점을  잘 융합하는 하이브리드 마이크로 서비스의 시대 : 2015


최근에 다양한 마이크로  서비스를 통해 분산처리되고 관리가 되는 어플리케이션 구성에 고민을 하고 있으며

시대에따라 달라 질수도 있지만 그러한 관점에서 모던한 개발에서 필요한것이 무엇인가? 를 정의를 할필요가 있다고 봅니다.


어떠한 언어나 플랫폼이 아니라, 우리 도메인에서 필요한게 무엇이고? 개발자에게 필요한 역량이 무엇인가를  정리하고 탐구하는것입니다.

이미 잘하고 있는 CRUD만 하는 방식을 최신언어 최신 플랫폼으로 다시 작성하는것은 의미가 없으며, 최신 언어기법만을 사용한것이 모던한 개발을 의미 하지 않습니다.


모던한 개발의 도전과제

  • 도메인 객체인 엔티티,Aggregate,Repository를 OOP를 통해 분리하는 방법 (OOP설계능력 향상을 통한 도메인처리)
  • 대용량 처리에서 역압력 사용을 위한 스트림의 활용과 메시지큐의 활용 ( Akka,Kafka 등등)
  • 분산처리를 위한 라우팅설계및 클러스터활용과 다른 플랫폼을 상호 연동하는 방법
  • 전통적인 예외처리를 개선하는 패러다임의 활용 ( Let it Crash By Supervisor )
  • 다양한 테스트 개발환경 구축과 유닛테스트 커버리지를 올릴수 있는 방안및 지속적 통합(CI)


부록 : 분산처리 부하테스트

이제 구성 서비스가 분산처리가 되는것에 넘어, 이러한 시스템을 테스팅하는 툴 역시 고도화되기 시작하였습니다.

위 지표는 실제 제가 작성한 신규 서비스를 분산 테스트팀과 함께 램프업( 사용자가 증가하고 감소하는 실제 시나리오)

로드 테스트를 시도하고 리포팅을 내본 결과입니다. 


5기 : 클라우드의 전성기 : 2019


 클라우드에는 우리가 필요로하는 모든것이 갖추어지기 시작했으며,

서버를 작동시키기위해 IDC센터로 주기적으로 방문해야했던 시기에서 원클릭으로 서버구성이 가능할뿐아니라

도커의 발전과 함께 베어메탈(VM)을 통한 서버 구성은 점점 사라지고 있습니다.


지금 시대에 개발자의 지식탐구 방향을 어떻게 할것인가? 를 고민해볼필요가 있으며

OPEN STACK을 이해하고 활용할것인가? VS SASS를 잘이용하고 이용한만큼 비용지불을 할것인가?

OPEN STACK : Redis,Kafka,RabbitMq 등 이것을 사용하기위한 기술적인 부분을 포괄

SASS : OpenStack 기술을 변형하여 제공하거나 유사한 기능을 서비스형태로 바로 제공함 ex>kinesiss

필자가 선택하는 방식은, OPEN STACK을 먼저 이해하고 SASS방식도 고려하는것이며

어느것이 항상 옳다는 방식이 아닌, 개발팀이 가진 수준과 비용을 고려 어느것이 더 비지니스 가치를 창출하기위해 효율적인가? 입니다.


현재 유행하는 도커기반은 OpenStack 활용하는것에 더 유연한 방법을 제공하고 있으며

OpenStack의 활동은 폭팔적이고 안정적으로 생태계 구성이 이미 잘된 상태입니다.

당분간 Sass에 대응할수 있겠지만....

이것 역시 언젠가.. 일부 웹개발에서 OOP가 실종했듯이, 개발자의 수준이  OpenStack을 빌드하고 활용하는 능력이 점점사라지면서

Sass방식을 Fitst로 사용하는 방식으로 변화할지 모르겠습니다. 모든 개발 요소가 SASS로 대체되지 않겠지만

OpenStack활용 직접구현 + SASS 의 조합은 당분간 이어질것같습니다.


참고 링크 : SASS 선택과 관련된 주제


부록: DataDog

원클릭으로 시스템모니터링뿐만아니라 다양한 로깅툴을 연결하고 AI기술과 연합하여 장애를 푸시하는 수준을 넘어

예측하는 서비스를 이용할수 있다.






  • No labels