Dubbo简介以及SpringBoot2.X集成Dubbo2.7.8

2 篇文章 0 订阅
1 篇文章 0 订阅

Dubbo

前言

一、什么是分布式框架

​ 分布式系统是若干独立系统的集合,但是用户使用起来像是在使用一套系统


二、为什么需要分布式系统

规模的逐步扩大和业务的复杂,单台计算机扛不住双十一那样的流量,俗话说:三个臭皮匠抵一个诸葛亮。


三、应用架构的发展演变


(1)单一架构

当网站流量很小的时候,我们将所有的应用(业务)放到一台服务器上,打包运行公司管理系统/超市收银系统

优点:开发简单,部署简单

缺点:扩展不容易(怎么处理日益增长的流量),谁都改一个,维护不容易,性能提升难

(2)垂直应用架构

将大应用拆分成为小应用(一般按照业务拆分),根据不同的访问频率决定各自业务部署的服务器数量

优点:扩展容易

缺点:页面一改,可能造成整个项目重新部署,业务和界面没有分离开,随着业务种类增加,怎么解决业务之间的互相调用问题,订单服务器和用户服务器交互效率的问题

(3)分布式架构(基于RPC:远程过程调用)

将业务拆分后,用某种方式实现各个业务模块的远程调用和复用,这时一个好的RPC框架就决定了你的分布式架构的性能,怎么调用,何时调用,服务器挂了怎么办…我们需要一个框架来帮我们解决这个问题(当然大大神可以自己写一个,但是应对大流量的成功者莫过于中国的阿里巴巴公司,顶住了淘宝双十一的流量,反观一些学校内部的选课系统,对于大流量时只有两个字–宕机)。

(4)流动计算架构

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。


第一章:初识Dubbo

1.1为什么Dubbo说自己性能高

​ 高性能要从底层的原理说起,既然是一个RPC框架,主要干的就是远程过程(方法)调用,那么提升性能就要从最关键、最耗时的两个方面入手:序列化和网络通信。

​ 序列化:我们学习Java网络开发的时候知道,本地的对象要实现Serializable接口,也就是必须序列化。我们序列化的方案很多:xml、json、二进制流…其中效率最高的就是二进制流(因为计算机就是二进制的)。然而Dubbo采用的就是效率最高的二进制。

​ 网络通信:不同于HTTP需要进行7步走(三次握手和四次挥手),Dubbo采用Socket通信机制,一步到位,提升了通信效率,并且可以建立长连接,不用反复连接,直接传输数据


1.2别的RPC框架

gRPC

Thrift

HSF


1.3dubbo的前世今生

dubbo之前一直都作为Alibaba公司内部使用的框架。

2011年dubbo被托管到了GitHub上(开源)

2014年11月发布2.4.11版本后宣布停止更新。此后一段时间很多公司开源了自己基于Dubbo的变种版本(例如当当网的Dubbo X,网易考拉的Dubbo K)

2017年SpringCloud横空出世,Dubbo感觉到压力后连续更新了几个版本

2018年1月,阿里公司联合当当网将Dubbo和Dubbo X合并,发布了2.6版本

2018年除夕夜阿里将Dubbo贡献给了Apache基金会

2018除夕夜至今,Apache维护和更新Dubbo


第二章:Dubbo框架


2.1:dubbo概述

​ Apache Dubbo |ˈdʌbəʊ| 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。

  1. 面向接口代理的高性能RPC调用:提供高性能的基于代理的远程调用能力,服务以接口为粒度,为开发者屏蔽远程调用底层细节。
  2. 负载均衡:内置多种负载均衡策略,智能感知下游节点健康状况,显著减少调用延迟,提高系统吞吐量。
  3. 服务自动注册和发现:支持多种注册中心服务,服务实例上下线实时感知。
  4. 高度可扩展能力:遵循微内核+插件的设计原则,所有核心能力如Protocol、Transport、Serialization被设计为扩展点,平等对待内置实现和第三方实现。
  5. 运行流量调度:内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能。
  6. 可视化的服务治理与运维:内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能。

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

官网:Apache Dubbo在这里插入图片描述


Dubbo架构

在这里插入图片描述

init:初始化

async:异步

sync:同步

在这里插入图片描述


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

Dubbo 架构具有以下几个特点,分别是连通性健壮性、伸缩性、以及向未来架构的升级性


2.2:Dubbo支持的协议

​ 支持多种协议:dubbo,hessian,rmi,http,webservice,thrift,memcached,redis。dubbo官方推荐使用dubbo协议。dubbo协议默认端口20880

第三章:其他

3.1:启动时检查

在启动时检查依赖的服务是否可用

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"

可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。

三种方式

1.通过@DubboReference注解添加属性

如果是springboot项目的话只需在@DubboReference注解中添加check=false(@DubboReference(check=false))


2.通过properties文件配置

#摘自官网示例
#对某个接口不检查
dubbo.reference.com.foo.BarService.check=false
#对提供者不检查
dubbo.reference.check=false
#对消费者不检查
dubbo.consumer.check=false
#对注册中心不检查
dubbo.registry.check=false

3.通过配置xml

<!--关闭某个服务的启动时检查 (没有提供者时报错)-->
<dubbo:reference interface="com.foo.BarService" check="false" />
<!--关闭所有服务的启动时检查 (没有提供者时报错)-->
<dubbo:consumer check="false" />
<!--关闭注册中心启动时检查 (注册订阅失败时报错)-->
<dubbo:registry check="false" />


3.2:容错与屏蔽


容错

顾名思义就是当服务提供者出现异常时,消费者是否能够正常处理,在这里,我们关闭掉服务提供者,再进行调用,观察是否会报错

进行容错操作
在这里插入图片描述

在这里插入图片描述


屏蔽

当对某个服务启动屏蔽时,此时消费者调用该服务时均会返回空对象。首先我们需要确保提供者与消费者均已启动,然后在消费者中对提供者进行屏蔽。

在这里插入图片描述

在这里插入图片描述


自定义

其实屏蔽与容错还有更高级的配置,基本的屏蔽是返回空对象,我们甚至可以自定义返回内容。

进入动态配置,选择新增

在这里插入图片描述


3.3:负载均衡

Dubbo 提供的集群负载均衡策略

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。

可以自行扩展负载均衡策略,参见:负载均衡扩展


负载均衡策略

Random LoadBalance

  • 随机,按权重设置随机概率。
  • 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance

  • 轮询,按公约后的权重设置轮询比率。
  • 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance

  • 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
  • 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance

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

  • 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

  • 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing

  • 缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />

  • 缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />


    配置

    在springboot中配置@DubboReference(loadbalance = “roundrobin”)就可以了

    服务端服务级别

    <dubbo:service interface="..." loadbalance="roundrobin" />
    

    客户端服务级别

    <dubbo:reference interface="..." loadbalance="roundrobin" />
    

    服务端方法级别

    <dubbo:service interface="...">
        <dubbo:method name="..." loadbalance="roundrobin"/>
    </dubbo:service>
    

    客户端方法级别

    <dubbo:reference interface="...">
        <dubbo:method name="..." loadbalance="roundrobin"/>
    </dubbo:reference>
    

第四章:SpringBoot2.x整合Dubbo


公共API


把所需要的公共实体类(需要实现Serializable接口,注:必须序列化)、异常、业务提取到一个项目中打包上传到本地仓

在提供者和消费者项目中引用其依赖


提供者(provider)


1.在pom文件中引入依赖
 <properties>
        <!--zookeeper注册中心版本号-->
        <zookeeper.version>2.12.0</zookeeper.version>
  </properties>

		

		 <!--组件common(公共API)依赖-->
        <dependency>
            <groupId>cn.smbms</groupId>
            <artifactId>smbms-common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
 		<!-- Dubbo依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.8</version>
        </dependency>
		 <!-- zookeeper注册中心的curator客户端依赖 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>

如果项目未能解决依赖项,请尝试添加以下存储库

<project>
    ........
	<repositories>
   		<repository>
       	 <id>apache.snapshots.https</id>
        	<name>Apache Development Snapshot Repository</name>
        	<url>https://repository.apache.org/content/repositories/snapshots</url>
        	<releases>
            	<enabled>false</enabled>
        	</releases>
        	<snapshots>
            	<enabled>true</enabled>
        	</snapshots>
    	</repository>
	</repositories>
 </project>

2.在application.properties中配置
#spring的应用名称
spring.application.name=user-boot-provider
#应用名称(两种都可以↑↓)
#dubbo.application.name=user-boot-provider
#扫描dubbo组件的基本包
dubbo.scan.base-packages=cn.smbms.service.impl
#zookeeper注册中心的地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo的协议
dubbo.protocol.name=dubbo
#dubbo协议的端口号
dubbo.protocol.port=20804

3.在service实现类上加注解
/**
 * @Author 李延涛
 * @create 2021/5/16 19:14
 * @Component:标识为spring的组件
 * @DubboService(interfaceClass = cn.smbms.service.UserService.class):见解如下
 *   因为标识的是Dubbo的service,所以要添加@Component注解标示此类为spring的组件
 *   import org.apache.dubbo.config.annotation.DubboService;
 *   @DubboService:用于声明是提供方(provider)的注解
 *   interfaceclass:提供服务的接口
 */
@Component
@DubboService(interfaceClass = cn.smbms.service.UserService.class)
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Override
    public User searchUserById(Integer integer) {
        User user = userMapper.queryUserById(integer);
        return user;
    }
}

4.启动类
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 *@EnableDubbo:顾名思义启动dubbo服务
 */
@SpringBootApplication
@EnableDubbo
public class UserBootProviderApplication {

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

}
@EnableDubbo底层分析
/**
可以看到@EnableDubbo是@EnableDubboConfig和@DubboComponentScan的组合注解
@EnableDubboConfig:提供外部化配置属性与 Dubbo 配置类之间的绑定。
@DubboComponentScan:扫描dubbo暴露出来的接口的,要是不指定路径,在启动类配上会扫描整个项目。
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {

    /**
     * Base packages to scan for annotated @Service classes.
     * <p>
     * Use {@link #scanBasePackageClasses()} for a type-safe alternative to String-based
     * package names.
     *
     * @return the base packages to scan
     * @see DubboComponentScan#basePackages()
     */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y5e6BEp4-1621401999917)(C:\Users\123\AppData\Roaming\Typora\typora-user-images\image-20210517024031041.png)]


消费者(consumer)


1.在pom文件中引入依赖
 <properties>
        <!--zookeeper注册中心版本号-->
        <zookeeper.version>2.12.0</zookeeper.version>
  </properties>


		 <!--组件common(公共API)依赖-->
        <dependency>
            <groupId>cn.smbms</groupId>
            <artifactId>smbms-common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
 		<!-- Dubbo依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.8</version>
        </dependency>
		 <!-- zookeeper注册中心的curator客户端依赖 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>

如果项目未能解决依赖项,请尝试添加以下存储库

<project>
    ........
	<repositories>
   		<repository>
       	 <id>apache.snapshots.https</id>
        	<name>Apache Development Snapshot Repository</name>
        	<url>https://repository.apache.org/content/repositories/snapshots</url>
        	<releases>
            	<enabled>false</enabled>
        	</releases>
        	<snapshots>
            	<enabled>true</enabled>
        	</snapshots>
    	</repository>
	</repositories>
 </project>

2.在application.properties中配置
#spring应用名称
spring.application.name=meeting-boot-consumer
#zookeeper注册中心的地址
dubbo.registry.address=zookeeper://127.0.0.1:2181

3.service实现类
/**
 * @Author 李延涛
 * @create 2021/5/15 21:48
 * @Component:标识为spring的组件
 * 也可添加spring的service注解
 * @DubboReference:引用服务
 * @DubboReference(url = "dubbo://127.0.0.1:20804"):也可以不使用注册中心,
 *                              消费者和提供者直连,url="dubbo://localhost:20804"
 *@DubboReference(check=false):添加属性check:启动时检查是否开启(开:true,关:false,默认为开启状态)
 */
@Component
public class MeetingServiceImpl implements MeetingService {

    @DubboReference
   private UserService userService;
    /**
     * 根据会议编号Id查询会议详细信息
     *
     * @param meetingNo
     */
    @Override
    public Meeting searchMeetingById(String meetingNo) {
        Meeting meeting = new Meeting();
        meeting.setId(1001);
        meeting.setMettingNo(meetingNo);
        meeting.setTitle("开会");
        meeting.setContent("积极向上");
        meeting.setUid(1);
        System.out.println("远程服务调用:"+userService);
        meeting.setUser(userService.searchUserById(5));
        return meeting;
    }
}

4.启动类
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 *@EnableDubbo:顾名思义启动dubbo服务
 */
public class MeetingBootConsumerApplication {

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

}

效果图


项目启动前

在这里插入图片描述


项目都启动后

在这里插入图片描述


提供者

在这里插入图片描述


消费者

在这里插入图片描述


在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值