栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

为什么要用Dubbo

为什么要用Dubbo

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

一、Dubbo的功能二、Rpc比Http的优势三、Netty的优势四、Spi

1、Spi的优点


一、Dubbo的功能

拆分服务、屏蔽底层细节,解耦;减少Jar包大小服务治理(负载均衡、注册与发现、访问量统计、服务监控、灰度发布)


二、Rpc比Http的优势
RpcHttp所以
序列化方式针对二进制协议(如Hessian)做序列化与反序列化基于文本,比如json编码后的二进制数据小了,存储空间的硬件成本小了,传输带宽小了,系统的吞吐量变大
传输协议基于TCP|IP协议,分别是传输层和网络层额外多了应用层、表示层、会话层少了这三层
连接方式长连接大多都是短连接减少了因为连接损耗的时间

三、Netty的优势

jdk nio类库与api繁杂,api使用简单,开发门槛低预置了很多编码功能,支持多种主流协议可以通过Channelhandler对通信框架进行灵活的扩展综合性能最优、已经修复了jdk已知的所有bug 四、Spi 1、Spi的优点

1 支持缓存,实例缓存在cacheInstances中,通过map获取

// key:extensionName,value:Instance
private final ConcurrentMap> cachedInstances = new ConcurrentHashMap>();

    public T getExtension(String name) {
        if (name == null || name.length() == 0)
            throw new IllegalArgumentException("Extension name == null");
        if ("true".equals(name)) {
            return getDefaultExtension();
        }
        // 这里查缓存里的instance
        Holder holder = cachedInstances.get(name);
        if (holder == null) {
            cachedInstances.putIfAbsent(name, new Holder());
            holder = cachedInstances.get(name);
        }
        Object instance = holder.get();
        if (instance == null) {
            synchronized (holder) {
                instance = holder.get();
                if (instance == null) {
                    instance = createExtension(name);
                    holder.set(instance);
                }
            }
        }
        return (T) instance;
    }
 

2 Dubbo的SPI上有默认值

    private String cachedDefaultName;
        // synchronized in getExtensionClasses
    private Map> loadExtensionClasses() {
        final SPI defaultAnnotation = type.getAnnotation(SPI.class);
        if (defaultAnnotation != null) {
            String value = defaultAnnotation.value();
            if ((value = value.trim()).length() > 0) {
                String[] names = NAME_SEPARATOR.split(value);
                if (names.length > 1) {
                    throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()
                            + ": " + Arrays.toString(names));
                }
                // 这里赋值,后面用于动态生成适配器里的代码
                if (names.length == 1) cachedDefaultName = names[0];
            }
        }

        Map> extensionClasses = new HashMap>();
        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
        loadDirectory(extensionClasses, DUBBO_DIRECTORY);
        loadDirectory(extensionClasses, SERVICES_DIRECTORY);
        return extensionClasses;
    }

3.支持AOP与IOC

    private Set> cachedWrapperClasses;
    private void loadClass(Map> extensionClasses, java.net.URL resourceURL, Class clazz, String name) throws NoSuchMethodException {
    .....
    else if (isWrapperClass(clazz)) {
            // 1.1 刘峻峰 如果是包装类,会在这里先cache,当getExtension的时候,会把get到的实例再包装一层
            Set> wrappers = cachedWrapperClasses;
            if (wrappers == null) {
                cachedWrapperClasses = new ConcurrentHashSet>();
                wrappers = cachedWrapperClasses;
            }
            wrappers.add(clazz);
        } 
    .....
    }
    
    private T createExtension(String name) {
    		...
                if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
                for (Class wrapperClass : wrapperClasses) {
                    // 1.2 刘峻峰 调用包装类的有参构造方法,把这些类再包装起来
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            ...
            }
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号