Như mọi người đã biết kiến trúc Microservices đã cho phép các nhà phát triển xây dựng và phát hành phần mềm nhanh và độc lập hơn. Không giống như trong mô hình kiến trúc Monolith với các dịch vụ được liên kết chặt chẽ với nhau. Và khi chúng ta chia ứng dụng thành một tập hợp nhỏ các dịch vụ, số lượng thành phần trong kiến trúc sẽ ngày càng tăng lên.
Khi các hệ thống phân tán này mở rộng, việc các nhà phát triển có thể quan sát được cách dịch vụ của họ đang phụ thuộc vào hoặc đang ảnh hưởng đến các dịch vụ khác trở nên ngày càng khó khăn. Vì vậy, làm thế nào để chúng ta có thể quan sát hệ thống một cách tổng thể? Hãy cùng mình khám phá nhé!
1. OpenTelemetry là gì?
OpenTelemetry là một dự án mã nguồn mở được phát triển bởi Cloud Native Computing Foundation (CNCF) nhằm mục đích cung cấp các tiêu chuẩn và công cụ cho việc quản lý, giám sát và thu thập dữ liệu từ các ứng dụng và hệ thống phân tán.
Từ đó ta có thể tập trung vào việc thu thập dữ liệu từ ứng dụng và hệ thống, giúp người quản lý và phát triển hiểu rõ hơn về các hoạt động của ứng dụng và nhanh chóng tìm ra lỗi.
Hiện nay trên thế giới có nhiều công cụ mã nguồn mở dùng để quan sát hệ thống. Có thể kể những cái tên nổi bật là Jaeger và Zipkin .
Trước khi chúng ta đi sâu vào OpenTelemetry, hãy tìm hiểu về khái niệm OpenTracing và OpenCensus:
- OpenTracing cung cấp API không phụ thuộc vào nhà cung cấp để từ đó có thể gửi dữ liệu telemetry đến hệ thống giám sát khác. Tuy nhiên, nó phải phụ thuộc vào các nhà phát triển để triển khai thư viện riêng và đáp ứng các yêu cầu kỹ thuật.
- OpenCensus cung cấp một tập hợp các thư viện cụ thể cho từng ngôn ngữ mà các nhà phát triển có thể sử dụng để quan sát mã nguồn của họ và gửi đến hệ thống giám sát khác.
Vì lợi ích của việc có một tiêu chuẩn duy nhất, OpenCensus và OpenTracing đã hợp nhất để tạo thành OpenTelemetry (viết tắt là OTel). Nó cung cấp những điểm tốt nhất của cả hai.
Mục tiêu của OTel là cung cấp tập hợp các SDK, API và một tiêu chuẩn chuẩn hóa không phụ thuộc vào bên thứ ba cho các việc thu thập, chuyển đổi và gửi dữ liệu telemetry đến một hệ thống giám sát khác.
2. Cách hoạt động của OpenTelemetry
Dưới đây là các bước thực hiện của OpenTelemetry trong quá trình thu thập và xử lý dữ liệu của ứng dụng.
- OpenTelemetry cung cấp các loại API để ứng dụng có thể dùng đó để ghi nhận lại các thông tin của request. Trong quá trình Tracing, OpenTelemetry sẽ theo dõi các request và gắn chúng vào các context của API cho phép chúng ta theo dõi quá trình thực thi từ đầu đến cuối.
- Ngoài ra, OpenTelemetry cung cấp SDK với nhiều ngôn ngữ lập trình khác nhau (Java, Python, Go, C#, và nhiều ngôn ngữ khác). Các SDK này giúp cho ứng dụng và hệ thống thu thập dữ liệu một cách nhanh chóng và dễ dàng hơn.
- OpenTelemetry ghi nhận dữ liệu của ứng dụng bao gồm thông tin về yêu cầu HTTP, thời gian xử lý, lỗi, thông tin về hiệu suất và nhiều thông tin khác.
- Những dữ liệu này được thu thập sau đó được xuất ra các hệ thống khác tùy theo nhu cầu giám sát như các nền tảng: Prometheus, Grafana, Jaeger hoặc các hệ thống lưu trữ dữ liệu như Elasticsearch, InfluxDB, và nhiều nền tảng khác. Các hệ thống bên ngoài này sẽ chịu trách nhiệm lưu trữ, truy vấn và hiển thị thông tin cho mục đích giám sát và phân tích.
3. Các thành phần cơ bản trong OpenTelemetry
Để hiểu rõ hệ thống từ góc nhìn bên ngoài, ứng dụng cần phải expose ra các thông số như traces, metrics và logs.
3.1. Log trong OpenTelemetry
Được hiểu là các thông điệp ghi nhận lại các sự kiện, trạng thái hoặc thông tin từ các ứng dụng và hệ thống. Log là một phần quan trọng trong việc giám sát và theo dõi ứng dụng để phát hiện ra sự cố, phân tích và khắc phục lỗi.
Điểm yếu của log là không cung cấp thông tin ngữ cảnh cần thiết, chẳng hạn như chúng được gọi từ đâu.
3.2. Span trong OpenTelemetry
Ngược lại với Log, Span đại diện cho một đơn vị công việc. Nó theo dõi các hoạt động cụ thể của một request được thực hiện. Từ đó tạo ra một bức tranh tổng thể về những gì đã xảy ra trong thời gian mà request đó được thực hiện.
3.3. Span Context trong OpenTelemetry
Đây là một phần của Span được chuỗi hóa và truyền kèm cùng với Distributed Context.
3.4. Distributed Trace trong OpenTelemetry
Nhìn vào bức ảnh trên, ta có thể hiểu Distributed Trace cung cấp cho chúng ta cái nhìn tổng quan về những gì xảy ra khi một yêu cầu được thực hiện đến một ứng dụng. Ngoài ra, nó cho phép các nhà phát triển theo dõi yêu cầu qua nhiều dịch vụ và thành phần. Điều này tăng khả năng quan sát từ đầu đến cuối trong các luồng phức tạp của hệ thống. Từ đó dễ dàng tìm được những điểm bottelneck[1] của hệ thống
Một Trace được tạo thành từ một hoặc nhiều Spans. Điều này có nghĩa là nhiều Spans sẽ có cùng traceId[2]. Mỗi root span
[3] rootSpan đại diện cho một yêu cầu từ đầu đến cuối. Các Span phía dưới Parent Span sẽ đưa ra ngữ cảnh chi tiết hơn về những gì xảy ra trong quá trình yêu cầu
bottelneck là nút thắt cổ chai, được định nghĩa là một điểm mà tại đó có thể không đủ dung lượng để có thể xử lý khối lượng công việc tại thời điểm đó ↩︎
traceId là mã định danh duy nhất của yêu cầu trong hệ thống theo dõi, bổ sung khả năng theo dõi lịch sử của yêu cầu một cách chi tiết ↩︎
rootSpan là span gốc, khởi nguồn của mỗi trace ↩︎
3.5. Attribute trong OpenTelemetry
Đây là cặp key-value chứa dữ liệu mô tả mà ta có thể sử dụng để chú thích thêm một số thông tin phục vụ cho việc tracking.
Ví dụ: nếu một Span theo dõi một hoạt động thêm sản phẩm vào giỏ hàng mua sắm của người dùng trong một hệ thống thương mại điện tử, ta có thể ghi lại ID của người dùng.
3.6. Context Propagation trong OpenTelemetry
- Context là một đối tượng chứa thông tin để các dịch vụ giữa bên nhận và bên gửi liên kết thành một Span để tạo thành một Trace tổng thể. Ví dụ, nếu service A gọi service B, thì một Span từ service A có ID trong ngữ cảnh sẽ được sử dụng làm Parent Span cho span tiếp theo được tạo ra trong service B.
- Propagation là cơ chế inject thông tin Context giữa các dịch vụ với nhau. Bằng cách làm như vậy, nó tạo thành một Distributed Trace. Nó sẽ serialize/deserialize Span Context và cung cấp thông tin Trace liên quan để truyền từ một dịch vụ này sang dịch vụ khác. Chúng ta có thể gọi đây là Trace Context.
4. Làm việc với Collectors trong OpenTelemetry
Ở mục này chúng ta sẽ đi qua lần lượt khái niệm về các thành phần trong Collector của OpenTelemetry.
Để làm việc với Otel collector, chúng ta có hai tùy chọn để triển khai.
- Agent: Một phiên bản Collector chạy cùng với ứng dụng hoặc trên cùng máy chủ với ứng dụng (ví dụ: binary, sidecar).
- Gateway: Một hoặc nhiều phiên bản Collector chạy như một dịch vụ độc lập (ví dụ: container hoặc deployment) thường là mỗi cụm, mỗi trung tâm dữ liệu.
Còn đây là một file ví dụ để cấu hình OpenTelemetry trong hệ thống.
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
exporters:
logging:
loglevel: debug
prometheus:
endpoint: "0.0.0.0:8889"
jaeger:
endpoint: jaeger-service:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [ otlp ]
processors: [ batch ]
exporters: [ logging, jaeger ]
metrics:
receivers: [ otlp ]
processors: [ batch ]
exporters: [ prometheus ]
Collector trong OpenTelemetry bao gồm một số thành phần quan trọng để thu thập, xử lý và xuất dữ liệu từ các ứng dụng và hệ thống. Dưới đây là một số thành phần chính của một Collector trong OpenTelemetry.
- Receivers là thành phần đầu tiên trong Collector, nó đóng vai trò như một cổng lắng nghe dữ liệu đến từ các nguồn khác nhau. Chúng ta có thể cấu hình nó lắng nghe dữ liệu từ các agent được triển khai trên các máy chủ ứng dụng, cổng giao thức (HTTP, gRPC, Thrift, etc.), hoặc từ các nguồn khác.
- Processors: Đóng vai trò để xử lý dữ liệu sau khi nó được nhận bởi Receiver. Các Processor thường thực hiện các tác vụ như chuyển đổi định dạng dữ liệu, lọc và lấy mẫu dữ liệu, thêm thông tin bổ sung (ví dụ: context) vào dữ liệu hoặc thực hiện các tác vụ tùy chỉnh khác tùy theo nhu cầu chúng ta mong muốn.
- Exporters chịu trách nhiệm xuất dữ liệu đã qua xử lý ở bước Processor ra ngoài hệ thống khác. Dữ liệu có thể được xuất ra các nền tảng giám sát như Prometheus, Jaeger, Grafana, hoặc các hệ thống lưu trữ dữ liệu như Elasticsearch, InfluxDB, và nhiều hệ thống khác. Exporter đảm bảo rằng dữ liệu được truyền sang một cách đáng tin cậy và hiệu quả.
- Extensions (tùy chọn) Collector có hỗ trợ các tiện ích mở rộng để cung cấp tính năng bổ sung hoặc tích hợp với các hệ thống và dịch vụ khác. Các tiện ích mở rộng này có thể liên quan đến bảo mật, quản lý session, logging và nhiều tính năng khác.
Để thu thập các thông số phân tích hệ thống, ứng dụng phải expose số liệu của mình dưới định dạng Prometheus hoặc OpenMetrics qua giao thức HTTP. Đối với các ứng dụng không thể làm điều đó, sẽ có các exporter thay thể làm thay công việc đó với format đi theo exporter quyết định.
Nếu chúng ta muốn xem dữ liệu Trace, ta nên sử dụng Zipkin exporter . Ngoài ra, chúng ta có thể sử dụng Prometheus exporter để xem dữ liệu theo Time series.
5. Ưu và nhược điểm của OpenTelemetry
Việc sử dụng OpenTelemetry mang lại nhiều lợi ích nhưng cũng đi kèm với đó là một số hạn chế nhất định. Dưới đây là những ưu và nhược điểm khi sử dụng OpenTelemetry.
5.1. Ưu điểm của OpenTelemetry
- Tiêu chuẩn và thống nhất: Là một tiêu chuẩn về việc thu thập dữ liệu giám sát. Điều này đồng nghĩa rằng các ứng dụng sử dụng OpenTelemetry có thể tích hợp dễ dàng với nhiều hệ thống khác nhau mà không cần thay đổi mã nguồn.
- Độ phủ rộng: OpenTelemetry hỗ trợ với nhiều ngôn ngữ lập trình và các framework phổ biến như Java, Python, Go, Node.js, và nhiều ngôn ngữ khác. Điều này giúp cho việc thu thập dữ liệu giám sát trở nên đa dạng và toàn diện hơn.
- Tùy chỉnh linh hoạt: Cho phép chúng ta tùy chỉnh cách thu thập dữ liệu theo nhu cầu cụ thể của ứng dụng. Ngoài ra có thể xác định được các metric và thông tin cần thu thập để đảm bảo hiệu suất và sự ổn định của ứng dụng.
- Hỗ trợ Cloud: OpenTelemetry được tích hợp tốt với các dịch vụ giám sát trên cloud như AWS X-Ray, Google Cloud Monitoring và nhiều nền tảng khác. Điều này giúp chúng ta dễ dàng quản lý và theo dõi các ứng dụng đang chạy trên cloud.
5.2. Nhược điểm của OpenTelemetry
- Khả năng triển khai khó khăn: Cài đặt và triển khai OpenTelemetry có thể phức tạp đối với các hệ thống lớn. Điều này đòi hỏi lượng kiến thức kỹ thuật cao và thời gian đầu tư vào cách thiết kế nhiều.
- Tính tương thích: Một số ứng dụng và hệ thống có thể cần sự tương thích hoặc tùy chỉnh đặc biệt để tích hợp hoàn toàn với OpenTelemetry. Điều này có thể gây khó khăn trong việc triển khai.
- Khả năng quản lý dữ liệu lớn: Với việc thu thập rất nhiều dữ liệu giám sát, có thể gây ra vấn đề về quản lý và lưu trữ dữ liệu. Cần có sự quản lý cẩn thận để đảm bảo dữ liệu được xử lý và lưu trữ an toàn, hiệu quả hơn.
6. Kết luận về OpenTelemetry, công cụ giám sát hệ thống
Tóm lại, sau khi cùng mình đi qua những khái niệm cơ bản trên chúng ta cần chú ý đến những điểm sau .
- Thiết lập OpenTelemetry Collector để lấy dữ liệu từ ứng dụng (hai tùy chọn triển khai như chúng ta đã đi qua ở phần trên).
- Chúng ta cần phải cấu hình receivers, processor, exporters trong tệp cấu hình. Điều này phụ thuộc vào dữ liệu mà chúng ta muốn quan sát hệ thống của mình.
- Cuối cùng, chúng ta phải thiết lập công cụ bên thứ ba để xem dữ liệu như Zipkin (để xem dữ liệu trace), Prometheus (xem dữ liệu theo Time series).
OpenTelemetry, với khả năng cung cấp một giải pháp giám sát và theo dõi hiệu suất đơn giản nhưng mạnh mẽ, đã trở thành một công cụ không thể thiếu trong hệ sinh thái DevOps.
Nó không chỉ giúp các nhà phát triển nắm bắt được thông tin chi tiết về hệ thống của mình, mà còn tạo điều kiện cho việc phân tích dữ liệu, tìm hiểu nguyên nhân gốc rễ của các vấn đề và tối ưu hóa hiệu suất.
Với OpenTelemetry, việc theo dõi và giám sát hệ thống không còn là một nhiệm vụ khó khăn. Hãy khám phá và tận dụng sức mạnh của OpenTelemetry để tạo ra những sản phẩm phần mềm chất lượng cao.
Bạn hãy thường xuyên theo dõi các bài viết hay về Lập Trình & Dữ Liệu trên 200Lab Blog nhé. Cũng đừng bỏ qua những khoá học Lập Trình tuyệt vời trên 200Lab nè.
Cùng 200Lab khám phá thế giới công nghệ sôi động và tạo ra những sản phẩm tuyệt vời. 200Lab không chỉ là một trung tâm đào tạo, mà còn là người bạn đồng hành tin cậy trong hành trình khám phá công nghệ của bạn. Hãy cùng 200Lab viết nên câu chuyện công nghệ của riêng bạn.
Một vài bài viết mới bạn sẽ thích:
Giải pháp scale WebSocket với Socket.IO
WebSocket là gì? Lý do sử dụng WebSocket
RabbitMQ là gì? RabbitMQ hoạt động như nào?
Kafka cơ bản: Cách sử dụng Kafka với Confluent & Go
REST API là gì? Cách thiết kế RESTful API bạn chưa biết
Bài viết liên quan
Grafana Loki là gì? So sánh Loki và Elasticsearch
Nov 16, 2024 • 6 min read
Webhook là gì? So sánh Webhook và API
Nov 15, 2024 • 8 min read
Two-Factor Authentication (2FA) là gì? Vì sao chỉ Mật khẩu thôi là chưa đủ?
Nov 13, 2024 • 7 min read
ELK là gì? So sánh hiệu suất giữa ELK và PLG
Nov 06, 2024 • 9 min read
Docker Best Practices: Tối ưu Dung lượng Docker Image
Oct 30, 2024 • 8 min read
SQL Injection là gì? Những cách phòng ngừa SQL Injection
Oct 25, 2024 • 10 min read