阅读 2

Dubbo笔记(四)

设计原则

Dubbo功能性需求

服务开发

RMI或Hessian只能简单的暴露和引用远程服务,进行开发。通过配置服务的URL地址进行调用,F5等硬件进行负载均衡。

服务软负载均衡

通过服务注册中心,动态的注册发现服务,是服务的位置透明,实现软负载均衡和容错机制,降低对硬件负载均衡的依赖,减少部分成本。

服务依赖管理

服务间依赖关系错综复杂时,人工难以描述,需要自动画出应用间的依赖关系图。

服务监控

统计服务每天的调用量,响应时间,作为容量规划的参考指标。将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阈值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

服务治理

可在线动态调整权重、服务分钟隔离、禁启用服务。

如何做到优雅的开放扩展

微核心+插件式,平等对待第三方。(类似springIOC的功能)

由一个插件生命周期管理容器,构成微核心,核心不包括任何功能,这样可以确保所有功能都能被替换,并且,框架作者能做到的功能,扩展者也一定要能做到,以保证平等对待第三方,所有,框架自身的功能也要用插件的方式实现,不能有任何硬编码。

首先要统一扩展点的加载方式。

通常微核心都会采用Factory,IOC,OSGI等方式管理插件的生命周期。Dubbo采用Factory方式管理插件,曾经采用过JDK的SPI方式来实现Factory。所有Dubbo有个废弃的@Extension注解,最后被自己造了个SPI,也就是@SPI注解。

扩展的方式

扩充式与增量式、泛化式与组合式

扩充式:有的场景需要使用OSGI序列化,有的需要使用非OSGI序列化,基于原有的非OSGI序列化进行OSGI扩展,方便简单 ,只需要将流转化成byte[]进行处理。这样不管是不是需要OSGI场景,都会讲流进行byte[]转化,用不到OSGI序列化的场景都要为此付出代价。

增量式:非OSGI的代码原封不动,再加一个OSGI的实现,要用OSGI的时候,直接依赖OSGI实现即可。

泛化式,将扩展点逐渐抽象,去所有功能并集,新加功能总是能套入并扩充旧功能的概念。

组合式,将扩展点正交分解,取所有功能交集,新加功能总是基于旧功能之上实现。

路由器;容错机制;负载均衡器;发布者;订阅者

Dubbo核心功能,Invoker+Protocol+Exporter,这样可以分成协议层,路由分成组合,是一种非常好的扩展方式。

最大化复用,每个扩展点只封装一个变化因子

比如想扩展RPC协议,可能只想换一种通信传输,其他的复用。需要将协议拆解如下

全管道式设计

使用截面拦截而非模板方法

模板方法:一般开发为做到复用,将统一的公共逻辑抽出放到父类中,具体不同的动作则抽象出方法,由子类实现。如果统一公共部分的逻辑也非常复杂,这种方式就不适合了 。

截面拦截:将公共逻辑抽出,截面包装类似AOP的Wrapper类,通过拦截器实现,形成一条链(管道),每个功能都是调用链上的一环。

类似压栈的过程,将目标放到最后,前面就相当于截面

private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
        final Invoker<T> last = invoker;
        List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
        if (!filters.isEmpty()) {
            for(int i = filters.size() - 1; i >= 0; --i) {
                final Filter filter = (Filter)filters.get(i);
                last = new Invoker<T>() {
                    public Class<T> getInterface() {
                        return invoker.getInterface();
                    }

                    public URL getUrl() {
                        return invoker.getUrl();
                    }

                    public boolean isAvailable() {
                        return invoker.isAvailable();
                    }

                    public Result invoke(Invocation invocation) throws RpcException {
                        return filter.invoke(last, invocation);
                    }

                    public void destroy() {
                        invoker.destroy();
                    }

                    public String toString() {
                        return invoker.toString();
                    }
                };
            }
        }
复制代码

看下filter

最少概念,一致性概念模型

保持尽可能上的概念,助于理解,对于开放的系统尤为重要。另外,各接口都使用一致的概念,neng能相互指引,并减少模型转换。

框架设计十层

关注下面的标签,发现更多相似文章
评论