当前位置: 首页 > news >正文

雷州网站开发公司大连seo交流群

雷州网站开发公司,大连seo交流群,亚马逊全球开店,手机免费创网站入口 Dubbo服务导出的入口#xff1a;服务导出是在DubboBootstrapApplicationListener在监听到ApplicationContextEvent的ContextRefreshedEvent事件后#xff0c;会触发dubboBootstrap.start(), 在这个方法中最后会导出Dubbo服务 DubboBootstrapApplicationListener Dub… 入口 Dubbo服务导出的入口服务导出是在DubboBootstrapApplicationListener在监听到ApplicationContextEvent的ContextRefreshedEvent事件后会触发dubboBootstrap.start(), 在这个方法中最后会导出Dubbo服务 DubboBootstrapApplicationListener DubboBootstrapApplicationListener是哪里注册进来的那 入口一在扫描DubboService的ServiceClassPostProcessor 里面会注册一个Dubbo的监听器 入口二在解析DubboReference的注解的时候调用registerCommonBeans的时候向Spring容器注册了一个类DubboApplicationListenerRegistrar DubboBootstrap.exportServices configManager就是一个配置缓存类里面放的都是之前的配置 configManager.getServices() 获取的是service将所有的service转换成serviceBean调用serviceBean.export()serviceBean继承的是serviceConfig最终会调用到serviceConfig.export ServiceConfig.export 判断bootstrap是否初始化如果没有初始化需要初始化检查并更新服务的参数checkAndUpdateSubConfigs private void checkAndUpdateSubConfigs() {// Use default configs defined explicitly with global scopecompleteCompoundConfigs();checkDefault();checkProtocol();// init some null configuration.ListConfigInitializer configInitializers ExtensionLoader.getExtensionLoader(ConfigInitializer.class).getActivateExtension(URL.valueOf(configInitializer://), (String[]) null);configInitializers.forEach(e - e.initServiceConfig(this));// if protocol is not injvm checkRegistryif (!isOnlyInJvm()) {checkRegistry();}this.refresh();if (StringUtils.isEmpty(interfaceName)) {throw new IllegalStateException(dubbo:service interface\\ / interface not allow null!);}// 检测 ref 是否为泛化服务类型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);}// 对 interfaceClass以及 dubbo:method 标签中的必要字段进行检查checkInterfaceAndMethods(interfaceClass, getMethods());checkRef();generic Boolean.FALSE.toString();}// local 和 stub 在功能应该是一致的用于配置本地存根if (local ! null) {if (true.equals(local)) { // 如果配置的事true那么默认类名就是 接口名拼接Locallocal interfaceName Local;}Class? localClass;try {// 获取本地存根类localClass ClassUtils.forNameWithThreadContextClassLoader(local);} catch (ClassNotFoundException e) {throw new IllegalStateException(e.getMessage(), e);}if (!interfaceClass.isAssignableFrom(localClass)) {throw new IllegalStateException(The local implementation class localClass.getName() not implement interface interfaceName);}}// 逻辑同上if (stub ! null) {if (true.equals(stub)) {stub interfaceName Stub;}Class? stubClass;try {stubClass ClassUtils.forNameWithThreadContextClassLoader(stub);} catch (ClassNotFoundException e) {throw new IllegalStateException(e.getMessage(), e);}if (!interfaceClass.isAssignableFrom(stubClass)) {throw new IllegalStateException(The stub implementation class stubClass.getName() not implement interface interfaceName);}}checkStubAndLocal(interfaceClass);ConfigValidationUtils.checkMock(interfaceClass, this);ConfigValidationUtils.validateServiceConfig(this);postProcessConfig();}检查ServiceConfig的配置如果ServiceConfig中的某些属性如果是空的那么就从AbstractInterfaceConfig、ModuleConfig、ApplicationConfig、ProviderConfig中获取并赋值给ServiceConfig对象中对应的属性。 检查provider属性值是否为空如果为空的话创建一个新的ProviderConfig并赋值给他。 检查协议如果没有单独的配置protocols则从provider获取配置的协议并赋值给ServiceConfig对应的属性。 如果配置中心的全局配置或应用配置中也配置了一个协议那么就会被添加到ServiceConfig中。 如果protocol协议配置的不是只有injvm协议那么就需要把服务注册到注册中心里去。 检查注册中心的配置如果没有配置的话从application对象里获取 刷新ServiceConfig配置 检查当前服务是否为泛化服务 检查Stub、Local、Mock 检验ServiceConfig配置的值是否合法长度、非法字符等 通过SPI调用ConfigPostProcessor实现类进行配置的后置处理 完善serviceMetadata的参数version、group、defaultGroup、serviceInterfaceName、serviceType、target等属性值 检查是否应该被导出。 如果是延迟暴露则使用线程池任务调用doExport方法导出。 如果是正常导出直接调用doExport方法。 发送导出完成事件。 ServiceConfig.doExport ServiceConfig.doExportUrls 讲讲这里做了几件事 把接口、具体的实现类、ServiceBean、ServiceDescriptor注册到本地仓库的provider 查询所有的注册中心构造出注册中心URL 遍历所有协议将每个协议都进行服务导出 doExportUrlFor1Protocol private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, ListURL registryURLs) {String name protocolConfig.getName();if (StringUtils.isEmpty(name)) {// 如果协议名为空或空串则将协议名变量设置为 dubboname DUBBO;}MapString, String map new HashMapString, String();// 添加 side、版本、时间戳以及进程号等信息到 map 中map.put(SIDE_KEY, PROVIDER_SIDE);ServiceConfig.appendRuntimeParameters(map);AbstractConfig.appendParameters(map, getMetrics());// 通过反射将对象的字段信息添加到 map 中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())) {// methods 为 MethodConfig 集合MethodConfig 中存储了 dubbo:method 标签的配置信息for (MethodConfig method : getMethods()) {// 添加 MethodConfig 对象的字段信息到 map 中键 方法名.属性名。// 比如存储 dubbo:method namesayHello retries2 对应的 MethodConfig// 键 sayHello.retriesmap {sayHello.retries: 2, xxx: yyy}AbstractConfig.appendParameters(map, method, method.getName());String retryKey method.getName() .retry;if (map.containsKey(retryKey)) {String retryValue map.remove(retryKey);// 检测 MethodConfig retry 是否为 false若是则设置重试次数为0if (false.equals(retryValue)) {map.put(method.getName() .retries, 0);}}// 获取 ArgumentConfig 列表ListArgumentConfig arguments method.getArguments();if (CollectionUtils.isNotEmpty(arguments)) {for (ArgumentConfig argument : arguments) {// convert argument type// 分支1 检测 type 属性是否为空或者空串if (argument.getType() ! null argument.getType().length() 0) {Method[] methods interfaceClass.getMethods();// visit all methodsif (methods.length 0) {for (int i 0; i methods.length; i) {String methodName methods[i].getName();// target the method, and get its signature// 1、比对方法名查找目标方法 2、通过反射获取目标方法的参数类型数组 argtypesif (methodName.equals(method.getName())) {Class?[] argtypes methods[i].getParameterTypes();// one callback in the methodif (argument.getIndex() ! -1) {// 检测 ArgumentConfig 中的 type 属性与方法参数列表// 分支2 中的参数名称是否一致不一致则抛出异常//1. 从 argtypes 数组中获取下标 index 处的元素 argType//2. 检测 argType 的名称与 ArgumentConfig 中的 type 属性是否一致//3. 添加 ArgumentConfig 字段信息到 map 中或抛出异常if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {// 添加 ArgumentConfig 字段信息到 map 中// 键前缀 方法名.index比如:// map {sayHello.3: true}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 { // 分支3 ⭐️//1. 遍历参数类型数组 argtypes查找 argument.type 类型的参数//2. 添加 ArgumentConfig 字段信息到 map 中// multiple callbacks in the methodfor (int j 0; j argtypes.length; j) {Class? argclazz argtypes[j];// 从参数类型列表中查找类型名称为 argument.type 的参数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) {// 用户未配置 type 属性但配置了 index 属性且 index ! -1// 分支4 ⭐️// 添加 ArgumentConfig 字段信息到 map 中AbstractConfig.appendParameters(map, argument, method.getName() . argument.getIndex());} else {throw new IllegalArgumentException(Argument config must set index or type attribute.eg: dubbo:argument index0 .../ or dubbo:argument typexxx .../);}}}} // end of methods for}// 检测 generic 是否为 true并根据检测结果向 map 中添加不同的信息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);}/*** 为接口生成包裹类 Wrapper ,Wrapper就是interface的一个动态代理类似于 mybatis的mapper也会生成一个* 只不过Dubbo用的是自己的动态代理mybatis用的是JDK动态代理*/String[] methods Wrapper.getWrapper(interfaceClass).getMethodNames();if (methods.length 0) {// 添加方法名到 map 中如果包含多个方法名则用逗号隔开比如 method init,destroylogger.warn(No method found in service interface interfaceClass.getName());map.put(METHODS_KEY, ANY_VALUE);} else {// 将逗号作为分隔符连接方法名并将连接后的字符串放入 map 中// - haveNoReturn,setTestgaga,getTestddd,hellomap.put(METHODS_KEY, StringUtils.join(new HashSetString(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();}// 添加 token 到 map 中if (!ConfigUtils.isEmpty(token)) {if (ConfigUtils.isDefault(token)) {// 随机生成 tokenmap.put(TOKEN_KEY, UUID.randomUUID().toString());} else {map.put(TOKEN_KEY, token);}}//init serviceMetadata attachmentsserviceMetadata.getAttachments().putAll(map);/*** ListURL registryURLs* 单个 URL - registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?applicationdemo-provider* dubbo2.0.2idregistry1mapping-typemetadatamapping.typemetadatapid10000qos.port22222* registryzookeepertimestamp1611892414279* 由此分析呢协议的路径 就是执行动作的类*/// export IP 获取 本地主机的IP,也就是要暴露接口服务所属主机的IP地址就是netty或者tomcat绑定的 IP String host findConfigedHosts(protocolConfig, registryURLs, map);// export port 获取 暴露的端口,也就是要暴露接口服务 所属 服务的 端口就是netty或者tomcat绑定的 端口,默认20880Integer port findConfigedPorts(protocolConfig, name, map);// 组装 URL// getContextPath(protocolConfig) 获取的就是 url的path// 成员变量path 就是 接口名 - org.apache.dubbo.demo.GreetingService// 所以最终组装的path就是 contextPath/path 但是这里contextPath为空// url dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-provider// bind.ip192.168.1.103bind.port20880deprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreeting// interfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremote// methodshaveNoReturn,setTestgaga,getTestddd,hellopid1144qos.port22222releaserevision1.0.0// sideprovidertimeout5000timestamp1611924667311version1.0.0URL url new URL(name, host, port, getContextPath(protocolConfig).map(p - p / path).orElse(path), map);/*** 前置工作做完接下来就可以进行服务导出了。服务导出分为导出到本地 (JVM)和导出到远程*/// You can customize Configurator to append extra parametersif (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class).hasExtension(url.getProtocol())) { // 没有自定义的话就不会进这个判断// 加载 ConfiguratorFactory并生成 Configurator 实例然后通过实例配置 urlurl ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class).getExtension(url.getProtocol()).getConfigurator(url).configure(url);}String scope url.getParameter(SCOPE_KEY);// dont export when none is configured// scope必须不是 none如果 scope none则什么都不做,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)) {// scope ! remote导出到本地/*** scope none不导出服务* scope ! remote导出到本地* scope ! local导出到远程* 不管是导出到本地还是远程。进行服务导出之前均需要先创建 Invoker* Invoker 是一个非常重要的模型。在服务提供端以及服务引用端均会出现 Invoker* Invoker 是实体域它是 Dubbo 的核心模型其它模型都向它靠扰或转换成它它代表一个可执行体* 可向它发起 invoke 调用它有可能是一个本地的实现也可能是一个远程的实现也可能一个集群实现。*/exportLocal(url);}// export to remote if the config is not local (export to local only when config is local)if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) { // scope ! local导出到远程if (CollectionUtils.isNotEmpty(registryURLs)) {for (URL registryURL : registryURLs) {/*** ListURL registryURLs* 单个 URL - registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?applicationdemo-provider* dubbo2.0.2idregistry1mapping-typemetadatamapping.typemetadatapid10000qos.port22222* registryzookeepertimestamp1611892414279* 由此分析呢协议的路径 就是执行动作的类*///if protocol is only injvm ,not registerif (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 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);}}// url dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-provider// bind.ip192.168.1.103bind.port20880deprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreeting// interfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremote// methodshaveNoReturn,setTestgaga,getTestddd,hellopid1144qos.port22222releaserevision1.0.0// sideprovidertimeout5000timestamp1611924667311version1.0.0// For providers, this is used to enable custom proxy to generate invoker// 看上面英文注释如果自定义代理工厂的话才会有这个keyString proxy url.getParameter(PROXY_KEY);if (StringUtils.isNotEmpty(proxy)) {registryURL registryURL.addParameter(PROXY_KEY, proxy);}/*** 为服务提供类(ref)生成 Invoker* Invoker 是由 ProxyFactory 创建而来Dubbo 默认的 ProxyFactory 实现类是 JavassistProxyFactory* ref - GreetingServiceImpl 接口实现类* interfaceClass - GreetingService 接口* registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()) - :* EXPORT_KEY - export* url.toFullString() - 就是url的全路径dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrue......* 这个url全路径包含了服务的IP地址端口接口名方法名数组等等* registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()) 目的就是把需要暴露的服务 encode成一个value* 然后作为一个export参数拼接到registryURL后面形如* registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?.....export经过encode的完整服务* 与上面exportLocal...对比着看*/Invoker? invoker PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()));// DelegateProviderMetaDataInvoker 用于持有 Invoker 和 ServiceConfigDelegateProviderMetaDataInvoker wrapperInvoker new DelegateProviderMetaDataInvoker(invoker, this);/*** 导出服务并生成 Exporter* 导出服务到本地相比导出服务到远程的过程要复杂不少* 其包含了服务导出与服务注册两个过程* PROTOCOL.export(wrapperInvoker) 这行代码呢根据dubbo-spi机制会先 url wrapperInvoker.getUrl(),* 然后 Protocol p url.getProtocol(),根据duboo-spi的 wrapper机制* p ProtocolFilterWrapper(ProtocolListenerWrapper(RegistryProtocol))*/Exporter? exporter PROTOCOL.export(wrapperInvoker);exporters.add(exporter);}} else { // 不存在注册中心仅导出服务// url dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-provider// bind.ip192.168.1.103bind.port20880deprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreeting// interfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremote// methodshaveNoReturn,setTestgaga,getTestddd,hellopid1144qos.port22222releaserevision1.0.0// sideprovidertimeout5000timestamp1611924667311version1.0.0// For providers, this is used to enable custom proxy to generate invokerif (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);// 此时根据dubbo-spi机制会进入 DubboProtocol的export方法Exporter? exporter PROTOCOL.export(wrapperInvoker);exporters.add(exporter);}MetadataUtils.publishServiceDefinition(url);}}this.urls.add(url);}获取协议名称如果为空设置为dubbo协议。设置side为provider。设置运行时参数dubbo版本、时间戳、协议版本等。将监控、应用、模块、提供者、协议、服务本身、元数据、接口方法、方法参数等信息放入map中。如果是泛化服务设置泛化服务相关信息。根据服务接口找到对应的Wrapper类拿到Wrapper类中所有的方法名字放入map。获取token配置放入maptoken可以在一定程度上防止人为调用dubbo服务。将map中的信息放入服务元数据的attachments中。获取host、port并构造URL。通过DubboSPI获取ConfiguratorFactory的实现类该步骤可以可以对URL的内容进行更改或做一些定制化操作。根据scope来判断是本地注册还是注册到注册中心如果是none则不进行导出如果是local代表导出到本地仅供本地JVM调用但是也是会走完整的dubbo流程的。将服务的元数据信息放、到元数据中心。通过代理工厂生成Invoker并进行服务导出!!! PROTOCAL.export()。 PROTOCOL.export(wrapperInvoker) PROTOCOL是一个自适应扩展对象之前讲过自适应扩展类的方法需要有URL参数或者参数的类里有getURL方法那么wrapperInvoker里面的URL长什么样呢由于太长了省略一部分 这个URL的协议头为register, 所以实际调用的方法为RegistryProtocol#export public T ExporterT export(final InvokerT originInvoker) throws RpcException {/*** 包含了 服务导出 与 服务注册 两个过程*//*** 获取注册中心 URL以 zookeeper 注册中心为例得到的示例 URL 如下* zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?applicationdemo-providerdubbo2.0.2* exportdubbo%3A%2F%2F192.168.1.103%3A20880%2Forg.apache.dubbo.demo.GreetingService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26bind.ip%3D192.168.1.103%26bind.port%3D20880%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26group%3Dgreeting%26interface%3Dorg.apache.dubbo.demo.GreetingService%26mapping-type%3Dmetadata%26mapping.type%3Dmetadata%26metadata-type%3Dremote%26methods%3DhaveNoReturn%2CsetTestgaga%2CgetTestddd%2Chello%26pid%3D2188%26qos.port%3D22222%26release%3D%26revision%3D1.0.0%26side%3Dprovider%26timeout%3D5000%26timestamp%3D1611975477170%26version%3D1.0.0idregistry1mapping-typemetadatamapping.typemetadatapid2188qos.port22222timestamp1611975477162* export解码后* exportdubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-providerbind.ip192.168.1.103bind.port20880deprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreetinginterfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremotemethodshaveNoReturn,setTestgaga,getTestddd,hellopid2188qos.port22222releaserevision1.0.0sideprovidertimeout5000timestamp1611975477170version1.0.0idregistry1mapping-typemetadatamapping.typemetadatapid2188qos.port22222timestamp1611975477162*/URL registryUrl getRegistryUrl(originInvoker);/*** url to export locally 获取已注册的服务提供者 URL其实就是上面的url的export的值比如* dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-providerbind.ip192.168.1.103bind.port20880deprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreetinginterfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremotemethodshaveNoReturn,setTestgaga,getTestddd,hellopid2188qos.port22222releaserevision1.0.0sideprovidertimeout5000timestamp1611975477170version1.0.0*/URL providerUrl getProviderUrl(originInvoker);// Subscribe the override data// FIXME When the provider subscribes, it will affect the scene : a certain JVM exposes the service and call// the same service. Because the subscribed is cached key with the name of the service, it causes the// subscription information to cover./*** 获取订阅 URL比如* provider://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-providerbind.ip192.168.1.103bind.port20880* categoryconfiguratorscheckfalsedeprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreetinginterfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremotemethodshaveNoReturn,setTestgaga,getTestddd,hellopid2188qos.port22222releaserevision1.0.0sideprovidertimeout5000timestamp1611975477170version1.0.0*/final URL overrideSubscribeUrl getSubscribedOverrideUrl(providerUrl);// 创建监听器final OverrideListener overrideSubscribeListener new OverrideListener(overrideSubscribeUrl, originInvoker);overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);providerUrl overrideUrlWithConfig(providerUrl, overrideSubscribeListener);/*** export invoker 导出服务*/final ExporterChangeableWrapperT exporter doLocalExport(originInvoker, providerUrl);// url to registry// 根据 URL 加载 Registry 实现类里面有很多spi机制使用最终得到 比如 ZookeeperRegistry// 但是 外面加了一层wrapper所以最终 registry ListenerRegistryWrapper// 同时会注册监听事件final Registry registry getRegistry(originInvoker);// dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-providerdeprecatedfalsedubbo2.0.2dynamictruegenericfalsegroupgreetinginterfaceorg.apache.dubbo.demo.GreetingServicemapping-typemetadatamapping.typemetadatametadata-typeremotemethodshaveNoReturn,setTestgaga,getTestddd,hellopid2188releaserevision1.0.0sideprovidertimeout5000timestamp1611975477170version1.0.0final URL registeredProviderUrl getUrlToRegistry(providerUrl, registryUrl);// decide if we need to delay publish 获取 register 参数boolean register providerUrl.getParameter(REGISTER_KEY, true);if (register) {// 向注册中心注册服务/*** 服务注册操作对于 Dubbo 来说不是必需的通过服务直连的方式就可以绕过注册中心。* 但通常我们不会这么做直连方式不利于服务治理.*/register(registryUrl, registeredProviderUrl);}// register stated url on provider modelregisterStatedUrl(registryUrl, registeredProviderUrl, register);exporter.setRegisterUrl(registeredProviderUrl);exporter.setSubscribeUrl(overrideSubscribeUrl);// Deprecated! Subscribe to override rules in 2.6.x or before.// 向注册中心进行订阅 override 数据.registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);notifyExport(exporter);//Ensure that a new exporter instance is returned every time export// 创建并返回 DestroyableExporterreturn new DestroyableExporter(exporter);}具体做了这几件事 通过registryUrlzookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?applicationdemo-providerdubbo2.0.2 providerUrl dubbo://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?any生成 overrideSubscribeUrlprovider://192.168.1.103:20880/org.apache.dubbo.demo.GreetingService?anyhosttrueapplicationdemo-provider在providerUrl的基础上增加参数categoryconfiguratorscheckfalse根据providerUrl、registryUrl对参数进行简化因为有些参数是没用的没有必要放到注册中心比如monitor、bind.ip、bind.port等简化后生成要注册的URL并注册到注册中心进行本地导出doLocalExport 由于这时候运行的协议为Dubbo所以回调用到DubboProtocol这里会启动Tomcat或者Netty等容器 根据url来获取服务key一般为接口类名构造一个DubboExporter并放入到缓存中开启Netty服务openServer 1. 根据传进来的URL生成服务URL该URL比原来新增加了channel.readonly.setTRUE、heartbeat6000、codecdubbo参数2. 从Url中获取协议的服务器端实现类型比如dubbo协议的mina、netty等http协议的jetty、tomcat等**默认为netty协议**3. 把创建好的Server进行返回在创建Server的时候最终**会调用到NettyServer.doOpen**设置netty的参数并启动netty 根据Invoker 中配置的optimizer 参数获取拓展的自定义序列号处理类 register(registerUrl, registeredProviderUrl) 通过Url来获取注册中心实例 ZookeeperRegistry调用register进行注册中心注册最终执行到FailbackRegistry.registry, 这个方法最终调用到zkClient.create将URL注册到注册中心。
http://www.zqtcl.cn/news/953267/

相关文章:

  • 电子商务网站建设需要哪些步骤网站开发维护合同书
  • 顺德网站设计成都网站优化方式
  • 宁波建网站哪家好用点网站后台 更新缓存
  • 如何推广网站链接做旅游网站的目的
  • 网站规划与设计课程设计中企动力网站建设 长春
  • 最新网站建设哪家公司好wordpress 顶部图片
  • 有什么网站可以做一起作业公司简介优秀文案
  • 太仓住房和城乡建设局网站seo网页推广
  • 网络公司 网站源码网页源代码修改了影响别人吗
  • 网站后台是怎样制作的app开发公司排行榜做软件的公司
  • 有专门做网站的公司吗西安分类信息seo公司
  • 重庆璧山网站制作公司哪家专业商城网站建设 优帮云
  • 双语网站建设费用安徽省芜湖建设定额网站
  • 常州市城乡建设局网站wordpress 阿里云cdn
  • 福州制作网站设计哪里比较好百度网址大全官方网站
  • 一般做美食网站的产品需求我想做个网站
  • 成品网站制作公司应用公园是免费的吗
  • 做毕业网站的流程网站建设价格一览表
  • 企业服务网站开发做网站怎样建立服务器
  • 电子商务他们的代表网站360免费wifi官网
  • 网站后端开发软件cc域名做门户网站
  • 保定设计网站超云建站
  • 建筑工程网官网入口优化网站关键词排名软件
  • 企业网站功能怎么设计wordpress文章图片轮播
  • 网站后台登陆验证码不对阳江房产网楼市数据
  • 营销型网站建设遨龙仙居住房和城乡建设规划局网站
  • 中国做视频网站有哪些淘宝做详情页代码网站
  • 网站开发一般多钱在网站设计公司上班好吗
  • 餐饮连锁企业网站建设方案北京软件研发公司
  • 外国网站架构新闻稿