Amazon ECS에 서비스 배포하기
2018-09-19
feat. Slack & Rust
AWSKRUG 통합소모임
#container
• 유은총
• 2015년부터 Spoqa에서 근무
• 2011년부터 Amazon Web Services 사용
• 4년째 Amazon ECS 사용
• 전업 Python 프로그래머
• 2017년부터 TypeScript 사용
• 2015년부터 React 사용
• 2014년부터 Rust 프로그래밍 시작
• 잡역부 풀스택 프로그래머
2
발표자
동종업계 1위의 오프라인 매장 포인트 멤버십 및 고객 관리 솔루션
누적 이용자 수 1,700만명, 가맹 매장 수 10,000점 (한국˙일본 합계)
위치 정보 기반의 오프라인 타겟 광고 서비스
핵심 파트너
3
Spoqa
• 2014년까지 도도 포인트는 커다란 모놀리틱 시스템으로 돌아가고 있었음
• 마이크로서비스로 가자
• 각 팀에서 제각각 서비스를 만들기 시작하면 답이 없겠다
• 적어도 배포 시스템은 일원화해야 한다
4
마이크로서비스 아키텍쳐로의 여행
• 괜찮은 패키징 솔루션
• 언어˙라이브러리와 무관하게 사용 가능
• 로컬에서도 이미지 빌드 및 실행이 가능하다
• EC2 + AMI보다 가벼운 배포 절차를 구성할 수 있음
• 클러스터링은 어떻게 하지……
• Docker Swarm이 갓 등장한 시기
• CoreOS? DC/OS?? Kubernetes???
5
Docker
• Geofront의 전례를 따라……
• https://spoqa.github.io/2014/07/09/geofront.html
• 스포카 마이크로서비스를 위한 플랫폼 구축이 목표
• 최종적으로 private subnet 안에 ECS 클러스터를 구성하는 것으로 마무리
• 원대한 목표가 있었지만 사이드잡이 다 그렇듯이 용두사미로 끝남
• 당초 계획했던 통합 배포 시스템이나 서비스 디스커버리 같은 건 온데간데없고……
6
Project Blackmoon
7
Longinus
• 결국 다른 팀에 계시던 분께서 만들어냄
• Stateless: 별도의 DB 없이 동작
• Docker Hub + Slack Button API
• AWS Lambda 위에서 도는 가벼운 서비스
• Python + Zappa
• 일단 설정하고 나면 Slack에서 간단히 배포 가능
8
Longinus
• 셋업이 귀찮음
• 새 서비스를 추가할 때마다 손으로 웹훅 주소를 Docker Hub 콘솔에다 붙여 넣어야
• Stateless의 한계
• 필요한 정보를 모조리 웹훅 URL에 때려넣으니 URL 길이 제한에 걸린다
• 결국 몇몇 서비스는 하드코딩하게 됨
• 로컬 테스트는……?
• 개발용 Lambda를 따로 띄워서……??
9
그렇게 한동안 버텼지만……
• 갑자기 일반인 코스프레
• Longinus를 계승
• 최대한 설정 없이 쓸 수 있는 방향으로
• Docker Hub 대신 Amazon ECR을 쓰자
• 로컬 테스트를 하기 쉽게 만들자
• AWS Lambda + Python ➡ Docker + Rust
10
Crane
?
• 시스템 프로그래밍 언어
• 조합 가능한 멀티코어 프로그래밍
• 패턴 매칭 + 제네릭
• 강한 타입 + 타입 추론
• Cargo 패키지 시스템
• 멀티플랫폼
• 메모리 안전
• 쓰레기 수집기(GC) 없음
• 매크로
12
Rust?
• 예전 프로젝트에서 그럴싸하게 써먹어 본 적이 있음
• https://www.rust-lang.org/ko-KR/friends.html
• 통상적으로는 C++ 또는 Java와 쓰이는 분야가 겹치는 언어
• 이걸로 웹 서비스도 만들 수 있을까?
• C++ 같았으면 가성비가 안 나오는 일이지만 Rust라면……?
13
Why Rust?
여기서부터는 거의 Rust 얘기만 나옵니다 ( ͡° ͜ʖ ͡°)
• Slack API 및 웹훅
• 웹훅 요청을 받을 웹 서비스가 필요
• 일반 웹훅 API로는 안 됩니다 Slack App을 만들어야 함
• ECR에 이미지가 올라오는 시점을 알아내기
• CloudTrail ➡ CloudWatch Events ➡ SQS
• 주기적으로 ReceiveMessage에 롱 폴링
• 보통 15초 정도 이내에 반응함
• 새 이미지로 ECS 서비스 배포
• 새 이미지와 같은 이름을 쓰는 작업 정의를 죄다 찾고 업데이트
• 업데이트된 작업 정의를 쓰는 서비스를 죄다 찾아 배포
• ECR을 사용한다면 별도의 설정이 필요없음
15
시작
• 모르겠고 일단 쓰레드 따서 돌린다!
• SQS로부터 메시지를 받을 쓰레드를 웹 서비스가 도는 쓰레드와 별도로 실행
• 내친김에 워커 쓰레드도 하나 만들자
• 쓰레드 사이의 통신은 MPSC 채널을 사용
• 하다 보니까 대책없이 쓰레드를 쓰고 있는데 이거 괜찮을까?
16
Fearless Concurrency!
• 트레이트(trait): 일종의 인터페이스
• 동시성 프로그래밍의 안전을 지키는 두 트레이트
• Send: 쓰레드 경계를 넘을 수 있음 (예: 참조를 포함하지 않는 대부분의 타입)
• Sync: 여러 쓰레드가 참조해도 괜찮음 (예: Mutex<T>, RwLock<T>, AtomicI32 등)
• 위의 규칙을 만족하지 않는 코드는 컴파일 에러
• 언어적으로 참조 공유와 값 변경이 극도로 제약되어 있음
• 뮤텍스가 보호하는 값은 반드시 보호될 거라는 확신이 생김
• 전례없이 편안한 마음으로 멀티쓰레드 프로그래밍을 할 수 있습니다
• 동적 타입 언어 쓰다가 정적 타입 언어로 돌아올 때의 그 느낌처럼
17
괜찮아, 문제없다
• 직업 프로그래머로 일하기 시작할 적에 새겨두었던 교훈
• 멀티쓰레드를 써야 할 것 같다면, 일단 다시 생각하라
• 그래도 써야 할 것 같다면, 멀티프로세싱이나 여하간 다른 방법을 찾아라
• Python GIL이 제 프로그래머로서의 가치관에 큰 영향을 끼쳤습니다 😂
• 결과적으로 제대로 된 멀티쓰레딩 경험이 전무한 상태였음
• 왠지는 모르겠지만 봇이 자꾸 먹통이 된다
• 메모리 누수 같은 리소스 누수나 논리적인 동시성 오류까지 Rust 컴파일러가 잡아주지는 못하더라
• 쓰레드를 잘 죽이려면 어떻게 해야 하지?
18
그러나
• 컴파일러와의 끝없는 투쟁
• 경험자들의 증언: 잘못될 가능성이 있는 코드는 다른 언어보다 Rust로 쓰기가 더 어렵더라
• 생각보다 그런 코드가 많습니다
• 가끔 논리적으로는 맞지만 타입 검사를 통과 못하는 경우를 밟기도 함
• 다행히 지속적으로 개선되고 있습니다 #
• 함수형 프로그래밍만큼은 아니더라도 어느 정도 코딩 습관을 바꾸게 됩니다
19
안전의 대가
• 기본적으로 거대한 JSON 값
20
ECR 이벤트 파싱
• Serialization/deserialization
• https://serde.rs/
• Killer feature
• 직렬화˙역직렬화 방법과 직렬화된 데이타 포맷이 서로 직교적
• serde_json, serde_yaml, serde_cbor, serde_protobuf, ……
• Rust 데이타 직렬화의 사실상 표준
21
Serde
• Rust용 AWS SDK (like boto)
• https://www.rusoto.org/
• 대부분의 AWS 서비스를 지원함
• SQS, ECS, ECR 모두 사용 가능했음
• SO HUGE!
• 모든 API 요청˙응답˙에러에 대한 구조체와 열거형이 각각 따로 만들어져 있음
• 컴파일 시간 증가에 혁혁한 공로
22
Rusoto
• CloudWatch Events로 ECS 클러스터 상태 이벤트를 수신할 수 있음 #
• 컨테이너 인스턴스나 서비스 상태를 모니터링한다거나 하는 데 쓸 수 있겠다
• 또는 배포 기록을 보존하거나
23
데이타베이스도 좀 써 봅시다
• Rust용 ORM 중에 가장 멀쩡한 라이브러리
• http://diesel.rs/
• 마이그레이션, 쿼리 DSL, 타입과 스키마 간 매핑 등등 기본적인 기능은 갖추고 있음
• PostgreSQL, MySQL, SQLite 지원
• 유의점
• Rust는 객체 지향 언어가 아닙니다
• 그래서 엄밀히 말해 이건 ORM은 아닙니다
• Java나 Python 같은 OO 언어에서와는 조금 다른 설계가 필요합니다
24
Diesel
25
Diesel
• Rocket
• Flask처럼 생김
• Rust여서 가능할 법한 기능들: request guards
• Flask처럼 보이기 위해 일부 nightly compiler 기능에 의존
• 비동기 지원 없음
• Rouille
• Rust스러운 웹 프레임워크 디자인을 찾기 위한 시도
• 하나의 커다란 request ➡ response 루프와 같은 구조
• 사실상 표준인 Hyper, Tokio 등과 아무 상관 없는 스택
• 역시나 비동기 지원 없음
26
웹 프레임워크
• https://actix.rs/
• 적당한 절충안
• 그럭저럭 익숙한 생김새
• 모든 것이 비동기!
• Actix 액터 프레임워크 기반
• 내친 김에 쓰레드 쓰던 코드들을 전부 액터 기반으로 갈아버림
27
Actix-web
• 그래도 멀티쓰레드보단 많은 경험이 있었음
• Gevent/Eventlet, asyncio, Promise 등등...
• Futures
• Promise랑 비슷합니다
• 프로덕션용으로는 0.1이 널리 쓰임. 0.3을 준비 중인 상태
• Tokio
• Futures 기반의 비동기 I/O 프레임워크
• Work-stealing task executor가 딸린 기본 런타임 제공
28
비동기 프로그래밍
• 소유권 및 lifetime 검사와 안 좋은 방식으로 상호작용
• 사실상 참조를 쓸 수 없는 수준
• async fn + Futures 0.3이 미래다
• 그래서 제가 미래에 살고 있는데요 nightly compiler의 세계는 험난하네요
• sync ➡ tokio-core ➡ tokio로 가는 과도기를 직격으로 겪음
• Rusoto가 꽤 늦게 트렌드를 따라 온 편이라 섞어 쓰느라 고생했었습니다
• Actix vs Tokio
• Actix 자체 런타임은 전체 애플리케이션 수준에서 단일 쓰레드를 강제 (tokio-core의 잔재)
• 일부 액터에 한해 쓰레드 풀링으로 동작
30
헬게이트 오픈
31
우여곡절 끝에 그래도 여기까지 왔습니다
• 예상했던 대로 rapid prototyping은 좀 어려움
• 메모리는 정말 조금 먹습니다 64MiB 이하
• Crane 자체도 ECS 서비스라 자기 자신을 배포하는 것도 되고 나름 만족하고 있습니다
• 비동기 프로그래밍을 하고 싶으시면 일단 기다리세요
• 올해 안에 async fn이 포함된 Rust 2018 edition이 나옵니다
• 웹 프레임워크는 일단 Actix-web 쓰세요 😂
32
그래서 할만하던가요
• 서비스 롤백
• 클러스터 유지보수 자동화
• 웹 콘솔
• 신규 서비스 등록
• 회사 내 다른 서비스도 Rust로?
• CI와 연동 및 이미지 자체 빌드 (AWS CodeBuild!)
• 여러 리전에 걸친 클러스터 관리하기
• 오픈소스?
• Slack App으로 공개?
33
앞으로 하고 싶은 것
We’re Hiring!
mailto:recruit@spoqa.com
서울 본사
서울특별시 강남구 테헤란로 420
메이플타워 9층
TEL 02-544-6463 FAX 02-544-6460
부산 지사
부산광역시 부산진구 부전동 426-7
신동아오피스텔 1007호
TEL 02-544-6463 FAX 02-544-6460
주식회사스포카
SEOUL·BUSAN·TOKYO
도쿄 지사
〒151-0053 東京都渋谷区代々木1-21-12ヤマ
ノ26ビル 3F
TEL 03-6869-3610
Question?
• a = b는 기본적으로 복사가 아닌 이동
• 언제나 하나의 값에 하나의 변수만 존재함. 구조체 필드에 넣거나 함수 인자로 전달해도 마찬가지.
• 마지막으로 값을 담았던 변수가 사라지는 지점이 그 값이 메모리에서 해제되는 지점
• 이동 의미론은 바꿀 수 없음. 언제나 C memcpy/memmove와 동등한 동작
• 복사는 a = b.clone()으로 명시적으로 하는 것이 기본
• 복사가 안전한 타입에 한해서 a = b로 복사가 가능
• 참조(&T)는 C 또는 C++의 포인터처럼 동작
• 어떤 참조도 자기가 참조한 변수보다 오래 남아있을 수 없음
• mut를 붙이지 않은 모든 변수와 참조는 불변(immutable)
• 동시에 하나의 &mut만 존재할 수 있음 (iterator invalidation 같은 걸 방지)
• 위에서 설명한 규칙은 모두 컴파일 시간에 검사됨
36
부록: Rust 주요 기능 요약
• enum은 tagged union
• match 식으로 패턴 매칭을 해서 원하는 값을 꺼낸다
• 널 포인터가 없고 명시적으로 None을 나타낼 수 있는 Option<T>가 존재
• 에러 처리에 쓰이는 Result<T, E>도 enum 타입
• 트레이트(trait)는 일종의 인터페이스. 제네릭 타입을 한정짓거나 동적 디스패치를 하는 데에 쓰임.
• 다른 라이브러리의 타입이나 i32 같은 기본 타입에 내가 정의한 트레이트를 구현하는 게 가능함
• Haskell의 타입 클래스 같은 겁니다
• Send나 Sync 같은 일부 트레이트는 자동으로 구현됨
• 클래스 같은 건 없어요
37
부록: Rust 주요 기능 요약 (2)

Slack과 Rust로 Amazon ECS에서 서비스 배포하기

  • 1.
    Amazon ECS에 서비스배포하기 2018-09-19 feat. Slack & Rust AWSKRUG 통합소모임 #container
  • 2.
    • 유은총 • 2015년부터Spoqa에서 근무 • 2011년부터 Amazon Web Services 사용 • 4년째 Amazon ECS 사용 • 전업 Python 프로그래머 • 2017년부터 TypeScript 사용 • 2015년부터 React 사용 • 2014년부터 Rust 프로그래밍 시작 • 잡역부 풀스택 프로그래머 2 발표자
  • 3.
    동종업계 1위의 오프라인매장 포인트 멤버십 및 고객 관리 솔루션 누적 이용자 수 1,700만명, 가맹 매장 수 10,000점 (한국˙일본 합계) 위치 정보 기반의 오프라인 타겟 광고 서비스 핵심 파트너 3 Spoqa
  • 4.
    • 2014년까지 도도포인트는 커다란 모놀리틱 시스템으로 돌아가고 있었음 • 마이크로서비스로 가자 • 각 팀에서 제각각 서비스를 만들기 시작하면 답이 없겠다 • 적어도 배포 시스템은 일원화해야 한다 4 마이크로서비스 아키텍쳐로의 여행
  • 5.
    • 괜찮은 패키징솔루션 • 언어˙라이브러리와 무관하게 사용 가능 • 로컬에서도 이미지 빌드 및 실행이 가능하다 • EC2 + AMI보다 가벼운 배포 절차를 구성할 수 있음 • 클러스터링은 어떻게 하지…… • Docker Swarm이 갓 등장한 시기 • CoreOS? DC/OS?? Kubernetes??? 5 Docker
  • 6.
    • Geofront의 전례를따라…… • https://spoqa.github.io/2014/07/09/geofront.html • 스포카 마이크로서비스를 위한 플랫폼 구축이 목표 • 최종적으로 private subnet 안에 ECS 클러스터를 구성하는 것으로 마무리 • 원대한 목표가 있었지만 사이드잡이 다 그렇듯이 용두사미로 끝남 • 당초 계획했던 통합 배포 시스템이나 서비스 디스커버리 같은 건 온데간데없고…… 6 Project Blackmoon
  • 7.
  • 8.
    • 결국 다른팀에 계시던 분께서 만들어냄 • Stateless: 별도의 DB 없이 동작 • Docker Hub + Slack Button API • AWS Lambda 위에서 도는 가벼운 서비스 • Python + Zappa • 일단 설정하고 나면 Slack에서 간단히 배포 가능 8 Longinus
  • 9.
    • 셋업이 귀찮음 •새 서비스를 추가할 때마다 손으로 웹훅 주소를 Docker Hub 콘솔에다 붙여 넣어야 • Stateless의 한계 • 필요한 정보를 모조리 웹훅 URL에 때려넣으니 URL 길이 제한에 걸린다 • 결국 몇몇 서비스는 하드코딩하게 됨 • 로컬 테스트는……? • 개발용 Lambda를 따로 띄워서……?? 9 그렇게 한동안 버텼지만……
  • 10.
    • 갑자기 일반인코스프레 • Longinus를 계승 • 최대한 설정 없이 쓸 수 있는 방향으로 • Docker Hub 대신 Amazon ECR을 쓰자 • 로컬 테스트를 하기 쉽게 만들자 • AWS Lambda + Python ➡ Docker + Rust 10 Crane
  • 11.
  • 12.
    • 시스템 프로그래밍언어 • 조합 가능한 멀티코어 프로그래밍 • 패턴 매칭 + 제네릭 • 강한 타입 + 타입 추론 • Cargo 패키지 시스템 • 멀티플랫폼 • 메모리 안전 • 쓰레기 수집기(GC) 없음 • 매크로 12 Rust?
  • 13.
    • 예전 프로젝트에서그럴싸하게 써먹어 본 적이 있음 • https://www.rust-lang.org/ko-KR/friends.html • 통상적으로는 C++ 또는 Java와 쓰이는 분야가 겹치는 언어 • 이걸로 웹 서비스도 만들 수 있을까? • C++ 같았으면 가성비가 안 나오는 일이지만 Rust라면……? 13 Why Rust?
  • 14.
    여기서부터는 거의 Rust얘기만 나옵니다 ( ͡° ͜ʖ ͡°)
  • 15.
    • Slack API및 웹훅 • 웹훅 요청을 받을 웹 서비스가 필요 • 일반 웹훅 API로는 안 됩니다 Slack App을 만들어야 함 • ECR에 이미지가 올라오는 시점을 알아내기 • CloudTrail ➡ CloudWatch Events ➡ SQS • 주기적으로 ReceiveMessage에 롱 폴링 • 보통 15초 정도 이내에 반응함 • 새 이미지로 ECS 서비스 배포 • 새 이미지와 같은 이름을 쓰는 작업 정의를 죄다 찾고 업데이트 • 업데이트된 작업 정의를 쓰는 서비스를 죄다 찾아 배포 • ECR을 사용한다면 별도의 설정이 필요없음 15 시작
  • 16.
    • 모르겠고 일단쓰레드 따서 돌린다! • SQS로부터 메시지를 받을 쓰레드를 웹 서비스가 도는 쓰레드와 별도로 실행 • 내친김에 워커 쓰레드도 하나 만들자 • 쓰레드 사이의 통신은 MPSC 채널을 사용 • 하다 보니까 대책없이 쓰레드를 쓰고 있는데 이거 괜찮을까? 16 Fearless Concurrency!
  • 17.
    • 트레이트(trait): 일종의인터페이스 • 동시성 프로그래밍의 안전을 지키는 두 트레이트 • Send: 쓰레드 경계를 넘을 수 있음 (예: 참조를 포함하지 않는 대부분의 타입) • Sync: 여러 쓰레드가 참조해도 괜찮음 (예: Mutex<T>, RwLock<T>, AtomicI32 등) • 위의 규칙을 만족하지 않는 코드는 컴파일 에러 • 언어적으로 참조 공유와 값 변경이 극도로 제약되어 있음 • 뮤텍스가 보호하는 값은 반드시 보호될 거라는 확신이 생김 • 전례없이 편안한 마음으로 멀티쓰레드 프로그래밍을 할 수 있습니다 • 동적 타입 언어 쓰다가 정적 타입 언어로 돌아올 때의 그 느낌처럼 17 괜찮아, 문제없다
  • 18.
    • 직업 프로그래머로일하기 시작할 적에 새겨두었던 교훈 • 멀티쓰레드를 써야 할 것 같다면, 일단 다시 생각하라 • 그래도 써야 할 것 같다면, 멀티프로세싱이나 여하간 다른 방법을 찾아라 • Python GIL이 제 프로그래머로서의 가치관에 큰 영향을 끼쳤습니다 😂 • 결과적으로 제대로 된 멀티쓰레딩 경험이 전무한 상태였음 • 왠지는 모르겠지만 봇이 자꾸 먹통이 된다 • 메모리 누수 같은 리소스 누수나 논리적인 동시성 오류까지 Rust 컴파일러가 잡아주지는 못하더라 • 쓰레드를 잘 죽이려면 어떻게 해야 하지? 18 그러나
  • 19.
    • 컴파일러와의 끝없는투쟁 • 경험자들의 증언: 잘못될 가능성이 있는 코드는 다른 언어보다 Rust로 쓰기가 더 어렵더라 • 생각보다 그런 코드가 많습니다 • 가끔 논리적으로는 맞지만 타입 검사를 통과 못하는 경우를 밟기도 함 • 다행히 지속적으로 개선되고 있습니다 # • 함수형 프로그래밍만큼은 아니더라도 어느 정도 코딩 습관을 바꾸게 됩니다 19 안전의 대가
  • 20.
    • 기본적으로 거대한JSON 값 20 ECR 이벤트 파싱
  • 21.
    • Serialization/deserialization • https://serde.rs/ •Killer feature • 직렬화˙역직렬화 방법과 직렬화된 데이타 포맷이 서로 직교적 • serde_json, serde_yaml, serde_cbor, serde_protobuf, …… • Rust 데이타 직렬화의 사실상 표준 21 Serde
  • 22.
    • Rust용 AWSSDK (like boto) • https://www.rusoto.org/ • 대부분의 AWS 서비스를 지원함 • SQS, ECS, ECR 모두 사용 가능했음 • SO HUGE! • 모든 API 요청˙응답˙에러에 대한 구조체와 열거형이 각각 따로 만들어져 있음 • 컴파일 시간 증가에 혁혁한 공로 22 Rusoto
  • 23.
    • CloudWatch Events로ECS 클러스터 상태 이벤트를 수신할 수 있음 # • 컨테이너 인스턴스나 서비스 상태를 모니터링한다거나 하는 데 쓸 수 있겠다 • 또는 배포 기록을 보존하거나 23 데이타베이스도 좀 써 봅시다
  • 24.
    • Rust용 ORM중에 가장 멀쩡한 라이브러리 • http://diesel.rs/ • 마이그레이션, 쿼리 DSL, 타입과 스키마 간 매핑 등등 기본적인 기능은 갖추고 있음 • PostgreSQL, MySQL, SQLite 지원 • 유의점 • Rust는 객체 지향 언어가 아닙니다 • 그래서 엄밀히 말해 이건 ORM은 아닙니다 • Java나 Python 같은 OO 언어에서와는 조금 다른 설계가 필요합니다 24 Diesel
  • 25.
  • 26.
    • Rocket • Flask처럼생김 • Rust여서 가능할 법한 기능들: request guards • Flask처럼 보이기 위해 일부 nightly compiler 기능에 의존 • 비동기 지원 없음 • Rouille • Rust스러운 웹 프레임워크 디자인을 찾기 위한 시도 • 하나의 커다란 request ➡ response 루프와 같은 구조 • 사실상 표준인 Hyper, Tokio 등과 아무 상관 없는 스택 • 역시나 비동기 지원 없음 26 웹 프레임워크
  • 27.
    • https://actix.rs/ • 적당한절충안 • 그럭저럭 익숙한 생김새 • 모든 것이 비동기! • Actix 액터 프레임워크 기반 • 내친 김에 쓰레드 쓰던 코드들을 전부 액터 기반으로 갈아버림 27 Actix-web
  • 28.
    • 그래도 멀티쓰레드보단많은 경험이 있었음 • Gevent/Eventlet, asyncio, Promise 등등... • Futures • Promise랑 비슷합니다 • 프로덕션용으로는 0.1이 널리 쓰임. 0.3을 준비 중인 상태 • Tokio • Futures 기반의 비동기 I/O 프레임워크 • Work-stealing task executor가 딸린 기본 런타임 제공 28 비동기 프로그래밍
  • 30.
    • 소유권 및lifetime 검사와 안 좋은 방식으로 상호작용 • 사실상 참조를 쓸 수 없는 수준 • async fn + Futures 0.3이 미래다 • 그래서 제가 미래에 살고 있는데요 nightly compiler의 세계는 험난하네요 • sync ➡ tokio-core ➡ tokio로 가는 과도기를 직격으로 겪음 • Rusoto가 꽤 늦게 트렌드를 따라 온 편이라 섞어 쓰느라 고생했었습니다 • Actix vs Tokio • Actix 자체 런타임은 전체 애플리케이션 수준에서 단일 쓰레드를 강제 (tokio-core의 잔재) • 일부 액터에 한해 쓰레드 풀링으로 동작 30 헬게이트 오픈
  • 31.
    31 우여곡절 끝에 그래도여기까지 왔습니다
  • 32.
    • 예상했던 대로rapid prototyping은 좀 어려움 • 메모리는 정말 조금 먹습니다 64MiB 이하 • Crane 자체도 ECS 서비스라 자기 자신을 배포하는 것도 되고 나름 만족하고 있습니다 • 비동기 프로그래밍을 하고 싶으시면 일단 기다리세요 • 올해 안에 async fn이 포함된 Rust 2018 edition이 나옵니다 • 웹 프레임워크는 일단 Actix-web 쓰세요 😂 32 그래서 할만하던가요
  • 33.
    • 서비스 롤백 •클러스터 유지보수 자동화 • 웹 콘솔 • 신규 서비스 등록 • 회사 내 다른 서비스도 Rust로? • CI와 연동 및 이미지 자체 빌드 (AWS CodeBuild!) • 여러 리전에 걸친 클러스터 관리하기 • 오픈소스? • Slack App으로 공개? 33 앞으로 하고 싶은 것
  • 34.
  • 35.
    서울 본사 서울특별시 강남구테헤란로 420 메이플타워 9층 TEL 02-544-6463 FAX 02-544-6460 부산 지사 부산광역시 부산진구 부전동 426-7 신동아오피스텔 1007호 TEL 02-544-6463 FAX 02-544-6460 주식회사스포카 SEOUL·BUSAN·TOKYO 도쿄 지사 〒151-0053 東京都渋谷区代々木1-21-12ヤマ ノ26ビル 3F TEL 03-6869-3610 Question?
  • 36.
    • a =b는 기본적으로 복사가 아닌 이동 • 언제나 하나의 값에 하나의 변수만 존재함. 구조체 필드에 넣거나 함수 인자로 전달해도 마찬가지. • 마지막으로 값을 담았던 변수가 사라지는 지점이 그 값이 메모리에서 해제되는 지점 • 이동 의미론은 바꿀 수 없음. 언제나 C memcpy/memmove와 동등한 동작 • 복사는 a = b.clone()으로 명시적으로 하는 것이 기본 • 복사가 안전한 타입에 한해서 a = b로 복사가 가능 • 참조(&T)는 C 또는 C++의 포인터처럼 동작 • 어떤 참조도 자기가 참조한 변수보다 오래 남아있을 수 없음 • mut를 붙이지 않은 모든 변수와 참조는 불변(immutable) • 동시에 하나의 &mut만 존재할 수 있음 (iterator invalidation 같은 걸 방지) • 위에서 설명한 규칙은 모두 컴파일 시간에 검사됨 36 부록: Rust 주요 기능 요약
  • 37.
    • enum은 taggedunion • match 식으로 패턴 매칭을 해서 원하는 값을 꺼낸다 • 널 포인터가 없고 명시적으로 None을 나타낼 수 있는 Option<T>가 존재 • 에러 처리에 쓰이는 Result<T, E>도 enum 타입 • 트레이트(trait)는 일종의 인터페이스. 제네릭 타입을 한정짓거나 동적 디스패치를 하는 데에 쓰임. • 다른 라이브러리의 타입이나 i32 같은 기본 타입에 내가 정의한 트레이트를 구현하는 게 가능함 • Haskell의 타입 클래스 같은 겁니다 • Send나 Sync 같은 일부 트레이트는 자동으로 구현됨 • 클래스 같은 건 없어요 37 부록: Rust 주요 기능 요약 (2)