分布式--Dubbo入门

Dubbo是阿里的内部RPC框架,于2011年对外提供,2019年捐献给Apache,至此由Apache维护更新,Dubbo依赖Spring,除了RPC访问外,还提供了服务治理功能,如:负载均衡、数据统计等

结合上图,Dubbo主要分为5个角色:

角色 描述
Provider 服务提供者
Container 容器,即Spring容器,提供者借助Spring初始化
Register 注册中心,存放提供者对外提供的信息。如ip、端口、协议、对外接口等
Consumer 消费者,RPC调用方
Monitor 监控中心,统计访问情况

图中虚线部分均为异步,实线为同步,流程为:

0. start:启动Spring容器时,初始化Provider
1. register:Provider信息注册到Registry
2. subscribe:Consumer通过Registry订阅
3. notify:Registry将Provider信息通知给Consumer
4. invoke:Consumer通过Provider信息调用Provider方法
5. count:将访问信息上传到Monitor

Dubbo支持的协议

协议 优点 缺点
Dubbo协议(官方推荐) 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好 大文件上传时,可能出现问题
RMI协议 JDK自带 偶尔连接失败
Hessian协议 可与原生Hessian互操作,基于HTTP协议 需hessian.jar支持,http短连接的开销大

Dubbo支持的注册中心

注册中心 优点 缺点
Zookeeper(官方推荐) 支持分布式,生态圈大 受限于zookeeper软件的稳定性,但通过分布式辅助软件可以解决
Multicast 去中心化,不需要单独安装软件 Provider和Consumer和Registry不能跨机房(路由)
Redis 支持集群,性能高 要求服务器时间同步,否则会出现集群失败问题
Simple 标准RPC服务,没有兼容问题 不支持集群

一、使用Dubbo

创建一个maven工程,依赖springboot

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.7.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.7.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.8</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.2.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

1. api模块

新建Maven子模块,作为对外接口:

定义接口:

public interface DemoService {
    public String demo(String demo);
}

2. provider模块

新建Maven子模块,作为提供者

2.1 导入依赖

provider不需要作为web项目

    <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>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>
        <!--api模块-->
        <dependency>
            <groupId>com.aruba.demo1</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
2.2 springboot配置文件

resources目录下新建application.yml,配置dubbo,内容如下:

dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181
2.3 实现对外接口

使用@DubboService注解,表示该对象为Dubbo使用的Provider对象

@DubboService
public class DemoServiceImpl implements DemoService {

    @Override
    public String demo(String demo) {
        return demo + ",hello";
    }

}
2.4 启动springboot

使用注解开启dubbo

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

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

}

3. consumer模块

创建一个Maven子模块,作为调用方

3.1 导入依赖
    <dependencies>
        <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>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>
        <!--api模块-->
        <dependency>
            <groupId>com.aruba.demo1</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
3.2 springboot配置文件

在resources目录下新建application.xml,内容为:

dubbo:
  application:
    name: dubbo-consumer
  registry:
    address: zookeeper://192.168.42.4:2181
3.3 service层

定义接口:

public interface DemoConsumerService {
    public String demoConsumer();
}

实现接口,远程对象使用@DubboReference注解注入:

@Service
public class DemoConsumerServiceImpl implements DemoConsumerService {

    @DubboReference
    private DemoService service;

    @Override
    public String demoConsumer() {
        return service.demo("dubbo");
    }
}
3.4 controller层
@RestController
public class DemoController {

    @Autowired
    private DemoConsumerService service;

    @RequestMapping("/demo")
    public String demo() {
        return service.demoConsumer();
    }

}
3.5 SpringBoot启动类

同样需要使用@EnableDubbo注解开启dubbo

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

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

}

浏览器访问结果:

二、负载均衡

Dubbo内置了以下负载均衡策略:

策略名 描述
Random(默认) 随机访问集群中节点,概论与权重有关
RoundRobin 轮询访问集群中节点,频率与权重有关,2.7.8版本权重不设置不生效
LeastActive 活跃数相同的随机,高活跃数的优先访问
ConsistentHash 相同请求参数总是发到一个节点
ShortestResponse 最快响应,选出响应时间最短的节点

使用方式

Provider和Consumer都可以使用以上策略,指定策略名使用全小写,第一种方式为注解时指定:

对象 注解 指定属性
Provider @DubboService loadbalance 如:@DubboService(loadbalance = "roundrobin")
Consumer @DubboReference loadbalance 如:@DubboReference(loadbalance = "random")

第二种方式为springboot配置文件中指定全局策略:

dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181
  #指定provider的负载均衡策略
  provider:
    loadbalance: random
  #指定consumer的负载均衡策略
  consumer:
    loadbalance: random

下面以Provider注解为例子

1. 为Provider实现类指定策略

方法中加个控制台输出,以便于后续观察负载均衡策略的效果

@DubboService(weight = 1, loadbalance = "roundrobin")
public class DemoServiceImpl implements DemoService {

    @Override
    public String demo(String demo) {
        System.out.println(demo);
        return demo + ",hello";
    }

}

2. 模拟集群环境

复制springboot启动类:

springboot配置文件中,指定协议端口,来启动多次

dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181
  protocol:
    name: dubbo
    port: 20881

修改port,我这边是从20881改到20884,每次修改完启动下对应的springboot启动类,4个启动完的效果:

3. Consumer调用

轮询的效果是依次访问节点,启动Consumer后,进行浏览器访问:

项目地址:

https://gitee.com/aruba/dubbo.git

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容