Production & Deployment
01 What is distributed tracing?
Solution and explanation
- Solution:
- Suppose one request travels through:
- React
- |
- Gateway
- |
- Application Service
- |
- Job Service
- |
- Company Service
- |
- Kafka
- |
- Notification Service
- If the user reports:
- "My application is taking 8 seconds."
- Without tracing, it is difficult to know where the time was spent.
- Distributed tracing assigns a trace ID.
- Example:
- traceId = 8f91ab
- The trace follows the request.
- Gateway:
- 200 ms
- Application Service:
- 500 ms
- Job Service:
- 100 ms
- Company Service:
- 6 seconds
- Now the bottleneck becomes visible.
- Trace IDs and span IDs allow operations teams to reconstruct the request path across services.
management:
tracing:
sampling:
probability: 0.1
logging:
pattern:
correlation: "[traceId=${spring.application.name},spanId=%X{traceId}]"
Trace one job application request across Gateway, Application Service and Notification Service.
Quick check
Which statement is correct?
02 What is Spring Boot Actuator?
Solution and explanation
- Solution:
- A production application needs operational information.
- Examples:
- Is the application alive?
- Is the database reachable?
- How many requests are being processed?
- What is the response time?
- Are JVM resources exhausted?
- Spring Boot Actuator exposes management endpoints.
- Common examples:
- /actuator/health
- /actuator/info
- /actuator/metrics
- /actuator/prometheus
- Health should be divided conceptually into:
- Liveness:
- Should this process be restarted?
- Readiness:
- Can this instance receive traffic?
- Sensitive management information should not be exposed publicly without authentication and network controls.
management:
endpoints:
web:
exposure:
include:
- health
- info
- prometheus
endpoint:
health:
probes:
enabled: true
Expose health and Prometheus metrics while keeping sensitive management endpoints protected.
Quick check
Which statement is correct?
03 How do you manage production configuration and secrets?
Solution and explanation
- Solution:
- Never put production passwords or API secrets directly into Git.
- Bad:
- spring.datasource.password=MyRealPassword123
- Better:
- spring.datasource.password=${DB_PASSWORD}
- The production environment supplies:
- DB_PASSWORD
- Other examples:
- JWT_SECRET
- DATABASE_URL
- REDIS_PASSWORD
- KAFKA_USERNAME
- KAFKA_PASSWORD
- PAYMENT_API_KEY
- Different environments can use:
- application.yml
- application-dev.yml
- application-test.yml
- application-prod.yml
- The code remains the same.
- Only environment-specific configuration changes.
- Secrets should also be rotated and access should be limited according to least privilege.
spring:
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
security:
jwt:
secret: ${JWT_SECRET}
payment:
api-key: ${PAYMENT_API_KEY}
Remove hard-coded production credentials and load database, JWT and payment secrets through environment configuration.
Quick check
Which statement is correct?
04 How do you Dockerize a Spring Boot application?
Solution and explanation
Solution:
A Spring Boot application can be packaged as a JAR.
Example:
target/job-portal.jar
A Docker image contains:
- Java runtime
- Application JAR
- Required runtime configuration
The container should not normally run as root.
Environment variables can provide configuration.
Example:
DATABASE_URL DATABASE_USERNAME DATABASE_PASSWORD
The image can then be deployed consistently across environments.
Production images should use a maintained runtime, minimize unnecessary packages and keep dependency versions controlled.
FROM eclipse-temurin:21-jre
WORKDIR /app
RUN useradd --system --create-home appuser
COPY target/job-portal.jar app.jar
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Build the Spring Boot JAR, create a non-root Docker image and pass database configuration through environment variables.
Quick check
Which statement is correct?
05 How do you deploy Spring Boot on Kubernetes?
Solution and explanation
- Solution:
- A Kubernetes deployment commonly contains:
- Deployment:
- Manages application replicas.
- Pod:
- Runs the Spring Boot container.
- Service:
- Provides stable internal networking.
- Ingress:
- Provides HTTP routing from outside the cluster.
- Example:
- Deployment
- |
- +-- Pod 1
- +-- Pod 2
- +-- Pod 3
- |
- Service
- |
- Ingress
- Readiness probe:
- Can this instance receive traffic?
- Liveness probe:
- Is the process healthy enough to continue running?
- Resource requests and limits help Kubernetes schedule and control workloads.
- For production applications, configuration and secrets should be externalized rather than baked into the image.
apiVersion: apps/v1
kind: Deployment
metadata:
name: job-service
spec:
replicas: 3
selector:
matchLabels:
app: job-service
template:
metadata:
labels:
app: job-service
spec:
containers:
- name: job-service
image: job-service:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
Deploy three Spring Boot replicas with readiness and liveness probes.
Quick check
Which statement is correct?
