转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/experience_1003/loadbalance_refactor.html
项目中的一个重构的过程及理由,用于知会团队成员,在这里备一个。
RPC远程调用框架中有很多可选的负载均衡策略,
比如:随机,轮循,最少连接等等,
这个时候就需要一个SPI扩展点,为后续增加新的策略提供可能,
重构前:
原接口形式,如下:
public class LoadBalance<T> {
// 给定资源和权重,返回选中资源的下标号
int select(T[] resources, int[] weights);
}
问题一:
返回下标号,使接口输入输出不一致,并且限制了资源的包装,如:
public class LoadBalance {
// 给定资源和权重,返回选中资源
<T> T select(T[] resources, int[] weights);
}
问题二:
作为扩展接口,即然使用泛型,表示策略实现不限制资源类型,接口本身定义泛型没有意义,泛型声明应该定义在方法上,如:
public class LoadBalance {
// 给定资源和权重,返回选中资源
<T> T select(T[] resources, int[] weights);
}
问题三:
作为扩展接口,权重信息的传递过于特殊化,
比如现在最小连接数策略要用到当前活跃连接数,
需增加新的参数actives,如:
public class LoadBalance {
// 给定资源和权重,返回选中资源
<T> T select(T[] resources, int[] weights, int[] actives);
}
问题四:
但像上面这样,你并不清楚后续还有什么参数要加入,接口的契约不容扩展,
另一种办法是,在最小连接数策略实现中将T强制转型成RpcInvoker接口,然后调用getActive(),
但即然active数通过get方获取,为什么weight却通过另一个参数传入,明显的不一致,
而且这里的强制转型,也会导致策略的实现并不能像原来期望的通用,
作为一个框架的扩展点,通用意义并不大,越通用越难用,上面的泛型T有过度设计之嫌,
直接用RpcInvoker作为参数,更能保证契约的完备性,如:
public class LoadBalance {
// RpcInvoker接口中有getWeight(), getActive()等获取参数方法
// 给定资源和权重,返回选中资源
RpcInvoker select(RpcInvoker[] resources);
}
如果有通用性需求,也可以考虑再抽取一个接口,如:
public class LoadBalance {
// 给定资源和权重,返回选中资源
Selectable select(Selectable[] resources);
}
问题五:
有一种需求是基于客户端一致性的,要求执行所有RpcInvoker,而不是选其中一个RpcInvoker执行,
原有实现,是将其作为特例,写死在代码中的,基于上面的LoadBalance接口,
完全可以将传入的所有RpcInvoker[]包装成一个总的RpcInvoker,里面用for循环委派所有调用。
如果有w + r > n(写节点 + 读节点 > 总节点)的一致性需求,也可以用相应方法处理,只是增加一些配置项,如:
public class AllLoadBalance {
public RpcInvoker select(RpcInvoker[] resources) {
return new AllRpcInvoker(resources);
}
}
class AllRpcInvoker implements RpcInvoker {
private RpcInvoker[] invokers;
public AllRpcInvoker(RpcInvoker[] invokers) {
this.invokers = invokers;
}
// Delegate all methods to invokers
}
问题六:
有的策略实现是带状态的,比如轮循策略需记录轮循序号,
也就是并不能单实例使用LoadBalance实例,
这对框架的维护非常不利,容易给后来的维护者埋下地雷,
而且,同一个resources集合,必需用同一个LoadBalance实例,
也就是LoadBalance实例的变更是跟随resources集合的变更,
即然如此,资源集合的设定,可以在select()之前确定,如:
public class LoadBalance {
// 初始化资源集合
void init(RpcInvoker[] resources);
// 返回选中资源
RpcInvoker select();
}
这样的好处是,LoadBalance的实现可以在init()时做预处理及缓存,
比如随机策略,需要统计总权重,如果在init()方法中统计,
select()时可以减少一次for循环,
而且,可以通过重复调用init()方法,复用单一LoadBalance实例,
当然,LoadBalance的实现需确保线程安全性。
------------------------
Dubbo设计分享系列:
一些设计上的基本常识
谈谈泛化式扩展与组合式扩展
分享到:
相关推荐
综上所述,这个重构的RPC方法库结合了Java反射、Fastjson序列化、负载均衡策略以及可能利用RabbitMQ的消息传递,为开发者提供了一个强大的工具,便于构建高可用、高性能的分布式Web应用。通过这些技术,开发者可以更...
因此,本文提出了对平台底层存储采用分布式技术的建议,并结合前端Web应用层的负载均衡进行架构重构,以实现高性能、高可用性和可伸缩性的目标。这种重构可以确保设计文档管理平台能够更好地适应企业的业务扩展和...
Cluster(集群)技术通过多台计算机的协作,提供高可用性和负载均衡。在物联网领域,TCP集群可保证物联网服务的持续稳定运行,即便其中的部分节点出现故障,集群也能确保业务的连续性。CPS重构技术方案针对TCP集群的...
这些扩展包括但不限于协议扩展、调用拦截器扩展、监听器扩展、集群扩展、路由扩展、负载均衡扩展、注册中心扩展、监控中心扩展等。通过这些扩展点,用户可以根据自己的需要,替换或者增加 Dubbo 的功能。 ### 实现...
此外,还引入了分布式系统的设计原则,如容错机制、负载均衡和一致性协议,以应对海量数据和高并发的挑战。 #### 工具与方法论 实现架构重构的过程中,支付宝运用了一系列先进的工具和技术,包括但不限于: - **...
在研究内容中,包括了对现有路由分发方法和可重构路由体系的分析,基于这些分析提出了TPRD模型,同时研究了模型中板卡路由分发速度和负载均衡状况。通过设计出实现TPRD模型的算法以及具体实施步骤,研究者们验证了...
5. **测试代码**:展示如何在应用中使用定义的Feign接口进行远程调用,测试不同负载均衡策略下的调用效果。 通过学习和实践这个"ad-search"示例,开发者可以深入理解Ribbon和Feign的工作原理,掌握如何在实际项目中...
- 在大型网站架构中,负载均衡是关键,如全局负载均衡系统(GSLB)、内容缓存系统(CDN)和服务器负载均衡系统(SLB)。 - 常见的负载均衡算法包括轮询、加权轮询、最少连接和加权最少连接,它们用于有效地分配...
文档列举了多种扩展点,如协议扩展、调用拦截扩展、引用监听扩展、暴露监听扩展、集群扩展、路由扩展、负载均衡扩展等。每一类扩展都有详细的介绍,说明如何通过配置和编程实现自定义扩展。 在实现细节方面,文档...
3. **负载均衡**:通过负载均衡器分配流量,确保单一节点的故障不会影响整体服务,同时允许添加新节点来处理增加的负载,实现水平扩展。 4. **弹性伸缩**:利用云服务的自动伸缩能力,可以根据实时需求动态调整资源...
3. 检索策略:设计高效的检索算法,如基于优先级的匹配、最短路径搜索、负载均衡算法等,以快速找到满足条件的构件。 4. 动态调整:在运行时监控网络状态,实时更新构件的分配,确保网络性能最优。 5. 故障恢复:当...
这可能涉及Docker容器化、RESTful API设计、负载均衡等技术,确保服务的稳定性和可扩展性。 通过这个项目,学生可以深入理解深度学习模型的运作,提升代码重构和系统集成的能力,同时熟悉不同编程语言和开发环境的...
- 实现数据库的读写分离,通过分布式缓存和负载均衡提高性能。 - 使用API Gateway进行服务间的通信管理和路由,降低内部耦合。 - 引入容器化和持续集成/持续部署(CI/CD)流程,加快开发和部署速度。 - 采用事件驱动...
在构建一个能承受亿级流量的网站架构时,面临的核心技术挑战主要包括高可用性、可扩展性、性能优化、负载均衡、数据存储与处理、安全防护以及监控与故障恢复等多个方面。下面将对这些关键点进行详细阐述。 1. 高...
1. **负载均衡**:通过分散请求到多个服务器,防止单一节点过载,提高系统整体处理能力。 2. **分布式服务**:将复杂应用拆分为多个独立的服务,每个服务都能独立部署和扩展,降低耦合度。 3. **缓存策略**:利用...
- 负载均衡:通过分配流量到多个服务器,减轻单一服务器的压力。 - 容错处理:设计系统能够自动检测和恢复故障。 - 自动扩展:根据当前负载动态调整资源分配。 - **作用**:确保系统即使在极端条件下也能提供稳定...
5. **负载均衡与弹性扩展**:使用云服务器ECS和负载均衡技术,实现流量自动分发,提供高可用性和扩展性。支持动态扩展,无须更换设备,对调用和访问者影响极小。同时,提供了DDoS防护和应用防火墙。 6. **消息系统*...
除了基本功能的验证,还需要验证设计功能的实现,比如负载均衡、高可用性、扩展性、资源隔离等。这确保了分布式数据库系统能够满足海量数据处理的需求。 综上所述,分布式数据库的设计涉及多个层面的技术考量,包括...
OpenNJet 实现了NGINX 云原生功能增强、安全加固和代码重构,利用动态加载机制可以实现不同的产品形态,如Web服务器、流媒体服务器、负载均衡、代理(Proxy)、应用中间件、API网关、消息队列等产品形态等等。...