dubbo从入门到实战

1 互联网系统架构演变

​ 随着互联网的发展,网站应用规模不断壮大,由此系统架构也在不断演变,下图是一张经典的演变过程图:

image-20220204143340306

  • 单一应用架构

    ​ 优点:当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本

    ​ 缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护

    ​ 此时:用于简化增删改查工作量的数据访问框架(ORM)是关键

    image-20220204135821620

  • 垂直应用架构

    ​ 优点:解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率

    ​ 缺点:但是在垂直架构中相同逻辑代码需要不断的复制,不能复用。

    ​ 此时:用于加速前端页面开发的Web框架(MVC)是关键

    image-20220204140523510

  • 分布式应用架构(RPC)

    ​ 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心

    ​ 此时:用于提高业务复用及整合的分布式服务框架(RPC)是关键

    image-20220204140538092

  • 流动计算架构(SOA)

    ​ 随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架

    ​ 此时,用于提高机器利用率**资源调度和治理中心(SOA)**是关键。

2 什么是Dubbo

​ Dubbo是一个微服务开发框架,提供了RPC通信微服务治理两大关键能力。它提供了远程过程调用的能力,使得远程调用像本地调用一样方便

image-20220204205020171

​ Dubbo提供的基础能力包括:

  • 服务发现
  • 流式通信
  • 负载均衡
  • 流量治理
  • 集群容错
  • 服务降级

3 Dubbo总体架构

​ 以下是官网的一张图

image-20220204205839887

节点 说明
Consumer 需要调用远程服务的服务消费方
Registry 注册中心
Provider 服务提供方
Container 服务运行的容器
Monitor 监控中心

​ 通过上图,可以知道服务发现整体流程如下:

  1. 服务提供者Provider启动然后向注册中心注册自己所能提供的服务。
  2. 消费者Consumer启动向注册中心订阅所需的服务。
  3. 然后注册中心返回服务提供者地址列表给消费者Consumer,如果有变更,注册中心将基于长连接推送变更数据给消费者Consumer。
  4. 消费者Consumer就可以负载均衡选择一个Provier直接调用。
  5. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4 快速入门

​ 新建两个Maven项目,JDK版本1.8,Dubbo版本2.7,一个消费者,一个提供者

image-20220204211356423

  1. 引入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
    <artifactId>dubbo</artifactId>
    <groupId>com.tiza.leo</groupId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo_001_p</artifactId>

    <!--引入依赖-->
    <dependencies>
    <!-- core context beans spring三件套-->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.4.RELEASE</version>
    </dependency>
    <!-- dubbo 2.5.3-->
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
    </dependency>
    <!-- zookeeper zkclient-->
    <dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.12</version>
    </dependency>
    <dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
    </dependency>
    <!-- junit-->
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    </dependency>
    </dependencies>
    </project>
  2. 提供端代码

    image-20220204211624171

    UserService

    1
    2
    3
    4
    5
    6
    7
    8
    package com.w1nd.dubbo.service;

    public interface UserService {
    public String findName(String name);

    public void addUser(String username);
    }

    UserServiceImpl

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.w1nd.dubbo.service;

    public class UserServiceImpl implements UserService {
    public String findName(String name) {
    System.out.println("姓名:" +name);
    return "hello: "+name;
    }

    public void addUser(String username) {
    System.out.println("添加用户,用户名为: "+username);
    }
    }

    spring-dubbo.xml(重要)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?xml version="1.0" encoding="UTF-8"?>
    <!--suppress SpringFacetInspection -->
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--通过duboo发布服务 -->
    <dubbo:application name="dubbo_001_p"></dubbo:application>

    <!--将服务注册到指定的注册中心-->
    <dubbo:registry address="multicast://224.5.6.7:1234"></dubbo:registry>

    <!--指定服务的协议 和 使用端口号 注意此处服务端使用客户端无需使用 -->
    <dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>

    <dubbo:provider timeout="5000"></dubbo:provider> <!--定义超时时间方式一-->
    <!--注册服务到注册中心-->
    <dubbo:service interface="com.w1nd.dubbo.service.UserService" ref="userService" timeout="4000"> <!--定义超时时间方二-->
    <dubbo:method name="findName" timeout="3000"></dubbo:method> <!--定义超时时间方式三-->
    </dubbo:service>

    <!--服务提供者-->
    <bean id="userService" class="com.w1nd.dubbo.service.UserServiceImpl"></bean>

    </beans>

    测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.w1nd.dubbo.publish;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import java.io.IOException;

    import static org.junit.Assert.*;

    public class PublishServiceTest {

    public static void main(String[] args) throws IOException {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo.xml");
    System.out.println("服务提供者,开始提供服务.....");
    System.in.read();
    }

    }
  3. 消费端代码

    UserService

    1
    2
    3
    4
    5
    6
    7
    package com.w1nd.dubbo.service;

    public interface UserService {
    public String findName(String name);

    public void addUser(String username);
    }

    spring-dubbo.xml(重要)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="UTF-8"?>
    <!--suppress SpringFacetInspection -->
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--通过dubbo消费服务-->
    <dubbo:application name="dubbo_001_c"/>

    <!--指定的注册中心-->
    <dubbo:registry address="multicast://224.5.6.7:1234"></dubbo:registry>

    <!--关闭所有服务的启动时检查 (没有提供者时报错):-->
    <dubbo:consumer timeout="5000" ></dubbo:consumer> <!--定义超时时间方式一-->

    <!--调用服务-->
    <dubbo:reference id="userService" interface="com.w1nd.dubbo.service.UserService" timeout="4000" > <!--定义超时时间方式二-->
    <dubbo:method name="findName" timeout="3000"></dubbo:method> <!--定义超时时间方式三-->
    </dubbo:reference>

    </beans>

    测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.w1nd.dubbo.invoke;

    import com.w1nd.dubbo.service.UserService;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class InvokeServiceTest {

    public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo.xml");
    UserService userService = (UserService) context.getBean("userService");
    userService.addUser("w1nd");
    /* String serverReturn = userService.findName("GouSheng");
    System.out.println("get message from server message is " + serverReturn);*/
    }

    }

5 集群

​ 不同消费者的使用端口号设置不一样,即可。

dubbo_cluster_001_p

1
<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>

dubbo_cluster_002_p

1
<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>

dubbo_cluster_003_p

1
<dubbo:protocol name="dubbo" port="20883"></dubbo:protocol>

参考

(96条消息) 朋友国企干了5年java,居然不知道Dubbo是做什么呢?我真信了!_敖丙-CSDN博客

Dubbo3 简介 | Apache Dubbo


dubbo从入门到实战
https://2w1nd.github.io/2022/02/04/框架/dubbo从入门到实战/
作者
w1nd
发布于
2022年2月4日
许可协议