前言
这几天简单的看了一下dubbo的一些源码,说实话没怎么看懂,最后看看博客,有一些心得写下来
dubbo架构
这个图很重要!
- Provider(提供者)绑定指定端口并启动服务
- 指供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储
- Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心
- 注册中心根据 消费 者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存。
- Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。
- Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer
服务暴露
- dubbo服务暴露会在spring对bean实例化完,ioc进行容器刷新完之后开始的
- 他会将配置文件中的配置解析到ServiceConfig,进行调用doExportUrlsFor1Protocol
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
exportLocal(url);
}
if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
if (registryURLs != null && !registryURLs.isEmpty()) {
for (URL registryURL : registryURLs) {
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter = protocol.export(wrapperInvoker);
exporters.add(exporter);
}
} else {
}
}
}
}
- 根据配置信息进行选择本地调用还是远程调用
- proxyFactory.getInvoker 利用java(javassist)动态代理生成invoker 对象
- 然后再通过 URL 参数选择对应的协议来进行 protocol.export,默认是 Dubbo 协议
- 最后添加到exporters 中存起来
服务引用
- 首先服务会根据url等配置信息进行组装
- 然后在RegistryProtocol doRefer方法中创建了RegistryDirectory,接着又向注册中心订阅了并且订阅提供者、配置、路由等节点
- 得知提供者的信息之后会进入 Dubbo 协议的引入,会创建 Invoker ,期间会包含 NettyClient,来进行远程通信
- 最后通过 Cluster (默认是FailoverCluster)来包装 Invoker ,最终返回代理类
服务调用
- 调用某个接口的方法会调用之前(服务引用)生成的代理类,
- 然后会从 cluster 中经过路由的过滤、负载均衡机制选择一个 invoker 发起远程调用,此时会记录此请求和请求的 ID 等待服务端的响应
- 服务端(服务提供者)接受请求之后会通过参数找到之前(服务暴露)暴露存储的 map,得到相应的 exporter ,然后最终调用真正的实现类,再组装好结果返回,这个响应会带上之前请求的 ID。
- 消费者收到这个响应之后会通过 ID 去找之前记录的请求,然后找到请求之后将响应塞到对应的 Future 中,唤醒等待的线程,最后消费者得到响应,一个流程完毕。
|