SlideShare a Scribd company logo
Deploying Swift

With Docker and Kubernetes
Swift Cloud Workshop 3

February 23rd, 2018
Chris Bailey

(@Chris__Bailey)
: Key Technologies
: Key Technologies
Container
: Key Technologies
Container Orchestration
: Key Technologies
Container Orchestration
Package and Deploy
: Key Technologies
Container Orchestration
MonitoringPackage and Deploy
: Key Technologies
Container Orchestration
Monitoring Fault TolerancePackage and Deploy
Building Swift
Microservices
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
FROM ibmcom/swift-ubuntu-runtime:4.0
# We can replace this port with what the user wants
EXPOSE 8080
# Install system level packages
# RUN apt-get update && apt-get dist-upgrade -y
# Add utils files
ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu-
docker/master/utils/run-utils.sh /swift-utils/run-utils.sh
ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu-
docker/master/utils/common-utils.sh /swift-utils/common-utils.sh
RUN chmod -R 555 /swift-utils
# Bundle application source & binaries
COPY . /swift-project
# Command to start Swift application
CMD [ "sh", "-c", "cd /swift-project && .build-ubuntu/release/
helium" ]
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
Dockerfile
Dockerfile-tools
$ docker build -t <your username>/swift-app .

$ docker build -t <your username>/swift-app .

$ docker run -p 49160:8080 -d <your username>/swift-app
$ docker build -t <your username>/swift-app .

$ docker run -p 49160:8080 -d <your username>/swift-app
$ docker build -t <your username>/swift-app .

$ docker run -p 49160:8080 -d <your username>/swift-app
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
apiVersion: v1
description: A Helm chart for Kubernetes
name: swift-app
version: 1.0.0
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: “{{ .Chart.Name }}-deployment"
labels:
chart: “{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}’
spec:
replicas: “{{ .Values.replicaCount }}”
revisionHistoryLimit: “{{ .Values.revisionHistoryLimit }}”
template:
metadata:
labels:
app: “{{ .Chart.Name }}-selector"
version: "current"
spec:
containers:
- name: “{{ .Chart.Name }}”
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /health
port: {{ .Values.service.servicePort }}
initialDelaySeconds:
{{.Values.livenessProbe.initialDelaySeconds}}
periodSeconds: {{ .Values.livenessProbe.periodSeconds}}
resources:
requests:
cpu: "{{ .Values.image.resources.requests.cpu }}"
memory: "{{ .Values.image.resources.requests.memory }}"
env:
- name: PORT
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: "{{ .Chart.Name }}-hpa-policy"
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1beta1
kind: Deployment
name: "{{ .Chart.Name }}-deployment"
minReplicas: {{ .Values.hpa.minReplicas }}
maxReplicas: {{ .Values.hpa.maxReplicas }}
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization:
{{.Values.hpa.metrics.cpu.targetAverageUtilization}}
- type: Resource
resource:
name: memory
targetAverageUtilization:
{{.Values.hpa.metrics.memory.targetAverageUtilization}}
{{ end }}
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: 'true'
name: "{{ .Chart.Name }}-service"
labels:
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+"
"_" }}"
spec:
type: {{ .Values.service.type }}
ports:
- name: http
port: {{ .Values.service.servicePort }}
selector:
app: "{{ .Chart.Name }}-selector"
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
HELM CHARTS
replicaCount: 1
revisionHistoryLimit: 1
image:
repository: registry.ng.bluemix.net/replace-namespace/swift-app
tag: v1.0.0
pullPolicy: Always
resources:
requests:
cpu: 200m
memory: 300Mi
livenessProbe:
initialDelaySeconds: 3000
periodSeconds: 1000
service:
name: Node
type: NodePort
servicePort: 8080
hpa:
enabled: false
minReplicas: 1
maxReplicas: 2
metrics:
cpu:
targetAverageUtilization: 70
memory:
targetAverageUtilization: 70
services:
base:
enabled: false
replicaCount: 1
image:
tag : v0.9.9
weight: 100
prometheus:
enabled: false
$ helm package ./chart/swift-app
$ helm package ./chart/swift-app
$ helm install ./swift-app-1.0.0.tgz
$ helm package ./chart/swift-app
$ helm install ./swift-app-1.0.0.tgz
$ helm package ./chart/swift-app
$ helm install ./swift-app-1.0.0.tgz
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
Jenkinsfile
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
chart/swift-app/Chart.yaml
chart/swift-app/templates/deployment.yaml
chart/swift-app/templates/hpa.yaml
chart/swift-app/templates/service.yaml
chart/swift-app/values.yaml
Jenkinsfile
#!groovy
@Library('MicroserviceBuilder') _
microserviceBuilderPipeline {
image = ‘swift-app’
}
Integrating with

Kubernetes
• Checks status of service
• Requires /health endpoint providing data

• Restarts service if not 200 OK
• Restarts service if no response

Microservice Health: Liveness Probes
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import LoggerAPI
func initializeHealthRoutes(app: App) {
app.router.get("/health") { request, response, _ in
let result = health.status.toSimpleDictionary()
if health.status.state == .UP {
try response.send(json: result).end()
} else {
try response.status(.serviceUnavailable).send(json:
result).end()
}
}
}
• Provides “fault tolerance” to an application

• Enables handling of failed downstream services
• Prevents repeated calls to failed services
• Provides alternative fallback function

• Integrates with monitoring
Microservice Resilience: Hystrix and CircuitBreaker
• Provides “fault tolerance” to an application

• Enables handling of failed downstream services
• Prevents repeated calls to failed services
• Provides alternative fallback function

• Integrates with monitoring
Microservice Resilience: Hystrix and CircuitBreaker
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
breaker = CircuitBreaker(
name: "breaker",

timeout: 10000,
maxFailures: 3,
rollingWindow: 60000,
command: myCommand,
fallback: myFallback)
func myFallback(err: BreakerError, msg: String) {
Log.verbose("Error: (error)")
Log.verbose("Message: (msg)")
}
func myCommand(invocation: Invocation<(String), String>) {



}
breaker.run(commandArgs: , fallbackArgs:)
CircuitBreaker
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
breaker = CircuitBreaker(
name: "breaker",

timeout: 10000,
maxFailures: 3,
rollingWindow: 60000,
command: myCommand,
fallback: myFallback)
func myFallback(err: BreakerError, msg: String) {
Log.verbose("Error: (error)")
Log.verbose("Message: (msg)")
}
func myCommand(invocation: Invocation<(String), String>) {



}
breaker.run(commandArgs: , fallbackArgs:)
CircuitBreaker
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
breaker = CircuitBreaker(
name: "breaker",

timeout: 10000,
maxFailures: 3,
rollingWindow: 60000,
command: myCommand,
fallback: myFallback)
func myFallback(err: BreakerError, msg: String) {
Log.verbose("Error: (error)")
Log.verbose("Message: (msg)")
}
func myCommand(invocation: Invocation<(String), String>) {



}
breaker.run(commandArgs: , fallbackArgs:)
CircuitBreaker
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
breaker = CircuitBreaker(
name: "breaker",

timeout: 10000,
maxFailures: 3,
rollingWindow: 60000,
command: myCommand,
fallback: myFallback)
func myFallback(err: BreakerError, msg: String) {
Log.verbose("Error: (error)")
Log.verbose("Message: (msg)")
}
func myCommand(invocation: Invocation<(String), String>) {



}
breaker.run(commandArgs: , fallbackArgs:)
CircuitBreaker
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
let circuitParameters = CircuitParameters(
timeout: 2000,
maxFailures: 2,
fallback: myFallback)
let request = RestRequest(method: .get, url: "/hello")
request.circuitParameters = circuitParameters
SwiftyRequest
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
let circuitParameters = CircuitParameters(
timeout: 2000,
maxFailures: 2,
fallback: myFallback)
let request = RestRequest(method: .get, url: "/hello")
request.circuitParameters = circuitParameters
SwiftyRequest
• Collects data from each enabled service

• Requires /metrics endpoint providing data

• Provides storage and correlation capabilities
• Provide customisable dashboard

• Integrates with Graphana, Graphite, etc
Microservice Metrics: Prometheus
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift

Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
Swift Cloud Workshop - Swift Microservices
Swift Cloud Workshop - Swift Microservices
• ‘SwiftMetricsDash’ provides self-hosted monitoring

• Inbound and Outbound request performance
• Resource monitoring
• ++ Dispatch queue monitoring

• ++ profiling and flame graphs
Deep Analysis: ‘SwiftMetricsDash’
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
‘SwiftMetricsDash’
$ kitura init$ kitura init
DEMO
Common
Microservices Approach
Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT
Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT
ibm-cloud-env hystrix-js /health appmetrics-prometheus jsonwebtoken
59
IBM Foundation
Support for Runtimes
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
Enterprise Support: Runtimes
60
LoopBack
IBM Foundation
Support for Runtimes
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
IBM Advanced
Support for Runtime
Frameworks
Enterprise Support: Frameworks
61
LoopBack
IBM Foundation
Support for Runtimes
IBM Advanced
Support for Runtime
Frameworks
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
Enterprise Support: Module Ecosystems
What’s Missing?
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR

FRONTEND
MICROSERVICES SERVICES
LOAD

BALANCER
BROWSER
TIME
BROWSER
LOAD BALANCER
TIME
BROWSER
LOAD BALANCER
WEB BFF
TIME
BROWSER
LOAD BALANCER
WEB BFF
ORDER SERVICE
TIME
BROWSER
LOAD BALANCER
WEB BFF
ORDER SERVICE
MongoDB
TIME
BROWSER
LOAD BALANCER
WEB BFF
ORDER SERVICE
MongoDB
INVENTORY SERVICE
TIME
MySQL
BROWSER
LOAD BALANCER
WEB BFF
ORDER SERVICE
MongoDB
INVENTORY SERVICE
TIME
MySQL
BROWSER
LOAD BALANCER
WEB BFF
ORDER SERVICE
MongoDB
INVENTORY SERVICE
MongoDB
TIME
• Collects data from each enabled service

• Propagates correlation ID using HTTP headers

• Provides sampling, tracing, and debug capabilities
• Collects microsecond timestamps

• Correlates data in Zipkin server
• Presents data in Zipkin dashboard
Request Tracking: OpenTracing and Zipkin
Swift Cloud Workshop - Swift Microservices
Questions?

More Related Content

PDF
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
PDF
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
PDF
HTTP APIs as first class procedures in your language: cutting out SDK complex...
PDF
InterConnect: Java, Node.js and Swift - Which, Why and When
PDF
GraphQL in Apache Sling - but isn't it the opposite of REST?
PDF
Seattle useR Group - R + Scala
PDF
用 Go 語言打造多台機器 Scale 架構
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
HTTP APIs as first class procedures in your language: cutting out SDK complex...
InterConnect: Java, Node.js and Swift - Which, Why and When
GraphQL in Apache Sling - but isn't it the opposite of REST?
Seattle useR Group - R + Scala
用 Go 語言打造多台機器 Scale 架構

What's hot (20)

PDF
Interactive Session on Sparkling Water
PDF
Functional Reactive Programming on Android
PDF
How to Make Hand Detector on Native Activity with OpenCV
PDF
Build microservice with gRPC in golang
PDF
Docker Voting App Orientation
PDF
Job Queue in Golang
PPTX
Taking Jenkins Pipeline to the Extreme
PDF
GraphQL IN Golang
PPTX
Transforming Infrastructure into Code - Importing existing cloud resources u...
PDF
Python to scala
PDF
Terraform modules and best-practices - September 2018
PDF
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
PDF
The Challenges of Container Configuration
PDF
PDF
R and C++
KEY
PyCon AU 2012 - Debugging Live Python Web Applications
PDF
Building Observable Applications w/ Node.js -- BayNode Meetup, March 2014
PDF
Automate Your Automation | DrupalCon Vienna
PDF
PyHEP 2018: Tools to bind to Python
Interactive Session on Sparkling Water
Functional Reactive Programming on Android
How to Make Hand Detector on Native Activity with OpenCV
Build microservice with gRPC in golang
Docker Voting App Orientation
Job Queue in Golang
Taking Jenkins Pipeline to the Extreme
GraphQL IN Golang
Transforming Infrastructure into Code - Importing existing cloud resources u...
Python to scala
Terraform modules and best-practices - September 2018
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
The Challenges of Container Configuration
R and C++
PyCon AU 2012 - Debugging Live Python Web Applications
Building Observable Applications w/ Node.js -- BayNode Meetup, March 2014
Automate Your Automation | DrupalCon Vienna
PyHEP 2018: Tools to bind to Python
Ad

Similar to Swift Cloud Workshop - Swift Microservices (20)

PDF
Istio Playground
PDF
GE Predix 新手入门 赵锴 物联网_IoT
PPTX
Docker Container As A Service - Mix-IT 2016
PPTX
Kubernetes walkthrough
PDF
Scaffolding for Serverless: lightning talk for AWS Arlington Meetup
PDF
OpenShift Meetup - Tokyo - Service Mesh and Serverless Overview
PDF
Pemrograman Python untuk Pemula
PDF
Weave Your Microservices with Istio
PDF
All Things Open 2019 weave-services-istio
PDF
Ato2019 weave-services-istio
PDF
Server(less) Swift at SwiftCloudWorkshop 3
PDF
Tasks: you gotta know how to run them
PPT
Bluemix hadoop beginners Guide part I
PPTX
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
PDF
InterConnect2016: WebApp Architectures with Java and Node.js
PPTX
Cloud nativemicroservices jax-london2020
PPTX
Cloud nativemicroservices jax-london2020
PDF
commit => #GitHub => #CircleCI => #Docker => #Kubernetes #AWS cluster
PDF
Helm Charts Security 101
PDF
H2O 3 REST API Overview
Istio Playground
GE Predix 新手入门 赵锴 物联网_IoT
Docker Container As A Service - Mix-IT 2016
Kubernetes walkthrough
Scaffolding for Serverless: lightning talk for AWS Arlington Meetup
OpenShift Meetup - Tokyo - Service Mesh and Serverless Overview
Pemrograman Python untuk Pemula
Weave Your Microservices with Istio
All Things Open 2019 weave-services-istio
Ato2019 weave-services-istio
Server(less) Swift at SwiftCloudWorkshop 3
Tasks: you gotta know how to run them
Bluemix hadoop beginners Guide part I
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
InterConnect2016: WebApp Architectures with Java and Node.js
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices jax-london2020
commit => #GitHub => #CircleCI => #Docker => #Kubernetes #AWS cluster
Helm Charts Security 101
H2O 3 REST API Overview
Ad

More from Chris Bailey (20)

PDF
NodeJS Interactive 2019: FaaS meets Frameworks
PDF
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
PDF
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
PDF
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
PDF
AltConf 2019: Server-Side Swift State of the Union
PDF
Server-side Swift with Swagger
PDF
Node Summit 2018: Cloud Native Node.js
PDF
Index - BFFs vs GraphQL
PDF
Swift Cloud Workshop - Codable, the key to Fullstack Swift
PDF
Try!Swift India 2017: All you need is Swift
PDF
Swift Summit 2017: Server Swift State of the Union
PDF
IBM Cloud University: Java, Node.js and Swift
PDF
FrenchKit 2017: Server(less) Swift
PDF
AltConf 2017: Full Stack Swift in 30 Minutes
PDF
InterConnect: Server Side Swift for Java Developers
PDF
Playgrounds: Mobile + Swift = BFF
PDF
Swift Summit: Pushing the boundaries of Swift to the Server
PDF
O'Reilly Software Architecture Conf: Cloud Economics
PDF
FrenchKit: End to End Application Development with Swift
PPTX
Node Summit 2016: Web App Architectures
NodeJS Interactive 2019: FaaS meets Frameworks
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
AltConf 2019: Server-Side Swift State of the Union
Server-side Swift with Swagger
Node Summit 2018: Cloud Native Node.js
Index - BFFs vs GraphQL
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Try!Swift India 2017: All you need is Swift
Swift Summit 2017: Server Swift State of the Union
IBM Cloud University: Java, Node.js and Swift
FrenchKit 2017: Server(less) Swift
AltConf 2017: Full Stack Swift in 30 Minutes
InterConnect: Server Side Swift for Java Developers
Playgrounds: Mobile + Swift = BFF
Swift Summit: Pushing the boundaries of Swift to the Server
O'Reilly Software Architecture Conf: Cloud Economics
FrenchKit: End to End Application Development with Swift
Node Summit 2016: Web App Architectures

Recently uploaded (20)

PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Online Work Permit System for Fast Permit Processing
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Digital Strategies for Manufacturing Companies
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
L1 - Introduction to python Backend.pptx
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Which alternative to Crystal Reports is best for small or large businesses.pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Online Work Permit System for Fast Permit Processing
2025 Textile ERP Trends: SAP, Odoo & Oracle
How to Migrate SBCGlobal Email to Yahoo Easily
How to Choose the Right IT Partner for Your Business in Malaysia
ISO 45001 Occupational Health and Safety Management System
Digital Strategies for Manufacturing Companies
Navsoft: AI-Powered Business Solutions & Custom Software Development
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Design an Analysis of Algorithms II-SECS-1021-03
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Softaken Excel to vCard Converter Software.pdf
L1 - Introduction to python Backend.pptx
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Design an Analysis of Algorithms I-SECS-1021-03
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises

Swift Cloud Workshop - Swift Microservices

  • 1. Deploying Swift
 With Docker and Kubernetes Swift Cloud Workshop 3
 February 23rd, 2018 Chris Bailey
 (@Chris__Bailey)
  • 5. : Key Technologies Container Orchestration Package and Deploy
  • 6. : Key Technologies Container Orchestration MonitoringPackage and Deploy
  • 7. : Key Technologies Container Orchestration Monitoring Fault TolerancePackage and Deploy
  • 9. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Kitura
  • 10. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Kitura import Kitura import LoggerAPI import CloudEnvironment import KituraContracts import Health public let projectPath = ConfigurationManager.BasePath.project.path public let health = Health() public class App { let router = Router() let cloudEnv = CloudEnv() public init() throws { } func postInit() throws { initializeMetrics(app: self) initializeHealthRoutes(app: self) } public func run() throws { try postInit() Kitura.addHTTPServer(onPort: cloudEnv.port, with: router) Kitura.run() } }
  • 11. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore
  • 12. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore FROM ibmcom/swift-ubuntu-runtime:4.0 # We can replace this port with what the user wants EXPOSE 8080 # Install system level packages # RUN apt-get update && apt-get dist-upgrade -y # Add utils files ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu- docker/master/utils/run-utils.sh /swift-utils/run-utils.sh ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu- docker/master/utils/common-utils.sh /swift-utils/common-utils.sh RUN chmod -R 555 /swift-utils # Bundle application source & binaries COPY . /swift-project # Command to start Swift application CMD [ "sh", "-c", "cd /swift-project && .build-ubuntu/release/ helium" ]
  • 13. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore Dockerfile Dockerfile-tools
  • 14. $ docker build -t <your username>/swift-app .

  • 15. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  • 16. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  • 17. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  • 18. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS
  • 19. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS apiVersion: v1 description: A Helm chart for Kubernetes name: swift-app version: 1.0.0
  • 20. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS apiVersion: extensions/v1beta1 kind: Deployment metadata: name: “{{ .Chart.Name }}-deployment" labels: chart: “{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}’ spec: replicas: “{{ .Values.replicaCount }}” revisionHistoryLimit: “{{ .Values.revisionHistoryLimit }}” template: metadata: labels: app: “{{ .Chart.Name }}-selector" version: "current" spec: containers: - name: “{{ .Chart.Name }}” image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: Always livenessProbe: httpGet: path: /health port: {{ .Values.service.servicePort }} initialDelaySeconds: {{.Values.livenessProbe.initialDelaySeconds}} periodSeconds: {{ .Values.livenessProbe.periodSeconds}} resources: requests: cpu: "{{ .Values.image.resources.requests.cpu }}" memory: "{{ .Values.image.resources.requests.memory }}" env: - name: PORT
  • 21. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: "{{ .Chart.Name }}-hpa-policy" namespace: default spec: scaleTargetRef: apiVersion: apps/v1beta1 kind: Deployment name: "{{ .Chart.Name }}-deployment" minReplicas: {{ .Values.hpa.minReplicas }} maxReplicas: {{ .Values.hpa.maxReplicas }} metrics: - type: Resource resource: name: cpu targetAverageUtilization: {{.Values.hpa.metrics.cpu.targetAverageUtilization}} - type: Resource resource: name: memory targetAverageUtilization: {{.Values.hpa.metrics.memory.targetAverageUtilization}} {{ end }}
  • 22. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS apiVersion: v1 kind: Service metadata: annotations: prometheus.io/scrape: 'true' name: "{{ .Chart.Name }}-service" labels: chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" spec: type: {{ .Values.service.type }} ports: - name: http port: {{ .Values.service.servicePort }} selector: app: "{{ .Chart.Name }}-selector"
  • 23. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml HELM CHARTS replicaCount: 1 revisionHistoryLimit: 1 image: repository: registry.ng.bluemix.net/replace-namespace/swift-app tag: v1.0.0 pullPolicy: Always resources: requests: cpu: 200m memory: 300Mi livenessProbe: initialDelaySeconds: 3000 periodSeconds: 1000 service: name: Node type: NodePort servicePort: 8080 hpa: enabled: false minReplicas: 1 maxReplicas: 2 metrics: cpu: targetAverageUtilization: 70 memory: targetAverageUtilization: 70 services: base: enabled: false replicaCount: 1 image: tag : v0.9.9 weight: 100 prometheus: enabled: false
  • 24. $ helm package ./chart/swift-app
  • 25. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  • 26. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  • 27. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  • 28. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml Jenkinsfile
  • 29. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Dockerfile Dockerfile-tools .dockerignore chart/swift-app/Chart.yaml chart/swift-app/templates/deployment.yaml chart/swift-app/templates/hpa.yaml chart/swift-app/templates/service.yaml chart/swift-app/values.yaml Jenkinsfile #!groovy @Library('MicroserviceBuilder') _ microserviceBuilderPipeline { image = ‘swift-app’ }
  • 31. • Checks status of service • Requires /health endpoint providing data
 • Restarts service if not 200 OK • Restarts service if no response
 Microservice Health: Liveness Probes
  • 32. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Kitura
  • 33. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Kitura import Kitura import LoggerAPI import CloudEnvironment import KituraContracts import Health public let projectPath = ConfigurationManager.BasePath.project.path public let health = Health() public class App { let router = Router() let cloudEnv = CloudEnv() public init() throws { } func postInit() throws { initializeMetrics(app: self) initializeHealthRoutes(app: self) } public func run() throws { try postInit() Kitura.addHTTPServer(onPort: cloudEnv.port, with: router) Kitura.run() } }
  • 34. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift Tests/* Package.swift README.md .gitignore Kitura import LoggerAPI func initializeHealthRoutes(app: App) { app.router.get("/health") { request, response, _ in let result = health.status.toSimpleDictionary() if health.status.state == .UP { try response.send(json: result).end() } else { try response.status(.serviceUnavailable).send(json: result).end() } } }
  • 35. • Provides “fault tolerance” to an application
 • Enables handling of failed downstream services • Prevents repeated calls to failed services • Provides alternative fallback function
 • Integrates with monitoring Microservice Resilience: Hystrix and CircuitBreaker
  • 36. • Provides “fault tolerance” to an application
 • Enables handling of failed downstream services • Prevents repeated calls to failed services • Provides alternative fallback function
 • Integrates with monitoring Microservice Resilience: Hystrix and CircuitBreaker
  • 37. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura breaker = CircuitBreaker( name: "breaker",
 timeout: 10000, maxFailures: 3, rollingWindow: 60000, command: myCommand, fallback: myFallback) func myFallback(err: BreakerError, msg: String) { Log.verbose("Error: (error)") Log.verbose("Message: (msg)") } func myCommand(invocation: Invocation<(String), String>) {
 
 } breaker.run(commandArgs: , fallbackArgs:) CircuitBreaker
  • 38. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura breaker = CircuitBreaker( name: "breaker",
 timeout: 10000, maxFailures: 3, rollingWindow: 60000, command: myCommand, fallback: myFallback) func myFallback(err: BreakerError, msg: String) { Log.verbose("Error: (error)") Log.verbose("Message: (msg)") } func myCommand(invocation: Invocation<(String), String>) {
 
 } breaker.run(commandArgs: , fallbackArgs:) CircuitBreaker
  • 39. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura breaker = CircuitBreaker( name: "breaker",
 timeout: 10000, maxFailures: 3, rollingWindow: 60000, command: myCommand, fallback: myFallback) func myFallback(err: BreakerError, msg: String) { Log.verbose("Error: (error)") Log.verbose("Message: (msg)") } func myCommand(invocation: Invocation<(String), String>) {
 
 } breaker.run(commandArgs: , fallbackArgs:) CircuitBreaker
  • 40. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura breaker = CircuitBreaker( name: "breaker",
 timeout: 10000, maxFailures: 3, rollingWindow: 60000, command: myCommand, fallback: myFallback) func myFallback(err: BreakerError, msg: String) { Log.verbose("Error: (error)") Log.verbose("Message: (msg)") } func myCommand(invocation: Invocation<(String), String>) {
 
 } breaker.run(commandArgs: , fallbackArgs:) CircuitBreaker
  • 41. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura let circuitParameters = CircuitParameters( timeout: 2000, maxFailures: 2, fallback: myFallback) let request = RestRequest(method: .get, url: "/hello") request.circuitParameters = circuitParameters SwiftyRequest
  • 42. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura let circuitParameters = CircuitParameters( timeout: 2000, maxFailures: 2, fallback: myFallback) let request = RestRequest(method: .get, url: "/hello") request.circuitParameters = circuitParameters SwiftyRequest
  • 43. • Collects data from each enabled service
 • Requires /metrics endpoint providing data
 • Provides storage and correlation capabilities • Provide customisable dashboard
 • Integrates with Graphana, Graphite, etc Microservice Metrics: Prometheus
  • 44. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Tests/* Package.swift README.md .gitignore Kitura
  • 45. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift
 Tests/* Package.swift README.md .gitignore Kitura import Kitura import LoggerAPI import CloudEnvironment import KituraContracts import Health public let projectPath = ConfigurationManager.BasePath.project.path public let health = Health() public class App { let router = Router() let cloudEnv = CloudEnv() public init() throws { } func postInit() throws { initializeMetrics(app: self) initializeHealthRoutes(app: self) } public func run() throws { try postInit() Kitura.addHTTPServer(onPort: cloudEnv.port, with: router) Kitura.run() } }
  • 46. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift Sources/Applicaton/Metrics.swift Tests/* Package.swift README.md .gitignore Kitura import Kitura import SwiftMetrics import SwiftMetricsDash import SwiftMetricsPrometheus import LoggerAPI var swiftMetrics: SwiftMetrics? var swiftMetricsDash: SwiftMetricsDash? var swiftMetricsPrometheus: SwiftMetricsPrometheus? func initializeMetrics(router: Router) { do { let metrics = try SwiftMetrics() let dashboard = try SwiftMetricsDash(swiftMetricsInstance: metrics, endpoint: router) let prometheus = try SwiftMetricsPrometheus(swiftMetricsInstance: metrics, endpoint: router) swiftMetrics = metrics swiftMetricsDash = dashboard swiftMetricsPrometheus = prometheus Log.info("Initialized metrics.") } catch { Log.warning("Failed to initialize metrics: (error)") } }
  • 49. • ‘SwiftMetricsDash’ provides self-hosted monitoring
 • Inbound and Outbound request performance • Resource monitoring • ++ Dispatch queue monitoring
 • ++ profiling and flame graphs Deep Analysis: ‘SwiftMetricsDash’
  • 50. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift Sources/Applicaton/Metrics.swift Tests/* Package.swift README.md .gitignore Kitura import Kitura import SwiftMetrics import SwiftMetricsDash import SwiftMetricsPrometheus import LoggerAPI var swiftMetrics: SwiftMetrics? var swiftMetricsDash: SwiftMetricsDash? var swiftMetricsPrometheus: SwiftMetricsPrometheus? func initializeMetrics(router: Router) { do { let metrics = try SwiftMetrics() let dashboard = try SwiftMetricsDash(swiftMetricsInstance: metrics, endpoint: router) let prometheus = try SwiftMetricsPrometheus(swiftMetricsInstance: metrics, endpoint: router) swiftMetrics = metrics swiftMetricsDash = dashboard swiftMetricsPrometheus = prometheus Log.info("Initialized metrics.") } catch { Log.warning("Failed to initialize metrics: (error)") } }
  • 51. func add(_ a: Int, to b: Int) -> Void { print(a + b) } let a = ”5” let b = 3 Sources/* Sources/Application/Application.swift Sources/Application/Routes/Health.swift Sources/Applicaton/Metrics.swift Tests/* Package.swift README.md .gitignore Kitura import Kitura import SwiftMetrics import SwiftMetricsDash import SwiftMetricsPrometheus import LoggerAPI var swiftMetrics: SwiftMetrics? var swiftMetricsDash: SwiftMetricsDash? var swiftMetricsPrometheus: SwiftMetricsPrometheus? func initializeMetrics(router: Router) { do { let metrics = try SwiftMetrics() let dashboard = try SwiftMetricsDash(swiftMetricsInstance: metrics, endpoint: router) let prometheus = try SwiftMetricsPrometheus(swiftMetricsInstance: metrics, endpoint: router) swiftMetrics = metrics swiftMetricsDash = dashboard swiftMetricsPrometheus = prometheus Log.info("Initialized metrics.") } catch { Log.warning("Failed to initialize metrics: (error)") } }
  • 53. $ kitura init$ kitura init
  • 54. DEMO
  • 56. Config Fault Tolerance Health Check Health Metrics JWT Propagation externalize configuration to improve portability build robust behavior to cope with unexpected failures common format to determine service availability common REST endpoints for monitoring service health interoperable authentication and role- based access control
  • 57. Config Fault Tolerance Health Check Health Metrics JWT Propagation externalize configuration to improve portability build robust behavior to cope with unexpected failures common format to determine service availability common REST endpoints for monitoring service health interoperable authentication and role- based access control CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT
  • 58. Config Fault Tolerance Health Check Health Metrics JWT Propagation externalize configuration to improve portability build robust behavior to cope with unexpected failures common format to determine service availability common REST endpoints for monitoring service health interoperable authentication and role- based access control CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT ibm-cloud-env hystrix-js /health appmetrics-prometheus jsonwebtoken
  • 59. 59 IBM Foundation Support for Runtimes generator-nodeserver appmetrics monitoring generator-swiftserver swiftmetrics monitoringjavametrics monitoring IBM Support for Runtimes Enterprise Support: Runtimes
  • 60. 60 LoopBack IBM Foundation Support for Runtimes generator-nodeserver appmetrics monitoring generator-swiftserver swiftmetrics monitoringjavametrics monitoring IBM Support for Runtimes IBM Advanced Support for Runtime Frameworks Enterprise Support: Frameworks
  • 61. 61 LoopBack IBM Foundation Support for Runtimes IBM Advanced Support for Runtime Frameworks generator-nodeserver appmetrics monitoring generator-swiftserver swiftmetrics monitoringjavametrics monitoring IBM Support for Runtimes Enterprise Support: Module Ecosystems
  • 63. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 64. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 65. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 66. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 67. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 68. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 69. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  • 74. BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB TIME
  • 75. BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE TIME
  • 76. MySQL BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE TIME
  • 77. MySQL BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE MongoDB TIME
  • 78. • Collects data from each enabled service
 • Propagates correlation ID using HTTP headers
 • Provides sampling, tracing, and debug capabilities • Collects microsecond timestamps
 • Correlates data in Zipkin server • Presents data in Zipkin dashboard Request Tracking: OpenTracing and Zipkin