Kubernetes(K8s) 의 구조

  • 크게 Kubernetes Cluster가 있음
  • 그 안에 Master와 여러개의 node가 있음
  • DevOps (개발자)는 mater를 통해 개발하고 배포
  • User(사용자)는 외부에서 Service, Ingress Object를 통해 사용

  • kubectl 은 서비스 호출 클라이언트
  • master에 API 서버와 상태 저장소를 관리
  • node에 각 서버의 에이전트(kubelet)와 통신하는 구조

Master

  • Master는 API Server, Scheduler, Controller Manager, etcd로 구성됨
  • API Server
    • 대부분의 요청을 처리하는 담당, 중요한 역할 임으로 다중화를 함
    • 모든 컴포넌트들은 API 서버를 통해서 커뮤니케이션을 함
    • 인증 및 인가 기능도 보유함
  • Scheduler
    • 컨테이너를 어떤 노드에서 가동할지 결정하는 컴포넌트
    • 노드들의 정보를 파악하고 컨테이너를 가동할 노드 선택
  • Controller Manager
    • K8s 클러스터의 상태 모니터링
    • Desired state를 유지함
    • 실제 요청 된 state와 현재 시스템의 state에 차이가 있는지 감시 -> 다를 경우 같은 state가 되도록 조치
  • etcd
    • 분산 key-value 저장소임
    • 클러스터의 모든 설정, 상태 데이터를 저장함
    • Scheduler와 Controller Manager 등이 API 서버를 통해 etcd의 데이터 조회 및 갱신
    • 마스터에서 분리하여 독자적으로 구축이 가능

Node

  • Node는 kube proxy, kubelet, 다수의 pod로 구성됨
  • Kubelet
    • Master로 부터 생성 요청을 받으면 컨테이너 생성
    • 컨테이너의 상태를 모니터링
    • 컨테이너의 상태를 Master의 API 서버로 전송
  • kube proxy
    • 각 노드에서 실행되는 네트워크 프록시임
    • 노드의 네트워크 규칙을 유지 관리함
    • 내부 네트워크 세션이나 클러스터 바깥에서 컨테이너로 네트워크 통신을 할 수 있도록 
  • pod
    • 1개의 독립적인 컨테이너임
    • Kubelet이 생성 시킴

K8s Objects

  • 대규모 분산 환경에 필요한 요소들이 추상화 되어 있음
  • 컨테이너, 애플리케이션 수행 방식, 네트워크 등을 추상화 함
  • 추상화 한 것들을 Object라 함

K8s 는 기능 별로 아래와 같은 Object로 구성됨

  • Application 및 배포
    • Pod, ReplicaSet, Deployment, DaemonSet, StatefulSet...
  • 네트워크
    • Service, Ingress..
  • 설정 정보 관리
    • ConfigMap, Secrests
  • 배치 잡 관리
    • Job, CronJob

Pod

  • K8s에서 배포할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
  • Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근 할 수 있음
  • 컨테이너를 하나만 사용하는 경우도 반드시 Pod로 관리해야함

ReplicaSet

  • Pod를 여러 개 복제하여 관리
  • Pod를 생성하고 개수를 유지하려면 ReplicaSet을 사용함
  • ReplicaSet는 아래의 설정 정보를 포함
    • 생성할 Pod를 복제할 개수
    • 생성할 Pod의 설정 정보

Deployment

  • K8s에서 실제 배포를 진행하는 기본 단위
  • 배포 전략 선택
    • Rolling Update
    • Recreate
  • 배포 Revision 관리 및 Roll Back 수행
  • 배포와 관련 된 다양한 기능 및 옵션 제공

DaemonSet

  • 클러스터 전체에 Pod를 띄울 때 사용하는 Controller
  • 항상 모든 Node에 특정 Pod가 실행 됨
  • 새로운 Node가 추가되면 자동으로 Pod 실행됨
  • 로그 수집기나 모니터링 에이전트 등 실행하는 용도

StatefulSet

  • K8s의 대부분의 Objet는 Stateless임
  • StatefulSet은 state를 유지하는 Pod를 위한 Object임
  • Volume을 사용해서 데이터를 저장하고 Pod 재기동 시에도 유지 가능
  • DB 등을 컨테이너화 할 때 사용 가능

Service

  • 네트워크와 관련된 Object임
  • Pod 간 연결 및 Pod와 외부 네트워크를 연결
  • 여러 개의 Pod에 대한 내부 로드밸런서
  • 내부 DNS에 서비스 등록하여 서비스 디스커버리 역할도 수행
  • Pod에 대한 L4 로드밸런싱 수행
  • 옵션 지정 가능
    • Cluster IP : 클러스터 내부에서만 통신 목적
    • Node Port : 외부로 IP Address를 노출
    • Load Balancer : 클라우드 서비스의 Load Balancer 기능 사용

Ingress

  • 외부 트래픽을 받는 Object임
  • http / https 등 L7 레벨로 라우팅 규칙, 로드밸런싱 규칙 등도 포함함
  • Service도 외부로 노출 가능하지만 L4 레벨만 가능
  • 일반적으로 K8s 클러스터를 외부로 노출 할 때에는 Ingress 사용

ConfigMap, Sercret

  • 설정 정보를 Key/Value 형태로 저장하고 Pod에서 참조

Job, CronKob

  • 배치 처리를 위해 특정 조건에 따라 작업이 수행 됨을 보장
  • 실패하면 자동 재 시작 하여 처리

Label과 Selector

  • K8s 내부 자원 관리를 위해 Label을 붙임
  • Selector를 이용해서 특정 Label이 붙여진 자원을 Filtering

Manifest 파일

  • K8s에서 선언적 설정을 위해 Manifest 파일을 사용함
  • YAML, Json 과 같은 파일로 작성 함
  • 리소스의 종류와 원하는 상태를 입력함
  • 식당 주문서와 유사함
  • Master 로 명세 파일을 제출하면 Master 에서 읽고 명세된 정보가 유지되도록 실행
  • 구성 요소
    • apiVersion : K8s API 버전 정보 
    • kind : Object의 종류
    • metadata.name : Object의 이름
    • spec : Object의 상세 정보

 

MSA를 구축하고 호스트 서버, 컨테이너를 관리할 때에는 아래의 기능이 필요

  1. 대량의 컨테이너를 쉽게/자동으로 관리하기 위해 사용
  2. 다수의 호스트(서버)를 하나의 클러스터처럼 사용
  3. 여러 개의 호스트(서버)에 컨테이너 배포
  4. 서비스 디스커버리로 서비스들을 연결
  5. 부하가 생기면 서버를 자동으로 Scale-out
  6. 장애가 발생하면 기존 컨테이너 kill 후 새로운 컨테이너 다시 생성
  7. 컨테이너 Health Check
  8. 컨테이너 간 Storage 및 Network 관리

Kubernetes

  1. 컨테이너 오케스트레이션 도구
  2. 분산 환경에서 대규모의 컨테이너 관리
  3. 이외 Docker Swarm, Apache Mesos/Marathon 등 도구들이 있음
  4. Kubernetes가 그중 거의 표준처럼 사용
  5. 멀티 호스트에서 컨테이너 관리
  6. 컨테이너 배포
  7. 컨테이너 간 네트워크 관리
  8. 컨테이너 모니터링
  9. 컨테이너 업데이트
  10. 장애 발생 시 자동 복구

Kubernetes 철학

  1. 철학 1 : Immutable Infrastructure
    1. 클라우드 환경에서 자원들을 간단하게 구축하고 파기 가능
    2. 한번 구축한 인프라는 수정하지 않음
    3. 원하는 상태를 만들어서 새로운 환경을 구축
    4. 현재 운영되고 있는 인프라의 상태를 관리
    5. 서버의 Java version은 올려야 하는 경우 업데이트한 Java version을 담고있는 컨테이너를 배포
  2. 철학 2 : Declarative Configuration
    1. 명령형이 아닌 선언형
      1. 구구절절 노노 -> 정해진 것 하나 shell 스크립트 하나 실행 시키듯.
    2. 원하는 상태를 만들기 위해 명령어를 하나 씩 치는 방식이 아님
    3. 원하는 상태를 기술하여 Kubernetes에 적용
    4. 원하는 상태 = 시스템이 되어 있어야 할 모습
      1. 앱을 클러스터 안에서 몇 개 올릴지
      2. 네트워크 구성은 어떻게 되어야 할지
    5. Desired State


      어떤 컨테이너들이 어떤 노드 위에서 동작 할지
      1. 컨테이너들이 replica set이 몇 개가 되어야하는지 등.. 
      2. 관리자가 최종적으로 바라는 상태
      3. 현재 상태를 실시간 모니터링
      4. 관리자가 설정한 원하는 새로운 상태를 주문하거나 클러스터의 상태가 변경되면  Kubernetes가 원하는 상태로 조정
  3. 철학 3 : Self Healing
    1. 장애 발생 시 자동으로 복구
    2. 사람의 개입을 최소화 함
    3. 시스템이 되어 있어야 하는 상태를 항상 감시
    4. 원하는 상태와 다를 경우에 자동으로 복구

 

 

 

 

Docker Swarm

  1. 설치와 사용이 Kubernetes에 비해 단순
  2. 단 대용량 분산환경에서 사용하기에는 기능이 부족
    1. 모니터링 기능 부재
    2. 스토리지 옵션 기능 부재

Apache Mesos/Marathon

  1. 분산 시스템 커널
  2. 분산 된 CPU, memory, storage 등을 추상화 하여 하나의 단일 리소스처럼 만듦
  3. Marathon은 컨테이너 관리 도구
  4. Mesos와 Marathon의 통합으로 대규모 환경의 컨테이너들을 관리할 수 있음

 

도커

  1. 컨테이너라는 독립적인 공간에서 동작하는 프로세스를 제공함
  2. 가상화 기술 중 하나
  3. 기존의 가상화 방식은 주로 OS를 통째로 가상화했음
  4. 동일한 컨테이너로 동작 시킬 시 컨테이너 위에서 동작하는 Application은 모두 동일한 환경(OS, 언어 런타임, 프레임워크 버전 등)에서 동작하게됨
  5. 변화하지 않는 실행 환경으로 Idempotency 확보
  6. 모든 대상 환경에 Dockerfile 파일을 통해 실행 환경 구축 가능
  7. 시스템을 구성하는 Application 및 미들웨어의 관리 용이성 증가

왼쪽 기존의 VM을 이용한 가상화, 오른쪽 도커 컨테이너를 이용한 가상화

MSA에 대한 성숙도 평가 방법은 표준은 없음

표준은 없으나 어느 정도 참고할만한 자료들이 있음

아래 2가지 사례는 유명 기업에서 사용하고 있는 평가 지표임

Rajesh RV 성숙도 모델

Application, Database, Infrastructure, Monitoring, Process 로 구분하여 Level을 적용함

  1. Application : 모놀리틱 -> API 기반 
  2. Database : 1개의 Fit한 DB -> Data Lake, 실시간 분석
  3. Infrastructure : 물리적 기계 -> 컨테이너
  4. Monitoring : 인프라만 모니터링 -> 로그 매니징 기반 중앙화
  5. Process : 폭포수 -> DevOps

Rishi Singh 제안 성숙도 모델

총 9개 영역에서 4 단계의 성숙도로 평가

  • Expanding 단계가 현실적인 MSA 수준임
  • Mature 단계는 이상적인 MSA 수준임 

마이크로서비스를 도입하는데 앞서 아래 4가지 capabailties이 내재되어 있어야함

Core capabilities- 서비스 별 배포 되는 SW 패키지에 필수 요소

Supporting  capabilities  - 지원 기술 및 설계 패턴

Infrastructure capabilities  - 컨테이너 및 컨테이너 오케스트레이션

Process & Governanace capabilities   - DevOps 및 문서화 

MSA 도입을 위해 필요한 4가지 역량(Core, Supporting, Infrastructure, Process & Governanace)


Core capabilities

 

Core capabilities은 단일 서비스 내에 패키징 되는 SW 컴포넌트들(구현체) 이다.

  • 서비스 Listener : 외부로부터 request 받았을 때 Endpoint로 전달하는 역할
  • Endpoint : 받은 request를 SW 컴포넌트로 전달하는 역 
  • Application  : 서비스 구현체 
  • 데이터 저장 : 단일 서비스의 데이터를 담고 있는 저장소

서비스 Listener

  • HTTP 등의 Listener 가 애플리케이션에 내장되어 있어야함
  • 새로운 서비스를 개발 했을 때 배포를 쉽게 하기 위함
  • 일례 : Web Server, Web Application Server, Spring Boot 같은 Self Contained 방식
  • tomcat 등의 WAS가 설치 되어 있고 앱을 WAS에 배포하는 형식은 하면 안됨, 새로운 서비스에 대한 배포가 힘듬

Endpoint

  • HTTP 요청을 받아 처리 할 API가 애플리케이션 내부에 있어야함
  • 다양한 프로토콜 사용 가능

Application

  • 서비스 로직의 구현체
  • 로직은 단일 책임의 원칙을 지켜야 함 (1기능만 수행)
  • 응집도 높게 구현, 계층형 아키텍처를 사용하는 것이 좋음
  • Hexagonal architecture를 만족해야함
    • 외부 기술과 분리시켜야함
    • 일례 1 DB를 무엇을 쓰던 비즈니스 핵심 로직은 변경이 필요 없어야함
    • 일례 2 Queue를 무엇을 쓰던 비즈니스 핵심 로직은 변경이 필요 없어야함
    • 일례 3 모바일/웹 등 UI에 따라서도 비즈니스 핵심 로직은 변경이 필요 없어야함

데이터 저장

  • 각 서비스 마다 데이터를 저장할 데이터 소스가 있어야 함
  • 데이터소스는 하나의 서비스에 한정 되야 함
  • 각각의 서비스는 데이터에 대해 독립적 이어야

Infrastructure capabilities

Infrastructure capabilities 아래 3가지의 역량이 필요함

  1. 클라우드
  2. 컨테이너 런타임
  3. 컨테이너 오케스트레이션

클라우드

  • On Demand
  • 대용량 확장 가능한 환경
  • 몇 번의 클릭만으로 리소스 사용 가능해야함
    • Auto Scaling으로 자동화 된 Provisioning
  • 다양한 자원/서비스 제공
    • 컴퓨팅 자원, DB, NoSQL, Big Data, AI

컨테이너 런타임

  • 각 서비스들이 다양한 기술 사용
  • 수백/수천 개의 인스턴스에 배포 해야함
  • 컨테이너 기술을 이용하여 빠른 환경 구성 및 배포 필요
    • 컨테이너 이미지에는 런타임과 코드가 동시에 존재
  • Docker

컨테이너 오케스트레이션

  • 많은 수의 컨테이너의 관리 역량 필요
  • 배포, 모니터링 등 운영 관리 비용을 최소화 하기 위함
  • Kebernetes

Supporting  capabilities 

  1. Service Discovery
  2. Config Server
  3. API Gateway
  4. SW Defined Load Balancer
  5. Circuit Breaker
  6. Distributed Tracing
  7. Data Lake
  8. Messaging

 

Service Discovery

  • 서비스 개수 및 인스턴스 개수가 급증함으로 전체 Topology가 복잡해
  • 한 서비스에서 다른 서비스를 호출 할 때 필요한 정보를 유지하는 것이 복잡해짐 (Service IP, Port 등..)

Service A가 Service B를 호출 할 필요한 정보 다루는 것은 Service가 증가 할 수록 복잡해짐

  • 중앙에서 시스템의 모든 서비스에 대한 정보를 저장
  • 새로운 인스턴스가 생성되면 중앙 시스템에게 자신의 정보를 등록
  • 서비스 간에는 다른 서비스의 정보를 유지해야 하는 기능을 제거
  • DNS 서버를 이용 하듯이 서비스를 호출할 인스턴스는 호출할 서비스의 이름(getAccount 등..)을 이용해 호출
  • 중앙 시스템은 인스턴스 및 서비스를 추가 삭제 가능해야함

Register -> Discovery -> Connect

 

Config Server

  • MSA를 도입하면 서비스가 많아 지면서 Config 파일, OS 설정 파일들의 갯수가 급증함
  • Service 구동 환경마다 새롭게 빌드/패키징을 해야하게 됨
  • 중앙 Config Server에서 설정 관리, 저장 Backend는 Git, DBMS를 사용함
  • 서비스들은 Application Runtime 중에 중앙 Config Server를 통해 정보를 획득
  • 설정 정보가 변경된다면 중앙 Config Server의 설정 파일을 툴을 이용해 변경

각각의 마이크로 서비스들은 Application Runtime 중에 중앙 Config Server로 부터 정보를 가져와서 수행!

Service Gateway

  • 다양한 서비스들에 대한 단일 진입 점을 제공
  • 인증, 인가, 로깅, 필터링 등의 공통 처리 수행
  • 서비스에 문제 발생 시 요청을 차단하거나 대안 경로로 변경하는 기능 수행

 

SW Defined Load Balancer

  • 서비스를 호출하는 클라이언트에서 SW로 Load Balancing 수행

전통적인 Load Balancer 구조
Service에서 코드레벨로 Load Balancing을 구현이때 중앙 시스템의 도움을 받음

Circuit Breaker

  • 서비스 장애 시 장애 전파를 막기 위함

Service C에서 오류가 생겼음에도 Service A,B 모두 오류 발생

 

  • 특정 Servivce의 장애는 그 Service만의 장애로 격리시키는 것이 중요함
  • Service 간의 Circuit Breaker 컴포넌트 도입
  • Service에게 요청했을 때 해당 요청은 Circuit Breaker를 통해 요청
  • Circuit Breaker를 연결되어있는 Service를 모니터링하여 문제 발생이 예측되는 경우 차단 시킴
  • Circuit Breaker에 의해 차단된 Service는 정상화 작업 수행 (문제 분석 -> 코드 수정 -> 빌드 -> 테스트 -> 배포)

 

Circuit Breaker가 Service C 호출을 막음

 

Distributed Tracing

  • 서비스 간 모든 호출에 추적 ID를 삽입 (ID 예시 : 암호화한 문자열, 암호화한 정보)
  • 추적 ID를 Key로 하여 단일 API 트랜잭션 활동을 파악

Zipkin을 이용한 호출 ID 추적

Data Lake

  • 비정형 raw 데이터를 그대로 저장( Hadoop, HDFS이용)
  • 데이터 분석 시점에 데이터 가공
  • 전통적인 ETL이 아닌 실시간 Data Ingestion 도구 사용 (Flume, Kafka, Logstash...)

Messaging

  • Messaging 기반 이벤트 주도 설계는 서비스 간 결합도를 낮춤
  • 고가용성의 Messaging 솔루션 필
  • RabbitMQ, ActiveMQ, Kafka, AWS Kinesis

Process & Governanace capabilities 

  1. DevOps
  2. 자동화 도구
  3. 컨테이너 레지스트리
  4. 문서화
  5. 참조 아키텍처 및 라이브러리

DevOps

  • 애자일과 DevOps는 필수임 (조직에 맞는 방법론을 선택 후 실행)
  • 한팀에서 지속적 통합, 배포, 운영, 모니터링이 되어야함
  • 애자일을 도입하여 짧은 개발 주기로 반복하여 빠른 업데이트 및 배포 (자동화!!!)
  • 통합, 배포, QA 모두 자동화!!

자동화 도구

  • 다수의 서비스를 테스트, 배포, 운영 가능 하도록 하는 자동화 도구를 갖춰야함
  • 테스트, 배포, 모니터링 경보 자동화

컨테리어 레지스트리

  • MSA에서 컨테이너는 필수임
  • 코드 형상 관리와 같이 이미지도 형상 관리를 해야함
  • Docker Hub, GCR, ECR ...

문서화

  • 서비스들은 인터페이스를 기준으로 통신함
  • 인터페이스 문서화!!
  • 인터페이스 문서는 아래 정보를 내포함
    • 필수/선택 파라미터
    • 버전
    • 응답 정보
    • 에러 코드
  • 인터페이스 정보는 웹으로 쉽게 열람할 수 있어야 함
  • Spring REST Docs, Swagger ...

참조 아키텍처 및 라이브러리

  • 탈중앙화 된 방식은 비효율성을 야기 할 수 있음
    • 서로 다른 아키텍처로 인한 유지 보수성 악화
    • 동일한 기능의 재개발
  • 조직의 기술 별 참조 모델, 아키텍처는 중요
    • 참조 아키텍처는 사내 프레임워크화 할 수도 있음 -> 전사 개발 팀들은 프레임워크를 기반으로 Service를 개발
  • 중족 개발을 막기위해 사내 오픈소스 라이브러리 활동
    • 사내 인프라에서 기능 검색
    • 사내 프레임워크 개발 활동에 대한 보상

 

 

 

 

 

마이크로서비스의 장점

  1. 작은 서비스 단위로 확장 가능
    1. 필요하면 추가하여 개발
    2. 다른 서비스와는 공통 인터페이스만 맞추면 됨
  2. 일부의 장애가 시스템 전체 장애로 이어 지지 않음
    1. 각 서비스 개별적인 장애는 다른 시스템에 장애를 일으키는 영향력이 적음.
  3. 서비스 단위로 자율적 배포 가능
    1. 각 서비스를 개발한 팀들은 기능 변경이 필요한 경우 개별 적으로 개발 후 배포
    2. 각 서비스들은 서로 다른 언어, 기술 스텍들을 이용해 개발할수있음.
  4. 빠르게 변화하는 비즈니스 환경에 민첩하게 대응 가능
    1. 각 서비스들은 성능 문제가 생기면 언어/프레임워크 자체를 교체하여 새롭게 개발할 수 있음.

-> 개인 의견 : 위 4개의 항목은 마이크로서비스의 SW 품질 요구 사항 같음

 

마이크로서비스의 단점

  1. 컴퓨팅 자원의 사용이 모놀리틱 보다 비효율적
  2. 성능 - 프로세스 내부 호출 보다 느리다.
  3. 메모리 - jvm 등 중복적인 자원 사용
  4. 운용 관리가 어려움
  5. 모니터링 대상 증가
  6. 배포 대상 서비스 증가 및 기술의 다변화
  7. 다양한 장애 상황 발생
  8. 단위 테스트 컴포넌트 테스트 난이도 증가
  9. DB 트랜잭션 처리 어려움
  10. 서비스 간 Polyglot Data Store 사용
  11. 분산 환경에서 트랜잭션 어려움

-> 개인 의견 : 1개의 서비스를 개발하던 팀이 통째로 나간다면..?? 그리고 단점이 생각보다 많음.

가장 큰 문제는 데이터의 일관성, 성능 문제 같음

마이크로서비스에서 요구하는 기술들

  1. Cloud 
    서비스 여러개를 배포하여 운영하는 클라우드
  2. NoSQL
    개별 서비스는 각기 다른 SQL과 개별 저장소를 이용하여 서비스를 운
  3. Docker, Kubernetes & Ecosystem
    도커 컨테이너를 이용해 편해진 배포 시스템
  4. Netflix OSS
    넷플릭스에서 배포한 마이크로서비스 지원 라이브러리
  5. 이외 여러 적용 사례 들 (아마존, 넷플릭스 등..)

 

 

 

 

 

마이크로서비스란?

  1. 별도의 프로세스에서 실행
  2. HTTP API 같은 가벼운 매커니즘으로 통신하는 작은 애플리케이션
  3. 여러개의 분리되어있는 서비스들은 각자의 비즈니스 기능을 담당함
  4. 자동화 된 절차에 따라 서비스들은 독립적으로 배포됨
  5. 각 서비스는 서로 다른 프로그래밍 언어로 개발되어도 괜찮고, 서로 다른 데이터 저장소를 사용할 수 있음

(왼)우리가 사용하는 넷플릭스, (우) 넷플릭스는 수많은 서비스들의 조합으로 비즈니스 기능을 수행

마이크로서비스 관련 유명한 글 : https://martinfowler.com/articles/microservices.html

 

Microservices

Defining the microservices architectural style by describing their nine common characteristics

martinfowler.com

 

아마존의 모놀리틱시스템에서 마이크로서비스로 도입할 때 적용 규칙

  1. 모든 팀은 해당 팀의 기능 및 데이터를 Service Interface를 통해서만 노출 해야 한다.
  2. 다른 팀의 기능/데이터를 사용하려면 Network를 통한 Service Interface를 호출해야 한다.
  3. Service Interface 기술을 상관 하지 않겠다.(HTTP, Corba, etc.)
  4. 누구든 이것을 지키지 않으면 해고하겠다.

아마존의 수많은 서비스들의 조합

넷플릭스에서 오픈소스로 개발한 아키텍처 패턴 및 OSS (Netflix OSS)

우리는 해당 시스템을들 이용하여 상대적으로 편하게 마이크로 서비스를 구현하면 됨

 

 

Mediator 패턴 그림

 

Mediator 패턴 개념

여러 객체 간의 통신을 관리하고, 각 객체가 서로 직접 참조하지 않고 중재자를 통해 통신할 수 있게 해주는 디자인 패턴. 통신 시스템에 적용하면, 모듈 간의 복잡한 상호작용을 단순화하고, 시스템의 결합도를 낮출 수 임.

 

Mediator 구성 요소

 

  • Mediator(중재자): 여러 객체 간의 통신을 중재하고 조율하는 객체.
  • Colleague(동료): Mediator를 통해 다른 객체와 상호작용하는 객체.

 

C++ 코드

Mediator 인터페이스 정의

class Colleague;

class Mediator {
public:
    virtual void sendMessage(const std::string &message, Colleague *colleague) = 0;
    virtual void registerColleague(Colleague *colleague) = 0;
};

 

 

Colleage 클래스 정의

class Colleague {
protected:
    Mediator *mediator;
public:
    Colleague(Mediator *m) : mediator(m) {}
    virtual void receiveMessage(const std::string &message) = 0;
};

 

Concrete Mediator 및 Concreate Colleague 구현

#include <vector>
#include <iostream>

class ConcreteMediator : public Mediator {
private:
    std::vector<Colleague*> colleagues;
public:
    void sendMessage(const std::string &message, Colleague *sender) override {
        for (auto colleague : colleagues) {
            if (colleague != sender) {
                colleague->receiveMessage(message);
            }
        }
    }

    void registerColleague(Colleague *colleague) override {
        colleagues.push_back(colleague);
    }
};

class ConcreteColleague : public Colleague {
public:
    ConcreteColleague(Mediator *m) : Colleague(m) {}

    void receiveMessage(const std::string &message) override {
        std::cout << "Colleague received: " << message << std::endl;
    }

    void send(const std::string &message) {
        mediator->sendMessage(message, this);
    }
};

 

사용 예제

int main() {
    ConcreteMediator mediator;

    ConcreteColleague colleague1(&mediator);
    ConcreteColleague colleague2(&mediator);

    mediator.registerColleague(&colleague1);
    mediator.registerColleague(&colleague2);

    colleague1.send("Hello from colleague 1");
    colleague2.send("Hello from colleague 2");

    return 0;
}

'Program > SW Design Patterns' 카테고리의 다른 글

CH8 스테이트 패턴  (0) 2023.12.04
CH7 어댑터&퍼사드 패턴  (0) 2023.03.19
CH6 커맨드 패턴  (0) 2023.03.07
CH5 데코레이터 패턴  (1) 2023.03.05
CH4 팩토리 패턴  (0) 2023.03.04
생각 없이 행할 수 있는 중요한 작업의 수가 늘어남에 따라 문명은 발전한다.
- Alfred North Whitehead

책에서 말한 Progmatic Starter Kit 은 아래 3가지 주제를 다룬다.

  1. 버전 관리
  2. 회귀 테스트
  3. 전체 자동화


1. 버전 관리

tip 89 버전 관리 시스템으로 빌드, 테스트, 릴리즈를 운용하자.

버전 관리 시스템의 커밋, 푸시로 빌드와 테스트, 배포가 시작된다.
빌드 : 클라우드의 컨테이너 위에서 빌드한다.
배포 : 빌드한 릴리즈 파일은 아래 2가지 서버 중 한 곳에 태그를 사용하여 지정한다.

  1. 테스트용 staging 서버
  2. 실제 서비스

key : 빌드 장비, 개발자의 장비에 의존하지 않고 지속적 배포가 가능해야함.
전체 흐름 : 커밋 or 푸시 -> 빌드 -> 배포(staging 서버 or 운용 서버)


2. 회귀 테스트

tip 90 일찍 테스트하고, 자주 테스트하라. 자동으로 테스트하라.
tip 91 모든 테스트가 끝날 때 까지는 코딩이 끝난게 아니다.
tip 92 버그를 심어 놓고 테스트를 테스트하라.
tip 93 코드 커버리지만 올리지 말고 상태 조합을 테스트하라.
tip 94 버그는 한 번만 잡아라.


자동 빌드가 모든 가용한 테스트를 수행한다.
실제 상황과 같은 테스트를 목표로 하는 것이 중요하다.
테스트 종류는 아래 4가지이며, 4가지를 갖춰도 완벽한 테스트를 한 것은 아니다.

  1. 단위 테스트(unit test) : 하나의 모듈을 테스트 (함수, Class)
  2. 통합 테스트(integration test) : 프로젝트를 구성하는 서브 시스템이 다른 서브 시스템들과 제대로 작동하는지 테스트 (시스템 연동 테스트)
  3. 유효성 평가 및 검증(validation and verification) : 사용자들이 필요로 한 것인지, 시스템의 기능적 요구 사항을 충족하는 것인지 확인
  4. 성능 테스트 (performance test) : 예상하는 사용자 수, 접속 수 혹은 초당 트랜잭션 숫자를 수용 하는가? 주기성을 만족 하는가?

한번 버그를 발견 했다면, 해당 버그를 발견하는 테스트 코드를 추가하자.

3. 전체 자동화

tip 95 수작업 절차를 사용하지 말라.

rsync, ssh를 넣은 셸 스크립트 부터 시작해서 Ansible, Puppet, Chef, Salt 처럼 좋은 기능을 갖춘 패키지를 사용하여 시스템을 전체 자동화 하자.
수작업 단계를 단 1개도 넣지 말자.


직접 찾아본 자동화 툴과 특징
1. Github Action(public 무료, private 유료)

가능한 자동화 : 빌드 -> 테스트 -> 배포 파이프라인
특징 :
Workflows, Events, Jobs, Steps, Actions, Runners 등 몇가지 구성 요소를 알고 있어야함.
yaml 파일 사용
컨테이너 기반 동작

2. Jenkins (무료)


가능한 자동화 : 빌드 -> 테스트 -> 배포 파이프라인 자동화
특징 :
Pipeline, Node, Stage, Step 등 몇가지 구성 요소를 알고 있어야함.
Declarative Pipleline 또는 Scripted Pipleline 2가지 방식으로 사용
외부 컴포넌트에 대해 Plugins 기능 제공 (Git Plugin, Pipeline 등…)
Jenkinsfile 파일 사용

3. 그외… AWS CodeBuild, Azure DevOps, Bamboo, Argo CD, 트래비스 CI


내가 사용한다면..?
1. 현재 사용 중인 언어 : C, C++, C#, python
2. 모의기 GUI framework : WPF
3. 사용중인 framework : .NET Framework
3. 주요 OS  : Ubuntu 20.04, Windows 10, 11
4. 사용 중인 컴파일러 : gcc, .NET

opencv 라이브러리를 호스트 시스템에서 크로스 컴파일하여 타깃 시스템에서 사용 할 경우

 

1. 타겟 시스템에서 원하는 opencv 버전을 설치한다. (apt-get install -> make -> install 까지 모두!!)

이유 : 타겟 시스템 (CPU) 에 맞게 컴파일한 opencv lib, include 파일 들을 생성하기 위함

2. 타겟 시스템에서 usr 폴더를 복사한다!

opencv가 설치된 /root/usr/include, /root/usr/lib 등..

이유 : 타겟 시스템에 맞게 컴파일한 opencv 를 가져오기 위함.

 

3. 호스트 PC의 작업 환경의 sysroot 폴더로 복사한다.

-> 예시 : 

폴더 workspace

      -> 파일 main.c

      -> 파일 main.h

      -> 폴더 sysroot 

           -> 폴더 usr

                -> 폴더 bin

                    ...

                -> 폴더 include
                    ...

                -> 폴더 lib

                    ...

                -> 폴더 sbin

                ...

     

4. 크로스 컴파일 명령어

gcc --sysroot=./sysroot -I/usr/local/opencv/include/opencv4 -L/usr/local/opencv/lib -static -lopencv_core -lopencv_imgcodecs -lopencv_highgui -o main ./main.c

 

5. 크로스 컴파일 후 해당 실행파일을 타겟 시스템에서 실행!!

+ Recent posts