国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Dubbo之消費(fèi)端服務(wù)RPC調(diào)用

這篇具有很好參考價值的文章主要介紹了Dubbo之消費(fèi)端服務(wù)RPC調(diào)用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

在消費(fèi)端服務(wù)是基于接口調(diào)用Provider端提供的服務(wù),所以在消費(fèi)端并沒有服務(wù)公共接口的實(shí)現(xiàn)類。

@RestController
@RequestMapping("/consumer")
public class CountryController {

    @DubboReference(version = "2.0",lazy = true)
    CountryService countryService;

    @GetMapping("/getCountry")
    public JSONObject getCountry() {
        JSONObject rtn = new JSONObject();
        rtn.put("msg",countryService.getCountry());
        return rtn;
    }
}
  1. 利用注解@DubboReference將目標(biāo)接口CountryService作為CountryController類的字段屬性,在解析類CountryController時獲取全部字段屬性并單獨(dú)關(guān)注解析存在注解@DubboReference的字段屬性。
  2. 通過步驟1得到服務(wù)公共接口類型,在生成RootBeanDefinition時設(shè)置其Class屬性為ReferenceBean,最終將服務(wù)公共接口CountryService注冊至IOC容器中。
  3. 通過JdkDynamicAopProxy對服務(wù)公共接口生成代理。

1.ReferenceAnnotationBeanPostProcessor

ReferenceAnnotationBeanPostProcessor后置處理器重置服務(wù)目標(biāo)接口CountryService在IOC注冊表class的屬性為ReferenceBean。

在Spring實(shí)例化 & 初始化?IOC容器中涉及所有bean時,觸發(fā)ReferenceBean的FactoryBean特性完成接口CountryServiceIOC容器中的bean管理。

public class ReferenceBean<T> implements FactoryBean<T>{
    @Override
    public T getObject() {
        if (lazyProxy == null) {
            // 對目標(biāo)類代理處理
            createLazyProxy();
        }
        return (T) lazyProxy;
    }

    private void createLazyProxy() {

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTargetSource(new DubboReferenceLazyInitTargetSource());
        proxyFactory.addInterface(interfaceClass);
        Class<?>[] internalInterfaces = AbstractProxyFactory.getInternalInterfaces();
        for (Class<?> anInterface : internalInterfaces) {
            proxyFactory.addInterface(anInterface);
        }
        if (!StringUtils.isEquals(interfaceClass.getName(), interfaceName)) {
            Class<?> serviceInterface = ClassUtils.forName(interfaceName, beanClassLoader);
            proxyFactory.addInterface(serviceInterface);
        }
        //jdk基于接口代理
        this.lazyProxy = proxyFactory.getProxy(this.beanClassLoader);
    }

    private Object getCallProxy() throws Exception {
        // 利用 ReferenceConfig 初始化 lazyTarget 屬性
        return referenceConfig.get();
    }

    private class DubboReferenceLazyInitTargetSource extends AbstractLazyCreationTargetSource {

        @Override
        protected Object createObject() throws Exception {
            return getCallProxy();
        }

        @Override
        public synchronized Class<?> getTargetClass() {
            return getInterfaceClass();
        }
    }
}

jdk動態(tài)代理技術(shù)生成目標(biāo)接口代理類過程中需要注意 DubboReferenceLazyInitTargetSourcelazyTarget屬性【屬性賦值時機(jī)、屬性使用時機(jī)】。

Dubbo中TargetSource之DubboReferenceLazyInitTargetSource可以控制屬性值lazyTarget初始化時機(jī),其實(shí)是通過抽象類AbstractLazyCreationTargetSource完成的。

1.1.服務(wù)公共接口CountryService代理過程

如下所示:接口CountryService的代理類在執(zhí)行代理方法過程中涉及利用TargetSource獲取lazyTarget屬性。

class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
	
	// 代理目標(biāo)類中的目標(biāo)方法
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;
		// 通過 ProxyFactory 獲取TargetSource之DubboReferenceLazyInitTargetSource
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		...

		Object retVal;
		// 此處就是獲取目標(biāo)接口CountryService的代理,其實(shí)就是lazyTarget屬性值
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

		if (chain.isEmpty()) {// 默認(rèn)情況下成立
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
		else {
			...
		}
		...
		return retVal;
	}
}

根據(jù)注解得知lazyTarget屬性賦值是懶加載方式得到的,即首次獲取lazyTarget對象時才真正觸發(fā)其完成賦值。但是實(shí)際情況是在創(chuàng)建目標(biāo)接口的代理類時就實(shí)現(xiàn)賦值操作【不知道為啥?】。?

public abstract class AbstractLazyCreationTargetSource implements TargetSource {
	/**
	 * Returns the lazy-initialized target object,
	 * creating it on-the-fly if it doesn't exist already.
	 * @see #createObject()
	 */
	@Override
	public synchronized Object getTarget() throws Exception {
		if (this.lazyTarget == null) {
			// 觸發(fā)CountryService的代理
			this.lazyTarget = createObject();
		}
		return this.lazyTarget;
	}
}

綜上所述:目標(biāo)接口代理類生成過程中還涉及l(fā)azyTarget屬性賦值。而且發(fā)現(xiàn)目標(biāo)接口代理類的類名、lazyTarget屬性名均為CountryServiceDubboProxy0。但是兩者區(qū)別是前者實(shí)例中持有的InvocationHandler類型為JdkDynamicAopProxy,后者持有的InvocationHandler類型為InvokerInvocationHandler。

1.2.ReferenceConfig

public class ReferenceConfig<T> extends ReferenceConfigBase<T> {

    private transient volatile T ref;

    @Override
    public T get() {
        if (ref == null) {
            getScopeModel().getDeployer().start();
            synchronized (this) {
                if (ref == null) {
                    init();
                }
            }
        }
        return ref;
    }
}

如上所示?ReferenceConfig 的核心字段?ref 最終指向類TargetSource中涉及的lazyTarget字段。

疑問:字段ref 賦值時機(jī):

  1. 可能是接口CountryService生成jdk代理類的過程。
  2. 可能是接口CountryService代理目標(biāo)方法執(zhí)行過程。
  3. 可能是監(jiān)聽器DubboDeployApplicationListener處理相關(guān)事件過程。

具體是哪個階段真正完成字段?ref 的賦值,尚未確定。


2.DubboDeployApplicationListener

該監(jiān)聽器的核心作用:字段?ref 的賦值流程。

public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> implements ModuleDeployer {

    private final ModuleConfigManager configManager;

    private final SimpleReferenceCache referenceCache;

    @Override
    public synchronized Future start() throws IllegalStateException {
        ...
        onModuleStarting();
        // initialize
        applicationDeployer.initialize();
        initialize();
        // export services
        exportServices();
        ...
        // refer services  這里面是核心功能
        referServices();
        ...
        return startFuture;
    } 

    private void referServices() {
        // 配置管理器中獲取 @DubboReference 注解引入的目標(biāo)接口配置信息
        configManager.getReferences().forEach(rc -> {
            ReferenceConfig<?> referenceConfig = (ReferenceConfig<?>) rc;
            ...
            referenceCache.get(rc);
        });
    }
}


public class SimpleReferenceCache implements ReferenceCache {

    public <T> T get(ReferenceConfigBase<T> rc) {
        String key = generator.generateKey(rc);
        Class<?> type = rc.getInterfaceClass();
        Object proxy = rc.get();// ReferenceConfig初始化字段ref
        ...
        return (T) proxy;
    }    
}

2.1.?Protocol協(xié)議之refer

接口Protocol的擴(kuò)展類如下圖所示:

public interface Protocol {
    // 服務(wù)提供者注冊目標(biāo)接口
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
    // 服務(wù)消費(fèi)端通過注解@DubboReference引進(jìn)目標(biāo)接口
    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
    default List<ProtocolServer> getServers() {
        return Collections.emptyList();
    }
}
public class ReferenceConfig<T> extends ReferenceConfigBase<T> {

    private Protocol protocolSPI;
    
    @Override
    public T get() {
        if (ref == null) {
            // ensure start module, compatible with old api usage
            getScopeModel().getDeployer().start();
            synchronized (this) {
                if (ref == null) {
                    init();
                }
            }
        }
        return ref;
    }

    protected synchronized void init() {
        ...
        ref = createProxy(referenceParameters);
        ...
    }

    private T createProxy(Map<String, String> referenceParameters) {
        ...
        createInvokerForRemote();
        ...
        // create service proxy
        return (T) proxyFactory.getProxy(invoker, ProtocolUtils.isGeneric(generic));
    }

    private void createInvokerForRemote() {
        // URL 協(xié)議類型為 registry
        URL curUrl = urls.get(0);
        invoker = protocolSPI.refer(interfaceClass, curUrl);
        if (!UrlUtils.isRegistry(curUrl)) {
            List<Invoker<?>> invokers = new ArrayList<>();
            invokers.add(invoker);
            invoker = Cluster.getCluster(scopeModel, Cluster.DEFAULT).join(new StaticDirectory(curUrl, invokers), true);
        }
    }
}

registry類型的url協(xié)議:代表注冊中心地址,即zk的IP & 端口號等相關(guān)注冊中心地址相關(guān)信息。

registry://zk-host:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-consumer&dubbo=2.0.2&pid=66082&qos.enable=false&register-mode=instance&registry=zookeeper&release=3.0.7&timestamp=1710075502746

?如圖所示接口Protocol擴(kuò)展類中真正初始化字段refer值的是RegistryProtocol#refer。

Dubbo之消費(fèi)端服務(wù)RPC調(diào)用,dubbo,rpc,java


2.1.1.RegistryProtocol

public class RegistryProtocol implements Protocol, ScopeModelAware {
    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        // 將registry協(xié)議替換為zookeeper協(xié)議
        url = getRegistryUrl(url);
        Registry registry = getRegistry(url);
        ...
        Cluster cluster = Cluster.getCluster(url.getScopeModel(), qs.get(CLUSTER_KEY));
        return doRefer(cluster, registry, type, url, qs);
    }

    protected <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url, Map<String, String> parameters) {
        ...
        // consumerUrl 即消費(fèi)端當(dāng)前的IP地址,該地址作用是:為provider服務(wù)提供響應(yīng)地址
        URL consumerUrl = new ServiceConfigURL (
            p,null,null,parameters.get(REGISTER_IP_KEY),0, getPath(parameters, type),parameters,consumerAttribute
        );
        url = url.putAttribute(CONSUMER_URL_KEY, consumerUrl);
        // migrationInvoker:MigrationInvoker
        ClusterInvoker<T> migrationInvoker = getMigrationInvoker(this, cluster, registry, type, url, consumerUrl);
        return interceptInvoker(migrationInvoker, url, consumerUrl);
    }

    protected <T> Invoker<T> interceptInvoker(ClusterInvoker<T> invoker, URL url, URL consumerUrl) {
        List<RegistryProtocolListener> listeners = findRegistryProtocolListeners(url);
        for (RegistryProtocolListener listener : listeners) {
            // 默認(rèn)情況下存在監(jiān)聽器之MigrationRuleListener
            listener.onRefer(this, invoker, consumerUrl, url);
        }
        return invoker;
    }
}

zookeeper協(xié)議:

zookeeper://zk-host:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-consumer&dubbo=2.0.2&pid=66082&qos.enable=false&register-mode=instance&release=3.0.7&timestamp=1710075502746

consumer協(xié)議:消費(fèi)端注冊服務(wù)時不需要指定端口,因?yàn)閜rovider端 & consumer端是通過tcp協(xié)議之Netty【端口:20880】完成兩端信息通信。

consumer://192.168.1.6/common.service.CountryService?application=dubbo-consumer&background=false&dubbo=2.0.2&interface=common.service.CountryService&lazy=true&methods=getCountry&pid=66082&qos.enable=false&register-mode=instance&register.ip=192.168.1.6&release=3.0.7&revision=2.0&side=consumer&sticky=false&timestamp=1710075502715&version=2.0

?文章來源地址http://www.zghlxwxcb.cn/news/detail-839011.html


3.ServiceDiscoveryRegistry

public class ServiceDiscoveryRegistry extends FailbackRegistry {

    private final AbstractServiceNameMapping serviceNameMapping;

    @Override
    public void doSubscribe(URL url, NotifyListener listener) {
        url = addRegistryClusterKey(url);
        serviceDiscovery.subscribe(url, listener);
        boolean check = url.getParameter(CHECK_KEY, false);
        String key = ServiceNameMapping.buildMappingKey(url);
        Lock mappingLock = serviceNameMapping.getMappingLock(key);
        mappingLock.lock();
        Set<String> subscribedServices = serviceNameMapping.getCachedMapping(url);
        MappingListener mappingListener = new DefaultMappingListener(url, subscribedServices, listener);
        subscribedServices = serviceNameMapping.getAndListen(this.getUrl(), url, mappingListener);
        mappingListeners.put(url.getProtocolServiceKey(), mappingListener);
        subscribeURLs(url, listener, subscribedServices);
    }

    protected void subscribeURLs(URL url, NotifyListener listener, Set<String> serviceNames) {
        // 
        serviceNames = toTreeSet(serviceNames);
        String serviceNamesKey = toStringKeys(serviceNames);
        String protocolServiceKey = url.getProtocolServiceKey();
        logger.info(String.format("Trying to subscribe from apps %s for service key %s, ", serviceNamesKey, protocolServiceKey));

        // register ServiceInstancesChangedListener
        Lock appSubscriptionLock = getAppSubscription(serviceNamesKey);
        try {
            appSubscriptionLock.lock();
            ServiceInstancesChangedListener serviceInstancesChangedListener = serviceListeners.get(serviceNamesKey);
            if (serviceInstancesChangedListener == null) {
                serviceInstancesChangedListener = serviceDiscovery.createListener(serviceNames);
                serviceInstancesChangedListener.setUrl(url);
                for (String serviceName : serviceNames) {//
                    // 獲取提供端服務(wù)的IP、端口號等信息
                    List<ServiceInstance> serviceInstances = serviceDiscovery.getInstances(serviceName);
                    if (CollectionUtils.isNotEmpty(serviceInstances)) {
                        serviceInstancesChangedListener.onEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
                    }
                }
                serviceListeners.put(serviceNamesKey, serviceInstancesChangedListener);
            }

            if (!serviceInstancesChangedListener.isDestroyed()) {
                serviceInstancesChangedListener.setUrl(url);
                listener.addServiceListener(serviceInstancesChangedListener);
                serviceInstancesChangedListener.addListenerAndNotify(protocolServiceKey, listener);
                serviceDiscovery.addServiceInstancesChangedListener(serviceInstancesChangedListener);
            } else {
                logger.info(String.format("Listener of %s has been destroyed by another thread.", serviceNamesKey));
                serviceListeners.remove(serviceNamesKey);
            }
        } finally {
            appSubscriptionLock.unlock();
        }
    }
}


public abstract class AbstractServiceNameMapping implements ServiceNameMapping, ScopeModelAware {

    @Override
    public Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener) {
        String key = ServiceNameMapping.buildMappingKey(subscribedURL);
        // use previously cached services.
        Set<String> mappingServices = this.getCachedMapping(key);
        // Asynchronously register listener in case previous cache does not exist or cache expired.
        if (CollectionUtils.isEmpty(mappingServices)) {
            ...
        } else {
            ExecutorService executorService = applicationModel.getFrameworkModel().getBeanFactory()
                .getBean(FrameworkExecutorRepository.class).getMappingRefreshingExecutor();
            executorService.submit(new AsyncMappingTask(listener, subscribedURL, true));
        }

        return mappingServices;
    }

    private class AsyncMappingTask implements Callable<Set<String>> {
        private final MappingListener listener;
        private final URL subscribedURL;
        private final boolean notifyAtFirstTime;

        public AsyncMappingTask(MappingListener listener, URL subscribedURL, boolean notifyAtFirstTime) {
            this.listener = listener;
            this.subscribedURL = subscribedURL;
            this.notifyAtFirstTime = notifyAtFirstTime;
        }

        @Override
        public Set<String> call() throws Exception {
            synchronized (mappingListeners) {
                Set<String> mappedServices = emptySet();
                try {
                    String mappingKey = ServiceNameMapping.buildMappingKey(subscribedURL);
                    if (listener != null) {
                        // 通過zk 客戶端 獲取服務(wù)提供端的服務(wù)名集合
                        mappedServices = toTreeSet(getAndListen(subscribedURL, listener));
                        Set<MappingListener> listeners = mappingListeners.computeIfAbsent(mappingKey, _k -> new HashSet<>());
                        listeners.add(listener);
                        if (CollectionUtils.isNotEmpty(mappedServices)) {
                            if (notifyAtFirstTime) {
                                // 將 提供端服務(wù)名 添加到本地集合緩存 serviceNameMapping 中
                                // DefaultMappingListener:本地緩存 & zk 服務(wù)端 之間保證 提供端服務(wù)名 一致性
                                listener.onEvent(new MappingChangedEvent(mappingKey, mappedServices));
                            }
                        }
                    } else {
                        mappedServices = get(subscribedURL);
                        if (CollectionUtils.isNotEmpty(mappedServices)) {
                            AbstractServiceNameMapping.this.putCachedMapping(mappingKey, mappedServices);
                        }
                    }
                } catch (Exception e) {
                    logger.error("Failed getting mapping info from remote center. ", e);
                }
                return mappedServices;
            }
        }
    }
}
NettyChannel真正netty發(fā)送數(shù)據(jù)。
CodecSupportNetty相關(guān)協(xié)議。

到了這里,關(guān)于Dubbo之消費(fèi)端服務(wù)RPC調(diào)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java 【dubbo rpc改feign調(diào)用】feign接口異常統(tǒng)一處理

    【框架改造問題點(diǎn)記錄,dubbo改為spring cloud alibaba】 【第一篇】feign接口異常統(tǒng)一處理 示例代碼中【ApplicationException 】、【Payload 】為自定義異常類和通用結(jié)果返回實(shí)體類: 示例代碼中【ApplicationException 】、【StringUtil】為自定義異常類和自定義工具,自己平替即可:

    2024年02月16日
    瀏覽(20)
  • 【SpringBoot集成Nacos+Dubbo】企業(yè)級項(xiàng)目集成微服務(wù)組件,實(shí)現(xiàn)RPC遠(yuǎn)程調(diào)用

    【SpringBoot集成Nacos+Dubbo】企業(yè)級項(xiàng)目集成微服務(wù)組件,實(shí)現(xiàn)RPC遠(yuǎn)程調(diào)用

    在日益增長的業(yè)務(wù)需求中,一開始使用的是每個項(xiàng)目獨(dú)立開發(fā),雖然都是前后端分離的項(xiàng)目,但是每一個項(xiàng)目之間互不干擾。后來,因?yàn)槟撤N需求,需要幾個項(xiàng)目的數(shù)據(jù)相互交錯獲取。 最開始的想法就是集成多個數(shù)據(jù)源。 舉例 有A、B、C三個項(xiàng)目,對應(yīng)著數(shù)據(jù)庫DBa、DBb、DBc、

    2024年02月04日
    瀏覽(25)
  • Java 【dubbo rpc改feign調(diào)用】feign接口調(diào)用 Body parameter 4 was null

    【框架改造問題點(diǎn)記錄,dubbo改為spring cloud alibaba】 【第四篇】feign接口調(diào)用 Body parameter 4 was null 【描述】Feign是一個聲明式的Web服務(wù)客戶端,它使得寫HTTP客戶端變得更簡單。如果你在使用Feign進(jìn)行服務(wù)調(diào)用時遇到了\\\"Body parameter 4 was null\\\"這樣的錯誤,這通常意味著你嘗試將一個

    2024年02月11日
    瀏覽(18)
  • Springboot3.X整合Dubbo3.XSpringCloudAlibaba微服務(wù) 2022.0 + Springboot3.X 集成 Dubbo實(shí)現(xiàn)對外調(diào)用http內(nèi)部調(diào)用RPC

    近期自己新開了一套SpringCloud Alibaba微服務(wù)項(xiàng)目,接口使用了對外HTTP,內(nèi)部RPC的設(shè)計,具體點(diǎn)說就是外部用戶或客戶端通過Nginx訪問到Gateway網(wǎng)關(guān)再分發(fā)到各個服務(wù),內(nèi)部各個服務(wù)之間統(tǒng)一使用Dubbo RPC進(jìn)行通信。下面是Springboot3.x集成Dubbo的分享: 1. 需要的關(guān)鍵依賴 2. 啟動程序入

    2024年02月15日
    瀏覽(25)
  • Mybatis-Plus+Nacos+Dubbo進(jìn)行遠(yuǎn)程RPC調(diào)用保姆級教程

    Mybatis-Plus+Nacos+Dubbo進(jìn)行遠(yuǎn)程RPC調(diào)用保姆級教程

    本文通過簡單的示例代碼和說明,讓讀者能夠了解Mybatis-Plus+Nacos+Dubbo進(jìn)行遠(yuǎn)程RPC調(diào)用的簡單使用? 默認(rèn)你已經(jīng)看過我之前的教程了,并且擁有上個教程完成的項(xiàng)目, 之前的教程?https://www.cnblogs.com/leafstar/p/17638782.html 項(xiàng)目鏈接在最后 ? 1.在bank1的pom文件中引入以下依賴 ? 2.使用

    2024年02月12日
    瀏覽(33)
  • jmeter測試rpc接口-使用dubbo框架調(diào)用【杭州多測師_王sir】

    jmeter測試rpc接口-使用dubbo框架調(diào)用【杭州多測師_王sir】

    1.基于SOAP架構(gòu)?;赬ML規(guī)范?;赪ebService協(xié)議。特點(diǎn):接口地址?wsdl結(jié)尾 2.基于RPC架構(gòu),基于dubbo協(xié)議,thrift協(xié)議。SpringCloud微服務(wù)。 3.基于RestFul架構(gòu),基于json規(guī)范。基于http協(xié)議(我們常用的都是這種,cms平臺也是) RestFul規(guī)則∶ 接口地址:?http://127.0.0.1/user?,?get(查詢用戶)?,?

    2024年02月13日
    瀏覽(20)
  • 【Dubbo3云原生微服務(wù)開發(fā)實(shí)戰(zhàn)】「Dubbo前奏導(dǎo)學(xué)」 RPC服務(wù)的底層原理和實(shí)現(xiàn)

    【Dubbo3云原生微服務(wù)開發(fā)實(shí)戰(zhàn)】「Dubbo前奏導(dǎo)學(xué)」 RPC服務(wù)的底層原理和實(shí)現(xiàn)

    Dubbo是一款高效而強(qiáng)大的RPC服務(wù)框架,它旨在解決微服務(wù)架構(gòu)下的服務(wù)監(jiān)控和通信問題。該框架提供了Java、Golang等多語言的SDK,使得使用者可以輕松構(gòu)建和開發(fā)微服務(wù)。Dubbo具備遠(yuǎn)程地址發(fā)現(xiàn)和通信能力,可通過Dubbo獨(dú)有的身臨其境的服務(wù)治理特驗(yàn)為主導(dǎo),以提高開發(fā)人員的功

    2024年02月05日
    瀏覽(21)
  • 介紹 dubbo-go 并在Mac上安裝,完成一次自己定義的接口RPC調(diào)用

    介紹 dubbo-go 并在Mac上安裝,完成一次自己定義的接口RPC調(diào)用

    對開發(fā)者更透明,減少了很多的溝通成本。 RPC向遠(yuǎn)程服務(wù)器發(fā)送請求時,未必要使用 HTTP 協(xié)議,比如還可以用 TCP / IP,性能更高(內(nèi)部服務(wù)更適用)。 ?? 注意:在整個流程中,最終的調(diào)用并不是由注冊中心來完成的。雖然注冊中心會提供信息,但實(shí)際上調(diào)用方需要自己進(jìn)行

    2024年02月10日
    瀏覽(18)
  • Dubbo源碼淺析(一)—RPC框架與Dubbo

    RPC,Remote Procedure Call 即遠(yuǎn)程過程調(diào)用,與之相對的是本地服務(wù)調(diào)用,即LPC(Local Procedure Call)。本地服務(wù)調(diào)用比較常用,像我們應(yīng)用內(nèi)部程序 (注意此處是程序而不是方法,程序包含方法) 互相調(diào)用即為本地過程調(diào)用,而遠(yuǎn)程過程調(diào)用是指在本地調(diào)取遠(yuǎn)程過程進(jìn)行使用。 而 RPC框

    2024年02月08日
    瀏覽(23)
  • 自定義Dubbo RPC通信協(xié)議

    Dubbo 協(xié)議層的核心SPI接口是 org.apache.dubbo.rpc.Protocol ,通過擴(kuò)展該接口和圍繞的相關(guān)接口,就可以讓 Dubbo 使用我們自定義的協(xié)議來通信。默認(rèn)的協(xié)議是 dubbo,本文提供一個 Grpc 協(xié)議的實(shí)現(xiàn)。 Google 提供了 Java 的 Grpc 實(shí)現(xiàn),所以我們站在巨人的肩膀上即可,就不用重復(fù)造輪子了。

    2024年01月19日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包