2017년 개발 연대기: 브라우저의 새 실행 형식과 모바일 금융의 출범
Kotlin의 Android 공식 지원, TensorFlow 1.0, WebAssembly, React 16과 Fiber, Kubernetes 1.8, Java 9, 국내 인터넷전문은행의 실제 출범으로 2017년의 개발 흐름을 살펴봅니다.
2017년에는 새로운 기술이 ‘사용할 수 있다’는 단계를 넘어 플랫폼의 공식 선택지와 안정된 기반으로 인정받기 시작했다. Google은 Kotlin을 Android 앱 개발의 공식 지원 언어로 발표했고, TensorFlow는 1.0에 도달해 Python API의 안정성을 약속했다.
브라우저에서는 WebAssembly의 초기 형식에 네 주요 브라우저가 합의하고 연말까지 실제 제품에 지원을 배포했다. React 16은 공개 API를 대부분 유지하면서 내부 renderer를 Fiber로 다시 작성했다. Kubernetes 1.8은 역할 기반 접근 제어를 안정화했고 주요 클라우드 사업자들이 관리형 Kubernetes 서비스를 발표했다.
국내에서는 전년도까지 인가와 구축 단계에 있던 케이뱅크와 카카오뱅크가 실제 고객 서비스를 시작했다. 은행 지점의 절차를 모바일 화면과 24시간 소프트웨어 시스템으로 옮긴 결과가 대규모 사용자를 만나면서, 개발·운영·보안이 금융 상품 자체의 경쟁력이 되는 장면이 나타났다.
2017년을 보여주는 장면
| 분야 | 주요 변화 | 개발자에게 생긴 의미 |
|---|---|---|
| Android | Kotlin 공식 지원 발표 | Java와 함께 Android 플랫폼이 공식 인정한 개발 언어로 편입 |
| 기계학습 | TensorFlow 1.0 | 주요 Python API 안정성과 tf.keras 등 고수준 API 제공 |
| 웹 실행 | WebAssembly MVP·브라우저 지원 | C·C++ 등으로 작성한 코드를 이식 가능한 이진 형식으로 브라우저에서 실행 |
| UI | React 16·Fiber | 컴포넌트 API를 유지하면서 rendering 내부 구조를 전면 교체 |
| 컨테이너 | Kubernetes 1.8·관리형 서비스 발표 | RBAC 안정화와 클라우드 사업자의 control plane 운영 대행 확대 |
| Java | Java 9·module system | JDK와 애플리케이션을 명시적인 module graph로 구성할 기반 도입 |
| 국내 금융 | 케이뱅크·카카오뱅크 영업 개시 | 지점 없는 모바일 은행이 실제 대규모 트래픽과 금융 업무를 처리 |
Kotlin, 커뮤니티의 선택에서 Android의 공식 언어로
Google은 5월 17일 Google I/O에서 Kotlin을 Android 개발의 공식 지원 언어로 추가한다고 발표했다. Kotlin 1.0은 이미 2016년에 나왔고 여러 기업이 Android 앱에 사용하고 있었지만, 플랫폼 제공자가 장기 지원과 도구 통합 의지를 공개한 것은 채택 위험을 크게 낮췄다.
Kotlin은 Java 바이트코드를 생성하고 기존 Java API와 양방향으로 호출할 수 있었다. 따라서 애플리케이션 전체를 다시 작성하지 않고 새 기능이나 테스트부터 Kotlin으로 만들 수 있었다. null 가능성을 타입으로 구분하고 data class·확장 함수·고차 함수를 사용하는 방식은 Android 코드의 반복을 줄였다.
data class Post(val year: Int, val title: String)
val label = Post(2017, "Android의 Kotlin 지원")
.let { "${it.year}: ${it.title}" }
10월 안정판으로 나온 Android Studio 3.0에는 Kotlin 플러그인이 기본 포함되었다. 새 프로젝트와 파일을 Kotlin으로 만들고 Java 코드를 Kotlin으로 변환할 수 있었으며, Google은 공식 문서와 예제를 추가하기 시작했다.
이 발표를 Android가 Java를 폐기한 사건으로 보면 안 된다. Google은 Java와 C++ 지원도 계속한다고 명시했고 기존 Android API의 상당 부분은 Java에서 정의되어 있었다. ‘Kotlin-first’ 정책은 2019년에 발표되었고, coroutines의 안정판과 Android KTX도 이후에 성숙했다. 2017년은 Kotlin이 공식적인 동등 선택지가 된 해였다.
TensorFlow 1.0, 빠르게 변하던 API에 안정 기준을 세우다
Google은 2월 15일 첫 TensorFlow Developer Summit에서 TensorFlow 1.0을 발표했다. 2015년 오픈 소스 공개 이후 0.x 버전에서 API 변경이 잦았던 프로젝트가 주요 Python API의 호환성을 약속하는 단계에 도달했다.
tf.layers, tf.metrics, tf.losses 같은 고수준 모듈이 추가되었고 Keras 호환 API인 tf.keras가 포함되었다. XLA compiler가 실험 기능으로 공개되어 TensorFlow 계산 그래프를 CPU와 GPU에 맞게 최적화할 기반도 마련되었다. 분산 학습 성능과 모바일 지원도 개선되었다.
import tensorflow as tf
x = tf.placeholder(tf.float32)
y = x * 2
with tf.Session() as session:
print(session.run(y, feed_dict={x: 3}))
1.0도 graph를 먼저 정의하고 Session에서 실행하는 모델이 중심이었다. eager execution은 아직 기본이 아니었고, 현재의 TensorFlow 2.x 코드와 그대로 호환되는 경험도 아니었다. Google은 1.0을 위해 NumPy와 더 비슷하도록 일부 API를 변경하고 migration guide와 변환 script를 제공했다.
버전 번호는 기계학습 연구가 완성되었다는 뜻이 아니라, 연구와 제품에서 함께 사용할 도구의 API를 더 예측 가능하게 만들었다는 뜻이었다. 모델 구조뿐 아니라 학습 데이터 pipeline, GPU 자원, checkpoint와 serving까지 관리하는 software engineering의 중요성이 커졌다.
WebAssembly, JavaScript와 함께 쓰는 이식 가능한 이진 형식
2월 28일 Chrome·Edge·Firefox·WebKit을 대표하는 WebAssembly Community Group 구성원들은 초기 MVP의 binary format과 JavaScript API 설계가 완료되었다고 합의했다. 이는 browser preview를 끝내고 각 브라우저가 WebAssembly를 기본 활성화해 배포할 수 있다는 신호였다.
WebAssembly는 특정 CPU의 기계어가 아니라 stack 기반 virtual machine을 위한 압축된 이진 명령 형식이었다. 브라우저가 빠르게 검증하고 compile할 수 있도록 설계됐으며 sandbox 안에서 실행되었다. Emscripten을 이용하면 기존 C·C++ 코드를 .wasm으로 compile해 JavaScript에서 불러올 수 있었다.
const response = await fetch("/module.wasm");
const bytes = await response.arrayBuffer();
const result = await WebAssembly.instantiate(bytes, {});
console.log(result.instance.exports.add(2, 3));
11월에는 Firefox와 Chrome에 이어 Safari와 Edge도 WebAssembly를 포함한 버전을 배포해 네 주요 브라우저의 실제 지원이 갖춰졌다. 게임 engine, 영상·음성 처리, CAD와 과학 계산처럼 계산량이 큰 기존 codebase를 웹으로 옮길 가능성이 커졌다.
그러나 WebAssembly가 JavaScript를 대체하거나 DOM을 직접 조작하는 완전한 웹 언어가 된 것은 아니었다. 초기 MVP에는 garbage collection, thread, SIMD와 안정된 system interface가 없었고 브라우저 API를 사용하려면 JavaScript와의 연결이 필요했다. W3C 권고안이 된 시점도 2017년이 아니라 2019년이다.
React 16, 달리는 자동차의 엔진을 교체하다
Facebook은 9월 26일 React 16을 출시했다. 개발 중 Fiber라고 부른 새 reconciler로 내부 구현을 전면 다시 작성했지만, 기존 컴포넌트 API를 대부분 유지했다. Facebook은 이를 운행 중인 자동차의 엔진을 교체하는 일에 비유했다.
기존 reconciler는 컴포넌트 tree를 동기적으로 순회해 큰 갱신이 시작되면 중간에 멈추기 어려웠다. Fiber는 rendering 작업을 더 작은 단위로 나타내고 우선순위를 부여하거나 중단·재개할 수 있는 내부 기반을 만들었다. 향후 asynchronous rendering을 지원하려는 설계였지만, React 16.0에서 모든 concurrent 기능이 사용자에게 즉시 제공된 것은 아니다.
React 16에는 component tree 밖의 DOM node에 children을 그리는 portal, rendering 중 발생한 오류를 포착하는 error boundary, 배열과 문자열을 반환할 수 있는 기능이 추가되었다. 새 renderer는 server-side rendering도 다시 구현했다.
출시 직전 Facebook은 React, Jest, Flow와 Immutable.js의 라이선스를 BSD+Patents에서 MIT로 바꾸겠다고 발표했고 React 16은 MIT 라이선스로 배포되었다. 특허 조항을 둘러싼 사용자와 기업의 우려에 대응한 결정이었다.
Fiber를 virtual DOM 자체의 발명이나 Hooks의 출시로 혼동해서는 안 된다. Hooks는 2018년 공개되고 2019년 React 16.8에 포함되었다. 2017년의 핵심은 공개 컴포넌트 모델을 깨뜨리지 않으면서 미래의 scheduling을 가능하게 할 내부 구조를 바꾼 데 있었다.
Kubernetes, 기능 성숙과 관리형 서비스의 등장
Kubernetes는 2017년에 1.6부터 1.9까지 빠르게 릴리스되었다. 9월의 1.8에서는 Kubernetes API 접근을 role과 binding으로 제어하는 RBAC가 stable 단계에 도달했다. 사용자는 기본적으로 권한이 없고 관리자에게 필요한 범위만 명시적으로 부여받는 구조를 표준 resource로 관리할 수 있었다.
Deployment·DaemonSet·ReplicaSet·StatefulSet 같은 workload API도 더 안정된 group으로 정리되었고, CronJob과 certificate rotation, network policy가 발전했다. 컨테이너를 배치하는 기능만큼 사용자·service account의 권한과 cluster lifecycle을 관리하는 기능이 중요해졌다.
클라우드 사업자도 control plane 운영을 서비스로 제공하기 시작했다. Microsoft는 10월 AKS의 preview를 발표했고 AWS는 11월 re:Invent에서 EKS preview를 공개했다. EKS의 일반 제공은 2018년이므로 2017년에 운영 서비스가 완전히 출시되었다고 적어서는 안 된다.
Docker는 containerd를 CNCF에 기증했고 여러 runtime이 Kubernetes와 연결될 수 있는 생태계가 커졌다. Kubernetes가 모든 컨테이너 문제를 해결한 것은 아니지만, 특정 이미지 도구나 클라우드와 분리된 orchestration API가 공급자 사이의 공통 언어로 자리 잡기 시작했다.
Java 9, module system과 더 짧아진 다음 릴리스까지의 시간
Oracle은 9월 21일 Java SE 9을 출시했다. 가장 큰 변화는 Project Jigsaw로 개발한 Java Platform Module System이었다. module-info.java에서 module이 외부에 공개할 package와 필요한 다른 module을 명시해 classpath의 암묵적인 의존성을 module graph로 바꾸려 했다.
module com.softground.chronicle {
exports com.softground.chronicle.api;
requires java.sql;
}
JDK 자체도 module로 나뉘어 jlink로 응용 프로그램에 필요한 module만 포함한 runtime image를 만들 수 있었다. JShell은 선언과 표현식을 즉시 실행하는 REPL을 제공했고, collection factory method인 List.of, Set.of, Map.of도 추가되었다.
module system은 큰 Java 응용 프로그램의 경계를 명확히 할 수 있었지만, reflection과 JDK 내부 API에 의존하던 기존 library에는 migration 부담을 주었다. 이름 없는 module과 automatic module 같은 호환 장치가 있었어도 build tool과 framework의 지원을 확인해야 했다.
Java 9은 오랫동안 유지되는 기준 버전이 되지 않았다. Oracle은 6개월 release cadence로 전환했고 다음 버전 Java 10은 2018년 3월에 나왔다. 장기 지원 기준은 2018년 Java 11로 이어졌다. 2017년은 언어 기능뿐 아니라 Java의 배포 주기 자체가 바뀌는 전환점이었다.
국내: 두 인터넷전문은행이 실제 고객을 만나다
케이뱅크는 4월 3일 국내 첫 인터넷전문은행으로 영업을 시작했다. 카카오뱅크는 4월 5일 본인가를 받은 뒤 7월 27일 두 번째 인터넷전문은행으로 서비스를 시작했다. 전년도의 예비인가·본인가와 달리 2017년은 사용자가 실제 계좌를 만들고 송금·대출·카드를 이용한 해였다.
두 은행은 지점 방문 없이 mobile device에서 비대면 실명 확인과 계좌 개설을 진행하고 24시간 서비스를 제공했다. 카카오뱅크는 공인인증서 없이 간결한 인증 흐름, 낮은 해외 송금 수수료와 친숙한 UI를 앞세웠고 서비스 첫날 약 30만 계좌가 개설되었다고 밝혔다.
빠른 가입은 곧바로 운영 시험이 되었다. 예상보다 많은 접속과 대출 신청, 체크카드 발급 수요는 application server뿐 아니라 금융 원장, 신용평가, 지급결제망, 상담과 배송 system 전체의 capacity planning을 요구했다. 금융 서비스에서는 잠시 느려지는 문제도 거래 중복이나 잔액 불일치 없이 복구해야 했다.
이 변화는 기존 은행도 mobile app의 가입 절차와 인증, UI를 다시 설계하도록 압력을 높였다. 인터넷전문은행의 경쟁력은 ‘오프라인 지점이 없다’는 사실보다 규제와 보안을 지키면서 금융 절차를 software product처럼 반복 개선할 수 있는가에 달려 있었다.
2017년의 의미
2017년에는 공식 지원과 안정성의 선언이 기술 채택을 움직였다. Kotlin은 Android의 공식 언어가 되면서 기존 community 사용이 platform의 장기 전략으로 바뀌었다. TensorFlow 1.0은 빠른 연구 도구에 API 안정성을 더했고, WebAssembly는 네 브라우저의 합의와 실제 배포를 통해 웹의 두 번째 저수준 실행 형식이 되었다.
React는 API 호환성을 지키며 Fiber로 내부를 바꾸었고, Kubernetes는 RBAC와 workload API를 다듬는 동시에 관리형 cloud service의 기반이 되었다. Java 9은 module system과 새 release cadence로 거대한 기존 생태계를 재구성하려 했다.
국내 인터넷전문은행의 출범은 software architecture와 사용 경험이 금융 사업의 전면에 설 수 있음을 보여주었다. 2018년에는 Kubernetes 관리형 서비스의 일반 제공, Docker와 Kubernetes의 결합, Java 11, React Hooks의 공개, GDPR 시행과 국내 데이터·cloud 환경의 변화가 이 흐름을 이어가게 된다.
참고 자료
- Android Developers Blog, Android Announces Support for Kotlin
- Android Developers Blog, Update on Kotlin for Android
- Google Open Source Blog, Announcing TensorFlow 1.0
- W3C WebAssembly Community Group, WebAssembly consensus and end of Browser Preview
- Mozilla, WebAssembly support now shipping in all major browsers
- Meta Engineering, React 16: An API-compatible rewrite
- Meta Engineering, Relicensing React, Jest, Flow, and Immutable.js
- Kubernetes, Kubernetes 1.8: Security, Workloads and Feature Depth
- Kubernetes, Using RBAC, Generally Available in Kubernetes 1.8
- Microsoft Azure, Introducing AKS managed Kubernetes preview
- AWS, Amazon EKS: 2017 preview and 2018 general availability
- Oracle, JDK 9 release notes
- 금융위원회, KakaoBank opens for service, July 27 2017
- 카카오, 은행코드 90, 모두의 스마트폰에 지점을 열다
- 케이뱅크, 2017년 4월 3일 케이뱅크 출범 회고