Dubbo/Dubbox的服务暴露(一)

dubboX提供rest服务 上一章,我们详细介绍了如何搭建dubbo服务,本章节我们将在dubbo服务的基础上,利用dubbox,对外提供rest服务。 1. 修改maven 依赖 目前的最新版是 dubbox-2.8.4 ,其实groupId和artifactId还是原来的不变,我们升级一下dubbo版本,并且新增dubbox依赖,修改后的pom文件如下 阅读详情

前言

源码入手

平时我要了解一个框架,基本会去从他的Listener入手,如果web.xml中没有配置listener可能还会有 filter,这是spring给我们的启示,可是当要去了解dubbo的时候,发现dubbo并没有自己的listener监听器。已知dubbo是一款和spring结合较好的rpc框架,那么其不使用web容器相关的方式,必然遵循spring的方式。依据平时开发经验,我们知道要想在Spring初始化之后,做一些自己的逻辑,有一种方法即实现org.springframework.beans.factory.InitializingBean接口,那么我们搜一下,dubbo有没有这么干。
这里写图片描述

前文 Dubbo 对配置文件的解析我们知道,服务(beans->dubbo:service)相关的节点配置会在com.alibaba.dubbo.config.spring.ServiceBean的实例中保存,这里正好巧了public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware
出去一些初始化参数的工作,这里我们主要关注这里

public void onApplicationEvent(ApplicationEvent event) {
        if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
            if (isDelay() && ! isExported() && ! isUnexported()) {
                if (logger.isInfoEnabled()) {
                    logger.info("The service ready on spring started. service: " + getInterface());
                }
                //暴露服务
                export();
            }
        }
    }

public synchronized void export() 方法里会做一些判断,我们这里只关注自己最关注的部分

public synchronized void export() {
        //.......如果当前服务被暴露过就不再暴露,等一些判断
        if (delay != null && delay > 0) {//delay 延迟暴露参数,如果配置延迟暴露。
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(delay);
                    } catch (Throwable e) {
                    }
                    doExport();
                }
            });
            thread.setDaemon(true);
            thread.setName("DelayExportServiceThread");
            thread.start();
        } else {
            doExport();
        }
    }

很尴尬,好多源码都没有相关的文档注释,如果没参考相关资料,第一次阅读会很难受
protected synchronized void doExport() 这个方法的作用大概是执行具体的服务暴露

 protected synchronized void doExport() {
        //......异常处理省略.......//
        //检查provider是否有配置,如果该属性为null,则new一个ProviderConfig对象,方法内部调用appendProperties(provider)方法,该方法内部会拼装一个 dubbo.tagName.属性名的key,在配置文件中查找值,如果有值则调用属性的setter方法,设置属性值。
        checkDefault();
        //如果ProviderConfig实例不为null的情况下,初始化一些配置,通常情况下很少会配置<dubbo:provider/>标签
        //提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
        if (provider != null) {
            //application 对应 <dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
            if (application == null) {
                application = provider.getApplication();
            }
            // module 对应<dubbo:module/>模块配置,用于配置当前模块信息,可选。
            if (module == null) {
                module = provider.getModule();
            }
            //registries 对应 <dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。
            if (registries == null) {
                registries = provider.getRegistries();
            }
            // monitor 对应 <dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。
            if (monitor == null) {
                monitor = provider.getMonitor();
            }
            //protocols 对应 <dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
            if (protocols == null) {
                protocols = provider.getProtocols();
            }
        }
        //........省略进一步初始化相关配置的代码行 .......//
        if (ref instanceof GenericService) { //判断是否是泛化调用接口,这里不重要。
            interfaceClass = GenericService.class;
            if (StringUtils.isEmpty(generic)) {
                generic = Boolean.TRUE.toString();
            }
        } else {
            try {

                interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            //检查接口类中是否存在指定的方法,如果dubbo:service->dubbo:method 没有配置的情况下,methods为null,该方法不会执行方法校验。如果有相关的配置,该方法会检查name属性对应的方法是否存在,不存在会抛IllegalStateException异常。
            checkInterfaceAndMethods(interfaceClass, methods);
            // 检查服务实现,如果ref不是服务的接口实现,则会抛出IllegalStateException异常。
            checkRef();
            // 声明该接口非泛化调用
            generic = Boolean.FALSE.toString();
        }
        if(local !=null){ //如果是本地服务,常用配置方案下,local 值为null
            if(local=="true"){
                local=interfaceName+"Local";
            }
            Class<?> localClass;
            try {
                localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if(!interfaceClass.isAssignableFrom(localClass)){
                throw new IllegalStateException("The local implemention class " + localClass.getName() + " not implement interface " + interfaceName);
            }
        }
        if(stub !=null){//如果是远程服务,常用配置方案下,stub值为null
            if(stub=="true"){
                stub=interfaceName+"Stub";
            }
            Class<?> stubClass;
            try {
                stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if(!interfaceClass.isAssignableFrom(stubClass)){
                throw new IllegalStateException("The stub implemention class " + stubClass.getName() + " not implement interface " + interfaceName);
            }
        }
        //检查应用配置,如果没有配置会创建默认对象。其内部会调用appendProperties(AbstractConfig config) 填充属性。检查失败会抛出IllegalStateException异常
        checkApplication();
        //检查注册中心配置,如果没有配置,则会检查配置文件中的dubbo.registry.address 设置,并创建默认对象。其内部会调用appendProperties(AbstractConfig config) 填充属性。检查失败会抛出IllegalStateException异常
        checkRegistry();
        //检查协议配置,该方法不会抛出异常,如果没配置dubbo:protocol,会取dubbo:provider相关配置填充,如果依旧protocols依旧为null,则创建默认对象。其内部会调用appendProperties(AbstractConfig config) 填充属性。
        checkProtocol();
        //填充属性 不多说
        appendProperties(this);
        //
        checkStubAndMock(interfaceClass);
        // 初始化path属性
        if (path == null || path.length() == 0) {
            path = interfaceName;
        }
        // 暴露服务的URL
        doExportUrls();
    }

doExportUrls(); 实现如下(吐槽,怀疑下到假的源码了,到处都没有文档注释):

 @SuppressWarnings({ "unchecked", "rawtypes" })
    private void doExportUrls() {
        //获得注册中心列表
        List<URL> registryURLs = loadRegistries(true);
        for (ProtocolConfig protocolConfig : protocols) {
            doExportUrlsFor1Protocol(protocolConfig, registryURLs);
        }
    }

protected List loadRegistries(boolean provider) 类相关解析

protected List<URL> loadRegistries(boolean provider) {
        // 检查注册中心
        checkRegistry();
        List<URL> registryList = new ArrayList<URL>();
        if (registries != null && registries.size() > 0) {
            for (RegistryConfig config : registries) {
            //一般这个拿到的是注册中心地址,例如:zookeeper://1.6.5.5:2181
                String address = config.getAddress();
                if (address == null || address.length() == 0) {
                    address = Constants.ANYHOST_VALUE;
                }

                String sysaddress = System.getProperty("dubbo.registry.address");
                if (sysaddress != null && sysaddress.length() > 0) {
                    address = sysaddress;
                }
                if (address != null && address.length() > 0 
                        && ! RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
                    Map<String, String> map = new HashMap<String, String>();
                    appendParameters(map, application);
                    appendParameters(map, config);
                    map.put("path", RegistryService.class.getName());
                    map.put("dubbo", Version.getVersion());
                    map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
                    if (ConfigUtils.getPid() > 0) {
                        map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
                    }
                    if (! map.containsKey("protocol")) {
                        //查询注册中心是否支持remote协议
                        if (ExtensionLoader.getExtensionLoader(RegistryFactory.class).hasExtension("remote")) {
                            map.put("protocol", "remote");
                        } else {
                            map.put("protocol", "dubbo");
                        }
                    }
                    //目前到这里是zookeeper://ip地址:2181/com.alibaba.dubbo.registry.RegistryService?application=配置应用名&dubbo=2.8.4&file=缓存文件路径&logger=log4j&organization=22222&owner=weiythi&pid=20772&timestamp=1510040471140
                    List<URL> urls = UrlUtils.parseURLs(address, map);
                    for (URL url : urls) {
                        url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
                        //这个url会被转换成这种格式 registry://ip:2181/com.alibaba.dubbo.registry.RegistryService?application=配置的应用名&dubbo=2.8.4&file=缓存文件路径&logger=log4j&organization=22222&owner=weiythi&pid=20772&registry=zookeeper&timestamp=1510040471140 即会将注册中心转换成registry参数放到url中,并将url的protocol设置成registry
                        url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
                        if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
                                || (! provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
                            registryList.add(url);
                        }
                    }
                }
            }
        }
        return registryList;
    }

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs)

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
        //获得协议信息,默认dubbo
        String name = protocolConfig.getName();
        if (name == null || name.length() == 0) {
            name = "dubbo";
        }

        String host = protocolConfig.getHost();
        if (provider != null && (host == null || host.length() == 0)) {
            host = provider.getHost();
        }
        boolean anyhost = false;
        //判断host是不是为null,或localhost,等本地ip地址
        if (NetUtils.isInvalidLocalHost(host)) {
            //......省略 使用各种方式获取本机的实际ip地址........//
            host = InetAddress.getLocalHost().getHostAddress();
            //......省略 使用各种方式获取本机的实际ip地址........//
        }


        Integer port = protocolConfig.getPort();
        //.....省略,如果port为null,则尝试使用默认的port,如果默认的port无法使用,则会尝试使用随机的端口
        Map<String, String> map = new HashMap<String, String>();
        if (anyhost) {
            map.put(Constants.ANYHOST_KEY, "true");
        }
        map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
        map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());
        map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
        if (ConfigUtils.getPid() > 0) {
            map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
        }
         // appendParameters 其实就是把属性值转到map中,这里不做说明
        appendParameters(map, application);
        appendParameters(map, module);
        appendParameters(map, provider, Constants.DEFAULT_KEY);
        appendParameters(map, protocolConfig);
        appendParameters(map, this);
        // 常用配置方案下,methods为null,上文代码注释中有说明
        if (methods != null && methods.size() > 0) {
            //......省略,当有暴露指定方法的配置时,会暴露指定方法
        }
        if (ProtocolUtils.isGeneric(generic)) {
            map.put("generic", generic);
            map.put("methods", Constants.ANY_VALUE);
        } else {
            String revision = Version.getVersion(interfaceClass, version);
            if (revision != null && revision.length() > 0) {
                map.put("revision", revision);
            }
            //获取接口中所有的方法名
            String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
            if(methods.length == 0) {
                logger.warn("NO method found in service interface " + interfaceClass.getName());
                map.put("methods", Constants.ANY_VALUE);
            }
            else {
                //拼接方法名为 a,b,c,d 这种形式
                map.put("methods", StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
            }
        }
        if (! ConfigUtils.isEmpty(token)) { //处理token
            if (ConfigUtils.isDefault(token)) {
                map.put("token", UUID.randomUUID().toString());
            } else {
                map.put("token", token);
            }
        }
        if ("injvm".equals(protocolConfig.getName())) {
            protocolConfig.setRegister(false);
            map.put("notify", "false");
        }
        // 导出服务
        String contextPath = protocolConfig.getContextpath();
        if ((contextPath == null || contextPath.length() == 0) && provider != null) {
            contextPath = provider.getContextpath();
        }
        // 注意这里的URL是com.alibaba.dubbo.common.URL 对象,最后会被处理成一个类似这样的格式,以dubbo协议为例
        //dubbo://ip:port/接口名?其他信息
        URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);

        if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                .hasExtension(url.getProtocol())) {
            url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                    .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
        }

        String scope = url.getParameter(Constants.SCOPE_KEY);
        //配置为none不暴露
        if (! Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {

            //配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)
            if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
                exportLocal(url);
            }
            //如果配置不是local则暴露为远程服务.(配置为local,则表示只暴露远程服务)
            if (! Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope) ){
                if (logger.isInfoEnabled()) {
                    logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
                }
                if (registryURLs != null && registryURLs.size() > 0
                        && url.getParameter("register", true)) {
                    for (URL registryURL : registryURLs) {//遍历注册中心

                        url = url.addParameterIfAbsent("dynamic", registryURL.getParameter("dynamic"));
                        URL monitorUrl = loadMonitor(registryURL);
                        if (monitorUrl != null) {
                            url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
                        }
                        if (logger.isInfoEnabled()) {
                            logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
                        }
                        //ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。
                        Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                        //Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。
                        Exporter<?> exporter = protocol.export(invoker);
                        exporters.add(exporter);
                    }
                } else {
                    Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);

                    Exporter<?> exporter = protocol.export(invoker);
                    exporters.add(exporter);
                }
            }
        }
        this.urls.add(url);
    }

下一篇集中处理如下代码流程,这一篇只是初步了解了dubbo 服务暴露预处理的一些逻辑,
至于为什么dubbo会选择生成 registry:// 和 dubbo:// 如下两种链接。以后篇幅讨论.
后续将继续跟踪以下代码片段的实现。

 //ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。
                        Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                        //Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。
                        Exporter<?> exporter = protocol.export(invoker);
                        exporters.add(exporter);
Dubbo的介绍以及Dubbox的区别 Dubbo官网:  http://dubbo.io/ Dubbox官网: https://github.com/dangdangdotcom/dubbox Dubbo 是阿里巴巴公司开源的一个基于Java的高性能开源RPC框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。后来因为某些原因没有维护,于是当当网在这之上推出了自己的Dubbox。 D... 阅读详情

相关推荐

Dubbo——各协议暴露和引用服务的逻辑

各协议暴露和引用服务的逻辑    目前Dubbox版本支持的协议有dubbo、injvm、rmi、hessian、thrift、memcached、redis、rest等九种,其中memcached和redis协议只支持服务引用不支持服务暴露;这些协议有的继承AbstractProxyProtocol类,有的实现了AbstractProtocol接口。服务暴露调用export方法,引用服务调用re...

meilong_whpu的专栏 5541

Dubbo和Zookeeper入门到实战,看这篇就够了

前沿:在当下流行的分布式架构中Dubbo是非常流行rpc框架,借着这几天有空学习学习,并在后面的项目中进行实战,为后面的分布式项目做铺垫。Dubbox简介Dubbox 是一个分布式rp...

weixin_44742132的博客 775

VECTOR硬件VN1600系列对比:VN1610、VN1611、VN1630A、VN1640A、VN1630log、VN1670

VN16系列说不清道不明的区别和关系

AmorRun的博客 2万+

Dubbox是什么,如何整合SpringBoot,有什么优势?

Dubbox是什么,如何整合SpringBoot,有什么优势?

杨荧的优快云博客 1410

AI绘画与医疗可视化:用AI生成医学插图的实践

医疗可视化是医学教育、临床沟通和学术研究的核心工具。传统医学插图依赖手工绘制或专业3D建模,存在制作周期长、成本高、更新迭代慢等问题。随着深度学习技术的发展,AI绘画工具(如Stable Diffusion、DALL-E)展现出强大的图像生成能力,但医疗领域对插图的解剖准确性、标注规范性和语义完整性有极高要求,通用AI模型难以直接应用。本文聚焦AI技术与医疗领域的交叉创新,系统阐述如何通过数据预处理、模型定制化训练和后处理校验,构建符合医疗标准的插图生成系统。

大模型应用工坊 1788

inno setup自定义卸载程序和美化

也就是DisplayName,因为我们在第一步的时候,将卸载程序名称也写入了注册表,所以,我们直接从注册表读DisplayName字段即可。1.要实现inno setup自定义卸载程序,首先需要关闭自带的卸载程序。在[Setup]的字段关闭卸载程序步骤和页面。2.删除应用程序目录里能够删除的并且返回进度。3.自定义卸载程序相关的注册表信息。4.删除启动菜单栏和guid注册表。2.自定义快捷方式和程序菜单。

cs821984831的博客 2348

Dubbox——基本认识

1. 简介 Dubbo就是资源调度和治理中心的管理工具。 是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点 Dubbo 就是类似于webservice的关于系统...

武汉小喽啰 471

基于Python的雪球网投资组合数据爬取与分析实战:从入门到精通

在当今数字化投资时代,数据已成为投资者最重要的资产之一。雪球网作为中国领先的投资社交平台,汇聚了大量优质的投资组合数据,这些数据对于量化投资研究和个人投资决策具有重要价值。本文将详细介绍如何使用Python最新技术栈构建一个高效、稳定的雪球网投资组合爬虫,并深入分析获取的数据。投资组合持仓明细及变动历史投资收益率曲线与风险指标投资者操作策略与调仓频率热门行业与个股关注度。

2201_76125261的博客 920

Dubbo 和 Dubbox 之间的区别

Dubbo 最早由阿里巴巴在 2011 年开源,是一个用于微服务架构的分布式服务框架。Dubbo 提供了高效的远程服务调用、服务注册与发现、负载均衡、服务容错等功能,帮助开发者构建和管理分布式系统。然而,在 2014 年左右,阿里巴巴停止了对 Dubbo 的维护。这段时间内,尽管 Dubbo 仍然在许多企业中广泛使用,但由于缺乏官方更新和维护,社区对 Dubbo 的发展感到担忧。Dubbo 和 Dubbox 都是强大的分布式服务框架,各自有其独特的功能和应用场景。

Flying_Fish_roe的博客 1075

18、知识表示与学习范式

本文探讨了智能系统中的核心组成部分——知识表示与学习范式。从基础知识到实际应用,详细解析了符号表示、框架表示、语义网络和本体表示等知识表示方法,并介绍了监督学习、无监督学习、半监督学习和强化学习等学习范式。此外,还深入分析了这些技术在自然语言处理、图像识别和推荐系统等领域的具体应用及操作步骤。最后,展望了未来可能的技术发展方向。

ttt77的博客 84

HINT: High-quality INpainting Transformer with Mask-Aware Encoding and Enhanced Attention 训练自己的数据集

HINT(高质量图像修复变换器)通过创新的掩码感知像素洗牌下采样模块(MPD)和空间激活通道注意力层(SCAL),显著提高了图像修复的质量,尤其在大面积缺失区域的情况下。实验表明,HINT在CelebA、CelebA-HQ、Places2和敦煌数据集上超越了现有的最先进模型,提升了图像的细节和结构一致性。

LJ1147517021的博客 312

Dubbo详细介绍与安装使用过程

1 Dubbo介绍1.1 dubbox简介随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。 单一应用架构 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。 垂直应用架构 当访问量逐渐增大,单一应用

徐刘根的博客 19万+

AgentScope实战训练营:构建计划可视化管理和HITL的AI智能计划助手

本文基于AgentScope Java SDK和Spring Boot WebFlux,从零构建一个支持SSE流式对话、计划可视化管理和HITL的AI智能计划助手Web应用PlanNotebook。涵盖项目架构设计、ReActAgent初始化、自定义工具注册、Hook机制实现、SSE事件协议定义、前端流式渲染等核心技术点,提供完整可运行的代码示例和详细的REST API参考。

program哲学 399

Dubbo/Dubbox的dubbo协议实现(一)-服务端启动

之前已经分析的dubbo的服务的发现和注册,这里先看一下dubbo协议是如何实现的,之前已经知道了,调用DubboProtocol类的export来暴露服务的,协议实现比较复杂,这里只关系主体实现即排除一些特性功能的处理代码本章主要处理服务端对应的暴露流程,继续回到···com.alibaba.dubbo.config.ServiceConfig···的doExportUrlsFor1Protoco

weiythi的Blog 2322

《电磁兼容设计》专栏说明

本专栏自2024年1月起开始更新,仅设此一个电磁兼容相关知识专栏,并将一直持续更新下去,无期限

linkking27的博客 791

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Dubbo/Dubbox的服务暴露(三)- 服务的注册

接上《 Dubbo/Dubbox的服务暴露(二)-扩展点机制》上文书依旧疑留的疑问,这两句到底在干啥Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()))

weiythi的Blog 525

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Dubbo 延迟服务暴露

前言 大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo 延迟服务暴露。在前一个章节中我们介绍了 Dubbo Stub 和 Mock,我们例举了常见的使用场景并且进行了源码解析来分析其实现原理,同时我们知道 Dubbo Stub 和 Mock 都是基于对调用代理对象的包装实现的,这样可以为我们在调用服务时做一些前置或后置处理工作。有的小伙伴可能会遇到这样的场景:在我们的应用服务中有很多的本地缓存或者分布式缓存,这些缓存有可能需要加载一段时间那么在这个缓存加载过程中我们希望接口不要对外提供服务,那

liyong1028826685的专栏 875

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Dubbo vs Dubbox:深度解析面试必看!

Dubbo 是阿里巴巴开源的高性能 Java RPC 框架,专注于服务发现与调用,支持多种协议及扩展机制;而 Dubbox 则是基于 Dubbo 的封装版本,主要面向 Spring 用户,提供了更便捷的 Web 服务开发能力。两者核心区别在于功能定位和扩展性:Dubbo 更底层、灵活,适合复杂场景;Dubbox 则封装了更多特性,简化开发但灵活性稍逊。同...

蓝鲸鱼计算机软件开发工作室 435

Dubbo/Dubbox的服务暴露(二)-扩展点机制

接上《 Dubbo/Dubbox的服务暴露(一)》上文书留的疑问,这两句到底在干啥 Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.t

weiythi的Blog 688

Dubbox简介与入门实战

前言 什么是Dubbox?Dubbox是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo,被国内电商及互联网项目中使用,后期阿里巴巴停止了Dubbo项目的维护(现Dubbo已捐献给Apache基金会),因为阿里巴巴内部的HSF框架比Dubbo更高效,更贴合他们业务。当当网便在Dubbo基础上进行优化,并继续进行维护,为了与原有的Dubbo区别,故将其命名为Dubbox。 Dubbox作用 d...

Wim的博客 7743

dubbo服务搭建教程

本文在dubbo的基础上提供rest服务

z_xiaocun的博客 2192

Dubbox框架简介

Dubbox框架简介 Dubbox是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继续维护,为了与原有的Dubbo区分,故将其命名为Dubbox。 Dubbox致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbox就是个服务框架,如果没有分布式需求...

Django的博客 7909

dubbo源码分析--预热warmup过程

阿飞Javaer,转载请注明原创出处,谢谢! 前言 今天群里小伙伴黄晓峰VIVO咨询一个问题:”dubbo接口怎么做预热呢,每次上线,都会有一小部分超时?”,熟悉JVM都知道,JVM重启后有一段预热过程,要运行一段时间,它的性能才能达到最佳状态;阿里JVM团队就针对这个缺陷进行了优化,其特性名曰:jwarmup,可以点击Alibaba JVM创新提效 获国际社区认可登台JVM圈顶会...

阿飞Javaer的专栏 4269

Dubbo和Dubbox

        Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继续维护,为了与原有的Dubbo区分,故将其命名为Dubbox。是个服务调用的东东,说白了就是个远程服务调用的分布式框架。                                    节点角色说明: ...

antushengV的博客 452

浅谈Dubbox原理

Dubbox介绍 Dubbox是一个分布式服务框架,前身是阿里旗下的开源项目Dubbo,后来阿里停止维护,当当网在Dubbo的基础上进行优化,并继续维护,为了与原来的Dubbo区分故将其改名为Dubbox,当当网在其原有的基础上实现了一些新功能REST(Representational State Transfer)风格,REST调用也是的Dubbox可以对当今特别流行的&quot;微服务&quot;架构提供支持...

迷途的博客 3218
上一篇: Java spi机制浅谈
下一篇: Dubbo/Dubbox的服务暴露(二)-扩展点机制
weiythi
博客等级 码龄16年 23粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值