6.服务暴露原理

简介: 本文详细解析了 Dubbo 服务发布的核心流程,包括本地暴露与远程暴露的区别、协议支持、服务注册等关键环节,并结合日志和源码分析了服务启动过程中的关键动作,帮助读者深入理解 Dubbo 的内部机制,适用于面试准备和技术研究。

前言

之前讲完了dubbo集群容错系列,现在开始讲比较重要的环节,也就是dubbo面试中比较喜欢问的两个点:服务发布服务引用.

插播面试题

  • 服务发布过程中做了哪些事
  • dubbo都有哪些协议,他们之间有什么特点,缺省值是什么
  • 什么是本地暴露和远程暴露,他们的区别

直入主题

从启动日志说起

大家都知道,dubbo是阿里巴巴开源的一个项目,前阵子阿里不仅发布的代码规范手册,还发布了相应的插件,从这点我们就知道,阿里是很注重这个代码规范的,从dubbo项目我们也发现了,他有完善的测试体系.说了这么说,那和我们今天要讲的dubbo的服务发布有什么关系呢?当然有,一个规范的项目,必然是有健全的日志系统.做过其他开发比如iOS开发的都知道,这个控制台输出在生产环境是不能随便输出的,太多日志有时候和没有日志是一样的.所以我们来看看这个服务启动过程中,日志究竟输出了什么.

这里我用不同颜色的框将关键的地方画了出来,一共有6种颜色,我一次从上到下说一下这发布过程的一些动作

  • 暴露本地服务
  • 暴露远程服务
  • 启动netty
  • 连接zookeeper
  • 到zookeeper注册
  • 监听zookeeper

从文档入手,了解全局

经常有人问到,看源码要怎么看.要了解这个服务发布,文档就是一个很好的切入口,如下

再献上文档提供的一个时序图

当然这些都是给已经对源码有一定熟悉的人看的,而我的源码解析类文档,是给对源码不熟悉的人看的.

其实我的每周一更dubbo源码系列文章,我的初衷有以下两个,一个就是做到系统分享,比如dubbo系列文章,我会从不少于内核,服务发布,服务引用,编解码这四个模块去剖析,后面如果有时间,会临摹一个简易的dubbo框架.另一个初衷就是把自己思考的过程和大家分享,在这个分享过程中,其实就是回答了"怎么看源码"这个问题

那么准备好五菱宏光,向秋名山出发

出发秋名山

我早年做Android开发的时候,就发现身边的人都是死在了一个点上,那就是配置环境.对于看源码,很多人最常问的一句话就是,怎么入手,也就是切入点.那么我们还是以开头的日志为例,来找一个这个切入点

仔细看输出日志,就会发现在暴露本地服务之前,有一句很重要的日志,就是


The service ready on spring started. service: com.alibaba.dubbo.demo.DemoService, dubbo version: 2.0.0, current host: 127.0.0.1

我们利用编译器的搜索文本功能,定位到了ServiceBean这个类,这个类是干嘛的?好,我假设我也不知道,既然不知道,那我们来看一下他的继承体系图

从这个图我们看到了许多和spring有关的东西,还发现了一个重要的接口,那就是ApplicationListener.要能敏锐的发现这个关键的接口,首先还是要对spring有一定了解,这个就是spring的事件机制(event).什么是事件机制呢?就比如监听spring容器初始化完成.那我们就定位到这行日志的位置,往下debug




下面要开始敲黑板划重点了.




从方法名我们很直观知道目的,但是这里同事不止一次问过我,这个dubbo.properties文件是怎么时候加载的,好像我根本没有设置,另外这个dubbo.properties文件的名字能不能改?面对这种问题,我从来都是不会直接把答案告诉他,而是告诉他,我是怎么得到这个答案的,如下图

同理,对于log4j.xml这个文件,好像我从来没有写代码加载过,为什么他会加载呢,其实也是同理的

接下来继续往下走,下面这里就是我们的第二道面试题

这里为什么会进行遍历呢,因为dubbo是支持多协议的,看文档原话

dubbo支持多种协议,默认使用的是dubbo协议,具体介绍官方文档写得很清楚,传送地址:相关协议介绍

马不停蹄,下面就到了第三个面试题,也是服务发布的重点,本地暴露远程暴露

为什么会有本地暴露远程暴露呢?不从场景考虑讨论技术的没有意义是.在dubbo中我们一个服务可能既是Provider,又是Consumer,因此就存在他自己调用自己服务的情况,如果再通过网络去访问,那自然是舍近求远,因此他是有本地暴露服务的这个设计.从这里我们就知道这个两者的区别

  • 本地暴露是暴露在JVM中,不需要网络通信.
  • 远程暴露是将ip,端口等信息暴露给远程客户端,调用时需要网络通信.

本篇着重讲解服务发布的整体过程,细节和总结后面会陆续展开.我们忘记下.其实注意一下我这些截图就能发现,我截的时候会特意把类名和方法名都截出来,方便大家能迅速定位.



从上图可知,这里用到了Adaptive(这个东西非常关键,后面会专门一篇讲解).点进ProxyFactory查看源码

@Adaptive注解打在类上和方法上,他们是有区别的(面试也喜欢问这种区别类的问题,这个留在Adaptive专题说,记得关注肥朝每周一篇源码解析 _ ),他打在方法上,就会生成动态编译的Adaptive类,下面就介绍一下怎么看这个动态编译类的源码

首先要将这个log4j的level调整为DEBUG

为什么需要调整成DEBUG,更重要的是把如何知道的,告诉大家,比如如下图,当然这个时候可能会朋友说,我也不知道这个类也还是没办法找到这行代码.其实这个也是在后面专门的一篇Adaptive中会说,到时候我会提供另一种实现思路,我们一起思考对比优劣.


打开DEBUG后,我们重新启动,就会看到日志有如下输出,这段就是相关代码,我们根据包名新建文件,如下



我们在getInvoker方法上打上断点,重启一下.



由上图知道,本地暴露的url是以injvm开头的,下面来看下远程暴露,其实这个也是回答本地暴露远程暴露区别的一个回答点.面试回答要的并不是一个满分的答案,而是从一些细节中,看出一个人,是否真的研究过源码.

还是回到开头那句话,dubbo命名是很规范的,从Wrapper这个命名,其实可以和Spring的Bean Wrapper,以及装饰者设计模式联系起来.同时可以看看文档中的

写在最后

上面讲到了getInvoker方法,也就是拿到了Invoker,如果注意到本篇开头的文档说明中的那句Dubbo 处理服务暴露的关键就在 Invoker 转换到 Exporter 的过程,就知道,其实这个服务暴露还有很多细节是未完待续的,但是由于本篇已有一定篇幅,所以只能下周再见.


相关文章
|
数据采集 机器学习/深度学习 搜索推荐
探索数据之海——网络爬虫与数据抓取技术的应用与发展
在当今信息爆炸的时代,获取大量高质量的数据成为各行各业的迫切需求。网络爬虫和数据抓取技术作为一种有效的手段,正在被广泛应用于各个领域。本文将深入探讨网络爬虫的原理、应用场景以及未来的发展趋势,为读者带来关于数据抓取技术的全面了解。
1003 5
|
4月前
|
消息中间件 Java Nacos
SpringCloud概述
Spring Cloud是Spring团队推出的微服务一站式解决方案,弥补了各独立组件(如Nacos、RabbitMQ等)缺乏统一架构的不足。其特点为约定优于配置、组件丰富、开箱即用,支持云原生。版本以伦敦地铁站命名,避免与子项目冲突。Spring Cloud Alibaba由阿里贡献,集成Nacos、Sentinel、Seata等成熟组件,因Netflix套件停更,现成为主流选择,功能更完整且经大规模验证,是当前微服务架构的优选技术栈。
|
7月前
|
Dubbo 应用服务中间件 Apache
5.WebService
基于 Apache CXF 的 WebService 协议实现,支持与原生 WebService 服务互操作,适用于系统集成和跨语言调用。
|
人工智能 安全 Dubbo
Spring AI 智能体通过 MCP 集成本地文件数据
MCP 作为一款开放协议,直接规范了应用程序如何向 LLM 提供上下文。MCP 就像是面向 AI 应用程序的 USB-C 端口,正如 USB-C 提供了一种将设备连接到各种外围设备和配件的标准化方式一样,MCP 提供了一个将 AI 模型连接到不同数据源和工具的标准化方法。
7934 114
|
8月前
|
监控 搜索推荐 算法
小红书电商 API 接口:开启小红书种草商品销售转化新路径
小红书电商 API 接口打通“种草”与销售链路,助力商家实现高效转化。通过自动化数据对接、精准营销与个性化推荐,提升运营效率,降低人力成本,推动销售增长。
383 0
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
2020 12
|
10月前
|
缓存 NoSQL Java
Java Redis 面试题集锦 常见高频面试题目及解析
本文总结了Redis在Java中的核心面试题,包括数据类型操作、单线程高性能原理、键过期策略及分布式锁实现等关键内容。通过Jedis代码示例展示了String、List等数据类型的操作方法,讲解了惰性删除和定期删除相结合的过期策略,并提供了Spring Boot配置Redis过期时间的方案。文章还探讨了缓存穿透、雪崩等问题解决方案,以及基于Redis的分布式锁实现,帮助开发者全面掌握Redis在Java应用中的实践要点。
535 6
|
SQL Java 数据库连接
Mybatis实现及原理
什么是Mybatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
9479 0