dubbo的服务调用原理

article/2025/11/7 19:25:31

一、前言

在我们使用dubbo进行远程服务消费时,可以通过@Reference注解或dubbo:reference来配置引用的接口,最终会生成远程服务的代理类,转化成ReferenceBean,这样我们就可以像调用本地接口方法一样使用远程服务提供的功能;

二、实现服务调用的类;

ReferenceBean

public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {@Overridepublic Object getObject() throws Exception {return get();}public synchronized T get() {if (destroyed) {throw new IllegalStateException("Already destroyed!");}if (ref == null) {//此方法是ReferenceConfig的init();init();}return ref;}

获取被Reference标识的类的代理对象,从getObject开始,之后进入init()进行初始化

PS:如果第一次debug时,发现ref不为空,进入不了init()方法,可以参考:ref==null

ReferenceConfig

 private void init() {//判断是否已经初始化,因为是第一次执行,所以是falseif (initialized) {return;}initialized = true;if (interfaceName == null || interfaceName.length() == 0) {throw new IllegalStateException("<dubbo:reference interface=\"\" /> interface not allow null!");}// get consumer's global configurationcheckDefault();appendProperties(this);if (getGeneric() == null && getConsumer() != null) {setGeneric(getConsumer().getGeneric());}if (ProtocolUtils.isGeneric(getGeneric())) {interfaceClass = GenericService.class;} else {try {//加载接口的class文件interfaceClass = Class.forName(interfaceName, true, Thread.currentThread().getContextClassLoader());} catch (ClassNotFoundException e) {throw new IllegalStateException(e.getMessage(), e);}checkInterfaceAndMethods(interfaceClass, methods);}//......省略了很多检测配置文件的方法(不是此方法的重点,所以不分析)Map<String, String> map = new HashMap<String, String>();//map存放配置属性,可见下图Map<Object, Object> attributes = new HashMap<Object, Object>();map.put(Constants.SIDE_KEY, Constants.CONSUMER_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()));}if (!isGeneric()) {String revision = Version.getVersion(interfaceClass, version);if (revision != null && revision.length() > 0) {map.put("revision", revision);}//获取interfaceClass的方法名;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 {map.put("methods", StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));}}map.put(Constants.INTERFACE_KEY, interfaceName);//把相关配置属性加入 AbstractConfig中;appendParameters(map, application);appendParameters(map, module);appendParameters(map, consumer, Constants.DEFAULT_KEY);appendParameters(map, this);String prefix = StringUtils.getServiceKey(map);if (methods != null && !methods.isEmpty()) {for (MethodConfig method : methods) {appendParameters(map, method, method.getName());String retryKey = method.getName() + ".retry";if (map.containsKey(retryKey)) {String retryValue = map.remove(retryKey);if ("false".equals(retryValue)) {map.put(method.getName() + ".retries", "0");}}appendAttributes(attributes, method, prefix + "." + method.getName());checkAndConvertImplicitConfig(method, map, attributes);}}String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);if (hostToRegistry == null || hostToRegistry.length() == 0) {//从本地加载registry的ip;hostToRegistry = NetUtils.getLocalHost();} else if (isInvalidLocalHost(hostToRegistry)) {throw new IllegalArgumentException("Specified invalid registry ip from property:" + Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);}map.put(Constants.REGISTER_IP_KEY, hostToRegistry);//attributes are stored by system context.StaticContext.getSystemContext().putAll(attributes);//创建代理对象ref = createProxy(map);//把代理对象,接口名和方法再进一步封装;ConsumerModel consumerModel = new ConsumerModel(getUniqueServiceName(), this, ref, interfaceClass.getMethods());//交由应用程序管理;ApplicationModel.initConsumerModel(getUniqueServiceName(), consumerModel);}private T createProxy(Map<String, String> map) {URL tmpUrl = new URL("temp", "localhost", 0, map);final boolean isJvmRefer;if (isInjvm() == null) {if (url != null && url.length() > 0) { // if a url is specified, don't do local referenceisJvmRefer = false;} else if //查看是否存在本地服务;(InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {// by default, reference local service if there isisJvmRefer = true;} else {isJvmRefer = false;}} else {isJvmRefer = isInjvm().booleanValue();}//判断是否为Jvm本地引用;if (isJvmRefer) {URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);invoker = refprotocol.refer(interfaceClass, url);if (logger.isInfoEnabled()) {logger.info("Using injvm service " + interfaceClass.getName());}} else {if (url != null && url.length() > 0) { // user specified URL, could be peer-to-peer address, or register center's address.String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);if (us != null && us.length > 0) {for (String u : us) {URL url = URL.valueOf(u);if (url.getPath() == null || url.getPath().length() == 0) {url = url.setPath(interfaceName);}if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));} else {urls.add(ClusterUtils.mergeUrl(url, map));}}}//由于我使用了注册中心调用远程服务,直接跳到这一步;// assemble URL from register center's configuration} else { // AbstractInterfaceConfig的loadRegistries(false);//registry的相关属性和使用的协议封装成URL;List<URL> us = loadRegistries(false);if (us != null && !us.isEmpty()) {for (URL u : us) {// AbstractInterfaceConfig的loadMonitor();URL monitorUrl = loadMonitor(u);if (monitorUrl != null) {map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));}urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));}}if (urls == null || urls.isEmpty()) {throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");}}//只有一条注册中心数据,即单注册中心;        if (urls.size() == 1) {//此方法是RegistryProtocol的refer方法;//通过注册中心获取服务的代理对象;即将远程服务转为Invoker;invoker = refprotocol.refer(interfaceClass, urls.get(0));} else {//如果是多注册中心,就会存在多个Invoker,保存在List中;List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();URL registryURL = null;for (URL url : urls) {//遍历urls,构建invokerinvokers.add(refprotocol.refer(interfaceClass, url));if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {//会覆盖前遍历的注册中心,使用最后一条注册中心数据registryURL = url; // use last registry url}}if (registryURL != null) { // registry url is available// use AvailableCluster only when register's cluster is availableURL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);//StaticDirectory包装invoker,再通过cluster进行合并,并暴露其中一个invokerinvoker = cluster.join(new StaticDirectory(u, invokers));} else { // not a registry urlinvoker = cluster.join(new StaticDirectory(invokers));}}}Boolean c = check;if (c == null && consumer != null) {c = consumer.isCheck();}if (c == null) {c = true; // default true}if (c && !invoker.isAvailable()) {throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());}if (logger.isInfoEnabled()) {logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());}// create service proxy//根据SPI机制,实际调用的是JavassistProxyFactory.getProxy//利用动态代理,将Invoker转换成本地接口代理;return (T) proxyFactory.getProxy(invoker);}

map
在这里插入图片描述

RegistryProtocol

public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {url = url.setProtocol(url.getParameter(Constants.REGISTRY_KEY, Constants.DEFAULT_REGISTRY)).removeParameter(Constants.REGISTRY_KEY);//连接到registry,获取registry实例;Registry registry = registryFactory.getRegistry(url);if (RegistryService.class.equals(type)) {return proxyFactory.getInvoker((T) registry, type, url);}// group="a,b" or group="*"//获取服务消费元数据Map<String, String> qs = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY));     //从服务消费元数据获取分组信息String group = qs.get(Constants.GROUP_KEY);if (group != null && group.length() > 0) {if ((Constants.COMMA_SPLIT_PATTERN.split(group)).length > 1|| "*".equals(group)) {//执行Invoker转换工作return doRefer(getMergeableCluster(), registry, type, url);}}//执行Invoker转换工作return doRefer(cluster, registry, type, url);}private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {//RegistryDirectory服务发现,负责Invoker生成,配置信息变更监听等操作RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);//设置注册中心directory.setRegistry(registry);//设置协议directory.setProtocol(protocol);// all attributes of REFER_KEY//获取服务消费者的配置属性Map<String, String> parameters = new HashMap<String, String>(directory.getUrl().getParameters());//构建消费者的URLURL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, parameters.remove(Constants.REGISTER_IP_KEY), 0, type.getName(), parameters);if (!Constants.ANY_VALUE.equals(url.getServiceInterface())&& url.getParameter(Constants.REGISTER_KEY, true)) {//向注册中心注册服务消费者,在consumers目录下创建新节点registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,Constants.CHECK_KEY, String.valueOf(false)));}//再订阅注册中心的providers目录,之后触发DubboProtocol的refer方法//服务消费者订阅:服务提供端,动态配置,路由规则directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,Constants.PROVIDERS_CATEGORY+ "," + Constants.CONFIGURATORS_CATEGORY+ "," + Constants.ROUTERS_CATEGORY));// 对directory 进行包装,加上mock、failover功能//实际调用的是MockClusterWrapper的join;  Invoker invoker = cluster.join(directory);//对invoker、directory信息简单聚合,存入本地mapProviderConsumerRegTable.registerConsumer(invoker, url, subscribeUrl, directory);return invoker;}

RegistryDirectory

   public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener {@Overridepublic synchronized void notify(List<URL> urls) {List<URL> invokerUrls = new ArrayList<URL>();List<URL> routerUrls = new ArrayList<URL>();List<URL> configuratorUrls = new ArrayList<URL>();for (URL url : urls) {String protocol = url.getProtocol();String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);if (Constants.ROUTERS_CATEGORY.equals(category)|| Constants.ROUTE_PROTOCOL.equals(protocol)) {routerUrls.add(url);} else if (Constants.CONFIGURATORS_CATEGORY.equals(category)|| Constants.OVERRIDE_PROTOCOL.equals(protocol)) {configuratorUrls.add(url);} else if (Constants.PROVIDERS_CATEGORY.equals(category)) {invokerUrls.add(url);} else {logger.warn("Unsupported category " + category + " in notified url: " + url + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost());}}// configurators//更新服务端提供方配置if (configuratorUrls != null && !configuratorUrls.isEmpty()) {this.configurators = toConfigurators(configuratorUrls);}// routers//更新路由配置if (routerUrls != null && !routerUrls.isEmpty()) {List<Router> routers = toRouters(routerUrls);if (routers != null) { // null - do nothingsetRouters(routers);}}//加载服务提供方的服务信息List<Configurator> localConfigurators = this.configurators; // local reference// merge override parametersthis.overrideDirectoryUrl = directoryUrl;if (localConfigurators != null && !localConfigurators.isEmpty()) {for (Configurator configurator : localConfigurators) {this.overrideDirectoryUrl = configurator.configure(overrideDirectoryUrl);}}// providers//重新加载Invoker实例refreshInvoker(invokerUrls);}private void refreshInvoker(List<URL> invokerUrls) {if (invokerUrls != null && invokerUrls.size() == 1 && invokerUrls.get(0) != null&& Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(0).getProtocol())) {this.forbidden = true; // Forbid to accessthis.methodInvokerMap = null; // Set the method invoker map to nulldestroyAllInvokers(); // Close all invokers} else {this.forbidden = false; // Allow to accessMap<String, Invoker<T>> oldUrlInvokerMap = this.urlInvokerMap; // local referenceif (invokerUrls.isEmpty() && this.cachedInvokerUrls != null) {invokerUrls.addAll(this.cachedInvokerUrls);} else {this.cachedInvokerUrls = new HashSet<URL>();this.cachedInvokerUrls.addAll(invokerUrls);//Cached invoker urls, convenient for comparison}if (invokerUrls.isEmpty()) {return;}//加载新的Invoker MapMap<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);// Translate url list to Invoker mapMap<String, List<Invoker<T>>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap); // Change method name to map Invoker Map// state change// If the calculation is wrong, it is not processed.if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) {logger.error(new IllegalStateException("urls to invokers error .invokerUrls.size :" + invokerUrls.size() + ", invoker.size :0. urls :" + invokerUrls.toString()));return;}this.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;this.urlInvokerMap = newUrlInvokerMap;try {destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap); // Close the unused Invoker} catch (Exception e) {logger.warn("destroyUnusedInvokers error. ", e);}private Map<String, Invoker<T>> toInvokers(List<URL> urls) {Map<String, Invoker<T>> newUrlInvokerMap = new HashMap<String, Invoker<T>>();if (urls == null || urls.isEmpty()) {return newUrlInvokerMap;}Set<String> keys = new HashSet<String>();String queryProtocols = this.queryMap.get(Constants.PROTOCOL_KEY);for (URL providerUrl : urls) {// If protocol is configured at the reference side, only the matching protocol is selectedif (queryProtocols != null && queryProtocols.length() > 0) {boolean accept = false;String[] acceptProtocols = queryProtocols.split(",");for (String acceptProtocol : acceptProtocols) {if (providerUrl.getProtocol().equals(acceptProtocol)) {accept = true;break;}}if (!accept) {continue;}}if (Constants.EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {continue;}if (!ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {logger.error(new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() + " in notified url: " + providerUrl + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost()+ ", supported protocol: " + ExtensionLoader.getExtensionLoader(Protocol.class).getSupportedExtensions()));continue;}// 合并服务提供端配置数据URL url = mergeUrl(providerUrl);//过滤重复的服务提供端配置数据String key = url.toFullString(); // The parameter urls are sortedif (keys.contains(key)) { // Repeated urlcontinue;}keys.add(key);// Cache key is url that does not merge with consumer side parameters, regardless of how the consumer combines parameters, if the server url changes, then refer again// 缓存键是不与使用者端参数合并的url,无论使用者如何合并参数,如果服务器url更改,则再次引用Map<String, Invoker<T>> localUrlInvokerMap = this.urlInvokerMap; // local referenceInvoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(key);// 缓存无对应 invoker,再次调用 protocol#refer 是否有数据if (invoker == null) { // Not in the cache, refer againtry {boolean enabled = true;if (url.hasParameter(Constants.DISABLED_KEY)) {enabled = !url.getParameter(Constants.DISABLED_KEY, false);} else {enabled = url.getParameter(Constants.ENABLED_KEY, true);}if (enabled) {invoker = new InvokerDelegate<T>(protocol.refer(serviceType, url), url, providerUrl);}} catch (Throwable t) {logger.error("Failed to refer invoker for interface:" + serviceType + ",url:(" + url + ")" + t.getMessage(), t);}// 将新的 Invoker 缓存起来if (invoker != null) { // Put new invoker in cachenewUrlInvokerMap.put(key, invoker);}} else {// 缓存里有数据,则进行重新覆盖newUrlInvokerMap.put(key, invoker);}}keys.clear();return newUrlInvokerMap;  

总结:RegistryDirectory 这个类实现了 NotifyListener 这个通知监听接口,当订阅的服务,配置或路由发生变化时,会接收到通知,进行相应改变:

DubboProtocol
```java@Overridepublic <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {optimizeSerialization(url);// create rpc invoker.//通过getClient获取客户端实例,实例是ExchangeClient,底层依赖Netty通信,连接默认为共享连接;DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);invokers.add(invoker);return invoker;}

JavassistProxyFactory

 @Override@SuppressWarnings("unchecked")public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {//根据接口类生成代理对象,执行具体方法会通过InvokerInvocationHandler的invoke方法调用;return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));}

三、总结

1、Dubbo 服务引用的时机有两个,第一个是在 Spring 容器调用 ReferenceBean 的 afterPropertiesSet 方法时引用服务,第二个是在 ReferenceBean 对应的服务被注入到其他类中时引用,而入口都是getObject方法;
2、ReferenceBean的getObject()调用ReferenceConfig的init方法,实现初始化 ,init方法会检查配置,并把相关属性的组装成map,调用createProxy(map);
3、ReferenceConfig的createProxy方法,会先判断服务引入的方式,如果是本地引入,则构建injvm协议的URL,如果是通过注册中心引入,则根据协议构建URL;确定服务引入的方式后,再判断URL的size,如果只有一个URL,则直接根据协议引入生成invoker,如果有多个则遍历生成invoker并构建StaticDirectory,再由cluster封装成invoker,再调用refer方法;
4、RegistryProtocol的refer方法,先连接到registry,再通过doRefer方法,构建RegistryDirectory,向注册中心注册自己;
5、执行 directory.subscribe方法,为消息消费者添加category=providers,configurators,routers属性后,然后向注册中心订阅该URL,关注该服务下的providers,configurators,routers发生变化时通知RegistryDirectory,以便及时发现服务提供者、配置、路由规则的变化,之后触发DubboProtocol的refer方法;
6、DubboProtocol的refer中,最主要的是getClient方法,获取客户端实例,跟远程服务进行网络调用,底层依赖Netty进行网络通信;
7、对directory 进行包装,加上mock、failover功能;
8、最后通过JavassistProxyFactory的getProxy,生成代理对象,执行具体方法通过InvokerInvocationHandler的invoke方法调用;


http://chatgpt.dhexx.cn/article/crGe6qdR.shtml

相关文章

18. Dubbo原理解析-服务调用

服务消费方发起请求 当服务的消费方引用了某远程服务&#xff0c;服务的应用方在spring的配置实例如下&#xff1a; <dubbo:referenceid"demoService"interface"com.alibaba.dubbo.demo.DemoServ ice" /> demoService实例其实是代理工厂生产的代理…

Dubbo 原理和机制详解

Dubbo 是一款Java RPC框架&#xff0c;致力于提供高性能的 RPC 远程服务调用方案。作为主流的微服务框架之一&#xff0c;Dubbo 为开发人员带来了非常多的便利。 1. Dubbo核心功能 Dubbo主要提供了3大核心功能&#xff1a;面向接口的远程方法调用&#xff0c;智能容错和负载均…

从源码全面解析 dubbo 服务端服务调用的来龙去脉

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

Dubbo原理和面试问题

今天来说一说dubbo的原理&#xff0c;首先我们要知道dubbo到底是什么&#xff0c;都能提供些什么服务&#xff1f; 一、dubbo是什么&#xff1f; dubbo是⼀个分布式服务框架&#xff0c;提供⾼性能和透明化的RPC远程服务调⽤⽅案&#xff0c;以及SOA服务治理方案。说白了其实…

springboot启动dubbo客户端连接服务端过程

前言 如果我问你,dubbo客户端启动的时候是如何连接服务器端的&#xff1f;这个过程比较复杂&#xff0c;今天我们一起学习起来~ 本文分以下几个部分 1、springboot启动dubbo需要配置 2、初始化Reference过程 3、小结 一、项目应用 1、引入jar包 <dependency><g…

dubbo实现原理机制

Dubbo的总体架构如图所示&#xff1a; 框架分层架构中&#xff0c;各个层次的设计要点&#xff1a; 服务接口层&#xff08;Service&#xff09;&#xff1a;该层是与实际业务逻辑相关的&#xff0c;根据服务提供方和服务消费方的业务设计对应的接口和实现。 配置层&#xff0…

Dubbo源码分析(三):Dubbo之服务端(Service)

如上图所示的Dubbo的暴露服务的过程&#xff0c;不难看出它也和消费者端很像&#xff0c;也需要一个像reference的对象来维护service关联的所有对象及其属性&#xff0c;这里的reference就是provider。由于ServiceBean实现了 &#xfeff;&#xfeff; InitializingBean接口&am…

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo

文章目录&#xff1a; 1.RPC & 软件架构 1.1 单一应用架构 1.2 分布式微服务架构 1.3 RPC 2.Dubbo概述 2.1基本架构 2.2 dubbo支持的协议 3.直连方式实现dubbo 3.1 服务提供者的创建 3.2 服务消费者的创建 3.3 启动测试&#xff01;&#xff01;&#xff01; 1.…

分布式基本理解与Dubbo基本概念

学习dubbo之前&#xff0c;先要了解一下什么是分布式 分布式基础理论 什么是分布式系统 分布式系统是若干独立计算机的集合&#xff0c;这些计算机对于用户来说就像单个相关系统。 随着互联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的垂直应用架构已无法…

Dubbo的原理和机制

Dubbo :是一个RPC框架&#xff0c;SOA框架&#xff1a; Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c;适合于小数据量大并发的服务调用&#xff0c;以及服务消费者机器数远大于服务提供者机器数的情况。 作为RPC&#xff1a;支持各种传输协议&#xff0c;如dubbo,hes…

dubbo实现原理介绍

一、什么是dubbo Dubbo是Alibaba开源的分布式服务框架&#xff0c;它最大的特点是按照分层的方式来架构&#xff0c;使用这种方式可以使各个层之间解耦合&#xff08;或者最大限度地松耦合&#xff09;。从服务模型的角度来看&#xff0c; Dubbo采用的是一种非常简单的模型…

Dubbo-聊聊Dubbo协议

前言 Dubbo源码阅读分享系列文章&#xff0c;欢迎大家关注点赞 SPI实现部分 Dubbo-SPI机制 Dubbo-Adaptive实现原理 Dubbo-Activate实现原理 Dubbo SPI-Wrapper 注册中心 Dubbo-聊聊注册中心的设计 Dubbo-时间轮设计 通信 Dubbo-聊聊通信模块设计 什么是协议 在网…

dubbo客户端的实现

业界微服务大行其道。服务与服务之间的同学主要有有以下两大类。 阿里RPC框架&#xff1a;dubboRestFull风格的Http调用 我们知道Http接口我们找到PostMan这种Http客户端。 但是dubbo似乎并没有想关的客户端&#xff0c;我们调试的时常常需要同时打开两个以上的服务。 dubbo是…

dubbo组成原理-http服务消费端如何调用

dubbo协议已经用的很多了&#xff0c;这里来稍微介绍一下http协议&#xff0c;官方对http协议的说明简直少的让人发指。哈哈 百度大部分都只是讲了http服务端的配置 那就先从服务端的配置说起 dubbo需要的jar包这里就不说明了&#xff0c;网上找些maven的pom就可以 web.xml…

Dubbo基本原理机制

分布式服务框架&#xff1a; –高性能和透明化的RPC远程服务调用方案–SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架&#xff0c;基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c;适合于小数据量大并发的服务调用&#xff0c;以及服务消费…

Dubbo基本原理与机制

1、什么是Dubbo Dubbo 是一款高性能、轻量级的开源 RPC 框架&#xff0c;提供服务自动注册、自动发现等高效服务治理方案&#xff0c; 可以和 Spring 框架无缝集成。 2、Dubbo依赖关系 1、服务消费者&#xff08;Consumer&#xff09;: 调用远程服务的服务消费方&#xff0c…

dubbo原理和机制

Dubbo 框架是用来处理分布式系统中&#xff0c;服务发现与注册以及调用问题的&#xff0c;并且管理调用过程。 一&#xff0c;工作流程&#xff1a; 服务提供者在启动的时候&#xff0c;会通过读取一些配置将服务实例化。Proxy 封装服务调用接口&#xff0c;方便调用者调用。…

Dubbo的原理与机制

​ Dubbo 前言 在介绍Dubbo之前先了解一下基本概念&#xff1a; Dubbo是一个RPC框架&#xff0c;RPC&#xff0c;即Remote Procedure Call&#xff08;远程过程调用&#xff09;&#xff0c;相对的就是本地过程调用&#xff0c;在分布式架构之前的单体应用架构和垂直应用架…

Dubbo基础及原理机制

1. 什么是Dubbo&#xff1f; Dubbo是 阿里巴巴公司开源的一个高性能RPC 分布式服务框架&#xff0c;使得应用可通过高性能的 RPC 实现服务的输出和输入功能&#xff0c;可以和 Spring框架无缝集成&#xff0c;现已成为 Apache 基金会孵化项目。 2. 为什么要用Dubbo&#xff1…

Dubbo原理和机制详解(非常全面)

Dubbo是一款Java RPC框架&#xff0c;致力于提供高性能的RPC远程服务调用方案。Dubbo 作为主流的微服务框架之一&#xff0c;为开发人员带来了非常多的便利。 本文我们重点详解 Dubbo 的原理机制 mikechen 目录 Dubbo核心功能Dubbo核心组件Dubbo的架构设计Dubbo调用流程 1️…