Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Swift Cloud Workshop - Swift Microservices

1,098 views

Published on

How to deploy Swift micro-services using Docker and Kubernetes, with scaling, monitoring and fault tolerance using the Kitura server side Swift framework.

Published in: Software
  • Be the first to comment

Swift Cloud Workshop - Swift Microservices

  1. 1. Deploying Swift
 With Docker and Kubernetes Swift Cloud Workshop 3
 February 23rd, 2018 Chris Bailey
 (@Chris__Bailey)
  2. 2. : Key Technologies
  3. 3. : Key Technologies Container
  4. 4. : Key Technologies Container Orchestration
  5. 5. : Key Technologies Container Orchestration Package and Deploy
  6. 6. : Key Technologies Container Orchestration MonitoringPackage and Deploy
  7. 7. : Key Technologies Container Orchestration Monitoring Fault TolerancePackage and Deploy
  8. 8. Building Swift Microservices
  9. 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. 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. 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. 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. 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. 14. $ docker build -t <your username>/swift-app .

  15. 15. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  16. 16. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  17. 17. $ docker build -t <your username>/swift-app .
 $ docker run -p 49160:8080 -d <your username>/swift-app
  18. 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. 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. 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. 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. 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. 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. 24. $ helm package ./chart/swift-app
  25. 25. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  26. 26. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  27. 27. $ helm package ./chart/swift-app $ helm install ./swift-app-1.0.0.tgz
  28. 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. 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’ }
  30. 30. Integrating with
 Kubernetes
  31. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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)") } }
  47. 47. • ‘SwiftMetricsDash’ provides self-hosted monitoring
 • Inbound and Outbound request performance • Resource monitoring • ++ Dispatch queue monitoring
 • ++ profiling and flame graphs Deep Analysis: ‘SwiftMetricsDash’
  48. 48. 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. 49. 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)") } }
  50. 50. ‘SwiftMetricsDash’
  51. 51. $ kitura init$ kitura init
  52. 52. DEMO
  53. 53. Common Microservices Approach
  54. 54. 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
  55. 55. 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
  56. 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 CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT ibm-cloud-env hystrix-js /health appmetrics-prometheus jsonwebtoken
  57. 57. 59 IBM Foundation Support for Runtimes generator-nodeserver appmetrics monitoring generator-swiftserver swiftmetrics monitoringjavametrics monitoring IBM Support for Runtimes Enterprise Support: Runtimes
  58. 58. 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
  59. 59. 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
  60. 60. What’s Missing?
  61. 61. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  62. 62. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  63. 63. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  64. 64. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  65. 65. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  66. 66. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  67. 67. PUBLIC NETWORK CLOUD NETWORK CATALOG ORDER INVENTORY USER MySQL MongoDB SPARK ELASTICSEARCH BACKEND FOR
 FRONTEND MICROSERVICES SERVICES LOAD
 BALANCER
  68. 68. BROWSER TIME
  69. 69. BROWSER LOAD BALANCER TIME
  70. 70. BROWSER LOAD BALANCER WEB BFF TIME
  71. 71. BROWSER LOAD BALANCER WEB BFF ORDER SERVICE TIME
  72. 72. BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB TIME
  73. 73. BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE TIME
  74. 74. MySQL BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE TIME
  75. 75. MySQL BROWSER LOAD BALANCER WEB BFF ORDER SERVICE MongoDB INVENTORY SERVICE MongoDB TIME
  76. 76. • 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
  77. 77. Questions?

×