Dubbo(一)-----基础知识、最详细的springboot整合dubbo

0. 前言

1. 当今大型互联网项目架构目标

  1. 高性能:访问速度高,用户体验好。
  2. 高可用:要求服务一直都可以对外使用,一般采用集群方式,即使一个节点宕机了,还有其他节点通过服务。
  3. 可伸缩:根据具体情况,通过增加/减少硬件,从容提高/降低处理能力。如登录功能模块只使用一台以每秒处理10个请求的服务器,当用户量提升了,现每秒需要处理20个请求,那么可以增加另一台服务器提供登录功能模块的服务。
  4. 高可扩展:系统间耦合度低,方便通过新增/移除方式,增加/减少新的功能/模块。
  5. 安全性:保证网站的安全可靠。
  6. 敏捷性:随需应变,快速响应。

2. 架构演进

随着互联网的发展,网站应用的规模不断扩大,架构也在一步步演变,具体请看下图(从dubbo官网获取):
在这里插入图片描述

  1. 单体架构
    在这里插入图片描述

    1. 官网解释:当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
    2. 个人理解:业务或功能模块不拆分,放在同一个服务器上运行,**就如我们一开始学习javaweb,写好全部功能,一起打包放入同一个tomcat上运行。
      优点:简单,无论是开发还是部署都很方便,毕竟都是在同一个服务器运行。
      缺点
      1. 项目启动慢,因为当你的项目业务需要特别多,功能模块特别多,而又是在同一个服务器上运行,服务器资源毕竟有限,需要全部一口气编译运行才能对外提供服务。
      2. 可靠性差,当系统分别有A,B,C功能模块,突然B模块出现bug挂了,而其他模块也无法对外提供服务了。
      3. 可伸缩性差,因为全部功能模块都是部署在同一个服务器上,当想要增加某个模块处理能力,也无法为单体功能模块搭建集群,也只能整个服务器增加。
      4. 扩展性和可维护性差,因为当系统需要增加一个功能模块E时,需要将原服务器停止,并重新打包部署。
      5. 性能低,因为全部压力都在一台服务器上,当用户量很大时,服务器会出现瓶颈。
  2. 垂直架构:
    在这里插入图片描述

    1. 官网解释:当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
    2. 个人理解:将单体架构中的多个模块拆分为互不交互的独立项目,重点是互不交互,如上图,在app1中的A,B都不跟app2中的C、D模块进行交互,他们跟同一个DB交互就有。
    3. 优点:解决了单体架构大部分缺点。
      项目启动变快,因为功能模块被拆分到两台服务器上运行,不会集中在一台服务器。
      可靠性变好,由于AB与CD模块是独立在两台服务器上运行,当B模块bug挂了,并不影响app2的应用。
      可伸缩性变好,比如AB功能模块用户访问量大,可以多搭一个app1的应用服务器。
    4. 缺点:重复功能(重复代码)太多了,冗余很大。
      比如:app1是订单功能项目,aap2 是购物车功能项目,那这两个模块都需要用户信息,而app1,跟app2之间是互不交互的,因此可能会导致,在app1中有用户信息相关代码,而app2中也会有,如下图:
      在这里插入图片描述
  3. 分布式架构

    1. 官方解释:当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
    2. 个人解释:将重复的公共业务模块提取出来成分独立的服务,供其他调用者消费,以实现服务的共享和重用。
    3. 如上图,模块E是重复公共的,将它提取出来,给app1,app2调用如下图:
      在这里插入图片描述
    4. 垂直架构跟分布式架构的区别:首先他们都是将一个大系统划分成为各个不同功能模块,部署在不同的服务器上,但是垂直架构之间的应用互不交互,而分布式架构之间的应用是可以相互调用访问的。
    5. 优点:解决重复功能(重复代码)太多的问题。
    6. 缺点:(根据上图来解释)我们知道三个业务模块运行在3个服务器上,而之间要相互调用,必然是使用网络调用,而网络调用有需要三要素,协议,ip,端口,协议不用说了,关键是ip与端口,若一个规定好E服务的IP端口是 192.168.131.129:8000,而app1,app2在代码中就写好这个地址,这样子就可以正常调用,但是如果E服务的IP端口突然改变为192.168.130.128:7000了,那么就需要修改app1,app2相关信息,实在太麻烦了。
      缺点总结一句话就是:服务提供方一旦发生变更,则所有消费方都需要变更
  4. SOA架构:

    1. 为了解决上述问题,从而将架构改为如下:
      在这里插入图片描述

    2. ABC是消费方,DEF是服务提供方,而DEF服务将把自己的ip端口信息注册到ESB(服务中介中),如当A想要调用E的服务的时候,先去ESB中索要E服务的端口ip,当A拿到之后,就去通过网络调用E。而当E服务的ip端口发生改变的时候,E服务会重新将ip端口信息注册到ESB中,并通知A消费方,E服务的ip端口发生改变,请获取最新值,之后当A消费方又要调用E服务的时候,则重新去获取最新IP端口,完全不用想当初一样,修改ip端口什么乱七八糟操作。

    3. ESB服务总线,主要是提供了一个服务于服务之间的交互,包含的功能如:负载均衡,流量控制,加密处理,服务监控,异常处理,监控告急等等,dubbo就是做这个任务的。

    4. ESB又叫服务中介,中介嘛,大家都知道很多东西都交给他,他负责搞定大部分事情。

  5. 微服务架构:

    1. 微服务架构是在SOA上做的升华,微服务架构强调的一个重点是 “业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发,设计,运行的小应用,这些小应用之间通过服务完成交互和集成。
      在这里插入图片描述
    2. 业务需要彻底的组件化和服务化,组件化是重点理解,组件故名就是可以重复应用的。其次,单个业务系统会拆分为多个可以独立开发,设计,运行的小应用,独立开发、设计、运行 是重点理解,则说明一个功能模块可以直接在服务器上运行,拥有自己的数据库。
    3. 优点:
      1. 服务实现组件化:开发者可以自由选择开发技术,也不需要协调其他团队,只需要把自己那个服务彻底实现,并对外提供接口即可。
      2. 服务之间交互一般使用REST API
      3. 去中心化,每个微服务有自己私有的数据库持久化业务数据。
      4. 自动化部署:把应用拆分成为一个一个独立的单个服务,方便自动化部署、测试、运维。

2. Dubbo介绍

  1. Dubbo是阿里巴巴公司开源的、已经被apach收购的、一个高性能、轻量级的java RPC框架。

  2. 致力于提供高性能和透明化的RPC远程访问调用方案,以及SOA服务治理方案

  3. Dubbo的架构图如下:
    在这里插入图片描述

    1. Provider:暴露服务的服务提供方
    2. Consumer:调用远程服务的服务消费方
    3. Registry:服务注册与发现的注册中心
    4. Monior:统计服务的调用次数和调用时间的监控中心
    5. Container:服务运行的容器。
  4. 调用关系说明:

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

  6. 当服务越来越多时,服务 URL 配置管理变得非常困难, 此时需要一个服务注册中心,动态地注册和发现服务,使服务的位置透明。

  7. 服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器? 为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阈值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

3. Dubbo-admin可视化界面的安装

具体安装方法,请看这篇博客:https://blog.csdn.net/xueyijin/article/details/117872882

4. Dubbo使用springboot快速入门

  1. 在以前创建一个项目全部代码都是放在同一台服务器上的单机模式,如下图。
    在这里插入图片描述

  2. 现在需要将系统模块拆分,并部署到各个服务器上运行,并使用dubbo来作为服务中介。

1. 搭建服务提供者

  1. 创建springboot工程,取名为dubbo-service。

  2. 导入相应jar包坐标。

    <!--    若不加web包,则启动时候会导致dubbo服务一直无法启动成功,因此需要-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    <!--    dubbo的jar包-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.8</version>
            </dependency>
    
    <!--    curator是用于连接zk的客户端,因为需要将使用zk作为注册中心-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.2.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.2.0</version>
            </dependency>
    
  3. 编写application.yml配置文件

    # 设置springboot此项目的端口
    server:
      port: 9000
    
    dubbo:
      application:
      	# dubbo此服务的名字,是跟此项目名同名
        name: dubbo-service
      # 监控室
      monitor:
        protocol: register
      registry:
      	# 注册中心配置,protocol配置的是使用的通信协议
      	# 在dubbo中 协议 有http,dubbo
      	# address 配置注册中心的地址
        protocol: dubbo
        address: zookeeper://127.0.0.1:2181
      # 元数据配置,来由地址
      # 如果不配则无法看见元数据 
      # 什么是元数据,后面解释
      metadata-report:
        address: zookeeper://127.0.0.1:2181
    
  4. 编写服务类代码如下:
    在这里插入图片描述
    UserService接口

    public interface UserService {
        String sayHello(String msg);
    }
    

    UserServiceImpl具体实现类

    // 1. 以前这里的注解是@Service 
    // 2. 作用是将UserServiceImpl生成bean对象并放入spring容器
    // 3. @DubboService是将此服务信息(ip:port、服务名字),放在注册中心,提供给消费者。
    @DubboService
    public class UserServiceImpl implements UserService {
    
        @Override
        public String sayHello(String msg) {
            // 调用dao层....
            return "你好," + msg;
        }
    }
    
  5. 在springboot的启动类上添加@EnableDubbo注解,表示启动dubbo服务,如下:
    在这里插入图片描述

  6. 打开dubbo Admin查看。
    在这里插入图片描述
    点击详情,可以具体看见详细信息,如ip、port、权重等等。
    在这里插入图片描述
    继续往下看,则可以看见元数据,是指服务里面具体的方法名,参数列表,返回值。
    在这里插入图片描述

2. 搭建服务消费者

  1. 创建springboot工程,取名为dubbo-web。

  2. 导入相应jar包坐标。

    <!--    若不加web包,则启动时候会导致dubbo服务一直无法启动成功,因此需要-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    <!--    dubbo的jar包-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.8</version>
            </dependency>
    
    <!--    curator是用于连接zk的客户端,因为需要将使用zk作为注册中心-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.2.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.2.0</version>
            </dependency>
    
  3. 编写application.yml配置文件

    # 设置springboot此项目的端口
    server:
      # 与服务提供者区分
      port: 9001
    
    # 消费者可以只需要下面的配置
    # 1. dubbo服务名
    # 2. 注册中心的地址,因为消费者要远程调用服务器的时候,需要向注册中心获得服务的ip:port
    dubbo:
      application:
        name: dubbo-web
      registry:
        protocol: dubbo
        address: zookeeper://127.0.0.1:2181
    
  4. 编写web层相关代码。
    在这里插入图片描述在这里插入图片描述

  5. 提取共同模块,取名为dubbo-common,并把共同部分编写在此模块中。
    在这里插入图片描述

  6. 将dubbo-common模块 依赖给 dubbo-service模块,并发现实现类没有报错了。
    在这里插入图片描述

  7. 同理将 dubbo-web模块 依赖 dubbo-common模块。
    在这里插入图片描述

  8. 最正确的dubbo-web模块中Controller的代码。

    @RestController
    public class UserController {
    
    //    @Autowired
        @DubboReference
        UserService userService;
    
        @RequestMapping("/Hello")
        public String sayHello(String msg){
            return userService.sayHello(msg);
        }
    }
    
  9. 同理,在springboot的启动类上添加@EnableDubbo注解,表示启动dubbo服务。

  10. 由于web模块与service模块需要依赖 common模块,因此在启动过程中,应先让dubbo-common模块先打包。
    在这里插入图片描述

  11. 先启动dubbo-service服务模块,再启动dubbo-web消费者模块。
    在浏览器中输入 http://localhost:9001?msg=小明
    为什么是9001,因为dubbo-web在配置文件application.yml中server.port=9001
    为什么要加参数,因为我们HelloController代码中的sayHello方法需要参数。
    结果如下:
    在这里插入图片描述

  12. 我们还是可以去Dubbo Admin中查看。发现现在也有消费者的信息了。
    在这里插入图片描述

其他文章

目前安排,是先更新好rabbitmq,再持续更新dubbo

Dubbo(二)-----在springboot中的基本使用、高级使用

Dubbo(三)-----手写并模拟dubbo

Dubbo(四)-----dubbo源码分析(一)

Dubbo(四)-----dubbo源码分析(二)

Dubbo(四)-----dubbo源码分析(三)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值