1. Dubbo架构
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
Dubbo Consumer并不是直接通过https等方式直接调用Provider,而是Provider接口实现代理方式,让Consumer像调用本地方法一样进行远程调用Provider。这样通过代理方式好处:
a) Provider和Consumer解耦
b) 代理类中新增过滤操作、服务降级、容错等机制
c) 调用的负载均衡
d) 接口调用数据统计
2. Dubbo整体架构设计
Business Service层:业务层,日常开发中的业务逻辑层
Config 层:对外配置接口
proxy层:服务代理层,provider和consumer都会生成动态代理类。生成provider端Stub和consumer端Skeleton,负责远程调用和数据返回
registry层:注册中心,封装服务地址的注册和发现,注册中心保存provider的ip、port以及调用方式(proxy)
protocol层:远程调用层,封装rpc调用的具体过程
Cluster层:路由层,封装多个provider的路由和负载均衡
monitor层:监控中心,rpc调用次数和调用时间监控
serialize层:数据序列化层,负责provider和consumer网络传输数据的序列化与反序列化。一般是将需要传输的数据类implements Serializable
3. Dubbo原理
Dubbo远程调用是通过动态代理实现的,使用动态代理来屏蔽远程调用的细节。
Provider Consumer都是通过代理类实现,Invoker 就是 Dubbo 对远程调用的抽象。在服务提供方,Invoker用于调用服务提供类。在服务消费方,Invoker用于执行远程调用
3.1 Provider端:生成代理类、注册
首先provider启动,Protocol通过Proxy代理将需要暴露的接口封装成Invoker,是一个可执行体。然后通过Exporter包装发送到注册中心完成注册,至此provider端服务暴露完成。具体如下
- 服务提供者在启动的时候,会通过读取一些配置将服务实例化。
- Proxy 封装服务调用接口,方便调用者调用。客户端获取 Proxy 时,可以像调用本地服务一样,调用远程服务。
- Proxy 在封装时,需要调用 Protocol 定义协议格式,例如:Dubbo Protocol。
- 将 Proxy 封装成 Invoker,它是真实服务调用的实例。
- 将 Invoker 转化成Exporter,Exporter 只是把 Invoker 包装了一层,是为了在注册中心中暴露自己,方便消费者使用。
- 将包装好的Exporter 注册到注册中心。
3.2 Consumer端:服务调用
- 服务消费者建立好实例,会到服务注册中心订阅服务提供者的元数据(元数据包括服务 IP 和端口以及调用方式(Proxy)),并保存到本地缓存,这样及时所有注册中心宕机,provider和consumer也可以通过本地缓存进行通讯,只是其中一方信息变更另一方无法感知。
- 消费者会生成一个代理类,通过Proxyfactory生成一个Proxy代理类,Proxy持有一个Invoker可执行对象
- 调用 Invoker之后,通过 Directory 获取服务提供者的Invoker 列表。在分布式的服务中有可能出现同一个服务,分布在不同的节点上。
- 通过路由规则了解,服务需要从哪些节点获取。
- Invoker 调用过程中,通过 Cluster 进行容错,如果遇到失败策略进行重试。
- 调用中,由于多个服务可能会分布到不同的节点,就要通过 LoadBalance 来实现负载均衡。
- Invoker 调用之前还需要经过Filter,它是一个过滤链,用来处理上下文,限流和计数的工作。
- 接下来用 Client 进行数据传输,一般用Netty进行传输
- Codec 会根据 Protocol 定义的协议,进行协议的构造。
- 构造完成的数据,通过序列化 Serialization 传输给服务提供者。
-
3.3 Provider收到Consumer调用处理
- Request 已经到达了服务提供者,它会被分配到线程池(ThreadPool)中进行处理。
- Server 拿到请求以后查找对应的 Exporter(包含有 Invoker)。
- 由于 Export 也会被 Filter 层层包裹,通过Filter 后获得 Invoker最后,对服务提供者实体进行调用。
- 最终将结果原路返回
4 MDC
MDC可理解为线程安全的存放诊断日志的容器
MDC数据结构是key-value格式,api有MDC.put(k,v) MDC.remove(k), MDC.get(k)
MDC值是与线程绑定在一起的,不同线程间互不影响。其线程安全原因是底层使用ThreadLocal
MDC使用场景:
a) Web应用中,如果想在日志中输出请求用户IP、请求URL、系统耗时等,MDC都成支撑
b)借助MDC保存用户请求时requestId,当请求完成后再将这个requestId移除。这样通过grep requestId就可以轻松获取整个请求流程的日志轨迹
c)微服务中,链路追踪是一个难题,借助MDC去埋点,巧妙实现链路追踪
5 SPI
https://blog.csdn.net/yangbaggio/article/details/97617750
https://blog.csdn.net/JavaShark/article/details/125210297
参考文献:
https://huaweicloud.csdn.net/63a568d6b878a54545946c16.html?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2~default~ESLANDING~activity-4-125233339-blog-120353520.235^v27^pc_relevant_landingrelevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~ESLANDING~activity-4-125233339-blog-120353520.235^v27^pc_relevant_landingrelevant
https://blog.csdn.net/ChenRui_yz/article/details/127438988
https://blog.csdn.net/TaylorSwiftiiln/article/details/120353520
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix