dubbo源码中设计模式——负载均衡中模版模式的应用

news2025/2/2 8:28:45

模版模式介绍

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

使用场景:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
在这里插入图片描述

dubbo源码中应用

在这里插入图片描述
如上图,dubbo的负载均衡算法都继承同一个抽象类,抽象类中select方法把通用逻辑都完成了,留了一个抽象的doSelect方法给子类实现。源码如下:

public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        if (CollectionUtils.isEmpty(invokers)) {
            return null;
        }
        if (invokers.size() == 1) {
            return invokers.get(0);
        }
        return doSelect(invokers, url, invocation);
    }

dubbo支持的负载均衡算法如下:

算法特性备注
Weighted Random LoadBalance加权随机默认算法,默认权重相同
RoundRobin LoadBalance加权轮询借鉴于 Nginx 的平滑加权轮询算法,默认权重相同,
LeastActive LoadBalance最少活跃优先 + 加权随机背后是能者多劳的思想
Shortest-Response LoadBalance最短响应优先 + 加权随机更加关注响应速度
ConsistentHash LoadBalance一致性哈希确定的入参,确定的提供者,适用于有状态请求
P2C LoadBalancePower of Two Choice随机选择两个节点后,继续选择“连接数”较小的那个节点。
Adaptive LoadBalance自适应负载均衡在 P2C 算法基础上,选择二者中 load 最小的那个节点

代码实现逻辑图如下:
在这里插入图片描述

使用时由AbstractClusterInvoker(容错方法基类)初始化指定的LoadBalance,然后调用算法。初始化源码如下:

protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {
        ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(invocation.getModuleModel());
        if (CollectionUtils.isNotEmpty(invokers)) {
            return applicationModel
                    .getExtensionLoader(LoadBalance.class)
                    .getExtension(invokers.get(0)
                            .getUrl()
                            .getMethodParameter(
                                    RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE));
        } else {
            return applicationModel.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);
        }
    }

调用源码如下:

public Result invoke(final Invocation invocation) throws RpcException {
       .....省略代码
		// 初始化loadBalance
        LoadBalance loadbalance = initLoadBalance(invokers, invocation);
        RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);

        InvocationProfilerUtils.enterDetailProfiler(
                invocation, () -> "Cluster " + this.getClass().getName() + " invoke.");
        try {
        	// 传递给下层,调用loadBalance
            return doInvoke(invocation, invokers, loadbalance);
        } finally {
            InvocationProfilerUtils.releaseDetailProfiler(invocation);
        }
    }

总结

在多元化的实际业务应用中,模板模式以其灵活而强大的设计哲学,被广泛采用来构建可扩展且易于维护的代码结构。通过精心定义一个基类,我们不仅实现了共通的核心逻辑和校验机制,而且通过引入抽象方法,为子类提供了一个定制化实现的舞台,允许它们在不改变算法框架的前提下,注入特定的业务规则和行为。

这样的设计策略,既确保了整体架构的稳固性,又赋予了系统以必要的灵活性,使得新的业务需求能够在现有的模板基础上迅速得到适应与实现,从而提升了开发效率,并降低了后期维护的复杂性。

在项目架构的精妙设计中,我们精心定义了一系列的策略接口来应对多样化的业务场景。尽管策略接口众多,但大多数校验流程和调用模式却高度一致,唯一的差异在于各自的策略数据结构。

为了遵循软件设计的开闭原则——即对扩展开放,对修改封闭,我们采用了抽象基类来封装这些通用的方法。如此一来,当引入新的策略时,我们便无需触及已有的校验逻辑,仅需扩展基类,实现特定的策略方法即可。这种设计不仅提高了代码的复用性,也大大简化了后续的维护和扩展工作,确保了系统的健壮性和灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1454803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《隐私计算简易速速上手小册》第3章:隐私计算的法律与伦理(2024 最新版)

文章目录 3.1 数据保护法规概览3.1.1 基础知识3.1.2 重点案例&#xff1a;企业适应 GDPR3.1.3 拓展案例 1&#xff1a;国际公司处理多地法规3.1.4 拓展案例 2&#xff1a;小型创业公司的数据保护实践 3.2 隐私计算与伦理考量3.2.1 基础知识3.2.2 重点案例&#xff1a;数据隐私与…

【Java EE初阶十三】网络初识

1. 网络发展史 网络发展的几个主要时期&#xff1a; 单机时代->局域网时代->广域网时代->移动互联网时代 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同工作来完成 业务&#xff0c;就有了网络互…

VMware Tools安装教程(适用windows虚拟机)

一、资源 VMware-tools安装包已绑定在资源中 二、步骤 1、点击已经开启的虚拟机中的此图标&#xff0c;点击设置 2、将镜像文件选中&#xff0c;点击确定 3、之后会自动进入安装过程&#xff0c;点击下一步 4、选择典型安装&#xff0c;下一步直到完成&#xff0c;完成后重启…

洛谷 P6354 [COCI2007-2008#3] TAJNA

题目传送门https://www.luogu.com.cn/problem/P6354?contestId158451 参考代码 代码解读 for(int isqrt(len);i>0;i--) if(len%i0) { ri,slen/i; break; } -->计算矩阵大小 for(int i0;i<s;i) for(int j0;j<r;j)--&…

二叉树(4)——链式二叉树

1 二叉树的概念 二叉树是&#xff1a; 空树非空&#xff1a;根节点&#xff0c;根节点的左子树、根节点的右子树组成的。 二叉树定义是递归式的&#xff0c;因此后序基本操作中基本都是按照该概念实现的。 2 二叉树的遍历 2.1 前序、中序以及后序遍历 学习二叉树结构&#xf…

【教程】Linux使用aria2c多线程满速下载

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 安装aria2c&#xff1a; sudo apt-get install aria2多线程下载&#xff1a; aria2c -x 16 -s 16 <url> 比如&#xff1a; aria2c -x 16 -s 16 http://images.cocodataset.org/zips/test2017.zip

Vue22 Vue监测数据改变的原理_数组

实例 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>Vue监测数据改变的原理_数组</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"></script>&…

node命令yarn --version指向了java

问题描述 本地安装了java、hadoop和nodejs&#xff0c;并配置了环境变量&#xff0c;但是hadoop的bin目录下存在yarn命令&#xff0c;所以使用nodejs的yarn命令启动项目会出现找不到类&#xff0c;此时键入yarn -version也会显示java的版本。 原因分析 由于配置了hadoop环境…

2024年重磅消息:来自OpenAI发布的视频生成模型Sora

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

算法之力扣数青蛙

题目连接 文章目录 题目解析算法原理第一步第二步第三步第三步第四步指向o 代码讲解代码实现 题目解析 先给大家来讲解一下这个题目的意思吧&#xff0c;这个题目是说呢给你一个蛙叫的字符串让你去设计一个算法求出发出这种蛙叫最少需要几只青蛙。比如说第一个样例发出这种叫声…

反射的作用

获取一个类里面所有的信息&#xff0c;获取到了之后&#xff0c;再执行其他的业务逻辑结合配置文件&#xff0c;动态的创建对象并调用方法 练习1&#xff1a; public class MyTest {public static void main(String[] args) throws IllegalAccessException, IOException {Stude…

xstream.mapper和mybatisplus.core.mapper冲突

报错信息 [com.baomidou.mybatisplus.core.mapper.Mapper] conflicts with existing, non-compatible bean definition of same name and class [com.thoughtworks.xstream.mapper.Mapper] 问题描述&#xff1a; 由于一些原因&#xff0c;需要将该SpringBoot的程序&#xff0c…

Android稳定性相关知识

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、相关方法论3.1 crash3.2 性能3.3 高…

el-form validator的校验提示遮盖下边的内容

问题&#xff1a;表单的validator校验&#xff0c;无法自动撑起tip提示的高度&#xff0c;导致遮盖了下边内容 解决方式&#xff1a;将tip提示的样式的定位设置为遵循正常的文档流对象&#xff0c;实现自适应高度。 .el-form-item .el-form-item__content .el-form-item__err…

Linux+Win双系统远程重启到Win

背景 电脑安装了双系统&#xff08;ubuntu 22.04 win11&#xff09;&#xff0c;默认进入ubuntu系统。给电脑设置了WoL(Wake-on-LAN)&#xff0c;方便远程开机远程控制。 但是ubuntu的引导程序grub无法远程控制&#xff0c;远程开机会默认进入ubuntu。 虽然说可以进入ubuntu后…

C#安装CommunityToolkit.Mvvm依赖

这里需要有一定C#基础&#xff0c; 首先找到右边的解决方案&#xff0c;右键依赖项 然后选择nuget管理 这里给大家扩展一下nuget的国内源&#xff08;https://nuget.cdn.azure.cn/v3/index.json&#xff09; 然后搜自己想要的依赖性&#xff0c;比如CommunityToolkit.Mvvm 再点…

Unity数据持久化之PlayerPrefs

PlayerPrefs概述 什么是数据持久化 数据持久化就是将内存中的数据模型转换为存储模型&#xff0c;以及将存储模型转换为内存中的数据模型的统称。即将游戏数据存储到硬盘&#xff0c;硬盘中数据读取到游戏中&#xff0c;也就是传统意义上的存盘。 基本方法 PlayerPrefs是什么…

如何用Qt实现一个无标题栏、半透明、置顶(悬浮)的窗口

在Qt框架中&#xff0c;要实现一个无标题栏、半透明、置顶&#xff08;悬浮&#xff09;的窗口&#xff0c;需要一些特定的设置和技巧。废话不多说&#xff0c;下面我将以DrawClient软件为例&#xff0c;介绍一下实现这种效果的四个要点。 要点一&#xff1a;移除标题栏&#…

⭐北邮复试刷题103. 二叉树的锯齿形层序遍历 (力扣每日一题)

103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a;输入&#xff1a…

鱼皮项目_可下载

​ 一、网址 Sign in GitLab 二、登录 以个人邮箱登录 c7 三、下载 四、打开下载文件&#xff0c;后缀zip ​