SlideShare a Scribd company logo
Kotlin Backend @ Coupang
debop@coupang.com
Who is @debop
• Since 1993

• Robotics, BPM Solution, Healthcare

• C/C++, Object Pascal, C#, Java, Scala, Kotlin

• Use Kotlin since 2016.08 

• Sr. Principle Software Engineer in Coupang (2017~)

• 남의 코드 뒤집기 / 빨간펜 선생

• Common Library 제작

• Architecture 참견
Agenda
• Kotlin 도입 동기

• Kotlin 도입 사례

• Kotlinx (Common Library)

• 공용 Library 개발

• spring-data-requery

• Lesson & Learn
Kotlin 도입 동기
What is our problem?
• 개발자 수준 편차가 크다

• 조직 수준은 최하위 개발자 수준의 의해 결정된다
Our status
• Lack of Safety code

• Not Readable code

• Lack of Testing (Unit & Integration)

• Heavy oriented to JPA

• Lack of experience to Async/Non-Blocking
Programming
Our environments
• 1일 데이터 처리량 : 천만건(2016) -> 10억건(2018)

• MySQL (Aurora) : Replication delay120 sec (max)

• Backend Stack in 2016

• MySQL, RabbitMQ, Hive

• Spring 3, JPA
Our Challenges
• Akka Cluster with Lagom Framework (CQRS)

• Move to NoSQL (Cassandra, HBase)

• Migrate RabbitMQ to Kafka

• Adopting Scala (Pilot)

• Akka, Spark …
Failure
• Adopting Scala 

• Learning Curve (Almost Junior)

• Lack of Tech Leaders

• Try to develop too complex system

• Adopting Kafka

• Simultaneous development (duplicate same error)

• Offset managements
To pursue change
• 객관적 시각 유지

• History 및 현실 상황 대한 이해 (기술부채)

• 현 조직의 개발 역량 객관적 평가

• 동기부여 - 필요성 설득보다는 자각할 수 있도록 자극

• 충분한 학습 시간

• 변화 경험 공유

• ASP -> C#, Java -> Scala
Prepare
• Code Quality 중요성 자각 -> Code Review

• Enterprise Application Commons 

• Patterns 교육, Library 제공

• Enterprise Architecture 학습

• Asynchronous Programming 학습

• Kotlin Language 학습

• Kotlin is language for Android ?
Adopting Kotlin
• Safety Code / Readable Code

• Simple grammar (Easy to learn)

• Interoperability between Java and Kotlin

• Extension methods

• Asynchronous Programming by Coroutines
Environments 준비
• 개발 Tool 지원 - IntelliJ IDEA

• Static code analysis - ktlint, detekt

• Test code coverage - jacoco (sample)

• Sonarcube - sonar-kotlin plugin
Kotlin Backend 도입 사례
Use cases 2017
• Common Library (2017. 6 ~)

• Kotlin extension library

• Components (2017.08 ~ 2017.12)

• Aho-corasick, Korean Tokenizer, Kafka Client

• Standalone Web Application (2017.10~~2017.12)

• Audit Tool 

• Large scale system (2017.09~2018.01)

• Catalog creation pipeline system
1. Kotlin Extension library
• Coupang Standard Framework 대체 

• Kotlin Best practices 제공

• Object / IO / Utils / Cache / JDBC / Spring …

• Kotlin 학습 예제 제공 (Test cases / Examples)

• Based debop4k (personal project)
Kotlinx-Units
• 도량형(度量衡)(Standard Unit)

• Represent Meter Units

• Weight, Length, Area, Volume, Storage Volume

• Yard-Pound Units

• Pound, Yard/Miles, Volume, Fluid Volume …

• Others

• Temperature, Electlic powers, Frequency, Light,
Radiation, Pressure …
Our usages
enum class Unit(val description: String, val unitConversion: BigDecimal) {
NONE("없음", BigDecimal.ZERO),
// Length
MM("mm", 0.1.toBigDecimal()),
CM("cm", BigDecimal.ONE),
M("m", 100.toBigDecimal()),
KM("km", 100_000.toBigDecimal()),
Our usages
// Length (Inch)
IN("in", BigDecimal.ONE),
FT("ft", 12.toBigDecimal()),
YD("yd", 36.toBigDecimal()),
// Weight (gram)
MG("mg", 0.001.toBigDecimal()),
G("g", BigDecimal.ONE),
KG("kg", 1000.toBigDecimal()),
T("t", 1_000_000.toBigDecimal()),
OZ("oz", 28.349523.toBigDecimal()),
LB("lb", 453.59237.toBigDecimal()),
•Define Units by Enum
•Not support conversions
•Not support various units
•Not support operations
•Not readable code
Features for units
• Readable code like this 

• 5.kg() + 400.gram() => 5.4.kg()

• 100.cm() + 2.m() => 2.1.cm()

• Convert various units

• 5.kg().inGram() -> 5000.gram

• 2.5.Kb().inBytes() -> 2500.bytes()

• Convert SI Units <-> US Units
Use Kotlin extension methods
fun Double.millimeter(): Length = lengthOf(this, MILLIMETER)
fun Double.centimeter(): Length = lengthOf(this, CENTIMETER)
fun Double.meter(): Length = lengthOf(this)
fun Double.kilometer(): Length = lengthOf(this, KILOMETER)
1. Define Unit factors
enum class LengthUnit(val unitName: String, val factor: Double) {
MILLIMETER("mm", 1.0),
CENTIMETER("cm", 10.0),
METER("m", 1e3),
KILOMETER("km", 1e6);
}
Define Unit class
data class Length(val value: Double = 0.0): Comparable<Length>, Serializable {
operator fun plus(other: Length): Length = Length(value + other.value)
operator fun minus(other: Length): Length = Length(value - other.value)
operator fun times(scalar: Int): Length = Length(value * scalar)
operator fun times(scalar: Long): Length = Length(value * scalar)
operator fun times(scalar: Double): Length = Length(value * scalar)
operator fun times(other: Length): Area = Area(value * other.value)
operator fun div(scalar: Int): Length = Length(value / scalar)
operator fun div(scalar: Long): Length = Length(value / scalar)
operator fun div(scalar: Double): Length = Length(value / scalar)
operator fun unaryMinus(): Length = Length(-value)
Override Operators
2. Korean Tokenizer
• 중복상품 Merge 위한 Tokenizer 필요 (명사 위주)

• Twitter 에서 개발한 open-korean-text 를 Customizing

• Scala vs Kotlin 성능 비교 

• Kotlin version is 1.5 ~ 3X faster with Coroutines

• 효과

• Full Indexing per Day 부하 감소 : 30%

• Elastic Search 질의 부하 : 80%
“제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열”
은전한닢 Twitter
블랙
비치
비치트렁크
계열
제테스
3928PR
블랙블랙계열
PR
MSW
,
(
)-
트렁크
3928
95
제테스
남성
“제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열”
은전한닢 Twitter
블랙
비치
비치트렁크
계열
제테스
3928PR
블랙블랙계열
PR
MSW
,
(
)-
트렁크
3928
95
제테스
남성
“제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열”
은전한닢 Twitter
블랙
비치
비치트렁크
계열
제테스
3928PR
블랙블랙계열
PR
MSW
,
(
)
L -
트렁크
3928
95
제테스
남성
Tokenizer Benchmark
은전한닢 Twitter RATIO
RPS 73.2 429.5 5.87 X
Avg Latency 626 ms 106 ms 5.91 X
Avg CPU Load 90% 55% 35 % Down
Twitter Tokenizer 는 한음절을 분석하지 못하는 단점이 있다
Scala Kotlin RATIO
Tokenize 668.620 ms 197.632 ms 3.38 X
Phrase extractor 644.902 ms 212.500 ms 3.13 X
구문 : “동해물과 백두산이 마르고 닳도록“
Benchmark by jmh

Linux Mint 18.2 Intel I7, 32GB, SSD
Why Kotlin is faster?
• Scala 의 loop는 느리다 - 아주 느릴 수 있다

• eclipse-collections 사용

• 메모리 절약

• Primitive type collection 지원

• Kotlin Coroutines

• 비동기 / Non-Blocking
3. Kafka Client - Wilson
• 동기 

• 안정된 Kafka 사용을 위해 Offset 관리가 필수

• 각 팀별 중복된 Client 구현 및 삽질

• 효과

• Message 중복 / 유실 없음 (Latest strategy)

• Retry / Circuit breaker 지원

• Metrics 를 활용한 Ack 지원

• 전사 확대 적용 중
Wilson message flows
Producer ConsumerKafka
Retry
Circuit Breaker
Metrics
Retry
Circuit Breaker
Metrics
Dead letters
Sending box
Redis
MySQL
Couchbase
Dead letters
Received box
Last sent timestamp Kafka Offset Manager
Message Managements
• Metrics
• Recovery / Retry
• Deadletter handling
Wilson Dashboard
4. Audit Tool
• 상품 정보 Audit System

• developers : 1 senior, 2 junior developer 

• Software stack

• React 

• Spring Boot 1.5 on Vitamin Framework

• jOOQ (향후 requery로 변환 예정)

• Pilot 로 시작, 개발자들의 노력으로 정식 시스템으로 승격
4. Audit Tool
Kotlin Coroutines + Spring MVC
5. Creation Pipeline System
• 상품 정보 생성 프로세스 관리 시스템

• Features

• Workflow (Heavy use Kafka)

• Asynchronous / Non-blocking System

• Need High throughput
Seller
Retail
Kafka
Deduplication
Refining
Processing
Creation
Logging
Message Dispatcher
Creation Pipeline flow
Kafka
5. Creation Pipeline System
Spring Boot 1.x Kafka 0.10.x
Kotlin 1.2.x on JVM 8
Couchbase 4.x
Zookeeper
3.x
%
%
Use cases 2018
• Tagging system (2018.1 ~ 2018.3)

• Spring Data Requery (alternative to JPA) (2018.4 ~)

• Rule engine (Thanos rule engine) (2018.6 ~)

• Wakanda system (Reactive + Coroutines) (2018.9 ~)

• Creation Pipeline Upgrade (2018.10 ~)
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Aurora Cassandra ElasticSearch HBase
JVM 8
Spring DataRequery JPA/Hibernate
Virtualization

kubernetes
Docker
Spring Framework 5.xKodein
Kotlin Coroutines with Reactor / RxJava
Services

Kafka
Redis
Spring Boot 2.x Webflux with Netty / gRPC
Common Backend Stack (2018)
Boo1vsBoo2Performance
Spring MVC + Cassandra
Spring WebFlux + Cassandra Reactive
출처: Reactive Java Performance Comparison
6. Tagging System
• 상품 정보에서 원하는 특성을 추출하는 시스템

• Matching 과 Refinement 에서 따로 관리

• 범용화 필요 (Configuration, Plugin)

• 기존 Java & Scala 혼용

• 장애 대응에 문제

• High Throughput
Tagging for Matching
스톤 9.0cm 여성하이힐 MZ-135 블랙 245
Brand Gender
Shoes
Type
Color Size
7. spring-data-requery (2018)
• RequeryOperations

• Wrap EntityDataStore

• RequeryTransactionManager for TransactionManager

• Support Spring @Transactional

• Better performance than spring-data-jpa

• when exists, paging, not load all entities
https://www.slideshare.net/debop/alternatives-of-jpahibernate
https://www.slideshare.net/debop/requery-overview
https://www.slideshare.net/debop/spring-data-requery
spring-data-requery
• Repository built in SQL

• ByPropertyName Auto generation methods

• @Query for Native SQL Query

• Query By Example

• Not Supported

• Association Path (not specified join method)

• Named parameter in @Query (just use `?`)
Define Entity - Java
@Getter
@Entity(name = "BasicUser", copyable = true)
@Table(name = "basic_user")
public abstract class AbstractBasicUser extends AuditableLongEntity {
@Key
@Generated
protected Long id;
protected String name;
protected String email;
protected LocalDate birthday;
protected Integer age;
@ForeignKey
@OneToOne
protected AbstractBasicLocation address;
@ManyToMany(mappedBy = "members")
protected Set<AbstractBasicGroup> groups;
@Column(unique = true)
protected UUID uuid;
Use @Query in Repository
interface DeclaredQueryRepository extends RequeryRepository<BasicUser, Long> {
@Query("select * from basic_user u where u.email = ?")
BasicUser findByAnnotatedQuery(String email);
@Query("select * from basic_user u where u.email like ?")
List<BasicUser> findAllByEmailMatches(String email);
@Query("select * from basic_user u limit ?")
List<BasicUser> findWithLimits(int limit);
@Query("select * from basic_user u where u.name=? and u.email=? limit 1")
BasicUser findAllBy(String name, String email);
@Query("select u.id, u.name from basic_user u where u.email=?")
List<Tuple> findAllIds(String email);
@Query("select * from basic_user u where u.birthday = ?")
List<BasicUser> findByBirthday(LocalDate birthday);
}
Query By Example
BasicUser user = RandomData.randomUser();
user.setName("example");
requeryTemplate.insert(user);
BasicUser exampleUser = new BasicUser();
exampleUser.setName("EXA");
ExampleMatcher matcher = matching()
.withMatcher("name", startsWith().ignoreCase())
.withIgnoreNullValues();
Example<BasicUser> example = Example.of(exampleUser, matcher);
Return<? extends Result<BasicUser>> query = buildQueryByExample(example);
BasicUser foundUser = query.get().firstOrNull();
assertThat(foundUser).isNotNull().isEqualTo(user);
Query by Property
List<User> findByFirstnameOrLastname(String firstname, String lastname);
List<User> findByLastnameLikeOrderByFirstnameDesc(String lastname);
List<User> findByLastnameNotLike(String lastname);
List<User> findByLastnameNot(String lastname);
List<User> findByManagerLastname(String name);
List<User> findByColleaguesLastname(String lastname);
List<User> findByLastnameNotNull();
@Query("select u.lastname from SD_User u group by u.lastname")
Page<String> findByLastnameGrouped(Pageable pageable);
long countByLastname(String lastname);
int countUsersByFirstname(String firstname);
boolean existsByLastname(String lastname);
Note: Association Path is not supported
Note: Association Path is not supported
Future works
• Coroutines for Async JDBC Operations (working)

• Support Named parameter

• Support `@Param` in spring data

• Requery for SQL on Hadoop

• Apache Phoenix (HBase) (Done)

• Apache Hive, Apache Drill …
8. Rule Engine (2018)
• Embedded

• Support Language

• MVEL (almost like Java spec)

• KotlinScript

• Javascript

• Support Multi Rule combination

• Rule Definition DSL (Kotlin)

• Rule Editor in WEB (in construction)
Rule Engine
A rule engine can be viewed as a sophisticated interpreter for if/then
statements, where the statements themselves are known as rules.
Rule Definition
val rule = rule {
name = "myRule"
description = "myDescription"
priority = 3
condition {
condition1.evaluate(it)
}
action {
action1.execute(it)
}
action {
action2.execute(it)
}
}
val rule = RuleBuilder()
.name("myRule")
.description("myDescription")
.priority(3)
.whenever(condition)
.then(action1)
.then(action2)
.build()
@Rule(name = "weather rule", description = "if it rains then take an umbrella")
class WeatherRule {
@Condition
fun itRains(@Fact("rain") rain: Boolean): Boolean = rain
@Action
fun takeAnUmbrella() {
println("It rains, take an umbrella")
}
}
9. Wakanda
• Catalog 정보 관리 시스템의 핵심

• Read, Write Side 분리 제공

• 전사 통합에 의해 Write side만 존치

• Fully Reactive / Non-Blocking
Editable Catalog Process
Cassandra ElasticSearch
JVM 8
Cassandra Vanilla Driver
Virtualization

kubernetes
Docker
Spring Framework 5.x
Kotlin Coroutines with Reactor
Services

Kafka
Redis
Spring Boot 2.x Webflux
Wakanda Software stack
Lesson & Learns
반성해야 하는 점
• 기본기 학습 - 닥치고 코딩 (X) 

• Java와 차이점 및 Kotlin best practices 검토 필요

• 첫 술에 배부를 수 없다 

• 실망하지 말라, Refactoring 은 필수다

• Coroutines 에 대한 학습 및 테스트

• 어차피 비동기는 어렵다. 

• Coroutines는 하나의 방법일 뿐이다
안정적 도입을 위한 Tips
• 충분한 학습 기회 & 실습

• Code Quality 중요성 인식

• Upsource 전사 활용 중 (문화가 중요)

• 강력한 동기 부여

• Tech Leader의 지속적인 Leading & Coach

• 성공 사례 만들기 (작은 것부터)
효과
• Safety Code

• Readable Code

• 성능 향상

• Latency 감소, High Throughput 달성 

• Asynchronous/Non-Blocking 적용 용이

• 유지보수성 향상 (장애 감소)
언어별 Catalog Tribe 개발자 비율
(2017)
5%
Kotlin
10%
Scala
15%
Java
70%
Java Scala Kotlin Python
언어별 Catalog Tribe 개발자 비율
(2018)
17%
Kotlin
40%
Scala
13%
Java
30%
Java Scala Kotlin Python
Resources
• Kotlin Resources

• kotlinx.coroutines

• 20 Excellent Resources for learning Kotlin

• Books

• Kotlin in action, Joy of Kotlin

• Try Kotlin
Q&A
Thank you!

More Related Content

PDF
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
PDF
JUnit5 and TestContainers
Sunghyouk Bae
 
PDF
Requery overview
Sunghyouk Bae
 
PPTX
Kotlin coroutines and spring framework
Sunghyouk Bae
 
PDF
Alternatives of JPA/Hibernate
Sunghyouk Bae
 
PDF
Spring data requery
Sunghyouk Bae
 
PDF
Introduction of failsafe
Sunghyouk Bae
 
PDF
Clojure, Plain and Simple
Ben Mabey
 
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
JUnit5 and TestContainers
Sunghyouk Bae
 
Requery overview
Sunghyouk Bae
 
Kotlin coroutines and spring framework
Sunghyouk Bae
 
Alternatives of JPA/Hibernate
Sunghyouk Bae
 
Spring data requery
Sunghyouk Bae
 
Introduction of failsafe
Sunghyouk Bae
 
Clojure, Plain and Simple
Ben Mabey
 

What's hot (20)

PDF
Kotlin talk
Klemen Kresnik
 
KEY
Python在豆瓣的应用
Qiangning Hong
 
PDF
Scala @ TechMeetup Edinburgh
Stuart Roebuck
 
PDF
Clojure made-simple - John Stevenson
JAX London
 
PDF
Scala coated JVM
Stuart Roebuck
 
PDF
Kotlin: Why Do You Care?
intelliyole
 
PDF
Python高级编程(二)
Qiangning Hong
 
PDF
Clojure for Java developers
John Stevenson
 
PDF
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
PPTX
Kotlin is charming; The reasons Java engineers should start Kotlin.
JustSystems Corporation
 
PPTX
BASTA 2013: Custom OData Provider
Rainer Stropek
 
PDF
#살아있다 #자프링외길12년차 #코프링2개월생존기
Arawn Park
 
PPTX
Scoobi - Scala for Startups
bmlever
 
PDF
Fun with Functional Programming in Clojure
Codemotion
 
PPTX
Akka Actor presentation
Gene Chang
 
PDF
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Taro L. Saito
 
PPTX
concurrency gpars
Paul King
 
PDF
Kotlin in action
Ciro Rizzo
 
ODP
GPars (Groovy Parallel Systems)
Gagan Agrawal
 
PPTX
Scale up your thinking
Yardena Meymann
 
Kotlin talk
Klemen Kresnik
 
Python在豆瓣的应用
Qiangning Hong
 
Scala @ TechMeetup Edinburgh
Stuart Roebuck
 
Clojure made-simple - John Stevenson
JAX London
 
Scala coated JVM
Stuart Roebuck
 
Kotlin: Why Do You Care?
intelliyole
 
Python高级编程(二)
Qiangning Hong
 
Clojure for Java developers
John Stevenson
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
Kotlin is charming; The reasons Java engineers should start Kotlin.
JustSystems Corporation
 
BASTA 2013: Custom OData Provider
Rainer Stropek
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
Arawn Park
 
Scoobi - Scala for Startups
bmlever
 
Fun with Functional Programming in Clojure
Codemotion
 
Akka Actor presentation
Gene Chang
 
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Taro L. Saito
 
concurrency gpars
Paul King
 
Kotlin in action
Ciro Rizzo
 
GPars (Groovy Parallel Systems)
Gagan Agrawal
 
Scale up your thinking
Yardena Meymann
 
Ad

Similar to Kotlin @ Coupang Backed - JetBrains Day seoul 2018 (20)

KEY
The Why and How of Scala at Twitter
Alex Payne
 
PPTX
Ceilosca
Fabio Giannetti
 
PPTX
Bluemix paas 기반 saas 개발 사례
uEngine Solutions
 
PDF
Microservice Automated Testing on Kubernetes
Shane Galvin
 
PDF
[AWS Dev Day] 실습워크샵 | Amazon EKS 핸즈온 워크샵
Amazon Web Services Korea
 
PPTX
Kubernetes Manchester - 6th December 2018
David Stockton
 
PPTX
Clustrix Database Percona Ruby on Rails benchmark
Clustrix
 
PPT
Distributed & Highly Available server applications in Java and Scala
Max Alexejev
 
PDF
Making Apache Kafka Even Faster And More Scalable
PaulBrebner2
 
PPTX
Exploring Twitter's Finagle technology stack for microservices
💡 Tomasz Kogut
 
PPTX
Kubernetes at NU.nl (Kubernetes meetup 2019-09-05)
Tibo Beijen
 
PDF
What to expect from Java 9
Ivan Krylov
 
PPTX
DOTNET8.pptx
Udaiappa Ramachandran
 
PDF
170215 msa intro
Sonic leigh
 
PDF
Building scalbale cloud native apps with .NET 8
GillesMathieu10
 
PDF
Innovating faster with SBT, Continuous Delivery, and LXC
kscaldef
 
PPTX
Microservices, Continuous Delivery, and Elasticsearch at Capital One
Noriaki Tatsumi
 
PDF
COMMitMDE'18: Eclipse Hawk: model repository querying as a service
Antonio García-Domínguez
 
PPTX
OS for AI: Elastic Microservices & the Next Gen of ML
Nordic APIs
 
PDF
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
Ortus Solutions, Corp
 
The Why and How of Scala at Twitter
Alex Payne
 
Ceilosca
Fabio Giannetti
 
Bluemix paas 기반 saas 개발 사례
uEngine Solutions
 
Microservice Automated Testing on Kubernetes
Shane Galvin
 
[AWS Dev Day] 실습워크샵 | Amazon EKS 핸즈온 워크샵
Amazon Web Services Korea
 
Kubernetes Manchester - 6th December 2018
David Stockton
 
Clustrix Database Percona Ruby on Rails benchmark
Clustrix
 
Distributed & Highly Available server applications in Java and Scala
Max Alexejev
 
Making Apache Kafka Even Faster And More Scalable
PaulBrebner2
 
Exploring Twitter's Finagle technology stack for microservices
💡 Tomasz Kogut
 
Kubernetes at NU.nl (Kubernetes meetup 2019-09-05)
Tibo Beijen
 
What to expect from Java 9
Ivan Krylov
 
DOTNET8.pptx
Udaiappa Ramachandran
 
170215 msa intro
Sonic leigh
 
Building scalbale cloud native apps with .NET 8
GillesMathieu10
 
Innovating faster with SBT, Continuous Delivery, and LXC
kscaldef
 
Microservices, Continuous Delivery, and Elasticsearch at Capital One
Noriaki Tatsumi
 
COMMitMDE'18: Eclipse Hawk: model repository querying as a service
Antonio García-Domínguez
 
OS for AI: Elastic Microservices & the Next Gen of ML
Nordic APIs
 
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
Ortus Solutions, Corp
 
Ad

More from Sunghyouk Bae (9)

PDF
measure metrics
Sunghyouk Bae
 
PPTX
Java naming strategy (자바 명명 전략)
Sunghyouk Bae
 
PPTX
테스트자동화와 TDD
Sunghyouk Bae
 
PPTX
SpringBoot with MyBatis, Flyway, QueryDSL
Sunghyouk Bae
 
PPTX
JUnit & AssertJ
Sunghyouk Bae
 
PPTX
좋은 개발자 되기
Sunghyouk Bae
 
PDF
Using AdoRepository
Sunghyouk Bae
 
PDF
Multithread pattern 소개
Sunghyouk Bae
 
PDF
Strategy Maps
Sunghyouk Bae
 
measure metrics
Sunghyouk Bae
 
Java naming strategy (자바 명명 전략)
Sunghyouk Bae
 
테스트자동화와 TDD
Sunghyouk Bae
 
SpringBoot with MyBatis, Flyway, QueryDSL
Sunghyouk Bae
 
JUnit & AssertJ
Sunghyouk Bae
 
좋은 개발자 되기
Sunghyouk Bae
 
Using AdoRepository
Sunghyouk Bae
 
Multithread pattern 소개
Sunghyouk Bae
 
Strategy Maps
Sunghyouk Bae
 

Recently uploaded (20)

PPTX
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
PDF
49785682629390197565_LRN3014_Migrating_the_Beast.pdf
Abilash868456
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PDF
Enhancing Healthcare RPM Platforms with Contextual AI Integration
Cadabra Studio
 
PDF
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PPTX
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
PDF
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
PDF
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
PPTX
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
PPTX
Can You Build Dashboards Using Open Source Visualization Tool.pptx
Varsha Nayak
 
PDF
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
PDF
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PPTX
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
PPTX
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
PPTX
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
PPTX
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
49785682629390197565_LRN3014_Migrating_the_Beast.pdf
Abilash868456
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
Enhancing Healthcare RPM Platforms with Contextual AI Integration
Cadabra Studio
 
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
Can You Build Dashboards Using Open Source Visualization Tool.pptx
Varsha Nayak
 
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 

Kotlin @ Coupang Backed - JetBrains Day seoul 2018

  • 2. Who is @debop • Since 1993 • Robotics, BPM Solution, Healthcare • C/C++, Object Pascal, C#, Java, Scala, Kotlin • Use Kotlin since 2016.08 • Sr. Principle Software Engineer in Coupang (2017~) • 남의 코드 뒤집기 / 빨간펜 선생 • Common Library 제작 • Architecture 참견
  • 3. Agenda • Kotlin 도입 동기 • Kotlin 도입 사례 • Kotlinx (Common Library) • 공용 Library 개발 • spring-data-requery • Lesson & Learn
  • 5. What is our problem? • 개발자 수준 편차가 크다 • 조직 수준은 최하위 개발자 수준의 의해 결정된다
  • 6. Our status • Lack of Safety code • Not Readable code • Lack of Testing (Unit & Integration) • Heavy oriented to JPA • Lack of experience to Async/Non-Blocking Programming
  • 7. Our environments • 1일 데이터 처리량 : 천만건(2016) -> 10억건(2018) • MySQL (Aurora) : Replication delay120 sec (max) • Backend Stack in 2016 • MySQL, RabbitMQ, Hive • Spring 3, JPA
  • 8. Our Challenges • Akka Cluster with Lagom Framework (CQRS) • Move to NoSQL (Cassandra, HBase) • Migrate RabbitMQ to Kafka • Adopting Scala (Pilot) • Akka, Spark …
  • 9. Failure • Adopting Scala • Learning Curve (Almost Junior) • Lack of Tech Leaders • Try to develop too complex system • Adopting Kafka • Simultaneous development (duplicate same error) • Offset managements
  • 10. To pursue change • 객관적 시각 유지 • History 및 현실 상황 대한 이해 (기술부채) • 현 조직의 개발 역량 객관적 평가 • 동기부여 - 필요성 설득보다는 자각할 수 있도록 자극 • 충분한 학습 시간 • 변화 경험 공유 • ASP -> C#, Java -> Scala
  • 11. Prepare • Code Quality 중요성 자각 -> Code Review • Enterprise Application Commons • Patterns 교육, Library 제공 • Enterprise Architecture 학습 • Asynchronous Programming 학습 • Kotlin Language 학습 • Kotlin is language for Android ?
  • 12. Adopting Kotlin • Safety Code / Readable Code • Simple grammar (Easy to learn) • Interoperability between Java and Kotlin • Extension methods • Asynchronous Programming by Coroutines
  • 13. Environments 준비 • 개발 Tool 지원 - IntelliJ IDEA • Static code analysis - ktlint, detekt • Test code coverage - jacoco (sample) • Sonarcube - sonar-kotlin plugin
  • 15. Use cases 2017 • Common Library (2017. 6 ~) • Kotlin extension library • Components (2017.08 ~ 2017.12) • Aho-corasick, Korean Tokenizer, Kafka Client • Standalone Web Application (2017.10~~2017.12) • Audit Tool • Large scale system (2017.09~2018.01) • Catalog creation pipeline system
  • 16. 1. Kotlin Extension library • Coupang Standard Framework 대체 • Kotlin Best practices 제공 • Object / IO / Utils / Cache / JDBC / Spring … • Kotlin 학습 예제 제공 (Test cases / Examples) • Based debop4k (personal project)
  • 17. Kotlinx-Units • 도량형(度量衡)(Standard Unit) • Represent Meter Units • Weight, Length, Area, Volume, Storage Volume • Yard-Pound Units • Pound, Yard/Miles, Volume, Fluid Volume … • Others • Temperature, Electlic powers, Frequency, Light, Radiation, Pressure …
  • 18. Our usages enum class Unit(val description: String, val unitConversion: BigDecimal) { NONE("없음", BigDecimal.ZERO), // Length MM("mm", 0.1.toBigDecimal()), CM("cm", BigDecimal.ONE), M("m", 100.toBigDecimal()), KM("km", 100_000.toBigDecimal()),
  • 19. Our usages // Length (Inch) IN("in", BigDecimal.ONE), FT("ft", 12.toBigDecimal()), YD("yd", 36.toBigDecimal()), // Weight (gram) MG("mg", 0.001.toBigDecimal()), G("g", BigDecimal.ONE), KG("kg", 1000.toBigDecimal()), T("t", 1_000_000.toBigDecimal()), OZ("oz", 28.349523.toBigDecimal()), LB("lb", 453.59237.toBigDecimal()), •Define Units by Enum •Not support conversions •Not support various units •Not support operations •Not readable code
  • 20. Features for units • Readable code like this • 5.kg() + 400.gram() => 5.4.kg() • 100.cm() + 2.m() => 2.1.cm() • Convert various units • 5.kg().inGram() -> 5000.gram • 2.5.Kb().inBytes() -> 2500.bytes() • Convert SI Units <-> US Units
  • 21. Use Kotlin extension methods fun Double.millimeter(): Length = lengthOf(this, MILLIMETER) fun Double.centimeter(): Length = lengthOf(this, CENTIMETER) fun Double.meter(): Length = lengthOf(this) fun Double.kilometer(): Length = lengthOf(this, KILOMETER)
  • 22. 1. Define Unit factors enum class LengthUnit(val unitName: String, val factor: Double) { MILLIMETER("mm", 1.0), CENTIMETER("cm", 10.0), METER("m", 1e3), KILOMETER("km", 1e6); }
  • 23. Define Unit class data class Length(val value: Double = 0.0): Comparable<Length>, Serializable { operator fun plus(other: Length): Length = Length(value + other.value) operator fun minus(other: Length): Length = Length(value - other.value) operator fun times(scalar: Int): Length = Length(value * scalar) operator fun times(scalar: Long): Length = Length(value * scalar) operator fun times(scalar: Double): Length = Length(value * scalar) operator fun times(other: Length): Area = Area(value * other.value) operator fun div(scalar: Int): Length = Length(value / scalar) operator fun div(scalar: Long): Length = Length(value / scalar) operator fun div(scalar: Double): Length = Length(value / scalar) operator fun unaryMinus(): Length = Length(-value) Override Operators
  • 24. 2. Korean Tokenizer • 중복상품 Merge 위한 Tokenizer 필요 (명사 위주) • Twitter 에서 개발한 open-korean-text 를 Customizing • Scala vs Kotlin 성능 비교 • Kotlin version is 1.5 ~ 3X faster with Coroutines • 효과 • Full Indexing per Day 부하 감소 : 30% • Elastic Search 질의 부하 : 80%
  • 25. “제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열” 은전한닢 Twitter 블랙 비치 비치트렁크 계열 제테스 3928PR 블랙블랙계열 PR MSW , ( )- 트렁크 3928 95 제테스 남성
  • 26. “제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열” 은전한닢 Twitter 블랙 비치 비치트렁크 계열 제테스 3928PR 블랙블랙계열 PR MSW , ( )- 트렁크 3928 95 제테스 남성
  • 27. “제테스 MSW-3928PR 남성 비치트렁크, 95(L), 블랙블랙계열” 은전한닢 Twitter 블랙 비치 비치트렁크 계열 제테스 3928PR 블랙블랙계열 PR MSW , ( ) L - 트렁크 3928 95 제테스 남성
  • 28. Tokenizer Benchmark 은전한닢 Twitter RATIO RPS 73.2 429.5 5.87 X Avg Latency 626 ms 106 ms 5.91 X Avg CPU Load 90% 55% 35 % Down Twitter Tokenizer 는 한음절을 분석하지 못하는 단점이 있다
  • 29. Scala Kotlin RATIO Tokenize 668.620 ms 197.632 ms 3.38 X Phrase extractor 644.902 ms 212.500 ms 3.13 X 구문 : “동해물과 백두산이 마르고 닳도록“ Benchmark by jmh Linux Mint 18.2 Intel I7, 32GB, SSD
  • 30. Why Kotlin is faster? • Scala 의 loop는 느리다 - 아주 느릴 수 있다 • eclipse-collections 사용 • 메모리 절약 • Primitive type collection 지원 • Kotlin Coroutines • 비동기 / Non-Blocking
  • 31. 3. Kafka Client - Wilson • 동기 • 안정된 Kafka 사용을 위해 Offset 관리가 필수 • 각 팀별 중복된 Client 구현 및 삽질 • 효과 • Message 중복 / 유실 없음 (Latest strategy) • Retry / Circuit breaker 지원 • Metrics 를 활용한 Ack 지원 • 전사 확대 적용 중
  • 32. Wilson message flows Producer ConsumerKafka Retry Circuit Breaker Metrics Retry Circuit Breaker Metrics Dead letters Sending box Redis MySQL Couchbase Dead letters Received box Last sent timestamp Kafka Offset Manager Message Managements • Metrics • Recovery / Retry • Deadletter handling
  • 34. 4. Audit Tool • 상품 정보 Audit System • developers : 1 senior, 2 junior developer • Software stack • React • Spring Boot 1.5 on Vitamin Framework • jOOQ (향후 requery로 변환 예정) • Pilot 로 시작, 개발자들의 노력으로 정식 시스템으로 승격
  • 35. 4. Audit Tool Kotlin Coroutines + Spring MVC
  • 36. 5. Creation Pipeline System • 상품 정보 생성 프로세스 관리 시스템 • Features • Workflow (Heavy use Kafka) • Asynchronous / Non-blocking System • Need High throughput
  • 38. 5. Creation Pipeline System Spring Boot 1.x Kafka 0.10.x Kotlin 1.2.x on JVM 8 Couchbase 4.x Zookeeper 3.x
  • 39. %
  • 40. %
  • 41. Use cases 2018 • Tagging system (2018.1 ~ 2018.3) • Spring Data Requery (alternative to JPA) (2018.4 ~) • Rule engine (Thanos rule engine) (2018.6 ~) • Wakanda system (Reactive + Coroutines) (2018.9 ~) • Creation Pipeline Upgrade (2018.10 ~)
  • 43. Aurora Cassandra ElasticSearch HBase JVM 8 Spring DataRequery JPA/Hibernate Virtualization kubernetes Docker Spring Framework 5.xKodein Kotlin Coroutines with Reactor / RxJava Services Kafka Redis Spring Boot 2.x Webflux with Netty / gRPC Common Backend Stack (2018)
  • 45. Spring MVC + Cassandra Spring WebFlux + Cassandra Reactive 출처: Reactive Java Performance Comparison
  • 46. 6. Tagging System • 상품 정보에서 원하는 특성을 추출하는 시스템 • Matching 과 Refinement 에서 따로 관리 • 범용화 필요 (Configuration, Plugin) • 기존 Java & Scala 혼용 • 장애 대응에 문제 • High Throughput
  • 47. Tagging for Matching 스톤 9.0cm 여성하이힐 MZ-135 블랙 245 Brand Gender Shoes Type Color Size
  • 48. 7. spring-data-requery (2018) • RequeryOperations • Wrap EntityDataStore • RequeryTransactionManager for TransactionManager • Support Spring @Transactional • Better performance than spring-data-jpa • when exists, paging, not load all entities https://www.slideshare.net/debop/alternatives-of-jpahibernate https://www.slideshare.net/debop/requery-overview https://www.slideshare.net/debop/spring-data-requery
  • 49. spring-data-requery • Repository built in SQL • ByPropertyName Auto generation methods • @Query for Native SQL Query • Query By Example • Not Supported • Association Path (not specified join method) • Named parameter in @Query (just use `?`)
  • 50. Define Entity - Java @Getter @Entity(name = "BasicUser", copyable = true) @Table(name = "basic_user") public abstract class AbstractBasicUser extends AuditableLongEntity { @Key @Generated protected Long id; protected String name; protected String email; protected LocalDate birthday; protected Integer age; @ForeignKey @OneToOne protected AbstractBasicLocation address; @ManyToMany(mappedBy = "members") protected Set<AbstractBasicGroup> groups; @Column(unique = true) protected UUID uuid;
  • 51. Use @Query in Repository interface DeclaredQueryRepository extends RequeryRepository<BasicUser, Long> { @Query("select * from basic_user u where u.email = ?") BasicUser findByAnnotatedQuery(String email); @Query("select * from basic_user u where u.email like ?") List<BasicUser> findAllByEmailMatches(String email); @Query("select * from basic_user u limit ?") List<BasicUser> findWithLimits(int limit); @Query("select * from basic_user u where u.name=? and u.email=? limit 1") BasicUser findAllBy(String name, String email); @Query("select u.id, u.name from basic_user u where u.email=?") List<Tuple> findAllIds(String email); @Query("select * from basic_user u where u.birthday = ?") List<BasicUser> findByBirthday(LocalDate birthday); }
  • 52. Query By Example BasicUser user = RandomData.randomUser(); user.setName("example"); requeryTemplate.insert(user); BasicUser exampleUser = new BasicUser(); exampleUser.setName("EXA"); ExampleMatcher matcher = matching() .withMatcher("name", startsWith().ignoreCase()) .withIgnoreNullValues(); Example<BasicUser> example = Example.of(exampleUser, matcher); Return<? extends Result<BasicUser>> query = buildQueryByExample(example); BasicUser foundUser = query.get().firstOrNull(); assertThat(foundUser).isNotNull().isEqualTo(user);
  • 53. Query by Property List<User> findByFirstnameOrLastname(String firstname, String lastname); List<User> findByLastnameLikeOrderByFirstnameDesc(String lastname); List<User> findByLastnameNotLike(String lastname); List<User> findByLastnameNot(String lastname); List<User> findByManagerLastname(String name); List<User> findByColleaguesLastname(String lastname); List<User> findByLastnameNotNull(); @Query("select u.lastname from SD_User u group by u.lastname") Page<String> findByLastnameGrouped(Pageable pageable); long countByLastname(String lastname); int countUsersByFirstname(String firstname); boolean existsByLastname(String lastname); Note: Association Path is not supported Note: Association Path is not supported
  • 54. Future works • Coroutines for Async JDBC Operations (working) • Support Named parameter • Support `@Param` in spring data • Requery for SQL on Hadoop • Apache Phoenix (HBase) (Done) • Apache Hive, Apache Drill …
  • 55. 8. Rule Engine (2018) • Embedded • Support Language • MVEL (almost like Java spec) • KotlinScript • Javascript • Support Multi Rule combination • Rule Definition DSL (Kotlin) • Rule Editor in WEB (in construction)
  • 56. Rule Engine A rule engine can be viewed as a sophisticated interpreter for if/then statements, where the statements themselves are known as rules.
  • 57. Rule Definition val rule = rule { name = "myRule" description = "myDescription" priority = 3 condition { condition1.evaluate(it) } action { action1.execute(it) } action { action2.execute(it) } } val rule = RuleBuilder() .name("myRule") .description("myDescription") .priority(3) .whenever(condition) .then(action1) .then(action2) .build() @Rule(name = "weather rule", description = "if it rains then take an umbrella") class WeatherRule { @Condition fun itRains(@Fact("rain") rain: Boolean): Boolean = rain @Action fun takeAnUmbrella() { println("It rains, take an umbrella") } }
  • 58. 9. Wakanda • Catalog 정보 관리 시스템의 핵심 • Read, Write Side 분리 제공 • 전사 통합에 의해 Write side만 존치 • Fully Reactive / Non-Blocking
  • 60. Cassandra ElasticSearch JVM 8 Cassandra Vanilla Driver Virtualization kubernetes Docker Spring Framework 5.x Kotlin Coroutines with Reactor Services Kafka Redis Spring Boot 2.x Webflux Wakanda Software stack
  • 62. 반성해야 하는 점 • 기본기 학습 - 닥치고 코딩 (X) • Java와 차이점 및 Kotlin best practices 검토 필요 • 첫 술에 배부를 수 없다 • 실망하지 말라, Refactoring 은 필수다 • Coroutines 에 대한 학습 및 테스트 • 어차피 비동기는 어렵다. • Coroutines는 하나의 방법일 뿐이다
  • 63. 안정적 도입을 위한 Tips • 충분한 학습 기회 & 실습 • Code Quality 중요성 인식 • Upsource 전사 활용 중 (문화가 중요) • 강력한 동기 부여 • Tech Leader의 지속적인 Leading & Coach • 성공 사례 만들기 (작은 것부터)
  • 64. 효과 • Safety Code • Readable Code • 성능 향상 • Latency 감소, High Throughput 달성 • Asynchronous/Non-Blocking 적용 용이 • 유지보수성 향상 (장애 감소)
  • 65. 언어별 Catalog Tribe 개발자 비율 (2017) 5% Kotlin 10% Scala 15% Java 70% Java Scala Kotlin Python 언어별 Catalog Tribe 개발자 비율 (2018) 17% Kotlin 40% Scala 13% Java 30% Java Scala Kotlin Python
  • 66. Resources • Kotlin Resources • kotlinx.coroutines • 20 Excellent Resources for learning Kotlin • Books • Kotlin in action, Joy of Kotlin • Try Kotlin
  • 67. Q&A