欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:Dubbo詳解

柚子快報(bào)激活碼778899分享:Dubbo詳解

http://yzkb.51969.com/

Dubbo從入門(mén)到源碼

Dubbo的基本應(yīng)用

什么是Dubbo

Dubbo是阿里巴巴公司開(kāi)源的一個(gè)高性能、輕量級(jí)的 Java RPC 框架

致力于提供高性能和透明化的 RPC 遠(yuǎn)程服務(wù)調(diào)用方案,以及 SOA 服務(wù)治理方案。

Dubbo的發(fā)展歷史

2011/10/27: 阿里巴巴巴宣布 Dubbo 開(kāi)源。

2012/10/23: 發(fā)布最后一個(gè)版本 2.5.3 并停止維護(hù)更新。

2017/07/31: 起死回生,官方宣布開(kāi)啟重新更新,并會(huì)得到重點(diǎn)維護(hù).

2017/09/07: 發(fā)布起死回生的第一個(gè)版本:dubbo-2.5.4。

2018/01/08:

1、Dubbo 團(tuán)隊(duì)透露 Dubbo 3.0 宣布正式開(kāi)工

2、發(fā)布了 dubbo-2.6.0 版本,主要合并了由當(dāng)當(dāng)網(wǎng)開(kāi)源的 dubbox 項(xiàng)目分支。PS:dubbo停止維護(hù)期間,當(dāng)當(dāng)網(wǎng)基于 dubbo 開(kāi)源了dubbox。

2018/01/22: Dubbo Spring Boot 版正式發(fā)布:dubbo-spring-boot-starter v1.0.0 公測(cè)版。

2018/02/09: Dubbo 通過(guò)投票正式進(jìn)入 Apache 基金會(huì)孵化器,更新了 Apache 官方域名,也不再僅限于 Java 語(yǔ)言。

2019/05/20: Apache 軟件基金會(huì)宣布 Dubbo 正式畢業(yè),成為 Apache 的頂級(jí)項(xiàng)目。

2021/7月1日 : Dubbo 3.0版本正式發(fā)布

Dubbo主要特性

面向接口代理的高性能RPC調(diào)用:提供高性能的基于代理的遠(yuǎn)程調(diào)用能力,服務(wù)以接口為粒度,屏蔽了遠(yuǎn)程調(diào)用底層細(xì)節(jié)。智能負(fù)載均衡:內(nèi)置多種負(fù)載均衡策略,智能感知下游節(jié)點(diǎn)健康狀況,顯著減少調(diào)用延遲,提高系統(tǒng)吞吐量。服務(wù)自動(dòng)注冊(cè)與發(fā)現(xiàn):支持多種注冊(cè)中心服務(wù),服務(wù)實(shí)例上下線(xiàn)實(shí)時(shí)感知。高度可擴(kuò)展能力:遵循微內(nèi)核+插件的設(shè)計(jì)原則,所有核心能力如Protocol、Transport、Serialization被設(shè)計(jì)為擴(kuò)展點(diǎn),平等對(duì)待內(nèi)置實(shí)現(xiàn)和第三方實(shí)現(xiàn)。運(yùn)行期流量調(diào)度:內(nèi)置條件、腳本等路由策略,通過(guò)配置不同的路由規(guī)則,輕松實(shí)現(xiàn)灰度發(fā)布,同機(jī)房?jī)?yōu)先等功能??梢暬姆?wù)治理與運(yùn)維:提供豐富服務(wù)治理、運(yùn)維工具:隨時(shí)查詢(xún)服務(wù)元數(shù)據(jù)、服務(wù)健康狀態(tài)及調(diào)用統(tǒng)計(jì),實(shí)時(shí)下發(fā)路由策略、調(diào)整配置參數(shù)。

Spring Cloud 團(tuán)隊(duì)

Spring Cloud Alibaba

HTTP 短連接 重新建立TCP連接

RPC Dubbo Spring Cloud

Dubbo的基本使用

Dubbo支持的注冊(cè)中心

consul

zk

Eureka

Redis

ectd

nacos

Dubbo Spring Cloud

DubboSpring Cloud服務(wù)注冊(cè)中心ZookeeperSpring Cloud Netfix Eureka服務(wù)調(diào)用方式RPCREST API服務(wù)監(jiān)控Dubbo-monitorSpring Boot Admin熔斷器不完善Spring Cloud Netflix Hystrix服務(wù)網(wǎng)關(guān)無(wú)Spring Cloud Netflix Zuul分布式配置無(wú)Spring Cloud Config服務(wù)跟蹤無(wú)Spring Cloud Sleuth數(shù)據(jù)流無(wú)Spring Cloud Stream批量任務(wù)無(wú)Spring Cloud Task信息總線(xiàn)無(wú)Spring Cloud Bus

Nacos

Dubbo Spring Cloud

Spring Cloud

功能組件Spring CloudDubbo Spring Cloud分布式配置(Distributed configuration)Git、Zookeeper、Consul、JDBCSpring Cloud 分布式配置 + Dubbo 配置中心服務(wù)注冊(cè)與發(fā)現(xiàn)(Service registration and discovery)Eureka、Zookeeper、ConsulSpring Cloud 原生注冊(cè)中心 + Dubbo 原生注冊(cè)中心負(fù)載均衡(Load balancing)Ribbon(隨機(jī)、輪詢(xún)等算法)Dubbo 內(nèi)建實(shí)現(xiàn)(隨機(jī)、輪詢(xún)等算法 + 權(quán)重等特性)服務(wù)熔斷(Circuit Breakers)Spring Cloud HystrixSpring Cloud Hystrix + Alibaba Sentinel 等服務(wù)調(diào)用(Service-to-service calls)Open Feign、RestTemplateSpring Cloud 服務(wù)調(diào)用 + Dubbo @Reference鏈路跟蹤(Tracing)Spring Cloud Sleuth + ZipkinZipkin、opentracing 等

以上對(duì)比表格摘自Dubbo Spring Cloud官方文檔。

本質(zhì)上 都是為業(yè)務(wù)而生

Dubbo多注冊(cè)中心

Dubbo多協(xié)議支持

Dubbo源碼

怎么學(xué)? spring的2.5之后 ,Spring支持自定義Schema擴(kuò)展XML配置

1.Xml Schema

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs) {

String name = protocolConfig.getName();

if (StringUtils.isEmpty(name)) {

name = DUBBO;

}

s

Map map = new HashMap();

//("side":"provide")

map.put(SIDE_KEY, PROVIDER_SIDE);

ServiceConfig.appendRuntimeParameters(map);

AbstractConfig.appendParameters(map, getMetrics());

AbstractConfig.appendParameters(map, getApplication());

AbstractConfig.appendParameters(map, getModule());

// remove 'default.' prefix for configs from ProviderConfig

// appendParameters(map, provider, Constants.DEFAULT_KEY);

AbstractConfig.appendParameters(map, provider);

AbstractConfig.appendParameters(map, protocolConfig);

AbstractConfig.appendParameters(map, this);

MetadataReportConfig metadataReportConfig = getMetadataReportConfig();

if (metadataReportConfig != null && metadataReportConfig.isValid()) {

map.putIfAbsent(METADATA_KEY, REMOTE_METADATA_STORAGE_TYPE);

}

if (CollectionUtils.isNotEmpty(getMethods())) {

for (MethodConfig method : getMethods()) {

AbstractConfig.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");

}

}

List arguments = method.getArguments();

if (CollectionUtils.isNotEmpty(arguments)) {

for (ArgumentConfig argument : arguments) {

// convert argument type

if (argument.getType() != null && argument.getType().length() > 0) {

Method[] methods = interfaceClass.getMethods();

// visit all methods

if (methods.length > 0) {

for (int i = 0; i < methods.length; i++) {

String methodName = methods[i].getName();

// target the method, and get its signature

if (methodName.equals(method.getName())) {

Class[] argtypes = methods[i].getParameterTypes();

// one callback in the method

if (argument.getIndex() != -1) {

if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {

AbstractConfig.appendParameters(map, argument, method.getName() + "." + argument.getIndex());

} else {

throw new IllegalArgumentException("Argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());

}

} else {

// multiple callbacks in the method

for (int j = 0; j < argtypes.length; j++) {

Class argclazz = argtypes[j];

if (argclazz.getName().equals(argument.getType())) {

AbstractConfig.appendParameters(map, argument, method.getName() + "." + j);

if (argument.getIndex() != -1 && argument.getIndex() != j) {

throw new IllegalArgumentException("Argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());

}

}

}

}

}

}

}

} else if (argument.getIndex() != -1) {

AbstractConfig.appendParameters(map, argument, method.getName() + "." + argument.getIndex());

} else {

throw new IllegalArgumentException("Argument config must set index or type attribute.eg: or ");

}

}

}

} // end of methods for

}

//泛化方式

if (ProtocolUtils.isGeneric(generic)) {

map.put(GENERIC_KEY, generic);

map.put(METHODS_KEY, ANY_VALUE);

} else {

String revision = Version.getVersion(interfaceClass, version);

if (revision != null && revision.length() > 0) {

map.put(REVISION_KEY, revision);

}

//獲取我們的包裝類(lèi)

String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();

if (methods.length == 0) {

logger.warn("No method found in service interface " + interfaceClass.getName());

map.put(METHODS_KEY, ANY_VALUE);

} else {

map.put(METHODS_KEY, StringUtils.join(new HashSet(Arrays.asList(methods)), ","));

}

}

/**

* Here the token value configured by the provider is used to assign the value to ServiceConfig#token

*/

if(ConfigUtils.isEmpty(token) && provider != null) {

token = provider.getToken();

}

if (!ConfigUtils.isEmpty(token)) {

if (ConfigUtils.isDefault(token)) {

map.put(TOKEN_KEY, UUID.randomUUID().toString());

} else {

map.put(TOKEN_KEY, token);

}

}

//init serviceMetadata attachments

serviceMetadata.getAttachments().putAll(map);

// export service

String host = findConfigedHosts(protocolConfig, registryURLs, map);

Integer port = findConfigedPorts(protocolConfig, name, map);

URL url = new URL(name, host, port, getContextPath(protocolConfig).map(p -> p + "/" + path).orElse(path), map);

// You can customize Configurator to append extra parameters

if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)

.hasExtension(url.getProtocol())) {

url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)

.getExtension(url.getProtocol()).getConfigurator(url).configure(url);

}

String scope = url.getParameter(SCOPE_KEY);

// don't export when none is configured

if (!SCOPE_NONE.equalsIgnoreCase(scope)) {

// export to local if the config is not remote (export to remote only when config is remote)

if (!SCOPE_REMOTE.equalsIgnoreCase(scope)) {

exportLocal(url);

}

// export to remote if the config is not local (export to local only when config is local)

if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) {

if (CollectionUtils.isNotEmpty(registryURLs)) {

for (URL registryURL : registryURLs) {

//if protocol is only injvm ,not register

if (LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {

continue;

}

url = url.addParameterIfAbsent(DYNAMIC_KEY, registryURL.getParameter(DYNAMIC_KEY));

URL monitorUrl = ConfigValidationUtils.loadMonitor(this, registryURL);

if (monitorUrl != null) {

url = url.addParameterAndEncoded(MONITOR_KEY, monitorUrl.toFullString());

}

if (logger.isInfoEnabled()) {

if (url.getParameter(REGISTER_KEY, true)) {

logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);

} else {

logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);

}

}

// For providers, this is used to enable custom proxy to generate invoker

String proxy = url.getParameter(PROXY_KEY);

if (StringUtils.isNotEmpty(proxy)) {

registryURL = registryURL.addParameter(PROXY_KEY, proxy);

}

//?

Invoker invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()));

DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);

//?

Exporter exporter = PROTOCOL.export(wrapperInvoker);

exporters.add(exporter);

}

} else {

if (logger.isInfoEnabled()) {

logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);

}

Invoker invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, url);

DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);

Exporter exporter = PROTOCOL.export(wrapperInvoker);

exporters.add(exporter);

}

/**

* @since 2.7.0

* ServiceData Store

*/

WritableMetadataService metadataService = WritableMetadataService.getExtension(url.getParameter(METADATA_KEY, DEFAULT_METADATA_STORAGE_TYPE));

if (metadataService != null) {

metadataService.publishServiceDefinition(url);

}

}

}

this.urls.add(url);

}

Dubbo擴(kuò)展點(diǎn)

指定名稱(chēng)的擴(kuò)展點(diǎn)

ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("name");

自適應(yīng)的擴(kuò)展點(diǎn)

ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

激活擴(kuò)展點(diǎn)

ExtensionLoader.getExtensionLoader(Protocol.class).getExtension();

指定名稱(chēng)的拓展點(diǎn)

或者說(shuō)你直接從指定文件中找到我們的name

我們?nèi)绾闻卸╠ubbo中哪些類(lèi)是拓展點(diǎn)呢?

找出拓展點(diǎn)并加載的流程

1.找到路徑:在我們的META-INF/dubbo/inertnal下面

random=org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance

roundrobin=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance

leastactive=org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance

consistenthash=org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance

shortestresponse=org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance

3.Package.Class

4.解析文件 properties文件的解析

5.內(nèi)容放進(jìn)內(nèi)存 key(name) value =org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance

6.key(name) value =Class newInstance

自適應(yīng)拓展點(diǎn)

在運(yùn)行期間,我們會(huì)根據(jù)上下文來(lái)判斷當(dāng)前你返回哪個(gè)拓展點(diǎn)。

getAdaptiveExtension()

標(biāo)識(shí)位:

@Adaptive

聲明在我們的方法級(jí)別聲明在我們的類(lèi)級(jí)別

實(shí)現(xiàn)原理:

如果修飾在方法級(jí)別,那么我們會(huì)動(dòng)態(tài)的創(chuàng)建一個(gè)代理類(lèi) (javassist)如果修飾的是類(lèi),那么我們直接返回被修飾的這個(gè)類(lèi)

如果我們當(dāng)前架子啊的擴(kuò)展點(diǎn)存在自適應(yīng)的類(lèi),那么我們直接返回,

否則,我們會(huì)動(dòng)態(tài)的創(chuàng)建一個(gè)字節(jié)碼,然后進(jìn)行返回。

激活拓展點(diǎn)

相當(dāng)于Spring當(dāng)中的Conditional

@ConditionalOnBean(XXX.class)

只要你的@Activate注解中有value,那么這個(gè)時(shí)候我們當(dāng)前的Filter就會(huì)被激活。

1.判斷是否要發(fā)布到遠(yuǎn)程服務(wù),或者說(shuō)是否需要發(fā)布服務(wù),如果為none,那么我們就不需要發(fā)布

2.循環(huán)遍歷注冊(cè)中心的配置,實(shí)際上這里就是對(duì)多注冊(cè)中心支持的最好體現(xiàn)

Protoco$Adaptive --> export方法

1.進(jìn)行了Netty服務(wù)的啟動(dòng)

2.進(jìn)行服務(wù)注冊(cè)

protocol = protocol$Adaptive

Protocol = Wrapper(((DubboProtocol)))

Dubbo – Netty4

ServerSocket serverSocket;

20880(默認(rèn)端口)

RegistryFactoryWrapper(ZookeeperRegistryFactory)

服務(wù)注冊(cè)的總結(jié):

1.生成invoke對(duì)象

2.doLocalExport方法發(fā)布一個(gè)本地服務(wù),實(shí)際上就是利用配置去進(jìn)行一個(gè)監(jiān)聽(tīng)

3.通過(guò)Registy去進(jìn)行服務(wù)注冊(cè)

invoker對(duì)象是什么

對(duì)象實(shí)例 — 保存在Map集合中的

收到客戶(hù)端的請(qǐng)求,(方法名稱(chēng),接口的全路徑,參數(shù),參數(shù)類(lèi)型)

根據(jù)接口的全路徑做為key,找到實(shí)例方法,反射調(diào)用他

Invoker invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()));

1.如果假設(shè)我們的Url中有配置了proxy,我就按照我們Proxy參數(shù)的配置來(lái)進(jìn)行查找

但是,如果沒(méi)有配置,那么我們采用默認(rèn)的拓展點(diǎn)

public Invoker getInvoker(T proxy, Class type, URL url) {

final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf(36) < 0 ? proxy.getClass() : type);

return new AbstractProxyInvoker(proxy, type, url) {

//當(dāng)我們的服務(wù)端接受到請(qǐng)求之后,我們接下來(lái)調(diào)用具體的方法

protected Object doInvoke(T proxy, String methodName, Class[] parameterTypes, Object[] arguments) throws Throwable {

return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);

}

};

}

invoker本身就是一個(gè)調(diào)用器

服務(wù)本身會(huì)以我們invoker的形態(tài)存在

服務(wù)消費(fèi)

關(guān)鍵性注解

1.生成遠(yuǎn)程服務(wù)的代理

2.獲取目標(biāo)服務(wù)的Url

2.1 建立與注冊(cè)中心的動(dòng)態(tài)感知

3.網(wǎng)絡(luò)連接的建立(啟動(dòng)時(shí)創(chuàng)建還是通信是創(chuàng)建?) --> Dubbo啟動(dòng)時(shí)創(chuàng)建 Netty(nio)

4.服務(wù)通信

4.1 filter過(guò)濾

4.2 負(fù)載均衡

4.3 容錯(cuò)

用到Spring的一系列知識(shí)

服務(wù)消費(fèi)端的操作

服務(wù)消費(fèi)端的對(duì)象的注入

Xml注解的方式

BeanPostProcessor

柚子快報(bào)激活碼778899分享:Dubbo詳解

http://yzkb.51969.com/

推薦閱讀

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19605349.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪(fǎng)問(wèn)

文章目錄