Ribbon之IRule
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,IRule是选择服务的一种策略。IRulepublic interface IRule{ /* * choose one alive server from lb.allServers
千家信息网最后更新 2025年12月03日Ribbon之IRule
IRule是选择服务的一种策略。
IRule
public interface IRule{ /* * choose one alive server from lb.allServers or * lb.upServers according to key * * @return choosen Server object. NULL is returned if none * server is available */ public Server choose(Object key); public void setLoadBalancer(ILoadBalancer lb); public ILoadBalancer getLoadBalancer(); }choose选择可用的服务。
RandomRule
随机选择一个UP的服务。
Random rand; // 随机计数器public RandomRule() { rand = new Random();}public Server choose(ILoadBalancer lb, Object key) { ... List upList = lb.getReachableServers(); List allList = lb.getAllServers(); int index = rand.nextInt(serverCount); // 随机选择一个 server = upList.get(index); ...} RoundRobinRule
轮询获取服务。
public RoundRobinRule() { nextServerCyclicCounter = new AtomicInteger(0);// int线程安全计数器}public Server choose(ILoadBalancer lb, Object key) { ... int nextServerIndex = incrementAndGetModulo(serverCount); // nextServerCyclicCounter依次向后获取服务。 server = allServers.get(nextServerIndex); ...}// 轮询方法private int incrementAndGetModulo(int modulo) { for (;;) { int current = nextServerCyclicCounter.get(); int next = (current + 1) % modulo; if (nextServerCyclicCounter.compareAndSet(current, next)) return next; }}BestAvailableRule
跳过熔断的服务,获取请求数最少的服务.通常与ServerListSubsetFilter一起使用.
public Server choose(Object key) { if (loadBalancerStats == null) { return super.choose(key); // 如果没有loadBalancerStats,则采用RoundRibonRule. } List serverList = getLoadBalancer().getAllServers(); int minimalConcurrentConnections = Integer.MAX_VALUE; long currentTime = System.currentTimeMillis(); Server chosen = null; for (Server server: serverList) { ServerStats serverStats = loadBalancerStats.getSingleServerStat(server); if (!serverStats.isCircuitBreakerTripped(currentTime)) { int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); if (concurrentConnections < minimalConcurrentConnections) { minimalConcurrentConnections = concurrentConnections; chosen = server; } } } if (chosen == null) { return super.choose(key); } else { return chosen; }} WeightedResponseTimeRule
权重的方式挑选服务.服务实例响应时间越小的服务,则更容易被选中.如果服务实例响应的时间相差不大的,排在前面的服务实例更容易被选中.
// 继承了RoundRobinRule,也就是当WeightedResponseTimeRule不满足条件的时候,则采用RoundRobinRule的方式.public class WeightedResponseTimeRule extends RoundRobinRule {// 这个方式很重要,就是定时的计算每个服务实例的响应时间,并以此作为每个服务实例的权重.void initialize(ILoadBalancer lb) { if (serverWeightTimer != null) { serverWeightTimer.cancel(); } serverWeightTimer = new Timer("NFLoadBalancer-serverWeightTimer-" + name, true); serverWeightTimer.schedule(new DynamicServerWeightTask(), 0,serverWeightTaskTimerInterval); // do a initial run ServerWeight sw = new ServerWeight(); sw.maintainWeights(); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { logger.info("Stopping NFLoadBalancer-serverWeightTimer-"+ name); serverWeightTimer.cancel(); } }));}// 定时任务内部类class DynamicServerWeightTask extends TimerTask { public void run() { ServerWeight serverWeight = new ServerWeight(); try { serverWeight.maintainWeights(); } catch (Exception e) { logger.error("Error running DynamicServerWeightTask for {}", name, e); } }}// 计算服务实例权重的核心方法.class ServerWeight { public void maintainWeights() { ILoadBalancer lb = getLoadBalancer(); if (lb == null) { return; } if (!serverWeightAssignmentInProgress.compareAndSet(false, true)) { return; } try { logger.info("Weight adjusting job started"); AbstractLoadBalancer nlb = (AbstractLoadBalancer) lb; LoadBalancerStats stats = nlb.getLoadBalancerStats(); if (stats == null) { // no statistics, nothing to do return; } double totalResponseTime = 0; // find maximal 95% response time for (Server server : nlb.getAllServers()) { // this will automatically load the stats if not in cache ServerStats ss = stats.getSingleServerStat(server); totalResponseTime += ss.getResponseTimeAvg(); } // weight for each server is (sum of responseTime of all servers - responseTime) // so that the longer the response time, the less the weight and the less likely to be chosen Double weightSoFar = 0.0; // create new list and hot swap the reference List finalWeights = new ArrayList(); for (Server server : nlb.getAllServers()) { ServerStats ss = stats.getSingleServerStat(server); double weight = totalResponseTime - ss.getResponseTimeAvg(); // 平均响应时间越短,则权重越大,就越容易被选中. weightSoFar += weight; finalWeights.add(weightSoFar); } setWeights(finalWeights); } catch (Exception e) { logger.error("Error calculating server weights", e); } finally { serverWeightAssignmentInProgress.set(false); } }}public Server choose(ILoadBalancer lb, Object key) { ... // 根据权重选择服务的核心代码 double randomWeight = random.nextDouble() * maxTotalWeight; // pick the server index based on the randomIndex int n = 0; for (Double d : currentWeights) { if (d >= randomWeight) { serverIndex = n; break; } else { n++; } } server = allList.get(serverIndex); ...}} RetryRule
在RoundRobinRule的基础上,增加了重试的机制.
- ZoneAvoidanceRule
服务
实例
选择
权重
时间
方式
方法
核心
计数器
重要
安全
不大
也就是
代码
任务
基础
就是
性能
时候
机制
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库更新技术指标
小程序怎么查服务器
大连豆瓣网络技术
计算机网络技术研究中心刘敏
我工作任务是软件开发英文
爱康诺软件历史数据库
贵州pdu服务器电源生产公司
sql数据库的链接符号
华为泰山服务器 opencv
数据库主属性是主键么
做软件开发需要学哪些技术
用u盘怎么装服务器系统
网络正常但串口服务器测试不通
西安天迅网络技术
一年级网络安全手抄报简单文案
天翼云服务器如何远程登入
筛选机软件开发
咨询费 软件开发
网络安全的心得
网络安全d模块
辽宁网络技术咨询报价
宁波软件开发薪资水平
系统网络安全事件应急预案
数据库的死锁会一直等待
数据采集类软件开发
河北技校网计算机网络技术
网络安全防护措施记心中
家用机做服务器要装服务器系统吗
数据库普通索引
山东线下生鲜配送软件开发