Dịch Vụ Đăng Ký và Phát Hiện (Eureka)
Các Khái Niệm Cơ Bản
Trong kiến trúc vi dịch vụ, số lượng dịch vụ lớn và có thể thay đổi động. Để các dịch vụ có thể gọi nhau, cần có cơ chế đăng ký và phát hiện dịch vụ. Eureka là một thành phần mở nguồn của Netflix được tích hợp vào Spring Cloud để cung cấp API đơn giản cho chức năng này. Eureka bao gồm hai thành phần chính: Eureka Server (trung tâm đăng ký) và Eureka Client (các nhà cung cấp và người tiêu dùng dịch vụ).
Eureka Server
- Tính Năng: Giữ một danh sách đăng ký các dịch vụ, ghi nhận thông tin như tên dịch vụ, địa chỉ IP, cổng kết nối. Các dịch vụ cung cấp sẽ đăng ký với Eureka Server, và các dịch vụ tiêu dùng sẽ lấy thông tin từ đó.
- Nguyên Lý Hoạt Động: Eureka Server hoạt động theo cụm, sao chép dữ liệu giữa các nút để đảm bảo tính nhất quán. Các dịch vụ gửi yêu cầu "heartbeat" định kỳ đến Eureka Server để duy trì trạng thái sống. Nếu không nhận được heartbeat trong một khoảng thời gian, dịch vụ sẽ bị loại khỏi danh sách đăng ký.
Eureka Client
- Dịch Vụ Cung Cấp: Khi khởi động, dịch vụ cung cấp sẽ đăng ký thông tin của mình lên Eureka Server và gửi heartbeat định kỳ để duy trì trạng thái đăng ký.
- Dịch Vụ Tiêu Dùng: Dịch vụ tiêu dùng khi khởi động sẽ lấy danh sách đăng ký từ Eureka Server và lưu vào bộ nhớ đệm. Khi cần gọi một dịch vụ khác, nó sẽ tìm kiếm thông tin từ bộ nhớ đệm và thực hiện cuộc gọi dựa trên thông tin đó. Nó cũng cập nhật danh sách định kỳ để đảm bảo có thông tin mới nhất.
Ví Dụ Thực Tế
Tạo Eureka Server
Bước 1: Tạo Dự Án Spring Boot
Sử dụng Spring Initializr để tạo một dự án Spring Boot mới, thêm phụ thuộc `spring-cloud-starter-netflix-eureka-server`.
Bước 2: Cấu Hình `pom.xml`
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
Bước 3: Bật Eureka Server
Thêm chú thích `@EnableEurekaServer` vào lớp chính.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class TrungTamDangKyApplication {
public static void main(String[] args) {
SpringApplication.run(TrungTamDangKyApplication.class, args);
}
}
Bước 4: Cấu Hình `application.properties`
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Giải thích:
- `server.port=8761`: Chỉ định cổng cho Eureka Server.
- `eureka.client.register-with-eureka=false`: Không tự đăng ký bản thân vào trung tâm đăng ký.
- `eureka.client.fetch-registry=false`: Không cần lấy danh sách đăng ký từ trung tâm.
Tạo Dịch Vụ Cung Cấp
Bước 1: Tạo Dự Án Spring Boot
Tạo dự án Spring Boot mới và thêm phụ thuộc `spring-cloud-starter-netflix-eureka-client`.
Bước 2: Cấu Hình `pom.xml`
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
Bước 3: Bật Eureka Client
Thêm chú thích `@EnableEurekaClient` vào lớp chính.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class DichVuCungCapApplication {
public static void main(String[] args) {
SpringApplication.run(DichVuCungCapApplication.class, args);
}
}
Bước 4: Cấu Hình `application.properties`
server.port=8081
spring.application.name=dich-vu-cung-cap
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
Giải thích:
- `server.port=8081`: Chỉ định cổng cho dịch vụ cung cấp.
- `spring.application.name=dich-vu-cung-cap`: Chỉ định tên dịch vụ.
- `eureka.client.service-url.defaultZone=http://localhost:8761/eureka/`: Chỉ định địa chỉ của Eureka Server.
Tạo Dịch Vụ Tiêu Dùng
Bước 1: Tạo Dự Án Spring Boot
Tạo dự án Spring Boot mới, thêm phụ thuộc `spring-cloud-starter-netflix-eureka-client` và `spring-boot-starter-web`.
Bước 2: Cấu Hình `pom.xml`
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Bước 3: Bật Eureka Client
Thêm chú thích `@EnableEurekaClient` vào lớp chính.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class DichVuTieuDungApplication {
public static void main(String[] args) {
SpringApplication.run(DichVuTieuDungApplication.class, args);
}
}
Bước 4: Cấu Hình `application.properties`
server.port=8082
spring.application.name=dich-vu-tieu-dung
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
Bước 5: Sử Dụng RestTemplate Gọi Dịch Vụ Cung Cấp
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class TieuDungController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/goi-cung-cap")
public String goiCungCap() {
List<ServiceInstance> instances = discoveryClient.getInstances("dich-vu-cung-cap");
if (instances != null && !instances.isEmpty()) {
ServiceInstance instance = instances.get(0);
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/xinchao";
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(url, String.class);
}
return "Không có dịch vụ cung cấp khả dụng.";
}
}