为什么要用Dubbo

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


一、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<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<String, Holder<Object>>();

    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<Object> holder = cachedInstances.get(name);
        if (holder == null) {
            cachedInstances.putIfAbsent(name, new Holder<Object>());
            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<String, Class<?>> 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<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();
        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
        loadDirectory(extensionClasses, DUBBO_DIRECTORY);
        loadDirectory(extensionClasses, SERVICES_DIRECTORY);
        return extensionClasses;
    }
  • 3.支持AOP与IOC
    private Set<Class<?>> cachedWrapperClasses;
    private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
    .....
    else if (isWrapperClass(clazz)) {
            // 1.1 刘峻峰 如果是包装类,会在这里先cache,当getExtension的时候,会把get到的实例再包装一层
            Set<Class<?>> wrappers = cachedWrapperClasses;
            if (wrappers == null) {
                cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();
                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));
                }
            }
            ...
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值