Bootstrap

Dubbo经典之作(Dubbo使用详解)

认识Dubbo

Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。

Dubbo3 定义为面向云原生的下一代 RPC 服务框架。3.0 基于 Dubbo 2.x 演进而来,在保持原有核心功能特性的同时, Dubbo3 在易用性、超大规模微服务实践、云原生基础设施适配、安全性等几大方向上进行了全面升级。

Apache Dubbo 总体架构能很好的满足企业的大规模微服务实践,因为它从设计之初就是为了解决超大规模微服务集群实践问题,不论是阿里巴巴还是工商银行、中国平安、携程等社区用户,它们都通过多年的大规模生产环境流量对 Dubbo 的稳定性与性能进行了充分验证,因此,Dubbo 在解决业务落地与规模化实践方面有着无可比拟的优势:

  • 开箱即用
    易用性高,如 Java 版本的面向接口代理特性能实现本地透明调用
    功能丰富,基于原生库或轻量扩展即可实现绝大多数的微服务治理能力
  • 面向超大规模微服务集群设计
    极致性能,高性能的 RPC 通信协议设计与实现
    横向可扩展,轻松支持百万规模集群实例的地址发现与流量治理
  • 高度可扩展
    调用过程中对流量及协议的拦截扩展,如 Filter、Router、LB 等
    微服务治理组件扩展,如 Registry、Config Center、Metadata Center 等
  • 企业级微服务治理能力
    国内公有云厂商支持的事实标准服务框架
    多年企业实践经验考验,参考用户实践案例

Dubbo 基本工作流程

分布式系统

分布式系统是若干独立计算机的集合,是建立在网络之上的软件系统,在一个分布式系统中,一组独立的计算机展现给用户的是一个统一的整体,因此,我们可以将应用拆分几个核心的业务,通过分布式部署,集群构成一个分布式系统,对于用户来说,用户是感觉不到系统的分布性。

分布式系统特征

  • (1)分布性。分布式系统由多台计算机组成,它们在地域上是分散的,可以散布在一个单位、一个城市、一个国家,甚至全球范围内。整个系统的功能是分散在各个节点上实现的,因而分布式系统具有数据处理的分布性。
  • (2)自治性。分布式系统中的各个节点都包含自己的处理机和内存,各自具有独立的处理数据的功能。通常,彼此在地位上是平等的,无主次之分,既能自治地进行工作,又能利用共享的通信线路来传送信息,协调任务处理。
  • (3)并行性。一个大的任务可以划分为若干个子任务,分别在不同的主机上执行。
  • (4)全局性。分布式系统中必须存在一个单一的、全局的进程通信机制,使得任何一个进程都能与其他进程通信,并且不区分本地通信与远程通信。同时,还应当有全局的保护机制。系统中所有机器上有统一的系统调用集合,它们必须适应分布式的环境。在所有CPU上运行同样的内核,使协调工作更加容易。

RPC 框架

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,编写的调用代码基本相同。

Dubbo工作流程

在这里插入图片描述
Dubbo 首先是一款 RPC 框架,它定义了自己的 RPC 通信协议与编程方式。如上图所示,用户在使用 Dubbo 时首先需要定义好 Dubbo 服务;其次,是在将 Dubbo 服务部署上线之后,依赖 Dubbo 的应用层通信协议实现数据交换,Dubbo 所传输的数据都要经过序列化。

流程说明

Dubbo 的第一步就是定义 Dubbo 服务,服务在 Dubbo 中的定义就是完成业务功能的一组方法的集合,可以选择使用与某种语言绑定的方式定义,如在 Java 中 Dubbo 服务就是有一组方法的 Interface 接口,定义好服务之后,服务端(Provider)需要提供服务的具体实现,并将其声明为 Dubbo 服务,而站在服务消费方(Consumer)的视角,通过调用 Dubbo 框架提供的 API 可以获得一个服务代理(stub)对象,然后就可以像使用本地服务一样对服务方法发起调用了。 在消费端对服务方法发起调用后,Dubbo 框架负责将请求发送到部署在远端机器上的服务提供方,提供方收到请求后会调用服务的实现类,之后将处理结果返回给消费端,这样就完成了一次完整的服务调用。如图中的 Request、Response 数据流程所示。

随着微服务架构的发展,应用的部署、发布、扩缩容变得极为频繁,Dubbo通过引入注册中心来协调提供方与消费方的地址,提供者启动之后向注册中心注册自身地址,消费方通过拉取或订阅注册中心特定节点,动态的感知提供方地址列表的变化。
在这里插入图片描述
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。

服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

调用关系说明

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

Dubbo 核心特性

  • 高性能 RPC 通信协议
    Dubbo3 还提供更丰富的通信模型选择:
    消费端异步请求(Client Side Asynchronous Request-Response)
    提供端异步执行(Server Side Asynchronous Request-Response)
    消费端请求流(Request Streaming)
    提供端响应流(Response Streaming)
    双向流式通信(Bidirectional Streaming)
  • 自动服务(地址)发现机制
    Dubbo 提供的是 Client-Based 的服务发现机制,使用者可以有多种方式启用服务发现:
    使用独立的注册中心组件,如 Nacos、Zookeeper、Consul、Etcd 等。
    将服务的组织与注册交给底层容器平台,如 Kubernetes,这被理解是一种更云原生的使用方式
  • 运行态流量管控
    透明地址发现让 Dubbo 请求可以被发送到任意 IP 实例上,这个过程中流量被随机分配。当需要对流量进行更丰富、更细粒度的管控时,就可以用到 Dubbo 的流量管控策略,Dubbo 提供了包括负载均衡、流量路由、请求超时、流量降级、重试等策略,基于这些基础能力可以轻松的实现更多场景化的路由方案,包括金丝雀发布、A/B测试、权重路由、同区域优先等,更酷的是,Dubbo 支持流控策略在运行态动态生效,无需重新部署。
  • 丰富的扩展组件及生态
    支持的组件与部署架构 :注册中心(Zookeeper,Nacos,Kubernetes),元数据中心(Zookeeper,Nacos,Redis),配置中心(Zookeeper,Nacos,Redis,Apollo,Mesh),数据面 Envoy,控制面 Istio,SPI 集成:这里有众多的 Dubbo 扩展实现,包括协议、序列化、注册中心等,网关组件,链路追踪 ,等等

使用Dubbo

1. 安装dubbo-admin管理控制台

1.1下载dubbo管理端:dubbo-admin https://github.com/apache/dubbo-admin
1.2配置信息
下载代码: git clone https://github.com/apache/dubbo-admin.git
dubbo-admin-server/src/main/resources/application.properties中指定注册中心地址
本次使用到的注册、配置中心使用的是nacos,nacos使用教程参考Nacos注册中心,配置中心的使用教程
在这里插入图片描述

构建

mvn clean package -Dmaven.test.skip=true

启动
进入dubbo-admin-develop\dubbo-admin-server\target目录,运行

java -jar dubbo-admin-server-0.5.0.jar

访问 http://localhost:8080
在这里插入图片描述
启动管理端成功

建立服务提供者

1pom文件

<?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>spring-cloud-alibaba</artifactId>
        <groupId>com.awei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-gmall-user</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.awei</groupId>
            <artifactId>dubbo-reference</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 引入dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>3.0.9</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
    </dependencies>

</project>

2.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>

    <bean id="userServiceImpl" class="com.awei.service.impl.UserServiceImpl"/>

    <!--当前应用的名字  -->
    <dubbo:application name="user-provider"></dubbo:application>
    <!--指定注册中心的地址  -->
    <dubbo:registry address="nacos://localhost:8848" />
    <!--使用dubbo协议,将服务暴露在20880端口  -->

    <dubbo:protocol name="dubbo" port="8888" />
    <!-- 指定需要暴露的服务 -->
    <dubbo:service interface="com.awei.services.UserService" ref="userServiceImpl" />

</beans>

3.业务类

package com.awei.service.impl;

import com.awei.entitis.UserAddress;
import com.awei.services.UserService;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Awei
 * @date 2022/10/22 16:28
 */
public class UserServiceImpl implements UserService {
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        ArrayList<UserAddress> array = new ArrayList<UserAddress>();
        array.add(new UserAddress(1,"贵州省云岩区汇金路88号", "000",
                "陈林睿","13598452584","1"));
        array.add(new UserAddress(2,"贵州省云岩区汇金路99号", "000",
                "陈林睿1","13598452584","0"));

        return array;
    }
}

4.启动程序

package com.awei.service.impl.com.awei.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * @author Awei
 * @date 2022/10/22 17:46
 */
public class UserMain {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
        //启动
        ioc.start();
        System.in.read();
    }
}

5.查看dubbo管理端,服务注册成功
在这里插入图片描述

## 建立服务消费者

1.pom文件

<?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>spring-cloud-alibaba</artifactId>
        <groupId>com.awei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-gamll-order</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.awei</groupId>
            <artifactId>dubbo-reference</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- 引入dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>3.0.9</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>2.0.4</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

    </dependencies>


</project>

2.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>

    <context:component-scan base-package="com.awei.service"></context:component-scan>

    <dubbo:application name="order-consumer"></dubbo:application>

    <dubbo:registry address="nacos://localhost:8848" />

    <!--声明要调用的远程服务接口:生成远程服务代理-->
    <dubbo:reference interface="com.awei.services.UserService" id="userService"></dubbo:reference>

</beans>


3.启动服务,调用服务提供者接口

package com.awei.service.impl;

import com.awei.entitis.UserAddress;
import com.awei.services.OrderService;
import com.awei.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Awei
 * @date 2022/10/22 17:25
 */
@Component
public class OrderServiceImpl implements OrderService {

    UserService userService;
    @Override
    public List<UserAddress> CreatOrder(String id) {
        List<UserAddress> userAddresses = userService.getUserAddressList(id);
        return userAddresses;
    }
}

4.调用结果
在这里插入图片描述
更多使用说明可参考dubbo官网文档dubbo xml配置

;