Microservices với Spring Boot và Spring Cloud (Phần 1) - Giới thiệu về Microservices
Để tiếp cận được series này, bạn yêu cầu phải có cơ bản về Java Core, nếu bạn chưa có kiến thức cơ bản về Java Core bạn có thể tham khảo series Java Core Basics
Các khái niệm
Spring Boot là gì ?
Spring Boot là một framework được xây dựng trên nền tảng của Spring Framework và được thiết kế để giúp cho việc phát triển ứng dụng Spring nhanh hơn và đơn giản hóa việc cấu hình. Nó cung cấp cho các nhà phát triển một cách tiếp cận mới để phát triển các ứng dụng web Spring một cách nhanh chóng, mà không cần phải tốn nhiều thời gian để cấu hình hoặc sắp xếp các dependency phức tạp. Spring Boot cung cấp nhiều tính năng tiện lợi như auto-configuration, embedded web server, starter dependencies và actuator để giúp việc phát triển và triển khai ứng dụng Spring trở nên đơn giản hơn.
Spring Cloud là gì?
Spring Cloud là một framework phát triển trên nền tảng Spring để giúp cho việc xây dựng các ứng dụng phân tán trở nên dễ dàng hơn. Nó cung cấp các tính năng và công cụ để giải quyết các vấn đề phức tạp như phân tán, khả năng mở rộng, cân bằng tải, khả năng phục hồi, giám sát và quản lý cấu hình. Spring Cloud cũng hỗ trợ các công nghệ mở như Netflix OSS (Open Source Software) và các giải pháp đám mây như Eureka, Ribbon, Hystrix, Zuul, Config Server, và nhiều hơn nữa. Sử dụng Spring Cloud giúp cho việc triển khai các ứng dụng phân tán trở nên đơn giản và dễ quản lý hơn.
Microservices là gì?
Có nhiều định nghĩa khác nhau về Microservices và có thể bạn sẽ bị bối rối không biết cái nào đúng, cái nào tối ưu. Định nghĩa sau đấ sẽ kết hợp các khái niệm phổ biến nhất của Microservices.
Một microservice là một phương pháp kỹ thuật tập trung vào việc phân tách (decomposing) ứng dụng thành các module chức năng đơn (single-function ) với các giao diện được xác định rõ ràng (well-defined interfaces), được triển khai và vận hành độc lập (Independent) bởi các nhóm nhỏ (Small Teams) có quản lý toàn bộ vòng đời (Entire Lifecycle) của dịch vụ.
Microservices giúp gia tăng tốc độ phát triển bằng cách giảm thiểu sự giao tiếp (Minimizing Communication) và phối hợp giữa các thành viên trong nhóm, đồng thời giảm phạm vi và rủi ro của các thay đổi (The scope and risk of change) .
Phân tách (Decomposing) là gì?
Decomposing trong ngữ cảnh của microservices nghĩa là phân tách ứng dụng thành các module chức năng đơn. Tức là, thay vì có một ứng dụng lớn thì chúng ta sẽ tách thành nhiều ứng dụng nhỏ hơn, mỗi ứng dụng nhỏ này có chức năng rõ ràng và phục vụ cho một nhu cầu cụ thể của ứng dụng lớn. Việc phân tách này giúp cho việc phát triển và bảo trì ứng dụng trở nên dễ dàng hơn và tăng tính linh hoạt của hệ thống.
Ví dụ:
class BookApp {
User getBook() {
// 1. lấy thông danh sách book
// 2. lấy thông tin chi tiết book
// 3. ghi lịch sử book đã xem
}
}
class BookApp {
void getBooks() { ... }
User getDetailBook() { ... }
void logHistoryReadBook() { ... }
}
Single-function (Chức năng đơn) là gì?
Single-function là thuật ngữ trong kiến trúc Microservices, chỉ định rằng mỗi microservice chỉ nên chứa một chức năng cố định, thực hiện một nhiệm vụ cụ thể của hệ thống. Điều này giúp tách biệt các chức năng khác nhau của ứng dụng và giúp cho việc phát triển và bảo trì các microservice trở nên đơn giản hơn.
Giao diện được xác định rõ ràng (well-defined interfaces) là gì?
Well-defined interfaces là các giao diện được định nghĩa rõ ràng và cung cấp các quy tắc về cách các thành phần khác của hệ thống có thể tương tác với chúng. Các giao diện này giúp đảm bảo tính tương thích và khả năng mở rộng trong hệ thống phân tán, bởi vì các thành phần khác nhau có thể giao tiếp với nhau thông qua các giao diện được định nghĩa trước đó mà không cần biết chi tiết bên trong của nhau.
Độc lập (Independent) là gì?
Trong ngữ cảnh của microservices, độc lập (independent) thường được hiểu là các service có thể hoạt động hoàn toàn độc lập với nhau, mà không bị phụ thuộc vào các service khác. Nói cách khác, các service có thể triển khai và vận hành độc lập, và không cần phải liên tục phối hợp với nhau để thực hiện một chức năng nào đó. Điều này giúp giảm thiểu sự phụ thuộc giữa các service và làm cho hệ thống dễ dàng mở rộng và bảo trì hơn.
Ví dụ:
Giả sử rằng chúng ta cần triển khai một microservice độc lập để tính toán giá trị VAT cho các sản phẩm bán hàng. Ta sẽ tạo một ứng dụng Spring Boot mới với một REST endpoint để tính toán VAT cho một sản phẩm.
Trước tiên, ta sẽ tạo một interface để định nghĩa các phương thức cần thiết để tính toán giá trị VAT:
public interface VatCalculator {
double calculateVat(double price, double vatRate);
}
Sau đó, ta sẽ tạo một implementation của interface này:
@Service
public class VatCalculatorImpl implements VatCalculator {
@Override
public double calculateVat(double price, double vatRate) {
return price * vatRate / 100;
}
}
Cuối cùng, ta sẽ tạo một REST controller để xử lý yêu cầu và trả về kết quả tính toán VAT:
@RestController
public class VatController {
@Autowired
private VatCalculator vatCalculator;
@GetMapping("/calculate-vat")
public double calculateVat(@RequestParam double price, @RequestParam double vatRate) {
return vatCalculator.calculateVat(price, vatRate);
}
}
Như vậy, ta đã tạo ra một microservice độc lập trong Java sử dụng Spring Boot để tính toán giá trị VAT cho các sản phẩm bán hàng.
Các nhóm nhỏ (Small Teams) là gì?
- Chúng ta chia công việc và phân nhóm cho các dịch vụ. Mỗi nhóm tập trung vào một dịch vụ cụ thể, họ không cần biết về các hoạt động nội bộ của các nhóm khác.
- Những nhóm này có thể làm việc hiệu quả, giao tiếp dễ dàng và mỗi dịch vụ có thể triển khai nhanh chóng ngay khi sẵn sàng.
Toàn bộ vòng đời (Entire Lifecycle) là gì?
- Đội ngũ chịu trách nhiệm cho toàn bộ vòng đời của dịch vụ; từ việc viết mã, kiểm thử, phát triển, triển khai, gỡ lỗi và bảo trì.
- Trong một ứng dụng truyền thống, chúng ta có thể có một nhóm chịu trách nhiệm cho việc viết mã, và một nhóm khác chịu trách nhiệm cho việc triển khai. Tuy nhiên, trong kiến trúc microservices, điều này không đúng.
Giảm thiểu sự giao tiếp (Minimizing Communication) là gì?
- Giảm thiểu sự giao tiếp không có nghĩa là các thành viên trong nhóm không cần quan tâm đến nhau. Điều này có nghĩa là chỉ giao tiếp cần thiết giữa các nhóm nên thông qua giao diện mà mỗi dịch vụ cung cấp.
- Các nhóm cần đồng ý về giao diện bên ngoài để việc giao tiếp giữa các dịch vụ được xác định rõ ràng.
Giảm phạm vi và rủi ro của các thay đổi (The scope and risk of change) là gì?
- Các dịch vụ nên được thay đổi mà không làm hỏng các dịch vụ khác. Và miễn là chúng ta không thay đổi giao diện bên ngoài thì sẽ không có vấn đề cho các dịch vụ khác.
- Kết quả của các thay đổi là phiên bản của các dịch vụ được cập nhật một cách độc lập và không có mối quan hệ giữa chúng.
Monolithic Vs Microservices
- Sự lựa chọn giữa hai phương pháp phụ thuộc vào ngữ cảnh và độ phức tạp của ứng dụng.
- Thực sự, microservices giải quyết các vấn đề xuất hiện trong ứng dụng lớn khi nói đến khả năng mở rộng, quản lý, nhưng nó không phải lúc nào cũng là giải pháp tối ưu.
- Quan trọng là phải nhớ rằng microservices có thể được sử dụng trong ngữ cảnh không phù hợp, dẫn đến tăng thêm công sức và chi phí, thậm chí là thất bại của dự án.
- Hầu hết các vấn đề trong Microservices được thừa kế do việc có các thành phần riêng lẻ.
- Ví dụ, việc giao tiếp giữa các phương thức trong monolithic nhanh hơn rất nhiều so với giao tiếp bất đồng bộ trong các dịch vụ, điều này khiến nó chậm hơn, khó gỡ lỗi và phải được bảo mật.
- Và chắc chắn, sẽ có thêm công sức cho các hoạt động liên quan đến vận hành, triển khai, mở rộng, cấu hình, giám sát và kiểm thử vì mỗi dịch vụ đều là độc lập.
- Do đó, chúng ta cần có một nhóm DevOps có kỹ năng để xử lý độ phức tạp liên quan đến triển khai và tự động giám sát.
Bài viết tham khảo: https://medium.com/omarelgabrys-blog/microservices-with-spring-boot-intro-to-microservices-part-1-c0d24cd422c3
Vậy là chúng ta đã hoàn thành phần giới thiệu về Microservices
Cảm ơn bạn đã đọc! Nếu bạn thấy bài viết hữu ích, vui lòng nhấn 👍️ (upvote), dể mình có động lực làm nhiều bài viết hay hơn
All rights reserved