Dubbo架构和简单应用

项目架构演变过程

1、单体架构

在这里插入图片描述

单体架构所有模块和功能都集中在一个项目中 ,部署时也是将项目所有功能部整体署到服务器中

  • 优点
    • 小项目开发快 成本低
    • 架构简单
    • 易于测试
    • 易于部署
  • 缺点
    • 大项目模块耦合严重 不易开发 维护 沟通成本高
    • 新增业务困难
    • 核心业务与边缘业务混合在一块,出现问题互相影响

2. 垂直架构

  根据业务把项目垂直切割成多个项目,因此这种架构称之为垂直架构。为了避免上面提到的那些问题,可以针对模块做垂直划分,做垂直划分的原则是需要基于产品的业务特性,核心目标,第一个是为了业务之间互不影响,第二个是为了提高效率,减少互相之间的依赖。
在这里插入图片描述

  • 优点
    • 系统拆分实现了流量分担,解决了并发问题
    • 可以针对不同系统进行优化
    • 方便水平扩展,负载均衡,容错率提高
    • 系统间相互独立,互不影响,新的业务迭代时更加高效
  • 缺点
    • 服务系统之间接口调用硬编码
    • 搭建集群之后,实现负载均衡比较复杂
    • 服务系统接口调用监控不到位 调用方式不统一
    • 服务监控不到位
    • 数据库资源浪费,充斥慢查询,主从同步延迟大

3.分布式架构(SOA )

  SOA全称为Service Oriented Architecture,即面向服务的架构 。它是在垂直划分的基础上,将每个项目拆分出多个具备松耦合的服务,一个服务通常以独立的形式存在于操作系统进程中。各个服务之间通过网络调用,这使得构建在各种各样的系统中的服务可以 以一种统一和通用的方式进行交互。在上面垂直划分以后,业务模块随之增多,系统之间的RPC逐渐增多,维护的成本也越来越高,一些通用的业务和模块重复的也越来越多,这个时候上面提到的接口协议不统一、服务无法监控、服务的负载均衡等问题更加突出,为了解决上面的这些问题,需要对原有的业务层进一步拆分,将通用的业务逻辑继续下沉到通用服务层,通过接口暴露,供其他业务场景调用。同时引入RPC框架例如阿里巴巴开源的Dubbo来完成服务治理的工作。
在这里插入图片描述

  • 优点
    • 服务以接口为粒度,为开发者屏蔽远程调用底层细节 使用Dubbo 面向接口远程方法调用屏蔽了底层调用细节
    • 业务分层以后架构更加清晰 并且每个业务模块职责单一 扩展性更强
    • 数据隔离,权限回收,数据访问都通过接口 让系统更加稳定 安全
    • 服务应用本身无状态化 这里的无状态化指的是应用本身不做内存级缓存 而是把数据存入db
    • 服务责任易确定 每个服务可以确定责任人 这样更容易保证服务质量和稳定
  • 缺点
    • 粒度控制复杂 如果没有控制好服务的粒度 服务的模块就会越来越多 就会引发 超时 分布式事务等问题
    • 服务接口数量不宜控制 容易引发接口爆炸 所以服务接口建议以业务场景进行单位划分 并对相近的业务做抽象 防止接口爆炸
    • 版本升级兼容困难 尽量不要删除方法 字段 枚举类型的新增字段也可能不兼容
    • 调用链路长 服务质量不可监控 调用链路变长 下游抖动可能会影响到上游业务 最终形成连 锁反应 服务质量不稳定 同时链路的变成使得服务质量的监控变得困难

4.微服务架构

  微服务架构是一种将单个应用程序 作为一套小型服务开发的方法,每种应用程序都在其自己的进程中独立运行,并使用轻量级机制(通常是HTTP资源的API)进行通信。这些服务是围绕业务功能构建的,可以通过全自动部署机制进行独立部署。这些服务的集中化管理非常少,它们可以用不同的编程语言编写,并使用不同的数据存储技术。
  微服务是在SOA上做的升华 , 粒度更加细致,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”。

Dubbo架构

1、Dubbo 架构概述

  Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。
三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

更多dubbo 的特性参考官网

Dubbo 的服务治理:
  服务治理(SOA governance),企业为了确保项目顺利完成而实施的过程,包括最佳实践、架构原则、治理规程、规律以及其他决定性的因素。服务治理指的是用来管理SOA的采用和实现的过程。
参考官网 服务治理的需求

2.Dubbo 处理流程

在这里插入图片描述
节点说明:

节点角色名称
Provider暴露服务的服务提供方
Consumer调用远程服务的服务消费方
Registry服务注册与发现的注册中心
Monitor统计服务的调用次数和调用时间的监控中心
Container服务运行容器 负责启动 加载 运行服务提供者

调用关系说明:

  • 虚线 代表异步调用 实线代表同步访问
  • 蓝色虚线 是在启动时完成的功能
  • 红色虚线 是程序运行中执行的功能

调用流程:

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

3.服务注册中心Zookeeper

  通过前面的Dubbo架构图可以看到,Registry(服务注册中心)在其中起着至关重要的作用。Dubbo官方推荐使用Zookeeper作为服务注册中心。Zookeeper 是 Apache Hadoop 的子项目,作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
 Zookeeper的安装及其使用见上一模块,此处不再赘述。

4、Dubbo开发实战

  在Dubbo中所有的的服务调用都是基于接口去进行双方交互的。双方协定好Dubbo调用中的接口,提
供者来提供实现类并且注册到注册中心上。
  调用方则只需要引入该接口,并且同样注册到相同的注册中心上(消费者)。即可利用注册中心来实现集
群感知功能,之后消费者即可对提供者进行调用。
  所有的项目都是基于Maven去进行创建,这样相互在引用的时候只需要以依赖的形式进行展现就可以了。
并且这里会通过maven的父工程来统一依赖的版本。
程序实现分为以下几步骤:

  1. 建立maven工程 并且 创建API模块: 用于规范双方接口协定
  2. 提供provider模块,引入API模块,并且对其中的服务进行实现。将其注册到注册中心上,对外来
    统一提供服务。
  3. 提供consumer模块,引入API模块,并且引入与提供者相同的注册中心。再进行服务调用。

创建接口

  1. 创建maven工程,添加依赖管理
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.elvis</groupId>
    <artifactId>dubbo-study</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>service-api</module>
        <module>service-provider</module>
        <module>service-consumer</module>
    </modules>

    <properties>
        <dubbo.version>2.7.8</dubbo.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-common</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-remoting-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-common</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-nacos</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-rpc-dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-remoting-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-common</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-remoting-netty4</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-remoting-api</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-serialization-hessian2</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-common</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- 日志配置 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>

        <!-- json数据化转换 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

创建api模块

  1. 创建maven
<?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-study</artifactId>
        <groupId>com.elvis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-api</artifactId>


</project>
  1. 创建接口
package com.elvis.service;

/**
 * @author Elvis
 * @create 2021-06-13 9:23
 */
public interface HelloService {
    String helloService(String name);
}

创建服务提供者

在这里插入图片描述

  1. 创建maven
<?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-study</artifactId>
        <groupId>com.elvis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.elvis</groupId>
            <artifactId>service-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-rpc-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-remoting-netty4</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-serialization-hessian2</artifactId>
        </dependency>

    </dependencies>


</project>
  1. 创建dubbo配置文件
    在resources目录下创建dubbo.properties
dubbo.application.name=dubbo-demo-annotation-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
  1. 创建接口实现类
package com.elvis.service.impl;
/**
 * @author Elvis
 * @create 2021-06-13 9:26
 */

import com.elvis.service.HelloService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Service;

/**
 * @program: dubbo-study
 * @Description
 * @author Elvis
 * @date 2021-06-13 9:26    
 */
@DubboService
public class HelloServiceImpl implements HelloService {
    @Override
    public String helloService(String name) {
        return "hello :" + name;
    }
}
  1. 创建provider的启动类
package com.elvis.main;
/**
 * @author Elvis
 * @create 2021-06-13 9:27
 */

import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.IOException;

/**
 * @program: dubbo-study
 * @Description
 * @author Elvis
 * @date 2021-06-13 9:27    
 */
public class ServiceProviderMain {
    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        context.start();
        System.in.read();
    }

    @Configuration
    @EnableDubbo(scanBasePackages = "com.elvis.service.impl")
    @PropertySource("classpath:/dubbo.properties")
    static class ProviderConfiguration {

        @Bean
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setAddress("zookeeper://192.168.137.144:2181?timeout=10000");
            return registryConfig;
        }
    }
}
  1. 运行

创建服务消费者

在这里插入图片描述

  1. 创建maven
<?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-study</artifactId>
        <groupId>com.elvis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.elvis</groupId>
            <artifactId>service-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-rpc-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-remoting-netty4</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-serialization-hessian2</artifactId>
        </dependency>

    </dependencies>

</project>
  1. 创建dubbo配置文件
    resources目录下创建dubbo.properties
dubbo.application.name=service-consumer
dubbo.registry.address=zookeeper://192.168.137.144:2181
dubbo.consumer.timeout=4000
  1. 创建调用代理对象
	package com.elvis.bean;
/**
 * @author Elvis
 * @create 2021-06-13 9:42
 */

import com.elvis.service.HelloService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;

/**
 * @program: dubbo-study
 * @Description
 * @author Elvis
 * @date 2021-06-13 9:42    
 */
@Component
public class ConsumerBean {
    @DubboReference
    HelloService hello;

    public String helloService(String name) {
        return hello.helloService(name);
    }
}

  1. 创建消费者的启动类
package com.elvis.main;
/**
 * @author Elvis
 * @create 2021-06-13 9:41
 */

import com.elvis.bean.ConsumerBean;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.IOException;

/**
 * @program: dubbo-study
 * @Description
 * @author Elvis
 * @date 2021-06-13 9:41    
 */
public class ServiceConsumerMain {
    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        ConsumerBean bean = context.getBean(ConsumerBean.class);
        while (true) {
            System.in.read();
            String  hello = bean.helloService("world");
            System.out.println("result:"+hello);
        }
    }

    @Configuration
    @PropertySource("classpath:/dubbo.properties")
    @ComponentScan(basePackages = "com.elvis.bean")
    @EnableDubbo
    static  class  ConsumerConfiguration{

    }

}

  1. 运行
    如果启动时出现下面的异常 qos-server can not bind localhost:22222, dubbo version: 2.7.8
    在配置文件中添加 dubbo.application.qosEnable=false 关闭qos功能
    或者修改qos绑定的端口 dubbo.application.qosPort=33333

在这里插入图片描述

  1. 测试

在这里插入图片描述

xml配置方式

参考官网,快速开始指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值