OpenTelemetry Là Gì?
OpenTelemetry là một bộ công cụ mã nguồn mở được thiết kế để thu thập, xử lý và xuất các dữ liệu giám sát như traces, metrics và logs từ các ứng dụng phân tán. Nó hỗ trợ việc quan sát các hệ thống phức tạp, giúp bạn phát hiện và phân tích hiệu suất hoạt động của ứng dụng, đặc biệt trong môi trường microservices và cloud-native.
Tính Năng Nổi Bật Của OpenTelemetry:
- Cung cấp một chuẩn chung giúp thu thập dữ liệu giám sát từ nhiều ngôn ngữ lập trình và hệ thống khác nhau.
- Dễ dàng tích hợp với các công cụ giám sát và quản lý hiện có như Prometheus, Jaeger và Grafana.
- Hỗ trợ phát hiện các tắc nghẽn (bottlenecks) trong quy trình hoạt động của ứng dụng, cải thiện hiệu suất hệ thống.
- Tối ưu cho môi trường microservices, cloud-native với tính năng theo dõi các dịch vụ phân tán.
OpenTelemetry hỗ trợ hầu hết các ngôn ngữ lập trình phổ biến như Java, .NET, Go, Python, C++, Javascript, Ruby, và nhiều hơn nữa.
Trong bài viết này, chúng ta sẽ tập trung vào việc thu thập trace cho ứng dụng Java backend. Các dữ liệu khác như metrics và logs cũng có quy trình tương tự và có thể áp dụng cho các loại ứng dụng viết bằng ngôn ngữ khác. Để tìm hiểu sâu hơn, bạn có thể tham khảo tài liệu chính thức của OpenTelemetry (còn gọi là Otel).
Traces Là Gì?
Traces (hay còn gọi là dấu vết) là một loại dữ liệu Telemetry giúp theo dõi và ghi lại luồng thực thi của các yêu cầu trong hệ thống phân tán. Mỗi trace cung cấp một bản ghi chi tiết về cách một yêu cầu di chuyển qua các dịch vụ, thành phần và lớp khác nhau của ứng dụng.
Ví dụ đơn giản về việc theo dõi trace trong một ứng dụng có thể bao gồm:
- Người dùng gửi yêu cầu thông qua phần Frontend (FE).
- FE gửi yêu cầu đến Backend (BE).
- BE gửi yêu cầu đến database (DB).
- DB gửi dữ liệu trở lại BE, và BE cuối cùng trả dữ liệu về FE.
Khoảng thời gian giữa các bước trên chính là một trace, và việc theo dõi tất cả các bước này sẽ giúp bạn có cái nhìn rõ ràng về hiệu suất của ứng dụng.
Lợi Ích Của Traces:
- Giúp theo dõi các bước chi tiết của một yêu cầu khi di chuyển qua các dịch vụ và thành phần khác nhau.
- Cung cấp thông tin chi tiết về lỗi và thời gian phản hồi, giúp bạn phát hiện các bottlenecks và lỗi trong hệ thống.
- Phân tích traces sẽ giúp bạn tối ưu hóa luồng yêu cầu, từ đó cải thiện hiệu suất của hệ thống.
Dựng Ứng Dụng Java
Trong bài viết này, chúng ta sẽ sử dụng ứng dụng Java Spring Boot với MySQL làm database và Redis cho việc lưu trữ. Bạn có thể clone dự án từ đây hoặc từ repo của anh Mai Trung Đức, tác giả của series Docker và CI/CD.
Lưu ý: Hệ thống của bạn cần cài đặt Java 11, Docker và Docker Compose để thực hiện theo hướng dẫn này.
Sau khi đã clone về, hãy mở Dockerfile để xem nội dung bên trong:
dockerfile
# Build stage
FROM eclipse-temurin:17-jdk-alpine as build
WORKDIR /app
COPY build.gradle settings.gradle gradlew ./
COPY gradle /app/gradle
RUN ./gradlew build || return 0
COPY . .
RUN ./gradlew build -x test
# Production stage
FROM eclipse-temurin:17-jre-alpine as production
WORKDIR /app
COPY --from=build /app/build/libs/demo-0.0.1-SNAPSHOT.jar app.jar
COPY otel/opentelemetry-javaagent.jar /app/otel-agent.jar
ENV OTEL_SERVICE_NAME=spring-boot-application
ENV OTEL_TRACES_EXPORTER=otlp
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://172.16.1.24:4318
ENTRYPOINT ["java", "-jar", "app.jar"]
Dockerfile này có hai giai đoạn chính: giai đoạn build và giai đoạn production. Chúng ta sẽ sử dụng ảnh Docker từ eclipse-temurin:17-jdk
với bản phân phối Alpine để xây dựng ứng dụng Java.
Giai đoạn build sẽ tạo ra một file JAR có tên demo-0.0.1-SNAPSHOT.jar
, được định nghĩa trong file cấu hình và sử dụng nó trong giai đoạn production. Hiện tại, chúng ta chưa cần quan tâm đến opentelemetry-javaagent.jar
và các biến môi trường, vì vậy ta sẽ tạm thời xóa 4 dòng liên quan trong Dockerfile như sau:
dockerfile
COPY otel/opentelemetry-javaagent.jar /app/otel-agent.jar
ENV OTEL_SERVICE_NAME=spring-boot-application
ENV OTEL_TRACES_EXPORTER=otlp
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://172.16.1.24:4318
Bây giờ, hãy chạy ứng dụng để kiểm tra. Trước tiên, chúng ta sẽ tiến hành xây dựng ảnh Docker và gán cho nó tên java-spring
với tag là v1
:
bash
docker build -t java-spring:v1 .
Nếu bạn đặt tên khác cho ảnh, hãy nhớ thay đổi tên trong file docker-compose.yml
. Chúng ta cũng sẽ cấu hình thêm database MySQL và Redis như sau:
yaml
version: '3.7'
services:
app:
image: java-spring:v1
restart: always
ports:
- "8081:8081"
volumes:
- ./docker_application.properties:/app/application.properties:ro
depends_on:
- db
- redis
db:
image: mysql:8
restart: always
volumes:
- ./.docker/data/db:/var/lib/mysql
- ./db.sql:/docker-entrypoint-initdb.d/db.sql:ro
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: demo_app
redis:
image: redis:6-alpine
restart: always
volumes:
- ./.docker/data/redis:/data
Sau khi đã thiết lập đầy đủ, bạn hãy khởi động ứng dụng bằng Docker Compose:
bash
docker compose up -d
Sau khi chạy thành công, hãy đợi khoảng 15 giây để database khởi động hoàn toàn. Tiếp theo, truy cập địa chỉ http://localhost:8081 trên trình duyệt. Đăng nhập với username/password là user/Password1
để thao tác với ứng dụng. Bạn có thể thêm, chỉnh sửa hoặc xóa người dùng trong ứng dụng.
Như vậy, ứng dụng Java đã được khởi động và có thể hoạt động ổn định.
source: viblo