千家信息网

Ribbon之IRule

发表于:2025-01-25 作者:千家信息网编辑
千家信息网最后更新 2025年01月25日,IRule是选择服务的一种策略。IRulepublic interface IRule{ /* * choose one alive server from lb.allServers
千家信息网最后更新 2025年01月25日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
使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。










服务 实例 选择 权重 时间 方式 方法 核心 计数器 重要 安全 不大 也就是 代码 任务 基础 就是 性能 时候 机制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 常州营销软件开发流程 虹口区工商数据库系统职能 智能科技互联网企业文化 敏捷模型是不是软件开发模型 网络安全枪神什么意思 网络安全审查对外国通讯的影响 长春先进网络技术服务质量推荐 深圳c语言软件开发报价 网络软件开发制作 手机登录服务器密码已更改 蓝凌软件开发公司 软件开发需要考什么证 在今后工作中对网络安全的 漯河械棺网络技术有限公司 2017 全球服务器发货量 香港大宽带云服务器 2010服务器修改登录密码 软件开发设计师优势 公安机关网络技术人才的培养 光遇服务器更新一般要多久 互联网金融属于科技股吗 计算机网络技术综合布线 临沂智慧党建软件开发软件 软件开发组织与管理制度 日本软件开发价格 计算机网络技术顶尖 环保网络技术图片 与网络技术相关的考研专业 怎么把数据库的表导出 安全狗服务器退出用户名
0