Speaker
Android
민경운 : 실 프로젝트에서 CleanArchitecture 적용기
이상은 : 안드로이드 유지보수 정착기
iOS
길준호 & 정기욱 : Core ML과 Vision Framework
BackEnd
이재성 : 고 언어로 간단한 영상 스트리밍 서버 만들기
장호동 : 동시성 및 병렬 처리에 관한 고찰 in 서버 / DB
고영훈 : Service Architecture
먼저 Android 직군 세션 발표 부터 살펴 보겠습니다.
첫번째 발표는 현재 DDD 안드로이드 운영진 으로 활동하고 계신
민경운(갱스터)님이 발표를 진행 하셨습니다 :)
“ 프로젝트 시작 시 아키텍처 고민 사항 ”
어떻게 하면 각각의 DI(Dependency Injection) 결합도 낮출까?
어떻게 하면 재 사용성 이 높은 코드가 나올까?
어떻게 하면 테스트코드 짜기 용이한 구조로 만들수있을까?
….
“ CleanArchitecture ”
클린 아키텍처 라는 말은 2012년도에 나왔습니다.
해당 글은 적용 기에 다루는 내용이라 보다 자세히 알고 싶으신분은
여기 를 참고 하시길 바라겠습니다.
“ 적용 후 ”
좋다고 생각되었던 부분
- 재 사용성
- 보다 낮은 의존성 관계
- 테스트 코드 용이
현재까지의 고민 혹은 단점
- 각 레이어의 entity를 어디까지 가지고 있어야 될까?
- 초반의 러닝커브
이어서 두번째 발표자는 현재 DDD 안드로이드 운영진 으로 활동하고 계신
이상은님이 발표를 진행 하셨습니다 :)
안드로이드 앱 유지보수?
주니어 개발자가 처음 안드로이드 앱 유지보수 업무를 맡았을 때 무엇부터 시작해야 할까요?
이번 발표에서는 실제 업무에서 접하게 되는 환경 측면에서의 이슈 그리고 이슈를 처리 절차를 개선한 과정에 대해 들려주셨습니다.
다음은 iOS 직군 세션 발표를 살펴보겠습니다.
발표는 DDD. 3기 정기욱님이 진행해주셨고, 실습은 DDD. 3기 길준호님이 진행해 주셨습니다!
Core ML?
Core ML은 Apple에서 제공하는 Machine Learning Framework입니다.
WWDC 2017에서 처음 공개되어, WWDC 2019에서 Core ML 3를 발표했습니다.
Vision?
Vision Framework는 이미지 & 동영상 분석 알고리즘을 지원하는 Framework 입니다.
Apple의 Machine Learning 학습 기법
일반적인 Machine Learning 학습 기법은 여러 개의 심층 신경망을 거쳐 이미지의 특징을 뽑아내어 분류 하는 방법입니다.
하지만, Apple의 ML Framework는 Transfer Learning (전이 학습) 기법을 사용합니다.
Transfer Learning을 설명하기 위해서 다음과 같은 예시를 들 수 있습니다.
우리가 영어를 공부하게 되면 1번의 Hello를 읽을 수 있습니다. 그렇다면 2번과 3번은 스페인어와 프랑스어를 공부해야 읽을 수 있을까요?
언어는 서로 달라도 알파벳에 근거한 표기법을 사용하기 때문에 우리는 Ola, Bonjour를 읽을 수 있습니다.
이러한 학습 기법을 Transfer Learning이라고 합니다.
Apple에서의 Transfer Learning은 아주 간단합니다.
신경망 앞 단의 Freezing Layer는 미리 학습된 데이터를 사용하고, Labeling 된 데이터를 신경망의 끝 부분에서만 학습시켜, 미리 학습된 부분을 거치지 않고도 학습시킬 수 있게되었습니다.
데이터를 학습 시키는 방법은 Sliding Window 기법을 사용합니다.
다양한 Scale의 Window를 이미지의 왼쪽 위부터 오른쪽 아래까지 Sliding 하며 Score를 계산합니다.
이를 통해 적합한 이미지 영역을 찾아 학습합니다.
그렇다면 Core ML과 Vision Framework를 사용하여 앱을 만들기 위해서 이러한 이론을 모두 알아야 할 수 있을까요?
다음은 Create ML을 이용해 직접 ML을 만들어보는 시간을 가졌습니다.
Live Capture를 이용해 카카오 캐릭터를 분류하는 예제와 ImagePicker를 사용해 선택한 카카오 캐릭터 이미지를 구분하는 예제를 만들어보았습니다.
실습 프로젝트 예제와 방법은 준호님께서 YouTube 영상으로 제작해주셨습니다.
다음은 Backend직군 세션 발표를 살펴보겠습니다.
첫번째 발표는 DDD.3기 이재성님께서 진행해주셨습니다.
재성님은 Go 언어를 이용하여 RTMP 서버를 구축한 경험을 공유해주셨습니다.
RTMP 란?
리얼 타임 메시징 프로토콜 (Real-Time Messaging Protocol)로 오디오, 비디오 및 기타 데이터를 인터넷을 통해 스트리밍할 때 쓰이는 하나의 통신 규약입니다.
이 외에도 P2P통신으로 이루어지는 WebRTC, SSL이 적용된 RTMPS, HTTP 기반 적응 비트 전송률 스트리밍 통신 프로토콜 HLS 등의 선택지가 있었다고 소개를 해주셨는데요.
그 중 재성님은 twitch에서 사용중인 RTMP를 구현한 내용을 소개해주셨습니다. 데모를 위해 직접 서버 구축, Android 를 구현하여 핸드폰으로 찍는 영상을 실시간으로 전송하는 과정을 보여주셨습니다.
두번째 발표는 DDD.3기 장호동님께서 진행해주셨습니다.
호동님은 우리가 대학에서 이론적으로만 배웠던 동시성, 병렬처리에 대한 내용을 실무에서 어떻게 처리를 하는지, 개념부터 적용사례까지 코드를 통해 설명해 주셨습니다.
ACID 기본 개념
- 원자성(Atomicity)
트랜잭션은 더 이상 분해가 불가능한 업무의 최소 단위이므로, 전부 처리되거나 아예 하나도 처리되지 않아야 한다. - 일관성(Consistency)
일관된 상태의 데이터베이스에서 하나의 트랜잭션을 성공적으로 완료하고 나면 그 데이터베이스는 여전히 일관된 상태여야 한다. 즉, 트랜잭션 실행의 결과로 데이터베이스 상태가 모순되지 않아야 한다. - 격리성(Isolation)
실행 중인 트랜잭션의 중간결과를 다른 트랜잭션이 접근할 수 없다. - 영속성(Durability)
트랜잭션이 일단 그 실행을 성공적으로 완료하면 그 결과는 데이터베이스에 영속적으로 저장된다.
Dirty Read와 같이 DB에서 발생할 수 있는 격리성(Isolation)의 사례를 소개해주셔서 실제 실무에서 어떤 점을 조심해야하는지에 대한 발표를 진행해주셨습니다.
세번째 발표는 DDD.3기의 운영진으로 활동하는 고영훈님께서 발표를 진행해주셨습니다.
영훈님은 Service 의 Architecture 와 Pattern 들에 대해서 소개를 해주셨습니다. 그 중에서도 MSA(MicroService Architecture)를 중심으로 기본 개념부터 MSA 를 사용하기 좋은 상황들에 대해 소개해주시고, 보완할 수 있는 Pattern 에 대한 내용을 공유해주셨습니다.
MSA란?
Monolithic Service 가 커지면 강결합에 따른 Side Effect 와 Service 개발 및 운영에서 Scale 조정, Update 등에 있어 전체 Service 를 건드려야 한다는 불편함이 발생합니다. 그래서 기존의 Monolithic 방식에서 MSA (Micro Service Architecture) 가 등장 하게 되었습니다.
MSA 의 가장 큰 장점은 Service 별 독립적으로 개발, 배포 및 운영이 가능하고, Service 간의 강결합이 없다는 점입니다. 이로 인해 Monolithic 과 달리 전체 Service 가 실패하는 확률을 줄이고, 각 Service 별 Isolation 이 보다 쉬워집니다. 또한, Containerized Application 에 보다 적합한 Architecture 로 분산 컨테이너 환경 등 대규모 분산 시스템에 보다 적합합니다. 그러나 모든 면에서 효율적인 것이 아니기 때문에 본인이 구현하는 서비스의 규모와 성격을 잘 분석해서 적절한 Architecture 와 Pattern 을 찾아 적용하는 것이 가장 중요합니다.
위의 그림에 나타나 있듯이 Microservice 를 구성할 때에는 기본적인 세 가지 디자인 원칙이 있습니다.
- 단일 목적 (Single Purpose): 각 Service 는 하나의 목적 (Purpose) 에 초점을 맞춰야한다.
- 느슨한 결합 (Loose Coupling): Service 간 서로에 대해 간섭하지 않고, Service 간의 통신은 Public Service Interface 를 통해서만 이루어진다.
- 높은 결합력 (High Cohesion): 각 Service 는 행위와 Data 를 Encapsulation 한다.
이러한 디자인 원칙을 지키기 위해서는 MSA 를 구현, 설계함에 있어서 각 Service 간의 경계를 나누는 것이 중요한데, Microservice 에서 Service 간의 경계를 나누는 방법으로는 DDD (Domain Driven Design) 의 Bounded Context 와 Aggregate 를 이용하는 방법, REST 에서의 Resource 를 이용하는 방법 등을 사용하여 각 Service 간의 경계를 만들고 구현할 수 있습니다.
You build, You run — DevOps, Amazon
MSA 는 어쩌면 DevOps 를 구현하고 실현할 수 있는 가장 좋은 방법 중 하나일 수 있습니다. 그러나 DevOps 가 가지는 빠르고, 안정성, 확장성 등의 이점을 가질 수 있지만 이를 이용하기 위해서는 높은 운영 능력, 보다 복잡한 장애 처리 등 고려해야할 사항들이 있습니다. MSA 를 구현할 때 고려해야할 사항으로는 Monolithic 과 비교했을때 MSA 로 구현했을때의 복잡도와 규모 대비 Monolithic 보다 구현, 운영 등에서 이점을 가져갈 수 있는지, Service 간 Transaction 구현, Latency 관리, DE-Centralized Governance 를 사용하게 될때 Alignment 조율 등을 잘 할 수 있는지 확인이 필요합니다.
MSA 를 소개하고 , 이어서 복잡한 CRUD Application 을 구현할때 사용할 수 있는 CQRS (Command Query Responsibility Segregation) 을 소개했습니다.
CQRS 란?
Command Query Responsibility Segregation 의 약자로 Application 의 Command 와 Query 를 분리하여 구현하는 Pattern 을 말합니다. 이는 Command (Create, Update, Delete) 와 Query (Read) 를 분리하여 복잡한 Domain model 을 구현하고, 요구사항 변경으로 인한 Domain Model 의 변질을 방지할 수 있습니다.
CQRS 에는 구현 복잡도가 다른 세 가지 등급의 방식 Regular, Premium, Deluxe 가 있습니다.
첫 번째로 가장 간단히 구현할 수 있는 Regular 입니다. 이 Model 은 단일 Data Store 를 사용하고, Application 안에서 Command 와 Query 를 분리하는 방식입니다. 이는 구현에 있어서는 간단하게 할 수 있지만, 이와 같은 구조는 하나의 단일 Data Store 를 사용하기 때문에 Database 의 성능 개선이 어려울 수 있습니다.
두 번째는 Command Data Store 와 Query Data Store 를 분리한 Premium 입니다. 이는 Regular Model 에서 추가적으로 Command 와 Query 의 Data Store 를 분리함으로써 각각 Command 와 Query 에 좀 더 적합한 Database 를 각각 사용할 수 있고, 이로 인해 Model 에 맞게 Data Store 개선이 가능합니다. 그러나 이 Model 에서는 Data Store 가 분리됨으로 인해 Data Store 간의 Data 동기화 처리가 보장되어야 합니다.
마지막으로 EventSourcing 을 적용한 Deluxe 입니다. 이는 가장 복잡한 Model 로 Command 에 대한 Event Stream 을 저장하고, 저장된 Event Stream 을 바탕으로 Data 를 Materialize 하여 구체화된 Data 를 Query 합니다. 구조가 복잡하고 규모가 크기 때문에 작고 간단한 Service 보다 규모가 큰 Service 에서 적합한 Model 입니다.
CQRS 후에 마지막으로 Kubernetes 등 Container Orchestration 을 이용하여 분산된 컨테이너 환경을 이용하는 사례가 많아지면서 분산 컨테이너 환경의 이점과 고려해야할 사항, Cluster 환경에서 사용할 수 있는 Container Design Pattern 들을 소개했습니다.
분산 컨테이너 환경에서 Container 배치 전략 중 중요한 사항은 다음과 같습니다.
- Container 의 재사용성
- Container 의 Isolation 및 Decoupling
- Container 간 공유 File System 및 Service 간 물리적 분리에 대한 고려 (Volume, Network)
- Container 가 구동되는 시점에 각 환경에 맞는 Config, Secret 을 받도록 설계
- Container Image 에 대한 문서화
이 밖에도 대규모 분산 컨테이너 환경에서는 Container 의 위치를 알기 어렵고, 분산된 Log Data 를 이용한 Debugging System, Network 등 고려해야 할 점이 많습니다. 이에 대한 해결 방안으로 Single Node Pattern 인 SideCar, Ambassador, Adapter Pattern 으로 Container 를 Kubernetes 의 Pod 와 같은 형태로 만들어서 사용할 수 있고, Container 의 State 에 따라 Replicated, Shared, Scatter/Gather 를 사용할 수 있습니다. 또한, Event 에 따라 동작하는 Functions and Event-Driven, Ownership 이 있는 Container 환경의 경우 Owenership Election, 대용량 데이터 병렬처리를 위한 Work Queue System, Batch Processing 등으로 분산 컨테이너 환경의 어려움을 해결할 수 있습니다.