转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/dev_related_1283/dubbo-extension.html
随着服务化的推广,网站对Dubbo服务框架的需求逐渐增多,
Dubbo的现有开发人员能实现的需求有限,很多需求都被delay,
而网站的同学也希望参与进来,加上领域的推动,
所以平台计划将部分项目对公司内部开放,让大家一起来实现,
Dubbo为试点项目之一。
既然要开放,那Dubbo就要留一些扩展点,
让参与者尽量黑盒扩展,而不是白盒的修改代码,
否则分支,质量,合并,冲突都会很难管理。
先看一下Dubbo现有的设计:
这里面虽然有部分扩展接口,但并不能很好的协作,
而且扩展点的加载和配置都没有统一处理,所以下面对它进行重构。
第一步,微核心,插件式,平等对待第三方。
即然要扩展,扩展点的加载方式,首先要统一,
微核心+插件式,是比较能达到OCP原则的思路,
由一个插件生命周期管理容器,构成微核心,
核心不包括任何功能,这样可以确保所有功能都能被替换,
并且,框架作者能做到的功能,扩展者也一定要能做到,以保证平等对待第三方,
所以,框架自身的功能也要用插件的方式实现,不能有任何硬编码。
通常微核心都会采用Factory,IoC,OSGi等方式管理插件生命周期,
考虑Dubbo的适用面,不想强依赖Spring等IoC容器,
自已造一个小的IoC容器,也觉得有点过度设计,
所以打算采用最简单的Factory方式管理插件,
最终决定采用的是JDK标准的SPI扩展机制,参见:java.util.ServiceLoader
也就是扩展者在jar包的META-INF/services/目录下放置与接口同名的文本文件,
内容为接口实现类名,多个实现类名用换行符分隔,
比如,需要扩展Dubbo的协议,只需在xxx.jar中放置:
文件:META-INF/services/com.alibaba.dubbo.rpc.Protocol
内容为:com.alibaba.xxx.XxxProtocol
Dubbo通过ServiceLoader扫描到所有Protocol实现。
并约定所有插件,都必须标注:@Extension("name"),
作为加载后的标识性名称,用于配置选择。
第二步,每个扩展点只封装一个变化因子,最大化复用。
每个扩展点的实现者,往往都只是关心一件事,
现在的扩展点,并没有完全分离,
比如:Failover, Route, LoadBalance, Directory没有完全分开,全由RoutingInvokerGroup写死了。
再比如,协议扩展,扩展者可能只是想替换序列化方式,或者只替换传输方式,
并且Remoting和Http也能复用序列化等实现,
这样,需为传输方式,客户端实现,服务器端实现,协议头解析,数据序列化,都留出不同扩展点。
拆分后,设计如下:
第三步,全管道式设计,框架自身逻辑,均使用截面拦截实现。
现在很多的逻辑,都是放在基类中实现,然后通过模板方法回调子类的实现,
包括:local, mock, generic, echo, token, accesslog, monitor, count, limit等等,
可以全部拆分使用Filter实现,每个功能都是调用链上的一环。
比如:(基类模板方法)
public abstract AbstractInvoker implements Invoker {
public Result invoke(Invocation inv) throws RpcException {
// 伪代码
active ++;
if (active > max)
wait();
doInvoke(inv);
active --;
notify();
}
protected abstract Result doInvoke(Invocation inv) throws RpcException
}
改成:(链式过滤器)
public abstract LimitFilter implements Filter {
public Result invoke(Invoker chain, Invocation inv) throws RpcException {
// 伪代码
active ++;
if (active > max)
wait();
chain.invoke(inv);
active --;
notify();
}
}
第四步,最少概念,一致性概念模型。
保持尽可能少的概念,有助于理解,对于开放的系统尤其重要,
另外,各接口都使用一致的概念模型,能相互指引,并减少模型转换,
比如,Invoker的方法签名为:
Result invoke(Invocation invocation) throws RpcException;
而Exporter的方法签名为:
Object invoke(Method method, Object[] args) throws Throwable;
但它们的作用是一样的,只是一个在客户端,一个在服务器端,却采用了不一样的模型类。
再比如,URL以字符串传递,不停的解析和拼装,没有一个URL模型类, 而URL的参数,却时而Map, 时而Parameters类包装,
export(String url)
createExporter(String host, int port, Parameters params);
使用一致模型:
export(URL url)
createExporter(URL url);
再比如,现有的:Invoker, Exporter, InvocationHandler, FilterChain
其实都是invoke行为的不同阶段,完全可以抽象掉,统一为Invoker,减少概念。
第五步,分层,组合式扩展,而不是泛化式扩展。
原因参见:
http://javatar.iteye.com/blog/690845
泛化式扩展指:将扩展点逐渐抽象,取所有功能并集,新加功能总是套入并扩充旧功能的概念。
组合式扩展指:将扩展点正交分解,取所有功能交集,新加功能总是基于旧功能之上实现。
上面的设计,不自觉的就将Dubbo现有功能都当成了核心功能,
上面的概念包含了Dubbo现有RPC的所有功能,包括:Proxy, Router, Failover, LoadBalance, Subscriber, Publisher, Invoker, Exporter, Filter等,
但这些都是核心吗?踢掉哪些,RPC一样可以Run?而哪些又是不能踢掉的?
基于这样考虑,可以将RPC分解成两个层次,只是Protocol和Invoker才是RPC的核心,
其它,包括Router, Failover, Loadbalance, Subscriber, Publisher都不核心,而是Routing,
所以,将Routing作为Rpc核心的一个扩展,设计如下:
第六步,整理,梳理关系。
整理后,设计如下:
------------------------
Dubbo设计分享系列:
配置设计
防痴呆设计
负载均衡扩展接口重构
一些设计上的基本常识
谈谈泛化式扩展与组合式扩展
- 大小: 118.8 KB
- 大小: 138 KB
- 大小: 161.9 KB
- 大小: 235.1 KB
分享到:
相关推荐
设计原则部分讨论了魔鬼在细节,设计上的基本常识,扩充式扩展与增量式扩展的区别,配置设计,设计实现的健壮性,防痴呆设计以及扩展点重构等要点。这些原则有助于开发者更加深入地理解框架的设计哲学和实践标准。 ...
- 扩展点重构:随着项目的发展,重构扩展点以维持其可管理性和可维护性。 ### 版本管理 版本管理部分会介绍如何管理 Dubbo 的版本,包括如何理解版本号,如何进行版本发布等。 ### 贡献 在贡献部分,文档会介绍...
在Java开发中,Dubbo是一个非常流行的分布式服务框架,它强调服务治理、高性能、轻量级,以及良好的可扩展性。本示例将深入探讨如何在Dubbo项目中使用注解进行服务的定义、消费和服务调用。注解的使用简化了配置,...
【标题】"idea--9.maven父子项目改造dubbo" 涉及的知识点主要集中在Maven的多模块项目管理...通过这样的改造,项目将更加模块化,便于维护,并且能够充分利用Dubbo的分布式服务治理能力,提高系统的可扩展性和稳定性。
- 对现有工程结构进行重构,如模块拆分、依赖梳理等。 - 使用模块化开发模式,比如Spring Boot的多模块项目结构。 - 规范代码和配置文件的命名规则,便于识别和管理。 ### 五、Dubbo管理控制台的安装与配置 #### ...
【标题】:“使用Dubbo进行规模服务化前的工程结构优化--源码.rar”涉及到...通过以上知识点的学习和实践,可以有效地将一个传统的非服务化工程优化为基于Dubbo的微服务架构,从而提高系统的灵活性、可扩展性和容错性。
对于这些问题,Dubbo提供了丰富的扩展点和配置选项,可以根据实际需求进行定制。 总结起来,本项目展示了如何使用Dubbo进行服务化改造,通过定义服务接口,实现服务提供者和消费者,以及在Tomcat中部署服务消费者...
3. **服务拆分与重构**:随着业务的发展,可以利用Dubbo对服务进行拆分或重构,提高系统的可扩展性和灵活性。 ### 总结 Dubbo是一款非常强大的分布式服务框架,它极大地简化了分布式系统的开发过程。通过对Dubbo的...
总的来说,这个项目展示了如何利用Maven和Dubbo实现服务化改造,通过模块化设计、服务注册与发现以及可执行jar包的构建,使得原本复杂的非服务化工程变得易于管理和扩展。理解并掌握这些知识点对于进行大型分布式...
结合Dubbo作为服务治理框架,可以实现高可用、高性能的服务间通信。同时,MySQL作为关系型数据库,为系统提供了稳定的数据存储和处理能力。接下来,我们将深入探讨这些技术栈的关键知识点。 **Spring Boot 2.0** ...
XDubbo Mic-Corexdubbo从扩展点也叫微内核设计着手思考如何重构,并配合本人设计的秒杀分布式系统架构演进进行实际超高并发场景压测重构的驱动思想是新兴springCloud,service mesh框架与实际行业特性之间存在哪些...
重构技术包括静态转动态、早绑定转晚绑定、继承转组合、编译时依赖转运行时依赖、紧耦合转松耦合,这些技术有助于保持代码的可维护性和可扩展性。 在架构风格上,采用了微服务架构,将单一应用程序分解为一组小服务...
优点在于可以根据需求灵活地扩展各个模块,但同时也增加了系统间的通信复杂度。 #### 四、项目实施步骤详解 - **第一天**: - **任务**: - 了解电商行业的基本概念和发展趋势。 - 对魔力商城项目进行整体规划和...
使用Spring Boot作为基础服务框架,Dubbo作为分布式RPC服务框架,Zookeeper作为服务注册中心,Docker作为服务发布容器。Jenkins用于持续集成。 4. **动静分离与CDN**:通过CDN实现静态资源的加速访问,静态数据(如...
- **易于重构**:API 网关的存在使得后端服务更易重构,降低重构时的风险。 **缺点:** - **性能开销**:API 网关会增加额外的网络延迟和处理时间; - **单点故障风险**:如果 API 网关出现故障,可能会导致整个...
14. 代码质量: Java软件工程师需要具备良好的代码质量,包括代码风格、代码重构、代码 review等,以便确保代码的可维护性和可扩展性。 15. 团队合作: Java软件工程师需要具备良好的团队合作精神,以便更好地与...
服务化拆分使得系统更模块化,每个服务有明确的职责,如健康检查、运维监控系统、全链路监控和Dubbo服务调用接入,以提高系统的可维护性和扩展性。 2. **技术栈选择**:有赞最初选择了Koa作为Node.js的基础,后来...
下面将对其中涉及的主要知识点进行详细阐述。 一、系统架构概述 系统架构是软件开发过程中的核心环节,它定义了系统的组织结构和组件,以及这些组件之间的关系。系统架构设计师需要理解并应用各种架构模式,以创建...
为了提升系统的扩展性和稳定性,团队采用了多种微服务框架进行技术选型,包括Dubbo、Netflix OSS、Thrift以及gRPC等。这些技术的选择有助于实现服务的快速扩展,比如通过复制实例(Scale by cloning)、拆分不同组件...
单点登录系统:为多个系统之间提供用户登录凭证以及查询登录用户的信息 XMall v1.1更新日志(需更新前后台代码及SQL) 接入自己开源的XPay个人免签收款支付系统 更新Dubbo(2.6.1)、ES(6.2.3)等依赖版本 消ES需在页面中...