Spring Cloud Ribbon là một công cụ cân bằng tải ở phía khách hàng được xây dựng dựa trên thư viện Netflix Ribbon. Nó giúp phân phối yêu cầu từ khách hàng đến các dịch vụ theo cách hiệu quả.
Các chiến lược cân bằng tải phổ biến
Khi nói về cân bằng tải, bạn có thể nghĩ đến Nginx - một công cụ thường được sử dụng để thực hiện nhiệm vụ này. Dưới đây là một số chiến lược cân bằng tải phổ biến:- Rota tuần tự (mặc định)
- Gán trọng số cho mỗi máy chủ
- Phân bổ theo địa chỉ IP của người dùng
- Chọn máy chủ có ít kết nối nhất
Sự khác biệt giữa Nginx và Ribbon
Nginx hoạt động như một thiết bị cân bằng tải độc lập giữa máy khách và máy chủ. Trong khi đó, Ribbon tích hợp logic cân bằng tải vào chính ứng dụng khách hàng. Khách hàng sẽ lấy danh sách các địa chỉ dịch vụ từ Eureka và tự chọn một máy chủ phù hợp.Tích hợp Ribbon vào dự án
Ribbon cung cấp khả năng cân bằng tải ở phía khách hàng (lựa chọn mặc định là rota tuần tự). Để sử dụng Ribbon, chúng ta cần cấu hình nó trong dự án client Eureka.1. Thêm phụ thuộc Ribbon
Thư viện Ribbon đã bao gồm sẵn trong phụ thuộc của Eureka, vì vậy bạn không cần thêm phụ thuộc riêng lẻ nếu đã sử dụng Eureka. Tuy nhiên, nếu muốn thêm rõ ràng, bạn có thể khai báo:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2. Cấu hình RestTemplate với @LoadBalanced
Để sử dụng Ribbon cùng với `RestTemplate`, bạn cần thêm annotation `@LoadBalanced`:
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate createRestTemplate() {
return new RestTemplate();
}
}
Sau khi thêm `@LoadBalanced`, Ribbon sẽ tự động áp dụng chiến lược cân bằng tải mặc định (rota tuần tự).
Tự định nghĩa chiến lược cân bằng tải
Bạn có thể tạo ra các chiến lược tùy chỉnh bằng cách triển khai giao diện `IRule`. Ví dụ:
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
public class CustomRule extends AbstractLoadBalancerRule {
@Override
public Server choose(Object key) {
List<Server> servers = this.getLoadBalancer().getReachableServers();
int serverCount = servers.size();
if (serverCount == 0) {
return null;
}
// Logic tùy chỉnh để chọn server
Random random = new Random();
return servers.get(random.nextInt(serverCount));
}
}
Để áp dụng chiến lược mới này cho một dịch vụ cụ thể, bạn cần sử dụng annotation `@RibbonClient` trong lớp khởi chạy ứng dụng:
@RibbonClient(name = "your-service-name", configuration = CustomRule.class)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Lưu ý rằng lớp `CustomRule` không nên nằm trong cùng gói hoặc con gói với lớp khởi chạy ứng dụng để tránh bị quét bởi `@ComponentScan`.