Giới thiệu
Trong bài này chúng ta sẽ tìm hiểu về Adapter Pattern và Ambassador Pattern, đây là một dạng Pattern mở rộng của Sidecar.
Structural Patterns sẽ bao gồm:
- Init Container
- Sidecar
- Adapter
- Ambassador
Adapter
Adapter Pattern được sáng tạo để giải quyết vấn đề không đồng nhất giữa các ứng dụng. Mục tiêu của mẫu thiết kế này là cung cấp một Adapter thống nhất cho các ứng dụng của chúng ta. Điều này giúp các ứng dụng khác có thể dễ dàng truy cập vào các ứng dụng đằng sau Adapter.
Vấn đề
Trong quá trình phát triển hệ thống Microservice, một vấn đề phổ biến là khi chúng ta bắt đầu phát triển ứng dụng bằng một ngôn ngữ cụ thể. Khi hệ thống cần mở rộng, chúng ta có thể nhận ra rằng ngôn ngữ hiện tại không phù hợp cho dịch vụ mới và cần sử dụng một ngôn ngữ khác. Điều này dẫn đến việc phát triển dịch vụ mới bằng ngôn ngữ khác.
Khi hệ thống mở rộng, chúng ta có thể có nhiều dịch vụ với các ngôn ngữ khác nhau. Sự không đồng nhất giữa các ngôn ngữ này tạo ra khó khăn trong việc truy cập và tương tác giữa các dịch vụ.
Ví dụ nếu ta cần giám sát các Service nhưng Metric của từng Service tạo ra lại khác nhau thì khiến các công cụ giám sát rất khó để thu thập dữ liệu.
Giải pháp
Để giải quyết vấn đề này, Adapter Pattern cung cấp một giao diện thống nhất để các ứng dụng bên ngoài có thể dễ dàng truy cập vào các dịch vụ qua Adapter. Việc này giúp chúng ta không cần quan tâm đến cách truy cập cụ thể của từng dịch vụ, mà chỉ cần biết rằng chúng ta có thể truy cập chúng thông qua Adapter một cách thống nhất.
Trong trường hợp giám sát, chúng ta có thể sử dụng Adapter để chuyển đổi các Metric khác nhau thành một định dạng thống nhất để công cụ giám sát có thể thu thập dữ liệu một cách hiệu quả. Adapter Container là một giải pháp phù hợp cho vấn đề này.
Ví dụ
Giả sử chúng ta có một Container chạy HTTP Server đơn giản, mỗi yêu cầu từ người dùng sẽ được ghi log vào tệp tin logs của Container đó. Một Container khác sẽ đọc log từ tệp tin logs của HTTP Server và chuyển chúng thành dạng Metric mà Prometheus hoặc các công cụ giám sát khác có thể đọc được. Điều này giúp HTTP Server không cần quan tâm đến việc Metric của nó sẽ được đọc từ Prometheus hay bất kỳ công cụ giám sát nào khác.
Tạo một tệp tin với tên là adapter.yaml
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: random-generator
spec:
replicas: 1
selector:
matchLabels:
app: random-generator
template:
metadata:
labels:
app: random-generator
spec:
containers:
- image: k8spatterns/random-generator:1.0
name: random-generator
env:
- name: LOG_FILE
value: /logs/random.log
ports:
- containerPort: 8080
protocol: TCP
volumeMounts:
- mountPath: /logs
name: log-volume
- image: k8spatterns/random-generator-exporter
name: prometheus-adapter
env:
- name: LOG_FILE
value: /logs/random.log
ports:
- containerPort: 9889
protocol: TCP
volumeMounts:
- mountPath: /logs
name: log-volume
volumes:
- name: log-volume
emptyDir: {}
Ở tệp tin cấu hình trên ta tạo một EmptyDir Volume tên là log-volume
và gắn nó vào bên trong cả hai Container ở thư mục logs
. HTTP Server ghi log vào tệp tin /logs/random.log
và prometheus-adapter
đọc log này sau đó chuyển nó thành định dạng mà Prometheus đọc được.
Adapter Container là một Reverse Proxy cho các ứng dụng bên ngoài có thể truy cập được các ứng dụng đằng sau nó một cách dễ dàng.
Ambassador
Ambassador Pattern là mẫu thiết kế ngược lại so với Adapter Pattern. Mục đích của Ambassador là cung cấp một giao diện thống nhất để các ứng dụng đằng sau nó có thể dễ dàng truy cập vào các ứng dụng bên ngoài.
Vấn đề
Một vấn đề thường gặp là khi cần truy cập vào các ứng dụng với các cách truy cập khác nhau. Thông thường, chúng ta phải viết các đoạn mã khác nhau để truy cập vào từng ứng dụng.
Ví dụ, hệ thống của chúng ta sử dụng cả Memcached và Redis làm bộ nhớ cache. Với Memcached, việc truy cập không yêu cầu bước xác thực, nhưng với Redis thì có.
Giải pháp
Thay vì phải viết mã để kết nối với các ứng dụng khác nhau, chúng ta nên để một Container khác thực hiện việc đó. Sau đó, trong ứng dụng, chúng ta chỉ cần kết nối với Container này thông qua một giao diện duy nhất. Container này sẽ xử lý việc kết nối với các ứng dụng khác nhau. Container này được gọi là Ambassador Container.
Ví dụ
Giả sử ứng dụng của chúng ta cần truy cập cả Memcached và Redis. Chúng ta xây dựng một Ambassador Container và để nó thực hiện việc kết nối với Memcached và Redis. Sau đó, ứng dụng của chúng ta chỉ cần kết nối với Ambassador thông qua URL localhost:8080
.
Ambassador Container đóng vai trò như một Proxy để ứng dụng bên trong nó có thể dễ dàng kết nối tới các ứng dụng bên ngoài.
Kết luận
Vậy là ta đã tìm hiểu xong về Adapter và Ambassador. Adapter sẽ đóng vai trò như là một Reverse Proxy còn Ambassador đóng vai trò như là một Proxy.
Nếu bài viết có gì sai hoặc cần cập nhật thì liên hệ Admin.
Tham gia nhóm chat của DevOps VN tại Telegram.
Kém tiếng Anh và cần nâng cao trình độ giao tiếp: Tại sao bạn học không hiệu quả?