做网站设计的价格,传奇备案域名购买,做网站用什么格式做好,网站制作和如何推广节点角色说明#xff1a; Provider:暴露服务的服务提供方。 Consumer::调用远程服务的服务消费方。 Registry:服务注册与发现的注册中心。 Monitor:统计服务的调用次调和调用时间的监控中心。 Container:服务运行容器。 调用关系说明#xff1a; 0.服务容器负责启动#xff…
节点角色说明 Provider:暴露服务的服务提供方。 Consumer::调用远程服务的服务消费方。 Registry:服务注册与发现的注册中心。 Monitor:统计服务的调用次调和调用时间的监控中心。 Container:服务运行容器。 调用关系说明 0.服务容器负责启动加载运行服务提供者。 1.服务提供者在启动时向注册中心注册自己提供的服务。 2.服务消费者在启动时向注册中心订阅自己所需的服务。 3.注册中心返回服务提供者地址列表给消费者如果有变更注册中心将基于长连接推送变更数据给消费者。 4.服务消费者从提供者地址列表中基于软负载均衡算法选一台提供者进行调用如果调用失败再选另一台调用。 5.服务消费者和提供者在内存中累计调用次数和调用时间定时每分钟发送次统计数据到监控中心。
暴露流程
首先服务器端服务提供者在框架启动时会初始化服务实例通过Proxy组件调 用具体协议Protocol ,把服务端要暴露的接口封装成Invoker 真实类型是 AbstractProxylnvoker ,然后转换成Exporter,这个时候框架会打开服务端口等并记录服务实例 到内存中最后通过Registry把服务元数据注册到注册中心。这就是服务端服务提供者整 个接口暴露的过程。
Proxy组件我们知道Dubbo中只需要引用一个接口就可以调用远程的服务并且 只需要像调用本地方法一样调用即可。其实是Dubbo框架为我们生成了代理类调用 的方法其实是Proxy组件生成的代理方法会自动发起远程/本地调用并返回结果, 整个过程对用户完全透明。 • Protocol顾名思义协议就是对数据格式的一种约定。它可以把我们对接口的配置, 根据不同的协议转换成不同的Invoker对象。例如用DubboProtocol可以把XML文 件中一个远程接口的配置转换成一个Dubbolnvoker。 • Exporter用于暴露到注册中心的对象它的内部属性持有了 Invoker对象我们可以 认为它在Invoker上包了 一层。 • Registry把Exporter注册到注册中心。
使用
提供者provider服务提供者需要提供xxx-api.jar供消费者引入并使用其中包含的接口同时自身引入并实现相应的接口
provider暴露服务
在dubbo.xml中的xsl:schemalocation中加入
http://code.alibabatech.com/schema/dubbo http://code.allbabatech.com/schema/dubbo/dubbo.xsd
并注册
dubbo:registry address“$(dubbo.registry.address)” protocolzookeepergroupS(dubbo.group.smart_pnr)idtts_smart_pnr/
在dubbo-service.xml:
dubbo:service interfacecom.gunar.flight.tts.smart.pnr.api.ISmartPnrServiceref“iSmartPnrServicelmpl” version-1.0.0timeout-30000registry-“tts_smart_pnrclusterfallfast”/
消费者
引入api.jar
dubbo:registry address“ d u b b o . r e g i s t r y . a d d r e s s ” p r o t o c o l “ z o o k e e p e r ” g r o u p “ {dubbo.registry.address}” protocol“zookeeper” group“ dubbo.registry.address”protocol“zookeeper”group“{dubbo.group.smart_pnr}” id“tts_smart_pnr”/
dubbo:service interface“com.qunar.flight.tts.smart.pnr.api.ISmartPnrService” ref“iSmartPnrServiceImpl” version“1.0.0” timeout“30000” registry“tts_smart_pnr” cluster“failfast”/dubbo:reference id“iSmartPnrService” interfacecom.qunar.flight.tts.smart.pnr.api.ISmartPnrService registrytts_smart_pnr timeout5000 checkfalse clusterfailfast version1.0.0dubbo:method name“validateOnpay” timeout“6000”/
addressdubbo注册的zk的集群
protocoldubbo注册使用的协议
groupdubbo服务的所属组
Interface所提供的服务
ref对应的实现类
version提供的dubbo服务的版本号
timeout服务提供者的超时时间
cluster重试机制常用的有failfast、failover默认3次可以配合retries使用自定义重试次数
服务暴露流程
首先会通过initialize()方法完成初始化装配各种Config对象为后续的服务暴露和引用准备好环境。
ServiceConfig对象就是Dubbo对服务的描述对象服务暴露的逻辑都在ServiceConfig#export()里面Dubbo暴露服务也就是遍历所有的ServiceConfig挨个进行暴露。
ServiceConfig描述了对外提供的服务ref属性引用了具体的服务实现对象当Provider接收到Consumer发起的RPC调用时会交给ref执行但是Dubbo不会直接使用ref因为不管是Provider还是ConsumerDubbo都在向Invoker靠拢。
Invoker是本地调用、远程调用、集群调用
Dubbo服务暴露的入口在ServiceConfig#export()方法
配置的校验和更新 暴露服务 分发服务暴露事件
public synchronized void export() {// 检查和更新配置checkAndUpdateSubConfigs();if (shouldDelay()) {// 延迟暴露DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);} else {// 暴露服务doExport();}// 分发暴露事件exported();
}其中的checkAndUpdateSubConfigs()
对ServiceConfig对象做一些配置的校验和自动更新。例如使用ProviderConfig的全局默认配置、将protocolIds转换成ProtocolConfig对象、自身的属性按照优先级进行刷新等等。配置更新完了接下来就是做服务暴露的前置Check例如注册中心是否有效、ref对象是否符合要求等等。
private void checkAndUpdateSubConfigs() {// 使用ProviderConfig默认配置completeCompoundConfigs();// ProviderConfig不存在则自动创建checkDefault();// protocolIds转换checkProtocol();if (!isOnlyInJvm()) {// 服务注册还要检查配置中心checkRegistry();}// 自身属性根据优先级刷新this.refresh();checkStubAndLocal(interfaceClass);ConfigValidationUtils.checkMock(interfaceClass, this);ConfigValidationUtils.validateServiceConfig(this);postProcessConfig();代码有精简...
}doExport()
ServiceRepository repository ApplicationModel.getServiceRepository();
// 注册Service
ServiceDescriptor serviceDescriptor repository.registerService(getInterfaceClass());
// 注册Provider
repository.registerProvider(getUniqueServiceName(),ref,serviceDescriptor,this,serviceMetadata);接下来获取当前服务需要注册到哪些注册中心加载对应的URL。// 加载配置中心URL
ListURL registryURLs ConfigValidationUtils.loadRegistries(this, true);在Check那一步就已经解析了服务需要通过哪些协议进行暴露所以接下来会遍历protocols进行单协议多注册中心暴露。for (ProtocolConfig protocolConfig : protocols) {String pathKey URL.buildKey(getContextPath(protocolConfig).map(p - p / path).orElse(path), group, version);repository.registerService(pathKey, interfaceClass);serviceMetadata.setServiceKey(pathKey);// 单协议多注册中心暴露doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}服务暴露需要用到各种参数用于构建后续的服务暴露URL这里会使用HashMap存储。Dubbo的配置粒度是到方法级别的对应的类是MethodConfig如果有方法级别的配置也需要解析到Map中。// 服务暴露的各种参数用于组装服务暴露URL
MapString, String map new HashMapString, String();
map.put(SIDE_KEY, PROVIDER_SIDE);
// 运行时参数
ServiceConfig.appendRuntimeParameters(map);
AbstractConfig.appendParameters(map, getMetrics());
AbstractConfig.appendParameters(map, getApplication());
AbstractConfig.appendParameters(map, getModule());
......参数组装完毕解析出服务暴露的host和port然后构建URL。// 查找服务暴露的host和port
String host findConfigedHosts(protocolConfig, registryURLs, map);
Integer port findConfigedPorts(protocolConfig, name, map);
// 构建URL
URL url new URL(name, host, port, getContextPath(protocolConfig).map(p - p / path).orElse(path), map);服务暴露的范围可以通过scope属性配置none代表不暴露、local仅暴露到本地JVM、remote会暴露到远程。Dubbo在服务暴露前会进行判断默认情况下会同时暴露到本地JVM和远程。
服务注册
protected Registry getRegistry(final Invoker? originInvoker) {// 注册中心URLURL registryUrl getRegistryUrl(originInvoker);// SPI加载Registry实现return registryFactory.getRegistry(registryUrl);
}解析出需要注册到注册中心的URL然后调用RegistryService#register()完成服务注册。final Registry registry getRegistry(originInvoker);
// 注册到注册中心的URL
final URL registeredProviderUrl getUrlToRegistry(providerUrl, registryUrl);
// 是否立即注册
boolean register providerUrl.getParameter(REGISTER_KEY, true);
if (register) {register(registryUrl, registeredProviderUrl);
}最终操作
public void doRegister(URL url) {final String serviceName getServiceName(url);final Instance instance createInstance(url);// 注册服务最终调用 NamingService#registerInstance()execute(namingService - namingService.registerInstance(serviceName,getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP), instance));
}Dubbo服务暴露先将ref封装成InvokerInvoker会根据Consumer的Invocation参数对ref发起调用Dubbo默认使用javassist字节码技术动态生成Wrapper类避免了Java反射带来的性能问题。 有了Invoker就可以通过Protocol根据协议进行服务暴露如果服务需要注册Dubbo会改写URL协议为registry这是个伪协议只是在原服务暴露的基础上增加了服务注册的功能。 在根据协议暴露服务前还需要关注两个包装类ProtocolFilterWrapper和ProtocolListenerWrapper前者用于构建Filter链后者用于服务取消暴露时触发事件。 以dubbo协议为例除了创建DubboExporter还会根据服务暴露的address创建ProtocolServer。Transporter是dubbo对网络传输层的抽象接口以Netty为例底层其实就是创建了ServerBootstrap然后bind本地接口监听网络请求。