百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

探索分布式服务框架-Dubbo整体架构与实现原理

ccwgpt 2024-10-02 12:10 33 浏览 0 评论

前言

一、简介

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

二、优点

1.面向接口的远程方法调用

2.智能容错和负载均衡

3.服务自动注册和发现

4.服务接口监控与治理

三、Dubbo架构

1、 节点说明

2、调用关系说明(6步)

0.服务容器负责启动,加载,运行服务提供者。 
1.服务提供者在启动时,向注册中心注册自己提供的服务。 
2.服务消费者在启动时,向注册中心订阅自己所需的服务。 
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

3、Dubbo提供的注册中心有如下几种类型可供选择

- Multicast注册中心
- Zookeeper注册中心(推荐使用)
	(注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。)
- Redis注册中心
- Simple注册中心

四、推荐顺序

1.启动zookeeper注册中心

2.启动管理控制台

3.编写并启动provider

4.最后编写并启动consumer

五、服务提供者

①、pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
</parent>

<dependencies>
    <!--基础环境-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!--dubbo的起步依赖-->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.5</version>
    </dependency>
    <!-- zookeeper的api管理依赖 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>4.2.0</version>
    </dependency>
    <!-- zookeeper依赖 -->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.12</version>
    </dependency>
        <!--依赖公共接口-->
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>dubbo-demo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
</dependencies>

②、编写service实现类

@Service // 注意:这里使用org.apache.dubbo包下的
public class UserServiceImpl implements UserService {

    @Override
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

③、application.yml

# dubbo.application.name       服务名称,一般跟模块名称一致即可
# dubbo.application.qos-port   服务质量模块的端口,默认值:22222
# dubbo.registry.address       注册中心的连接地址
# dubbo.protocol.name          当前服务的访问协议,支持dubbo、rmi、hessian、http、webservice、rest、redis等
# dubbo.protocol.port          当前服务的访问端口
# dubbo.scan.base-packages     包扫描,将对象交给ioc容器并暴露到注册中心

dubbo:
  application:
    name: dubbo-demo-provider
    qos-port: 22223
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20880
  scan:
    base-packages: com.zj.service

④、启动类

@SpringBootApplication
public class ProviderApp {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApp.class, args);
    }
}

六、服务消费者

①、pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
</parent>

<dependencies>
    <!--web环境-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--dubbo的起步依赖-->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.5</version>
    </dependency>
    <!-- zookeeper的api管理依赖 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>4.2.0</version>
    </dependency>
    <!-- zookeeper依赖 -->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.12</version>
    </dependency>
    <!--依赖公共接口-->
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>dubbo-demo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
</dependencies>

②、编写controller

@RestController
public class UserController {
 
    @Reference // 使用 org.apache.dubbo 包下注解
    private UserService userService;
    
    @GetMapping("/user/hello")
    public String sayHello(String name){
        return userService.sayHello(name);
    }
}

③、application.yml

# dubbo.application.name       服务名称,一般跟模块名称一致即可
# dubbo.registry.address       注册中心的连接地址
# dubbo.scan.base-packages     包扫描

dubbo:
  application:
    name: dubbo-demo-consumer
  registry:
    address: zookeeper://127.0.0.1:2181
  scan:
    base-packages: com.zj.controller

④、启动类

@SpringBootApplication
public class ConsumerApp {
    
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class, args);
    }
}

七、公共接口模块抽取

①、pom.xml

<dependencies>
    <!-- 因为本次我们简单练习案例,所以导入该坐标依赖,将实体类写到该模块
	-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
</dependencies>

<!--没有父工程进行版本锁定,所以手动设置jdk和字符集编码-->
<build>
    <plugins>
        <!-- 设置编译版本为1.8 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

②、编写service接口

 String sayHello(String name);

八、使用细节

1、序列化

dubbo底层是需要通过网络传输数据的,因此被传输的对象必须实现序列化接口 当消费者和服务生产者之间进行传输时,不管是参数还是返回值,只要是传输的都必须实现序列化接口

2、启动时检查

启动时检查,配置在服务消费者一方,用于服务消费者在启动的时候主动检查注册中心或者服务提供者是否准备好提供服务

1.如果配置为false,代表不检查

2.如果配置为true,代表检查,一旦检查到服务提供者未准备好,就会直接抛异常

dubbo:
	consumer:  # 检查服务提供者是否正常启动
		check: false
	registry:  # 检查注册中心是否正常启动
		check: false

3、服务超时

服务消费者在调用服务提供者的时候可能会发生阻塞、等待的情形,这个时候,如果服务消费者会一直等下去,就会造成线程堆积,服务宕机。

① 全局配置

如果同时设置了,消费者提供者优先级高

# dubbo允许设置一个服务的超时时间(默认为1s),如果超过这个时间,服务无法作出反应,直接终止线程。
dubbo:
	provider:
		timeout: 5000
		retries: 0

# 这个时间可以设置在服务调用者一端,也可以设置在服务提供者一端
dubbo:
	consumer:
		timeout: 3000
		retries: 0

② 局部配置【推荐】

dubbo还支持在类上定义超时时间,其优先级高于全局配置

//1. 在服务提供端声明
@Service(timeout = 3000, retries = 0) 
public class UserServiceImpl implements UserService{}

//2. 在服务调用端声明
public class Controller{
	@Reference(timeout = 6000,retries = 0)
	private UserService userService;    
}

4、服务重试

dubbo设置了超时时间,如果在这个时间段内,无法完成服务访问,则自动断开连接。

为了弥补这一特性的缺点,保证系统健壮,dubbo提供了重试机制。

public class Controller{
	@Reference(timeout = 2000,retries = 4)  // 默认值是重试两次
	private UserService userService;    
}

5、 服务降级

当一个请求发生超时,一直等待着服务响应,那么在高并发情况下,很多请求都是因为这样一直等着响应,直到服务资源耗尽产生宕机,而宕机之后会导致分布式其他服务调用该宕机的服务也会出现资源耗尽宕机, 这样下去将导致整个分布式服务都瘫痪。

@RestController
public class Controller {

    @Reference(mock = "fail:return 默认值")
    private Us`erService userService;
}

6、负载均衡–智能容错

负载均衡策略 : 解决服务器消费者的一个请求到底应该由哪一个服务提供者去处理

在高并发情况下,一个服务往往需要以集群的形式对外工作。

dubbo支持四种负载均衡策略:

Random:按权重随机选择,这是默认值。

RoundRobin:按权重轮询选择。

LeastActive:最少活跃调用数,相同活跃数的随机选择。

ConsistentHash:一致性Hash,相同参数的请求总是发到同一提供者。

使用:

@Reference(loadbalance = "RoundRobin")

集群和分布式区别:

集群:(高可用) 多台服务器重复完成同一个任务,即同一个任务部署在多台服务器上

分布式:(高性能) 多台服务器协同完成同一个任务,即同一个任务拆分为多个子任务,多个子任务部署在多台服务器上协同完成同一个任务

7 、多版本

dubbo使用version属性来设置和调用同一个接口的不同版本

实例:

①、服务提供者1(provider1)

@Service(version = "v1.0") //设置版本为v1.0
public class HelloServiceImpl implements HelloService {}

②、服务提供者2(provider2)

@Service(version = "v2.0")  //设置版本为v2.0
public class HelloServiceImpl implements HelloService {}

③、服务消费者(consumer)

@RestController
public class HelloController {
	@Reference(version = "v1.0")  // 指定哪个版本
	 private HelloService helloService;
}

最后

最近面试的小伙伴挺多的,小编整理了全套的Java面试宝典手册,“性能调优+微服务架构+并发编程+开源框架+分布式”等七大面试专栏,包含Tomcat、JVM、MySQL、SpringCloud、SpringBoot、Dubbo、并发、Spring、SpringMVC、MyBatis、Zookeeper、Ngnix、Kafka、MQ、Redis、MongoDB、memcached等等。如果你对这个感兴趣,小编可免费分享。

资料获取方式:关注小编+转发文章+私信【面试题】获取上述资料~

重要的事情说三遍,转发+转发+转发,一定要记得转发哦!!!

相关推荐

用Steam启动Epic游戏会更快吗?(epic怎么用steam启动)

Epic商店很香,但也有不少抱怨,其中一条是启动游戏太慢。那么,如果让Steam启动Epic游戏,会不会速度更快?众所周知,Steam可以启动非Steam游戏,方法是在客户端左下方点击“添加游戏”,然...

Docker看这一篇入门就够了(dockerl)

安装DockerLinux:$curl-fsSLhttps://get.docker.com-oget-docker.sh$sudoshget-docker.sh注意:如果安装了旧版...

AYUI 炫丽PC开发UI框架2016年6月15日对外免费开发使用 [1]

2016年6月15日,我AY对外发布AYUI(WPF4.0开发)的UI框架,开发时候,你可以无任何影响的去开发PC电脑上的软件exe程序。AYUI兼容XP操作系统,在Win7/8/8.1/10上都顺利...

别再说C#/C++套壳方案多了!Tauri这“借壳生蛋”你可能没看懂!

浏览器套壳方案,C#和C++有更多,你说的没错,从数量和历史积淀来看,C#和C++确实有不少方式来套壳浏览器,让Web内容在桌面应用里跑起来。但咱们得把这套壳二字掰扯清楚,因为这里面学问可大了!不同的...

OneCode 核心概念解析——Page(页面)

在接触到OneCode最先接触到的就是,Page页面,在低代码引擎中,页面(Page)设计的灵活性是平衡“快速开发”与“复杂需求适配”的关键。以下从架构设计、组件系统、配置能力等维度,解析确...

React是最后的前端框架吗,为什么这么说的?

油管上有一位叫Theo的博主说,React是终极前端框架,为什么这么说呢?让我们来看看其逻辑:这个标题看起来像假的,对吧?React之后明明有无数新框架诞生,凭什么说它是最后一个?我说的“最后一个”不...

面试辅导(二):2025前端面试密码:用3个底层逻辑征服技术官

面试官放下简历,手指在桌上敲了三下:"你上次解决的技术难题,现在回头看有什么不足?"眼前的候选人瞬间僵住——这是上周真实发生在蚂蚁金服终面的场景。2025年的前端战场早已不是框架熟练...

前端新星崛起!Astro框架能否终结React的霸主地位?

引言:当"背着背包的全能选手"遇上"轻装上阵的短跑冠军"如果你是一名前端开发者,2024年的框架之争绝对让你眼花缭乱——一边是React这位"背着全家桶的全能选...

基于函数计算的 BFF 架构(基于函数计算的 bff 架构是什么)

什么是BFFBFF全称是BackendsForFrontends(服务于前端的后端),起源于2015年SamNewman一篇博客文章《Pattern:BackendsFor...

谷歌 Prompt Engineering 白皮书:2025年 AI 提示词工程的 10 个技巧

在AI技术飞速发展的当下,如何更高效地与大语言模型(LLM)沟通,以获取更准确、更有价值的输出,成为了一个备受关注的问题。谷歌最新发布的《PromptEngineering》白皮书,为这一问题提供了...

光的艺术:灯具创意设计(灯光艺术作品展示)

本文转自|艺术与设计微信号|artdesign_org_cn“光”是文明的起源,是思维的开端,同样也是人类睁眼的开始。每个人在出生一刻,便接受了光的照耀和洗礼。远古时候,人们将光奉为神明,用火来...

MoE模型已成新风口,AI基础设施竞速升级

机器之心报道编辑:Panda因为基准测试成绩与实际表现相差较大,近期开源的Llama4系列模型正陷入争议的漩涡之中,但有一点却毫无疑问:MoE(混合专家)定然是未来AI大模型的主流范式之一。...

Meta Spatial SDK重大改进:重塑Horizon OS应用开发格局

由文心大模型生成的文章摘要Meta持续深耕SpatialSDK技术生态,提供开自去年9月正式推出以来,Meta持续深耕其SpatialSDK技术生态,通过一系列重大迭代与功能增强,不断革新H...

&quot;上云&quot;到底是个啥?用&quot;租房&quot;给你讲明白IaaS/PaaS/SaaS的区别

半夜三点被机房报警电话惊醒,顶着黑眼圈排查服务器故障——这是十年前互联网公司运维的日常。而现在,程序员小王正敷着面膜刷剧,因为公司的系统全"搬"到了云上。"部署到云上"...

php宝塔搭建部署thinkphp机械设备响应式企业网站php源码

大家好啊,欢迎来到web测评。本期给大家带来一套php开发的机械设备响应式企业网站php源码,上次是谁要的系统项目啊,帮你找到了,还说不会搭建,让我帮忙录制一期教程,趁着今天有空,简单的录制测试了一下...

取消回复欢迎 发表评论: