用DiscoveryClient手写负载均衡
前戏
在分布式微服务调用的时候我们会想到一个工具叫Ribbon,关于这个Ribbon的具体实现负载均衡的原理可以参考本人这篇文章 《Ribbon原理-RestTemplate使用@LoadBalanced负载均衡源码详解》, 本篇内容主要讲自己如何写一个简单的负载均衡逻辑,话不多说,直接开干!
1. 原理
在开干之前讲一下这个负载均衡的原理,很简单,就是拿到集群的服务列表,然后根据某种算法拿到一个服务来进行调用,算法可以是轮询,也可以是一致性哈希,也可以根据你的想法去定制,花里胡哨的都可以,Do what you think! 话不多说,来咯~
看下主角DiscoveryClient类
1.1 DiscoveryClient类
/**
* Represents read operations commonly available to discovery services such as Netflix
* Eureka or consul.io.
*
* @author Spencer Gibb
* @author Olga Maciaszek-Sharma
*/
public interface DiscoveryClient extends Ordered {
/**
* Default order of the discovery client.
*/
int DEFAULT_ORDER = 0;
/**
* A human-readable description of the implementation, used in HealthIndicator.
* @return The description.
*/
String description();
/**
* Gets all ServiceInstances associated with a particular serviceId.
* @param serviceId The serviceId to query.
* @return A List of ServiceInstance.
*/
List<ServiceInstance> getInstances(String serviceId);
/**
* @return All known service IDs.
*/
List<String> getServices();
/**
* Default implementation for getting order of discovery clients.
* @return order
*/
@Override
default int getOrder() {
return DEFAULT_ORDER;
}
}
这是个接口,主要方法是它的getServices方法和getInstances方法,能从注册中心获取所有的服务或服务实例,那谁去实现它呢,当然是springcloud家族的一些注册中心去实现它啦,我们在创建注册中心的时候会引入一些starter包,这些包里面就有DiscoveryClient的实现,看下图:
哇喔,看明白了不~,用的时候直接autowired就行了!
2. 准备工作
2.1 先建注册中心
注册中心用的是Eureka,很简单就不同多说啦
- EurekaServerBoot.java
@SpringBootApplication
@EnableEurekaServer //该服务为注册中心
public class EurekaServerBoot {
public static void main(String[] args) {
SpringApplication.run(EurekaServerBoot.class,args);
}
}
- application.yaml
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #这里我改了主机host,将eureka7002.com指向localhost
client:
register-with-eureka: false #是否向自己注册,作为注册中心不需要向自己注册
fetch-registry: false #表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ #向另一个节点注册
2.2 服务提供者
写两个服务提供者模拟集群服务,只是暴露的端口不同,