Education*
Devops
Architecture
F/B End
B.Chain
Basic
Others
CLOSE
Search For:
Search
BY TAGS
linux
HTTP
golang
flutter
java
fintech
개발환경
kubernetes
network
Docker
devops
database
tutorial
cli
분산시스템
www
블록체인
AWS
system admin
bigdata
보안
금융
msa
mysql
redis
Linux command
dns
javascript
CICD
VPC
FILESYSTEM
S3
NGINX
TCP/IP
ZOOKEEPER
NOSQL
IAC
CLOUD
TERRAFORM
logging
IT용어
Kafka
docker-compose
Dart
클라우드 엔지니어 면접을 위한 지식들 - 소프트웨어 엔지니어링
Recommanded
Free
YOUTUBE Lecture:
<% selectedImage[1] %>
yundream
2023-03-30
2023-03-27
7175
클라우드 엔지니어 면접을 위한 지식들로 "소프트웨어 엔지니어링"관련 내용을 정리했습니다. 다룬 주제들은 [클라우드 엔지니어 면접을 위한 지식들](https://www.joinc.co.kr/w/taglist?name=%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C%20%EC%97%94%EB%8B%88%EC%A7%80%EC%96%B4%20%EB%A9%B4%EC%A0%91%EC%9D%84%20%EC%9C%84%ED%95%9C%20%EC%A7%80%EC%8B%9D%EB%93%A4) 을 참고해주세요. ## N-Tier Architecture N-Tier 아키텍처는 애플리케이션을 논리적인 계층과 물리적인 계층으로 나눠서 구성하는 아키텍처 패턴이다. 각 계층은 특정 기능 집합을 담당하며, 각 계층간 통신은 잘 정의된 인터페이스만을 통해서 통신하도록 구성하여서 다른 계층과 독립적으로 작동할 수 있도록 설계한다. N-Tier 아키텍처는 다양한 계층으로 구성할 수 있지만 일반적으로 프리젠테이션 계층, 애플리케이션 계층, 데이터 계층으로 이루어진 3-Tier 아키텍처를 사용한다.  **프리젠테이션 계층** 클라이언트 계층이라고도 부르며 사용자와 상호작용하는 사용자 인터페이스 계층이다. 사용자의 입력을 수신하고 처리 결과를 출력하는 일을 하는 데스크탑 애플리케이션 혹은 모바일, 웹 애플리케이션일 수 있다. **애플리케이션 계층** 중간 계층이라고도 하며, 비즈니스 로직과 사용자 요청 처리 및 트랜잭션을 관리한다. 웹 서버, 애플리케이션 서버 또는 마이크로 서비스와 같은 다양한 기술을 사용해서 구현할 수 있다. **데이터 계층** 데이터베이스 계층이라고도 하며 애플리케이션에서 사용하는 데이터를 저장하고 검색하는 일을 한다. SQL, NoSQL, 파일 시스템 등 다양한 데이터 저장 매커니즘을 사용한다. N-Tier 아키텍처는 폐쇠형 레이어 아키텍처 또는 개방향 레이어 아키텍처를 사용 할 수 있다. * 폐쇠형 레이어 아키텍처 : 각 레이어는 바로 아래에 있는 레이어만 호출할 수 있다. * 개방형 레이어 아키텍처 : 각 레이어는 아래에 있는 모든 레이어를 호출할 수 있다. N-Tier 아키텍처는 일반적으로 VM에서 실행되는 IaaS 혹은 온-프레미스 기반의 애플리케이션에서 사용한다. 특히 온-프리미스 애플리케이션은 N-Tier 아키텍처로 개발하는 경우가 많기 때문에, 마이그레이션을 할 때 적합한 모델이다. **장점** 1. 확장성: 각 계층마다 독립적으로 확장할 수 있다. 2. 모듈성: 기능을 계층단위로 분리할 수 있으므로 모듈성을 촉진시킨다. 이렇게 하면 응용 프로그램의 다른 부분에 영향을 주지 않고 기능을 쉽게 추가하거나 제거할 수 있다. 3. 유지관리: 개발자가 다른 계층에 영향을 받지 않으면서 계층을 변경할 수 있으므로 유지/관리성을 높인다. 4. 보안: 각 계층마다 개별적으로 보호할 수 있도록 하여 애플리케이션의 보안을 향상시킬 수 있다. 5. 재사용성: 각 계층에 사용된 기술은 다른 애플리케이션 개발에도 그대로 사용할 수 있기 때문에 재사용성을 높인다. **단점** 1. 복잡성 : 관련된 계층이 많을 경우 아키텍처가 복잡해질 수 있다. 이로 인해 개발 시간과 비용이 증가할 수 있다. 2. 오버헤드 : 서로 다른 계층간의 통신과 관련된 오버헤드가 있다. 제대로 최적화하지 않을 경우 애플리케이션 속도가 느려질 수 있다. 3. 보안 : 각 계층을 개별적으로 보호해야 하므로 보안 모델이 복잡해질 수 있다. 4. 확장성 : 각 계층을 개별적으로 확장해야 하기 때문에 확장이 어려올 수 있다. 다만 클라우드 환경에서는 Auto scaling 등을 이용해서 해결 할 수 있다. 5. 유지관리 : 각 계층마다 서로 다른 기술을 사용해야 한다. 이를 위해서 찾기 어려울 수 있는 여러 기술에 대한 전문지식이 필요할 수 있다. 6. 통합 : 서로 다른 계층을 통합하기 위한 전문지식과 도구가 필요할 수 있다. 많은 요소들이 장점과 단점 두 가지를 모두 가지고 있다. 아키텍처는 장점이 극대화되도록 애플리케이션을 설계해야 한다. ## Monolithic Architecture 모놀리스라는 단어는 거대하고 통합된 구조물을 의미하는 경우가 많은데, 소프트웨어에서의 모노리식 아키텍처도 크게 다르지 않다. 모놀리식 아키텍처는 모든 비즈니스 관련 기능을 결합하는 하나의 코드베이스를 갖춘 대규모의 소프트웨어다. 이러한 종류의 애플리케이션을 변경하려면 코드 베이스의 전체 스택을 업데이트해야 한다. 이로인해서 업데이트 제한이 많고 개발에 많은 시간이 걸린다. 다만 프로젝트 초기에는 코드관리, 오버헤드, 배포의 용이성 면에서 모놀리스가 편하기 때문에 초기에는 모놀리스로 개발을 하고 필요에 따라서 마이크로서비스 아키텍처로 전환하는 방식을 사용하기도 한다. 이-커머스 애플리케이션을 모노리식으로 개발한다면 아래와 같은 모습이 될 것이다.  **장점** 1. 단일 코드베이스이기 때문에 프로젝트를 쉽게 시작할 수 있다. 2. 하나의 프로젝트에 기능들이 모두 포함되어 있기 때문에 서로 다른 기능들간의 상호 작용을 쉽게 디버그 할 수 있다. 3. 기술 스택을 단순화 할 수 있어서 유지 관리 및 문제해결이 덜 복잡하다. 4. 단일 jar/war 파일만 배포하면 되므로 배포가 더 쉽다. **단점** 1. 시간이 지나면서 코드의 크기가 너무 커지며 관리가 어려워진다. 2. 동일한 코드 기반에서 각 기능들이 다른 기능에 직접적으로 영향을 주기 때문에 병렬로 작업하기가 어렵다. 3. 대형 모놀리식 애플리케이션의 경우 새로운 기능을 구현하기 어렵다. 4. 모든 변경사항에 대해서 애플리케이션 전체를 새롭게 배포해야 한다. ## Micro Service Architecture 마이크로 서비스 아키텍처는 잘 정의된 API를 통해서 통신하는 작고 독립적인 서비스의 모음으로 구성하는 소프트웨어 개발 접근 방식이다. 각 마이크로서비스는 애플리케이션 내에서 하나의 특정 작업을 담당하며 독립적으로 개발 및 배포 확장 할 수 있다. **마이크로 서비스의 아키텍처의 특징**은 아래와 같다. 1. 마이크로 서비스는 작고 독립적이며 느슨하게 결합되어 있다. 마이크로 서비스를 구성하는 각 서비스는 소규모 개발팀이 독립적으로 유지 및 관리 할 수 있다. 2. 각 서비스는 독립적으로 배포할 수 있다. 3. 각 서비스는 데이터와 외부 상태를 독립적으로 유지한다. 이는 데이터가 공통 레이어가 되는 기존 모델(N-Tier)과 차이점이다. 4. 각 서비스는 API를 통해서 통신한다. 5. 각 서비스는 언어, 프레임워크, 라이브러리, 프로그래밍 언어가 서로 다를 수 있다. 마이크로서비스는 아래와 같은 장점을 가진다. 1. 확장성: 마이크로 서비스를 사용하면 각 개별 서비스를 독립적으로 확장할 수 있기 때문에 다양한 워크로드의 요구사항을 개발하는데 있어서 더 큰 유연성을 가진다. 2. 민첩성: 특정 서비스의 추가 기능이 전체 서비스에 영향을 주지 않기 때문에 새로운 기능을 쉽게 도입하고 기능을 업데이트 할 수 있다. 이를 통해 배포 속도를 높이고 시장 출시 기간을 단축할 수 있다. 3. 복원력: 하나의 서비스가 실패하더라도 전체 서비스가 중단되지 않고 영향을 받는 서비스만 중단된다. 4. 기술 다양성: 각 서비스는 작업을 수행하는데 가장 적합한 기술을 선택해서 개발할 수 있다. 이를 통해 기술 선택의 폭이 넓어지고 전체 시스템 성능을 향상시킬 수 있다. 5. 독립적인 팀 구성: 각 서비스는 독립적인 팀에서 개발, 배포, 관리 할 수 있으므로 더 빠른 주기, 더 나은 전문화 및 혁신이 가능하다. 마법의 은탄환은 없는법 마이크로서비스도 고유의 단점을 가지고 있다. 1. 복잡성: 마이크로서비스 아키텍처는 개발, 품질, 배포 관리가 독립적으로 더 많은 요소들로 구성되기 때문에 모놀리식 아키텍처보다 더 복잡해질 수 있다. 이로 인해 설정, 버전, 구성, API에 대한 유지 관리가 어려워질 수 있다. 2. 분산 시스템: 마이크로서비스 아키텍처는 네트워크를 통해서 서로 통신을 하는 **분산 시스템**이다. 이로 인해 서비스 검색, 로드밸런싱, 네트워크 보안 문제뿐만 아니라 추가적인 대기시간이 발생할 수 있다. 3. 테스트: 각 서비스가 독립적으로 개발,테스트,배포 되기 때문에 모놀리식 보다 더 어렵고 많은 시간이 소요될 수 있다. 왜냐하면 서비스의 각 상태가 서로다를 수 있어서 개별 서비스 수준뿐만 아니라 통합 수준에서도 테스트를 수행해야 하기 때문이다. 4. 운영 오버헤드: 더 많은 구성요소를 모니터링하고 업데이트해야 하기 때문에 모놀리식에 비해서 관리가 복잡해질 수 있다. 이로 인해 운영오버헤드가 증가하고 보다 전문기술을 가진 팀이 필요할 수 있다. 5. 데이터 일관성: 각 서비스가 자체 데이터베이스를 가지고, 데이터가 여러 서비스에 분산될 수 있으므로 데이터의 일관성으 유지하는게 더 어려워질 수 있다. 모노리식 아키텍처에서 다뤘던 이-커머스를 마이크로서비스에서는 아래와 같이 설계할 수 있다.  마이크로서비스 아키텍처는 많은 이점을 제공하지만 잠정적인 단점또한 명확하기 때문에, 단점을 과리하고 장점을 극대화할 수 있도록 신중하게 설계해야 한다. 마이크로 아키텍처를 잘 활용하기 위한 몇 가지 지침들을 소개한다. 1. CICD: 개발, 품질테스트, 릴리즈까지가 연결된 CICE 파이프라인을 구축한다. 그리고 CICD 파이프라인에 품질을 내장해보자. 품질 내장은 처음에는 유닛테스트, 테스트 커버리지에 대한 레포트를 받고, 로그를 표준화하고 로그를 남기는 것 부터 시작한다. 2. Service Mesh: 서비스메시는 마이크로서비스 아키텍처내에서 서비스간 통신을 제공하는 인프라 계층이다. 네트워크 통신의 복잡성을 줄이고, 서비스 검색(service discovery), 부하 분산, 보안, 사이드카 패턴등 추가 기능을 제공한다. 3. API Gateway: API 게이트웨이는 마이크로서비스 아키텍처를 구성하는 모든 서비스에 대한 단일한 진입점 역할을 하는 서버다. 인증, 속도제한(Rate limiting), 요청 라우팅과 같은 작업을 처리하여 마이크로 서비스에 대한 외부 인터페이스를 단순화하는데 도움을 준다. 4. Event Driven Architecture: 이벤트 기반 아키텍처를 사용하면 서비스가 직접 요청이 아닌 이벤트를 통해서 통신할 수 있으므로 네트워크 통신의 복잡성을 줄이고 내결함성을 개선할 수 있다. 5. Container Orchestration: Kubernetes, ECS와 같은 컨테이너 오케스트레이션 도구를 사용하면 마이크로서비스의 배포, 확장, 모니터링을 보다 효율적으로 그리고 자동화된 방식으로 관리할 수 있다. 6. Domain-Driven Design: 마이크로서비스 아키텍처로 애플리케이션을 구성하다보면, 마이크로서비스를 어떻게 나눠야 할지에 대해서 많은 고민을 하게 된다. 도메인 주도 디자인을 통해서 모듈성 및 유지관리성을 개선할 수 있다. 다양한 방식으로 마이크로서비스 아키텍처의 잠재적 문제점을 해결할 수 있지만 이를 위해서는 **개발조직이 상당한 개발역량**을 보유하고 있어야 한다. 마이크로서비스 아키텍처를 도입하기 위해서는 조직이 충분한 역량 학습할 시간이 있는지를 검토한 후 수행해야 한다. ## Event-Driven Architecture EDA(Event-Driven Architecture)는 이벤트를 생성하고 생성한 이벤트를 구독하여 이를 처리하는 방식이 중심이 되는 소프트웨어 아키텍처 패턴이다. 여기에서 이벤트란 시스템의 다른 구성요소가 감지하고 처리하고 응답해야 하는 시스템 상태의 중요한 변경 사항이다. 아래 그림은 EDA 방식으로 설계한 커피샵 주문관리 시스템을 묘사하고 있다.  커피샵 주문관리 시스템은 "커피 주문"과 "음식 주문"에 대한 상태변화를 관리해야 한다. 이들 상태변화를 Queue에 **게시(publish)** 하면, 이 Queue를 **구독(Subscribe)** 하는 작업자가 이벤트를 읽어서 처리한다. 처리 결과는 주문의 상태변화를 의미하므로 이 상태변화를 다시 Queue에 게시하여 처리한다. EDA는 빠른 응답성이 필요하며 확장 가능하며 분산되어야하는 시스템에서 자주 사용한다. **이벤트 버스**를 기준으로 각 구성요소를 분리할 수 있으므로 독립적으로 개발 및 배포할 수 있고 실시간으로 이벤트에 응답할 수 있기 때문이다. 따라서 EDA는 실시간 분석, 데이터 스트리밍, IoT 애플리케이션 사례에 적합하다. **장점** 1. 확장성: EDA를 이용하면 많은 양의 데이터와 이벤트를 처리할 수 있는 확장성이 뛰어난 시스템을 구축할 수 있다. 각 구성요소가 메시지 버스를 중심으로 분리되어 있으므로 다른 구성요소에 영향을 주지 않고 새로운 구성요소를 추가할 수 있다. 2. 탄력성: 각 구성요소가 느슨하게 연결되어 있기 때문에 한 구성요소의 오류가 다른 시스템에 영향을 미치지 않는다. 3. 실시간 처리: 이벤트를 실시간으로 처리할 수 있다. 금융 시스템 및 소셜 미디어와 같은 실시간 데이터 처리가 필요한 시스템에 유용하다. 4. 민첩성: 다른 시스템 구성요소에 영향을 주지않고 기능을 개밯할 수 있으므로 시스템을 빠르게 변경할 수 있다. 5. 통합: 메시지 버스의 데이터를 기반으로 다른 시스템과 쉽게 통합할 수 있다. ## HTTP HTTP(HyperText transfer protocol)는 애플리케이션 프로토콜 중 하나일 뿐이지만 인터넷의 가장 핵심이 되는 프로토콜이므로 소프트웨어 엔지니어는 HTTP 프로토콜의 목적, 특징, 장점, 단점을 알고 있어야 한다. HTTP는 인터넷을 통해 데이터를 전송하는데 사용되는 프로토콜이다. 서버/클라이언트 모델을 따르는 프로토콜로 클라이언트에서 서버로 문서를 요청하면, 서버는 클라이언트에 응답을 반환하는 구조다. 클라이언트는 웹 브라우저이며, 서버는 Apache, NginX와 같은 웹 서버다. HTTP는 웹 페이지에 포함된 HTML 문서와 이미지, 비디오 등을 검색할 수 있으므로 WWW(World Wide Web)의 기반이다.  HTTP는 서버/클라이언트 프로토콜로 HTTP-Request와 HTTP Response를 기반으로 작동한다. #### HTTP의 특징 HTTP의 주요특징은 아래와 같다. * Stateless: HTTP의 모든 요청과 응답은 서로 독립적이다. 서버는 클라이언트의 정보를 유지하지 않으므로 이전 상태를 알지못한다. 결과적으로 서버는 각 요청을 새로운 요청으로 처리한다. * Connectionless: HTTP는 연결을 유지하지 않는다. 즉 각 요청과 응답에 대해서 새로운 연결을 만든다. 응답이 전송되면 바로 연결이 종료된다. 이로 인해 요청과 응답이 많은 경우 연결을 설정하고 해제하는데 많은 오버헤드가 발생할 수 있다. HTTP/1.1에서는 Keep-Alive로 이 문제를 해결한다. * Text based: HTTP 메시지는 텍스트기반으로 사람이 읽고 편집할 수 있다. 쉽게 읽을 수 있으므로 디버깅이 편하다는 장점도 있다. * Platform-independent: HTTP는 플랫폼 독립적이므로 운영체제와 프로그래밍언어에 상관없이 사용할 수 있다. * 클라이언트/서버 아키텍처: HTTP는 클라이언트가 서버에 요청을 보내면 서버는 요청을 처리해스 응답하는 서버-클라이언트 아키텍처를 따른다. #### HTTP의 버전 최신 HTTP 버전은 (2022년)현재 **HTTP/2** 로 **HTTP/1.1** 과 함께 주로 사용되고 있다. **HTTP/3** 버전이 개발되어서 웹 브라우저에 채택되고 있지만 아직은 공식적으로 사용하고 있지 않다. 이들 버전의 주요 특징들만 간단히 살펴보자. **HTTP/1.1**의 주요 특징은 아래와 같다. * Host header: HTTP/1.0은 공식적으로 Host 헤더를 요구하지 않았다. Host 헤더가 추가됨으로서 동일한 IP를 가리키는 여러 도메인을 구별할 수 있게 됐다. * Persistent connection: HTTP/1.1에서는 단일 연결을 통해서 여러 요청을 실행할 수 있다. Connection 헤더에 keep alive를 설정하면 된다. * Chunked Transfer Encoding: 데이터를 단일 블록이 아닌 청크로 전송할 수 있다. 전체 응답을 받기전에 클라이언트가 데이터를 처리할 수 있으므려 데이터가 큰 응답의 처리에 유용하다. **HTTP/2**의 주요 특징은 아래와 같다. * Multiplexing: 단일 연결을 통해서 여러 요청과 응답을 동시에 주고 받을 수 있다. * Server Push: 클라이언트가 요청을할 때까지 기다리지 않고 서버가 클라이언트에 푸시할 수 있다. 이렇게하면 서버가 리소스를 전송하는 시간을 선택할 수 있기 때문에 대기 시간이 줄어들고 성능을 높일 수 있다. * Header Compression: HPAC 압축을 사용하여 클라이언트와 서버간에 전송되는 헤더의 크기를 줄인다. 데이터의 양이 줄어들기 때문에 성능을 향상시킬 수 있다. * Binary protocol: HTTP/1.1까지는 Text 기반 프로토콜이었으나 HTTP/2 부터는 바이너리 프로토콜을 사용한다. 이렇게하여 효율적으로 구문을 분석하고 효율을 향상시킬 수 있다. * Prioritization: 클라이언트의 요청에 우선순위를 할당할 수 있다. 이렇게하면 중요한 요청을 더 빨리 처리하여 UI/UX 관점에서 성능을 향상시킬 수 있다. **HTTP/3**의 주요 특징은 아래와 같다. * Transport Protocol: 가장 큰 차이점은 기존의 TCP 프로토콜 대신 QUIC(UDP)를 전송 프로토콜로 사용한다는 점이다. 이는 더 빠른 연결, 대기시간의 감소 등 많은 이점을 제공한다. * Multiplexing: HTTP/2와 마찬가지로 단일 연결을 통해 여러 요청과 응답을 동시에 보낼 수 있다. * Reduced Head-Of-Line Blocking: HTTP3는 HTTP/2에서 발생할 수 있는 HOL 차단 문제를 줄인다. HTTP/2에서 부터는 하나의 연결에 여러 요청을 병렬로 전송할 수 있다. 그런데 첫번째 요청의 처리가 오래걸리게 되면, 3번째 요청에 대한 응답까지 지연된다. HTTP/3는 서로 다른 연결을 통해 개별 스트림을 전송하는 것으로 이 문제를 해결한다. * Zero Round Trip Time(0-RTT) Handshake: 0-RTT handshake는 TLS 1.3에 도입된 기능으로 O-RTT를 사용하면 클라이언트가 서버의 응답을 기다리지 않고 연결의 첫번째 피킷에서 암호화된 데이터를 서버로 보낼 수 있다. 이렇게 하면 특히 작은 요청의 경우 연결을 설정하고 데이터 전송을 시작하는데 필요한 시간을 크게 줄일 수 있다. O-RTT 핸드세이크는 클라이언트가 동일한 서버의 이전 세션에서 세션 키 및 기타 암호화 매개 변수를 저장하고 사용하는 방식으로 작동한다. 다만 그만큼 보안리스크가 있으므로 이미지, CSS, Javascript와 같은 민감한 정보를 포함하지 않은 리소스의 통신에 사용해야 한다. 민감한 데이터 또는 트랜잭션은 일반 TLS 핸드셰이크를 사용하는 것이 좋다. #### HTTP Request Header HTTP 요청 메시지는 **요청 라인(Request Line), 요청 헤더(Request Header)와 요청본문(Request Body)** 의 세부분으로 구성된다.  **Request Line**은 HTTP Method, URL, HTTP Version으로 구성된다. 1. HTTP Method: HTTP 동사(verbs)라고도 부르는 HTTP Method는 요청이 어떤 행동타입인지를 서버에게 알려준다. GET, POST, PUT, DELETE등이 대표적인 Method다. 1. GET: URL에 있는 데이터를 검색한다. 웹페이지, 이미지, 비디오 등을 가져오기 위해서 사용한다. 2. POST: 일반적으로 서버에 리소스를 업데이트하거나 생성하기 위해서 사용한다. 종종 POST 문서를(가입양식 등) 제출하거나 파일을 업로드하는데 사용한다. 3. PUT: 서버에 리소스를 업데이트하는데 사용한다. 업데이트할 리소스가 없을 경우 새로 생성하기 위해서 데이터를 보낸다. 4. DELETE: 지정된 리소스를 삭제하도록 서버에 요청한다. 5. PATCH: 서버의 리소스에 대한 부분 업데이트를 요청한다. 6. OPTIONS: 특정 리소스 또는 서버에서 사용할 수 있는 통신 정보에 대한 정보를 요청한다. 7. HEAD: 컨텐츠가 아닌 리소스의 헤더만 검색한다. 2. URL(Uniform Resource Locator): 요청하는 리소스를(HTML문서, 이미지, 비디오 등) 설정한다. 3. HTTP Version: 클라이언트가 사용하는 HTTP 버전 정보 4. Connection: 클라이언트와 서버의 연결 방법으로 Keep-Alive와 Close가 있다. Keep-Alive는 단일 TCP 연결을 통해서 여러 HTTP요청밍 응답을 보낼 수 있는 HTTP 연결 기능이다. 이렇게 하면 각 요청과 응답을 설정하기 위한 오버헤드(TCP 3-Way handshake)를 줄여 성능을 개선할 수 있다. Close는 요청이 끝나면 TCP 연결을 바로 닫아 버린다. 5. Cookie: 서버에 전달할 추가적인 데이터들이다. 이 데이터를 이용해서 서버는 사용자를 식별하거나 상태를 추적할 수 있다. 기본적으로 Request Line만 있으면 서버로 요청을 보낼 수는 있다. 하지만 많은 경우 추가적인 정보가 필요한데 **Header Line**에 추가적인 정보를 설정할 수 있다. * Host: 요청을 전송할 Host의 이름을 설정한다. 어떤 인터넷 서비스는 하나의 로드밸런서에서 여러개의 도메인으로 서비스를 하는 경우가 있는데 Host 이름이 없을 경우 라우팅을 할 수가 없다. 사실상 필수 Header다. * User-Agent: 요청을 보내는 클라이언트 애플리케이션의 이름과 버전정보를 포함한다. 웹 서버는 클라이언트 정보를 읽어서 특정 클라이언트에 최적화된 컨텐츠를 제공할 수 있다. 예를 들어 사용자 에이전트가 모바일 버전이라면 그에 맞는 정보를 제공할 수 있다. **Body** Header와 Body는 빈라인(carriage return, line feed)로 구분한다. Body는 서버에 데이터를 전송하기 위해서 사용한다. 그러므로 PUT, POST 메서드를 사용할 때 Body를 사용한다. Body에는 서버가 요청하는 다양한 포멧의(일반 텍스트, JSON, XML, YAML, 이미지...) 문서가 포함된다. #### HTTP Response 서버의 응답은 **Status Line, Response Header, Body** 세개 부분으로 구성된다.  1. **Status Line**: 응답에 사용한 HTTP 버전과 상태코드(Status Code), 상태메시지(Status message)를 리턴한다. 엔지너에게 가장 중요한 정보는 상태코드일 것이다. 상태코드는 응답이 성공했는지 실패했는지를 나타낸다. 가장 흔하게 볼수 있는 상태코드는 **404**로 페이지를 찾을 수 없을때 반환한다. 서버 시스템에 오류가 발생했을 때는 5xx 코드를 반환한다. 2. **Header Line**: Content의 길이, Content의 포맷, Server 정보등을 반환한다. 중요한 부분은 Content-Type이다. 클라이언트는 Content-Type을보고 어떻게 처리할지를 결정한다. 만약 JSON 형식의 문서를 리턴해야 한다면 Content-Type을 "applitaion/json"로 설정해야 한다. 그렇지 않을 경우 클라이언트가 이를 제대로 처리할 수 없게 된다. 3. **Body**: HTML문서, JSON, YAML, 이미지, 비디오, XML등 다양한 형태의 문서를 반환한다. **참고** HTTP는 다뤄야 할 내용이 많아서 참고 문서를 따로 정리했다. * HTTP에 대한 자세한 내용은 [HTTP](https://www.joinc.co.kr/w/Site/Network_Programing/AdvancedComm/HTTP) 를 참고하자. * [Cookie](https://www.joinc.co.kr/w/man/12/cookie) ## REST & RESTful API **REST(Representational State Transfer)** 은 웹 기반 애플리케이션을 설계하는데 사용되는 아키텍처 스타일이다. REST는 어떤 솔류션이 아니며 몇 가지 주요 원칙을 제시하고 이에 따라서 설계하라는 일종의 모델이라고 볼 수 있다. REST는 기본적으로 **HTTP을 기반으로 하는 모델**로 아래와 같은 구성요소를 가진다. 1. Resource: 리소스는 REST의 기본 단위다. URL로 식별되며, 어떤 리소스를 다룰 것인지를 설정한다. 예를들어 이-커머스 서비스라면 "유저", "상품", "주문"이 리소스가 되며 URL로는 /user, /product /order 로 표현된다. 2. METHOD: 리소스에 대해서 어떤 작업을 수행할 것인지를 나타낸다. HTTP Metohd를 이용해서 나타내며 GET, POST, PUT, DELETE. PATCH 가 가장일번적으로 사용한다. GET은 조회, POST는 생성, PUT은 업데이트, DELETE는 삭제다. 3. Representation: 리소스가 클라이언트에 표시되는 형식이다. REST는 JSON, XML, HTML을 이용해서 리소스를 표현한다. REST API는 REST원칙을 적용한 API다. 예를들어 유저 ID가 1001인 유저의 정보를 가져오기 위한 API는 **GET /user/1001**과 같이 정의할 수 있다. REST의 특징은 아래와 같다. 1. Statelessness: REST 아키텍처는 상태 비저장으로 서버는 클라이언트의 이전 상태를 추적하지 않는다. 따라서 모든 요청은 개별적으로 처리가 되며, **cookie**와 **session**을 이용해서 상태를 식별한다. 2. Client-Server: REST는 클라이언트-서버 아키텍처를 기반으로 한다. 3. Uniform Interface: **HTTP URL과 HTTP Method** 를 이용한 균한일 인터페이스를 제공한다. 리소스에 대한 모든 상호작용은 URL과 GET, POST, PUT, DELETE와 같은 HTTP Method 동사집합을 통해서 이루어진다. 4. Cacheability: REST 아키텍처는 응답 캐싱을 지원하도록 설계되어 서버로 전송되는 요청의 수를 줄이고 성능을 향상시키는데 도움을 준다. 캐시가능성은 HTTP의 캐시메커니즘을 이용하는데 즉, Cache-Control, ETag, Last-Modified 헤더를 이용하여 캐시를 컨트롤 할 수 있다. RESTful API의 경우 **Swagger** 와 같은 툴을 이용해서 문서화 할 수 있어서 커뮤니케이션(프론트앤드, 백앤드, QA 간) 큰 도움이 된다. ## SOAP SOAP(Simple Object Access Protocol)은 인터넷을 통해 네트워크 애플리케이션간에 구조화된 정보를 교환하는데 사용하는 메시징 프로토콜이다. SOAP는 XML(Extensible Markup Language)를 사용하여 메시지 형식을 지정하고 응용프로그램간에 메시지를 교환하기 위한 규칙을 정의한다. SOAP는 envelope/header/body로 이루어져 있다.  아래는 SOAP XML 문서의 예제다. ```xml <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.example.com/webservices"> <soap:Header> <ns1:Security> <ns1:Session>user_session</ns1:Session> </ns1:Security> </soap:Header> <soap:Body> <ns1:GetUser> <ns1:UserID>123</ns1:UserID> </ns1:GetUser> </soap:Body> </soap:Envelope> ``` Header에는 user session 정보가 들어 있으며, Body에서 UserID가 123인 유저에 대해서 GetUser 즉 유저 정보를 요청하는 메시지임을 알 수 있다. SOAP 메시지는 HTTP, SMTP, TCP등 다양한 통신 프로토콜을 통해서 교환할 수 있다. 이런 점에서 REST와 역할이 상당히 겹치고 있다. 실제 최근 RESTful의 등장으로 SOAP가 인기를 잃고 있으며 "단순성","유연성","사용용이성"으로 인하여 RESTful API를 사용하는 것을 선호하고 있다. 예를 들어 위의 SOAP 문서는 아래와 같이 더 간단한 RESTful 문서로 사용할 수 있다. ``` GET /user/123 Cookie: session-id=user_session ``` 아래는 표는 SOAP와 REST를 비교하고 있다. | | SOAP | REST | | --- | ---------------------------------------------------------- | ---------------------------------------------------------------------------- | | 1 | XML-Base message protocol | Architectural style protocol | | 2 | Use WSDL | XML or JSON | | 3 | Invokes services by calling RPC method | Simply calls services via URL PATH | | 4 | Does not return human readable result | Result is readable which is just plain XML or JSON | | 5 | Javascript can call SOAP, but it is difficult to implement | Easy to call from JavaScript | | 6 | Performance is not great compared to REST | Performance is much better compared to SOAP less CPU intensive, leaner code. | ## gRPC RPC는 **Remote Produre Call**의 약자로 네트워크를 통해서 원격에 있는 컴퓨터의 기능이나 프로시저를 호출할 수 있도록 하는 프로토콜이다. 즉 서로 다른 시스템에서 실행되는 프로그램이 동일한 시스템에 있는 것처럼 호출하고 통신할 수 있다. gRPC(Google Remote Produre Call)는 구글에서 개발한 확장 가능한 고성능 API를 구축하기 위해서 사용하는 오픈소스 프레임워크다. 프로토콜 버퍼(protobuf)라는 데이터 직렬화 형식을 사용하여 서비스간 스펙을 정의하고 스펙에 따라서 통신할 수 있게 만든 현대적인 RPC 프레임워크다. gRPC는 RPC를 기반으로 하며 언어독립적으로 설계되어, 다양한 프로그래밍언어로 사용 할 수 있다. 예를 들어 서버측은 go 언어로 개발하고 클라이언트는 python 언어로 개발할 수도 있다. HTTP/2 프로토콜을 사용하여, 단일 TCP 연결을 통해 다중화 가능한 양방향 흐름제어 스트림을 제공한다. gRPC는 아래와 같은 이점을 제공한다. * 언어 독립적: C++, Java, Python, Go를 비롯한 여러 프로그래밍 언어를 지원하므로 서로 다른 언어로 작성된 시스템 간에 클라이언트 - 서버 통신환경을 구축할 수 있다. * 고성능: gRPC는 멀티플렉싱 및 흐름 제어를 지원하는 HTTP/2를 사용하여, 여러 요청을 병렬로 보내고 처리할 수 있어서 처리량이 높고 빠르게 처리 할 수 있다. * 확장성: gRPC는 스트리밍 및 배치 처리를 지원하여 클라이언트와 서버가 대량의 데이터 혹은 빈도가 높은 요청을 효율적으로 처리할 수 있다. * 자동 코드 생성: gRPC는 프로토콜 버퍼 형식을 "스펙문서"로 부터 클라이언트와 서버코드를 자동으로 생성한다. 이는 클라이언트와 서버 사이에 스펙의 불일치를 걱정할 필요 없이 통신을 할 수 있음을 의미한다. RESTful API의 경우 Swagger등을 이용해서 문서를 관리한다고 하더라도, 개발자가 직접 코딩을 해야하기 때문에 스펙이 일치하지 않아서 여러가지 문제가 발생하는데 gRPC는 이런 문제에서 자유롭다. ## SOA SOA(Service-Oriented Archiecture)는 분산 소프트웨어 애플리케이션을 설계하고 개발하기 위한 아키텍처 패턴이다. 이를 위해서 SOA는 아래와 같은 아키텍처 기본원칙을 제안하고 있다. 1. 상호운용성: SOA의 각 서비스는 서비스의 기능을 설명하기 위한 문서를 포함하고 있다. 클라이언트는 플랫폼이나 프로그래밍 언어에 상관없이 이 기능문서를 이용해서 서비스를 실행할 수 있다. 직접적인 상호작용이 없기 때문에 한 서비스의 변경 사항이 다른 서비스를 사용하는 구성요소에 영향을 미치지 않는다. 2. 느슨한 결합: SOA의 서비스는 느슨하게 결합되어야 하며 데이터 모델이나 정보 시스템과 같은 외부 리소스에 대한 종속성이 최대한 낮아야 한다. 또한 과거 세션이나 트랜잭션의 정보를 유지하지 않는 상태 비저장 서비스어야 한다. 그렇게 하면 서비스를 수정해도 서비스를 사용하는 클라이언트 애플리케이션과 기타 서비스에 큰 영향을 미치지 않는다. 3. 추상화: SOA의 클라이언트 또는 서비스 사용자는 서비스의 코드 또는 구현 세부정보를 알 필요가 없다. 클라이언트에게 서비스는 블랙박스이며 기능 및 API 문서를 통해 서비스를 사용할 수 있다. 4. 세분화: 서비스당 하나의 개별 비즈니스 기능을 제공할 수 있도록 적절한 크기와 범위를 가져야 한다. 전반적으로 MSA의 특징과 유사하다. 즉 MSA는 SOA의 구현 아키텍처라고 볼 수 있다. ## PUB/SUB PUB/SUB은 게시(PUB)와 구독(SUB)으로 구성된 서비스로, 메시지 전송자와 메시지 수신자로 분리되는 메시징 서비스다. PUB/SUB의 주요 개념은 아래와 같다. * 메시지: 메시지 큐를 중심으로 이동하는 데이터 * 토픽(Topic): 메시지를 구독하기 위한 이름 * 구독: 특정 주제의 메시지 수신의향을 나타내는 이름이 지정된 항목 * 구독자(Subscriber): 특정 구독에 대한 메시지를 수신한다. * 게시(Publisher): 특정 주제에 대한 메시지를 전송한다.  이 시나리오에서는 3개의 subscriber가 하나의 Topic을 구독하고 있다. Publisher가 Topic에 메시지를 전송하면, 이 메시지는 Topic을 구독하고 있는 하위 subscriber에게 복사되서 전송된다. PUB/SUB은 아래와 같은 목적으로 널리 사용하고 있다. 1. 실시간 데이터 스트리밍: 주식 가격, 뉴스 피드, 소셜 미디어 업데이트와 같이 정보를 여러 구독자에게 스트리밍하는데 사용한다. 메시지브로커는 모든 가입자가 업데이트를 폴링할 필요 없이 실시간으로 최신 업데이트를 받도록 한다. 2. Event-Driven architecture: 시스템의 구성요소들이 이벤트를 통해서 서로 통신하는 event-driven architecture에 자주사용한다. 3. Decoupled architectures: 게시자가 구독자가 서로의 존재를 알 필요 없는 느슨하게 연결된 아키텍처를 만드는데 사용할 수 있다. 다른 구성에 영향을 주지 않고 시스템의 구성요소를 추가하거나 제거할 수 있으므로 확정성과 유지관리성이 향상된다. 4. IoT: 분석 플랫폼 또는 여러 장치등으로 데이터를 생성하는 IoT 애플리케이션에서 자주사용한다. 5. Asynchronous processing: 메시지의 비동기 처리를 수행하는데 사용할 수 있다. 비동기 처리는 요청과 처리를 분리시큼으로 대량의 메시지 작업을 효율적으로 처리할 수 있다. ## Serverless 서버리스 아키텍처는 인프라를 관리할 필요 없이 애플리케이션과 서비스를 구축하고 실행하는 방식이다. 애플리케이션이 실행되는 모든 서버관리를 클라우드 서비스 제공자가 제공하므로 더 이상 서버, 데이터베이스, 스토리지 등을 관리할 필요가 없다. 이 아키텍처에서 개발조직은 클라우드나 온프레미스의 서버, 런타임관리 운영등을 걱정하지 않고 핵심 제품 개발에 집중할 수 있다. 서버리스 아키텍처를 사용할 경우 이점은 아래와 같다. * 선택, 보호, 패치적용 또는 관리할 운영체제가 없다. * 크기조정, 모니터링 또는 확장할 서버가 없다. * 프로비저닝 과다로 인한 비용 손실 위험이 없다. * 프로비저닝 부족으로 인한 성능저하 위험이 없다. 서버리스 아키텍처의 단점은 아래와 같다. * Cold Start Latency: 함수가 처음 호출될때 클라우드 공급자는 함수를 실행하기 위한 리소스 할당 작업을하는데 이때 눈에 띄는 지연이 있을 수 있다. 이 지연을 "콜드 스타트"라고 한다. 다만 클라우드 공급업체들도 이 문제를 인지하고 지속적으로 해결해 나가고 있다. AWS Lambda의 경우 **SnapStart** 등의 기술을 이용해서 Lambda 함수의 스냅샷을 생성한다음 일반적인 초기화 프로세스를 거치지 않고 간단히 시작함으로써 이 문제를 해결하고 있다. 이 기능을 이용할 경우 콜드 스타트 시간을 90% 개선할 수 있다고 한다. * 인프라에 대한 제어 제한: 서버리스 컴퓨팅을 이용하면 클라우드 공급자가 인프라를 관리하므로 개발자 환경에 대한 제어권한이 제한적이다. 애플리케이션에 특정 구성이나 종속성이 필요한 경우 적용이 어려울 수 있다. * 공급업체 종속: 서버리스 컴퓨팅을 채택하면 각 클라우드 공급자의 고유 기술을 사용해야 하기 때문에 공급업체 종속(lock-in)으로 이어질 수 있다. 멀티 클라우드 및 하이브리드 클라우드 전략을 사용한다면 고민이 필요하다. * 비용: 트래픽이 적은 소규모 애플리케이션에서는 비용효율적일 수 있으나 트래픽과 사용량이 증가하면 오히려 더 많은 비용이 들 수 있다. 서버리스 서비스는 가격정책이 복잡해서 예측하고 관리하기가 어렵다는 것도 문제다. * 성능제한: 콜드 스타트 또는 리소스 할당지연으로 응답시간이 급증할 수 있다. 고성능 또는 실시간 애플리케이션에 적합하지 않을 수 있다. ## CICD 난 개발 환경의 핵심은 CICD와 Test라고 생각한다. CICD와 테스트(TDD가 그렇게 중요한지는 모르겠고 일단 UnitTest와 Test coverage 부터 시작해도 충분하다고 생각한다.)만 잘 갖춰진다면 평균은 한다는게 내 생각이다. CICD는 **CI(Continous Intergration)**과 **CD(Continuouse Delivery or Deployment)** 의 줄임말로 지속적인 통합과 지속적인 전달/배포 시스템을 의미한다. 지속적으로 무언가를 하기 위해서는 "루틴"과 "파이프라인"이 필요한 법, 따라서 CICD 시스템을 구축하는 것은 CICD 파이프라인을 구축한다고 하기도 한다. 파이프라인은 어떤 자원을 투입하여 가치를 만들어내는 컨테이너 벨트다. 여기에 투입되는 자원은 "코드"이고 결과물은 작동하는 애플리케이션이다.  1. 코드가 변경된다. 2. 웹훅등으로 코드 변경 이벤트를 확인하고 빌드가 트리거 된다. 3. 빌드한다. 4. 빌드가 끝나면 테스트를 실행한다. UnitTest, Test Coverage, SonaQube 기타 테스트 스크립트를 이용해서 품질을 내장 할 수 있다. 5. 빌드와 테스트가 끝나면 레포트가 생성된다. 6. Dev, stage, product 각 stage에 배포된다. 파이프라인 즉 컨테이너벨트가 한번 구축되면, 파이프라인에 새로운 툴과 정책을 밀어 넣는 것으로 개발/품질/보안/문서 정책을 확장시켜나갈 수 있다. 특히 CICD는 MSA의 문제점인 복잡성을 낮출 수 있는 핵심 시스템이므로 반드시 구축해야 한다.  ## KISS KISS 원칙(Keep It Simple, Stupid)는 불필요한 복잡성을 피하고 단순함을 유지하라는 소프트웨어 개발의 설계원칙이다. 이 원칙은 개발자가 이해하고 유지 관리 및 수정하기 쉬운 시스템을 설계하도록 권장하고 있다. KISS 원칙은 디자인의 명확성과 단순성을 특히 강조한다. 단순한 디자인은 일반적으로 구현, 테스트, 유지관리가 더 쉽고 오류와 버그가 발생할 가능성이 적다고 생각하기 때문이다. KISS 원칙을 따를 경우 얻는 주요 이점은 아래와 같다. * 더 쉬운 유지관리: 간단한 시스템은 문제를 일으킬수 있는 복잡한 상호작용이나 종속성이 적기 때문에 유지및 관리가 쉽다. * 더 빠른 개발: 단순한 디자인은 보통 더 테스트하기 쉽워서 개발 시간과 비용이 줄어든다. * 안정성: 단순한 시스템은 실패 지점이 적고 테스트와 검증이 쉽기 때문에 오류와 버그가 발생할 가능성이 더 적으며, 오류가 발생하더라도 더 쉽게 찾아서 해결할 수 있다. * 확장성: 간단한 시스템은 종속성이 적고 변화하는 요구사항에 더 빠르게 대응할 수 있으므로 확장이 더 쉬운경우가 많다. 일반적으로 KISS원칙은 **오버 엔지니어링(Over-Engineering)** 로 발생하는 문제를 해결하기 위한 행동 원칙이다. 엔지니어는 자신이 만드는 컴포넌트의 최적화와 새로운 기술의 도입과 적용을 중요하게 생각하는 경우가 있다. 또한 먼 미래의 기술부채를 지금부터 미리 관리하고자 하는 욕구도 가지고 있다. 이에 따라서 최종 사용자가 필요로하지 않거나 사용에 큰 영향을 주지 않는 불필요한 복잡성, 기능의 개발, 과도한 확장성, 과도한 성능 목표를 달성하기 위해서 시스템이 지나치게 복잡하거나 비효율적이 될 수 있다. KISS 원칙을 상기하면서 프로젝트를 진행하면 적절한 시기에 충분한 품질을 가진 제품을 출시할 수 있게 한다. 반면 KISS 원칙을 잘 못 이해하고 사용하는 경우 발생할 수 있는 문제점들이 있다. 1. 지나친 단순화: 당장의 요구사항만을 만족하는 너무 단순한 시스템은 성능저하, 기능부족으로 이어질 수 있다. 단순성과 기능, 비기능의 균형이 필요하며 적절한 시스템을 설계해야 한다. 2. 복잡성 무시: 일부 시스템은 본질적으로 복잡하며 단순화하는 것이 불가능하거나 바람직하지 않을 수 있다. 이러한 경우 단순성을 강조하면 성능과 기능이 저하될 수 있다. 3. 혁신 부족: 엔지니어의 새로운 기술 도입은 혁신을 가속화 한다. 혁신을 위해서는 리스크를 감수할 수 있어야 한다. KISS 원칙은 개발자가 더 복잡한 요구사항을 효과적으로 처리할 수 있는 혁신적인 솔류션을 탐색하는 것을 방해하여 소프트웨어 개발과 창의성을 제한할 수 있다. 4. 유연성 부족: 너무 단순한 시스템은 요구사항의 변화에 적응하지 못할 수 있다. 이 경우 빈번한 재작성, 재설계를 해야할 수 있다. 요약하면 KISS는 일반적으로 좋은 설계원칙이지만 이 원칙을 적용하기 전에 시스템과 사용자의 요구사항을 먼저 고려하는 것이 중요하다. MVP(최소기능제품)을 출시하는 것은 좋은 방안이 될 수 있다. 기능이 작으면 단순함을 유지하면서도 유연성과 확장성을 가지는 아키텍처를 탐색할 시간을 벌 수 있기 때문이다. ## YANGNI  "You aren't gonna need it"의 약자다. 이는 개발자가 불필요한 기능을 추가하지 않도록 권장하는 소프트웨어 개발 원칙이다. YANGNI의 기본 아이디어는 개발자가 필요하지 않는 기능을 추가하기 전에 시스템요구사항 혹은 사용자의 요구사항을 충족하는데 필요한 기능의 구현을 우선해야 한다는 것이다. YANGNI는 단순성을 강조하는 KISS원칙과 밀접한 관련이 있다. 결국 오버엔지니어링을 피하고 가장 효율적인 방법으로 필수 요구사항을 충족하는데 집중하라는 것이다. KISS, YANGNI는 기술이라기 보다는 태도에 가까운 문제다. 아래와 같은 태도를 가짐으로써 KISS와 YANGNI 원칙을 잘 수행할 수 있다. 1. 문제를 해결하기 보다는 솔류션을 만든다. 2. 사용자 관점에서 생각 3. 컴포넌트가 아닌 시스템 관점에서 접근
Recent Posts
MLOps with Joinc - Kubeflow 설치
Vertex Gemini 기반 AI 에이전트 개발 05. 첫 번째 LLM 애플리케이션 개발
LLama-3.2-Vision 테스트
Vertex Gemini 기반 AI 에이전트 개발 04. 프롬프트 엔지니어링
Vertex Gemini 기반 AI 에이전트 개발 03. Vertex AI Gemini 둘러보기
Vertex Gemini 기반 AI 에이전트 개발 02. 생성 AI에 대해서
Vertex Gemini 기반 AI 에이전트 개발 01. 소개
Vertex Gemini 기반 AI 에이전트 개발-소개
생성 AI 모델 Flux.1 설치 및 사용
GPT를 이용한 Reranker 테스트
Archive Posts
Tags
aws
cloud
클라우드 엔니지어 면접을 위한 지식들
Copyrights © -
Joinc
, All Rights Reserved.
Inherited From -
Yundream
Rebranded By -
Joonphil
Recent Posts
Archive Posts
Tags