SpringCloud客户端负载均衡——Ribbon的LoadBalancer(负载均衡器)

所谓负载均衡,就是为资源分配负载,就是选择合适的服务处理请求。
SpringCloud的客户端负载均衡器LoadBalancerClient的默认实现RibbonLoadBalancerClient中,使用了RibbonILoadBalancer接口来实现chooseServer即负载均衡功能。

ILoadBalancer
// ILoadBalancer接口定义了负载均衡器的操作,包括初始化服务列表、选择服务实例、关停服务、获取服务列表等
interface ILoadBalancer {
   
	void addServers(List<Server> newServers);
	Server chooseServer(Object key);
	void markServerDown(Server server);
	List<Server> getReachableServers();
	List<Server> getAllServers();
}

ILoadBalancer的直接实现类是抽象类AbstractLoadBalancer

AbstractLoadBalancer

该抽象实现类,根据服务实例的状态,定义了一个服务分组枚举类ServerGroup,包含三种状态:All,Up,Not_Up
相应的定义了根据分组类型获取服务实例列表的getServerList方法
此外,还定义了获取负载均衡器统计信息的getLoadBalancerStats方法和选择服务实例的默认方法chooseServer

abstract class AbstractLoadBalancer implements ILoadBalancer{
   
	public enum ServerGroup {
   
		ALL, STATUS_UP, STATUS_NOT_UP
	}
	public Server chooseServer() {
    return chooseServer(null); } 
	public abstract List<Server> getServerList(ServerGroup serverGroup);
	public abstract LoadBalancerStats getLoadBalancerStats();
}
NoOpLoadBalancer——没有操作的实现类
BaseLoadBalancer

BaseLoadBalancer继承自AbstractLoadBalancer,实现了ILoadBalancer定义的所有方法和AbstractLoadBalancer中的抽象方法
BaseLoadBalancer是一个完整的负载均衡器的实现类,主要由以下职责:初始化服务实例列表、选择服务实例、关停服务、获取服务实例列表,

class BaseLoadBalancer extends AbstractLoadBalancer {
   
	psf IRule DEFAULT_RULE = new RoundRobinRule();
	psf SerialPingStrategy DEFAULT_PING_STRATEGY = new SerialPingStrategy();
	IRule rule = DEFAULT_RULE; // IRule接口有一个Server choose(Object key)方法,用于选择一个合适的服务实例,BaseLoadBalancer的chooseServer方法就是将工作委托给IRule的choose来完成,默认使用RoundRobinRule——线性负载均衡
	IPingStrategy pingStrategy = DEFAULT_PING_STRATEGY; // IPingStrategy接口有一个boolean[] pingServers(IPing, Server[]),定义了ping服务实例的策略,默认使用SerialPingStrategy——使用for循环线性遍历
	IPing ping = null; // IPing接口有一个boolean isAlive(Server)方法,用来定义如何去ping一个服务实例,判断其是否处于正常状态
	@Monitor(name = PREFIX + "AllServerList", type = DataSourceType.INFORMATIONAL)
	volatile List<Server> allServerList = Collections.synchronizedList(new ArrayList<>()); // 全部服务实例
	@Monitor(name = PREFIX + "UpServerList", type = DataSourceType.INFORMATIONAL)
	volatile List<Server> upServerList = Collections.synchronizedList(new ArrayList<>()); // UP正常状态的服务实例
	LoadBalancerStats lbStats; // 存储统计信息
	List<ServerListChangeListener> changeListeners = new CopyOnWriteArrayList<>(); // 监听服务变化的监听器,
	List<ServerStatusChangeListener> serverStatusListeners = new CopyOnWriteArrayList<>(); // 监听服务实例的状态变化的监听器,markServerDown时回调
	
	// -----------AbstractLoadBalancer接口定义的方法-----------
	void addServers(List<Server> newServers) {
    
		ArrayList<Server> newList = new ArrayList<>();
		newList.addAll(allServerList); // 将原已维护的服务实例allServerList
		newList.addAll(newServers);    // 和新传入的服务实例newServers一起,加入到newList中
		setServersList(newList);	   // 然后调用setServersList更新服务实例清单
	}
	Server chooseServer(Object key) {
    
		return rule.choose(key);	// 委托IRule选择服务实例
	}
	void markServerDown(Server server) {
    
		server.setAlive(false);		// 标记服务状态
		notifyServerStatusChangeListener(Collections.singleton(server));	// 通知serverStatusListeners中的ServerStatusChangeListener,回调serverStatusChanged方法
	}
	List<Server> getReachableServers() {
    
		return Collections.unmodifiableList(upServerList);	// 返回维护的正常服务实例清单upServerList
	}
	List<Server> getAllServers() {
   
		return Collections.unmodifiableList(allServerList); // 返回维护的所有服务实例清单allServerList
	}

	// -----------AbstractLoadBalancer定义的方法-----------
	List<Server> getServerList(ServerGroup serverGroup) {
    // 根据传入的不同分组,返回不同的服务实例清单
		ALL -> allServerList;
		STATUS_UP -> upServerList;
		STATUS_NOT_UP -> allServerList.removeAll(upServerList);
	}
	LoadBalancerStats getLoadBalancerStats() {
    // 返回统计信息
		return lbStats;
	}
	
	// -----------BaseLoadBalancer自身的方法-----------
	void setupPingTask() {
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值