Mykola Borozdin, TL
Wix Serverless from inside
mykola.borozdin@gmail.com
1
aka хуяк-хуяк в продакшн
Author
1. SE Master of science
2. 8 years in the industry
3. From enterprise outstaff to product infra
4. From Java to Scala-Typescript
5. Did not work with Node.JS before Wix
2
1. The Motivation
2. The Present
3. The Past
4. The Future
Agenda
3
Backend in Wix
4
▪ Microservices managed by K8s
▪ Outside calls - http
▪ Inside calls - GRPC sync calls
▪ Kafka async calls
Wix Node Platform
1. Wix Bootstrap - Scala, Java
2. JS - the most popular language
3. Frontenders & JVM languages !== Love
4. Node.js translation of Wix Bootstrap
5
Wix Node Platform without Serverless
6
Wix Node Platform without Serverless
7
Wix Node Platform without Serverless
8
Wix Node Platform without Serverless
9
Wix Node Platform without Serverless
10
Wix Node Platform without Serverless
11
Wix Node Platform without Serverless
12
Serverless
▪ Function as a service
▪ Resources on demand
▪ No infra management
13
Wix Serverless
▪ All plugins and testkits wired out of the box
▪ Built-in autoscaling, metrics, logs, alerts
▪ Create & deploy with #serverless in commit, CLI or web app
▪ From commit to production in less than a minute
▪ Deploy status Slack notifications
14
Create & deploy Serverless app
15
DOs
▪ IO-intensive services
▪ Call GRPC service
▪ Send message to Kafka
16
▪ CPU-intensive services
▪ Parsing 200 MB JSONs
▪ Rendering images
DON’Ts
Wix Serverless
▪ Function set as a service
▪ No wiring
▪ Resources mgmt only if needed
▪ Hot start
▪ Wix specific
17
▪ Function as a service
▪ No wiring
▪ No resources mgmt
▪ Cold start
▪ AWS specific
AWS Serverless
Current users
▪ ~600 production applications
▪ ~110k rpm http/grpc traffic
▪ ~600k rpm Kafka traffic
18
Wix Serverless app structure
19
serverless.ts
1. module.exports = (functionsBuilder: FunctionsBuilder) => functionsBuilder
2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => {
3. // business logic
4. })
5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => {
6. // business logic
7. });
8.
20
serverless.ts
1. module.exports = (functionsBuilder: FunctionsBuilder) => functionsBuilder
2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => {
3. // business logic
4. })
5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => {
6. // business logic
7. });
8.
21
serverless.ts
1. module.exports = (functionsBuilder: FunctionsBuilder) => functionsBuilder
2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => {
3. // business logic
4. })
5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => {
6. // business logic
7. });
8.
22
serverless.ts
1. module.exports = (functionsBuilder: FunctionsBuilder) => functionsBuilder
2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => {
3. // business logic
4. })
5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => {
6. // business logic
7. });
8.
23
Booting
24
Booting
25
Booting
26
Booting
27
Deployment to runtime
28
Deployment to runtime
29
Deployment to runtime
30
Deployment to runtime
31
Deployment to runtime
32
Deployment to runtime
33
The Past
34
Story 1
35
Deployment process evolution
Deploy process v1
▪ Download code from GitHub
▪ Npm install
▪ Require into runtime
36
Deploy flow v1
37
▪ It works
▪ Easy as a pie
▪ Github API requests: O(N) * O(M) * O(R) ~ 10k
▪ Npm requests: O(N) * O(P) * O(R) ~ 100k
N - apps, M - source files, P - packages, R - instances
Deploy flow v2: Caching
38
▪ Decreased number of requests (~x1000)
▪ Some tolerance to outside infra hiccups
▪ Npm install - resources spike on runtime
▪ Resources spikes for Npm and Github proxies
▪ Bad Typescript support
Deploy process v3: Serverless CI
39
Runtime
CI
1. Download code from GitHub
2. Git code download
3. Pnpm install
4. Build and test
5. Pack into tarball and upload to blob storage
1. Download tarball
2. Unpack code
3. Require into runtime
Deploy flow v3: Serverless CI
40
▪ Production stability
▪ Better resource management
▪ Own CI
41
in Serverless
Story 2
Taming the Greyhound
▪ Greyhound - Wix’s Kafka framework
▪ Retries, resilient producers, cluster discovery,
context propagation, serialization
▪ No successful Node.js alternative
▪ Need Greyhound in Serverless
42
Kafka v1: Crutch sidecar
43
▪ Scala Greyhound wrapper
▪ Works by http
▪ Runs in one container with runtime
Kafka v1: Crutch sidecar
44
Features
▪ It works!
Kafka v1: Crutch sidecar
45
Issues
▪ Our own Greyhound wrapper
▪ OOM Killer
Kafka v2: WNP K8s sidecar
46
▪ Docker container
▪ Runs in one pod with your container
▪ Lifecycle managed by K8s
Kafka v2: WNP K8s sidecar
47
Features
▪ Wix standard solution
▪ Much more stable
Kafka v2: WNP K8s sidecar
48
Issues
▪ Long startup time
▪ Wasted resources
Kafka v3: Daemon set
49
▪ Level-up of K8s sidecar
▪ Pod
▪ Running on the same node with your pod
▪ One sidecar per many runtimes
Kafka v3: Daemon set
50
Features
▪ Less resources needed
( ~70% for whole cluster)
▪ Startup speedup
( ~10 seconds vs 2+ minutes)
Kafka v3: Daemon set
51
Issues
▪ No direct resources control
The future of Serverless
52
▪ Small app
▪ Short lifecycle
The future of Serverless
53
▪ Complex app
▪ Years of development
▪ Monorepo
The future of Serverless
54
▪ Branch builds, rebuilds
▪ App movement
▪ Renaming
▪ Multiple CI support
Now you know
55
▪ Why companies need own frameworks
▪ What is Wix Serverless?
▪ The past, the present and the future of Wix Serverless
Thank you
mykola.borozdin@gmail.com
56

"Wix Serverless from inside", Mykola Borozdin

  • 1.
    Mykola Borozdin, TL WixServerless from inside mykola.borozdin@gmail.com 1 aka хуяк-хуяк в продакшн
  • 2.
    Author 1. SE Masterof science 2. 8 years in the industry 3. From enterprise outstaff to product infra 4. From Java to Scala-Typescript 5. Did not work with Node.JS before Wix 2
  • 3.
    1. The Motivation 2.The Present 3. The Past 4. The Future Agenda 3
  • 4.
    Backend in Wix 4 ▪Microservices managed by K8s ▪ Outside calls - http ▪ Inside calls - GRPC sync calls ▪ Kafka async calls
  • 5.
    Wix Node Platform 1.Wix Bootstrap - Scala, Java 2. JS - the most popular language 3. Frontenders & JVM languages !== Love 4. Node.js translation of Wix Bootstrap 5
  • 6.
    Wix Node Platformwithout Serverless 6
  • 7.
    Wix Node Platformwithout Serverless 7
  • 8.
    Wix Node Platformwithout Serverless 8
  • 9.
    Wix Node Platformwithout Serverless 9
  • 10.
    Wix Node Platformwithout Serverless 10
  • 11.
    Wix Node Platformwithout Serverless 11
  • 12.
    Wix Node Platformwithout Serverless 12
  • 13.
    Serverless ▪ Function asa service ▪ Resources on demand ▪ No infra management 13
  • 14.
    Wix Serverless ▪ Allplugins and testkits wired out of the box ▪ Built-in autoscaling, metrics, logs, alerts ▪ Create & deploy with #serverless in commit, CLI or web app ▪ From commit to production in less than a minute ▪ Deploy status Slack notifications 14
  • 15.
    Create & deployServerless app 15
  • 16.
    DOs ▪ IO-intensive services ▪Call GRPC service ▪ Send message to Kafka 16 ▪ CPU-intensive services ▪ Parsing 200 MB JSONs ▪ Rendering images DON’Ts
  • 17.
    Wix Serverless ▪ Functionset as a service ▪ No wiring ▪ Resources mgmt only if needed ▪ Hot start ▪ Wix specific 17 ▪ Function as a service ▪ No wiring ▪ No resources mgmt ▪ Cold start ▪ AWS specific AWS Serverless
  • 18.
    Current users ▪ ~600production applications ▪ ~110k rpm http/grpc traffic ▪ ~600k rpm Kafka traffic 18
  • 19.
    Wix Serverless appstructure 19
  • 20.
    serverless.ts 1. module.exports =(functionsBuilder: FunctionsBuilder) => functionsBuilder 2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => { 3. // business logic 4. }) 5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => { 6. // business logic 7. }); 8. 20
  • 21.
    serverless.ts 1. module.exports =(functionsBuilder: FunctionsBuilder) => functionsBuilder 2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => { 3. // business logic 4. }) 5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => { 6. // business logic 7. }); 8. 21
  • 22.
    serverless.ts 1. module.exports =(functionsBuilder: FunctionsBuilder) => functionsBuilder 2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => { 3. // business logic 4. }) 5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => { 6. // business logic 7. }); 8. 22
  • 23.
    serverless.ts 1. module.exports =(functionsBuilder: FunctionsBuilder) => functionsBuilder 2. .addWebFunction('POST', '/buy', async (ctx: FunCtx, req: WebReq) => { 3. // business logic 4. }) 5. .addKafkaConsumer('some-topic', async (ctx: FunCtx, msg: any) => { 6. // business logic 7. }); 8. 23
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
    Deploy process v1 ▪Download code from GitHub ▪ Npm install ▪ Require into runtime 36
  • 37.
    Deploy flow v1 37 ▪It works ▪ Easy as a pie ▪ Github API requests: O(N) * O(M) * O(R) ~ 10k ▪ Npm requests: O(N) * O(P) * O(R) ~ 100k N - apps, M - source files, P - packages, R - instances
  • 38.
    Deploy flow v2:Caching 38 ▪ Decreased number of requests (~x1000) ▪ Some tolerance to outside infra hiccups ▪ Npm install - resources spike on runtime ▪ Resources spikes for Npm and Github proxies ▪ Bad Typescript support
  • 39.
    Deploy process v3:Serverless CI 39 Runtime CI 1. Download code from GitHub 2. Git code download 3. Pnpm install 4. Build and test 5. Pack into tarball and upload to blob storage 1. Download tarball 2. Unpack code 3. Require into runtime
  • 40.
    Deploy flow v3:Serverless CI 40 ▪ Production stability ▪ Better resource management ▪ Own CI
  • 41.
  • 42.
    Taming the Greyhound ▪Greyhound - Wix’s Kafka framework ▪ Retries, resilient producers, cluster discovery, context propagation, serialization ▪ No successful Node.js alternative ▪ Need Greyhound in Serverless 42
  • 43.
    Kafka v1: Crutchsidecar 43 ▪ Scala Greyhound wrapper ▪ Works by http ▪ Runs in one container with runtime
  • 44.
    Kafka v1: Crutchsidecar 44 Features ▪ It works!
  • 45.
    Kafka v1: Crutchsidecar 45 Issues ▪ Our own Greyhound wrapper ▪ OOM Killer
  • 46.
    Kafka v2: WNPK8s sidecar 46 ▪ Docker container ▪ Runs in one pod with your container ▪ Lifecycle managed by K8s
  • 47.
    Kafka v2: WNPK8s sidecar 47 Features ▪ Wix standard solution ▪ Much more stable
  • 48.
    Kafka v2: WNPK8s sidecar 48 Issues ▪ Long startup time ▪ Wasted resources
  • 49.
    Kafka v3: Daemonset 49 ▪ Level-up of K8s sidecar ▪ Pod ▪ Running on the same node with your pod ▪ One sidecar per many runtimes
  • 50.
    Kafka v3: Daemonset 50 Features ▪ Less resources needed ( ~70% for whole cluster) ▪ Startup speedup ( ~10 seconds vs 2+ minutes)
  • 51.
    Kafka v3: Daemonset 51 Issues ▪ No direct resources control
  • 52.
    The future ofServerless 52 ▪ Small app ▪ Short lifecycle
  • 53.
    The future ofServerless 53 ▪ Complex app ▪ Years of development ▪ Monorepo
  • 54.
    The future ofServerless 54 ▪ Branch builds, rebuilds ▪ App movement ▪ Renaming ▪ Multiple CI support
  • 55.
    Now you know 55 ▪Why companies need own frameworks ▪ What is Wix Serverless? ▪ The past, the present and the future of Wix Serverless
  • 56.