springBoot-Dubbo和Zookeeper集成

1、Dubbo

Dubbo简介

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
springBoot-Dubbo和Zookeeper集成_第1张图片
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。

介绍了 Dubbo 要解决的需求

springBoot-Dubbo和Zookeeper集成_第2张图片
在大规模服务化之前,应用可能只是通过 RMI 或 Hessian 等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过 F5 等硬件进行负载均衡。

当服务越来越多时,服务 URL 配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。 此时需要一个服务注册中心,动态地注册和发现服务,使服务的位置透明。并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对 F5 硬件负载均衡器的依赖,也能减少部分成本。

当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。 这时,需要自动画出应用间的依赖关系图,以帮助架构师理清关系。

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

以上是 Dubbo 最基本的几个需求。

架构

Dubbo 架构

springBoot-Dubbo和Zookeeper集成_第3张图片springBoot-Dubbo和Zookeeper集成_第4张图片
升级性
当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力。下图是未来可能的一种架构:
springBoot-Dubbo和Zookeeper集成_第5张图片
springBoot-Dubbo和Zookeeper集成_第6张图片

2、 Zookeeper

Zookeeper是什么

官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

上面的解释有点抽象,简单来说zookeeper=文件系统+监听通知机制。

1、 文件系统

Zookeeper维护一个类似文件系统的数据结构:
springBoot-Dubbo和Zookeeper集成_第7张图片
每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据
的。
有四种类型的znode:

  • PERSISTENT-持久化目录节点

客户端与zookeeper断开连接后,该节点依旧存在

  • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

  • EPHEMERAL-临时目录节点

客户端与zookeeper断开连接后,该节点被删除

  • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

2、 监听通知机制

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。

就这么简单,下面我们看看Zookeeper能做点什么呢?

Zookeeper能做什么

zookeeper功能非常强大,可以实现诸如分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能,我们这里拿比较简单的分布式应用配置管理为例来说明。

假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。
springBoot-Dubbo和Zookeeper集成_第8张图片
如上,你大致应该了解Dubbo+zookeeper是个、两个东西,大概能做些什么了,我们马上来学习下zookeeper的安装及使用,并开发一个小程序来实现zookeeper这个分布式配置管理的功能
下载zookeeper安装包
1:重命名 zoo_sample.cfg 文件修改配置文件zoo-1.cfg,原配置文件里有的,修改成下面的值,没有的则加上(也可以不修改)

dataDir=/tmp/zookeeper-1
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

配置说明:

tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20 秒
syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 5*2000=10秒
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
Step4:再从zoo-1.cfg复制两个配置文件zoo-2.cfg和zoo-3.cfg,只需修改dataDir和clientPort不同即可

springBoot-Dubbo和Zookeeper集成

前台中台后台
	zookeeper :注册中心
	dubbo-admin:是一个监控管理后台-查看我们注册了哪些服务,哪些服务被消费了一
	Dubbo: jar包~

一、开启Zookeeper

springBoot-Dubbo和Zookeeper集成_第9张图片
在bin运行 zkServer.cmd
springBoot-Dubbo和Zookeeper集成_第10张图片

二、开启Dubbo

在安装Java环境的情况下 在git上面 下载dubbo-admin-master文件,他其实就是一个springboot项目用maven打成jar包,运行jar吧(在jar包路径中 cmd 执行命令 Java jar jar名)

默认 访问http://localhost:7001 用户名密码都是root

三、sprinBoot项目编写

1、建立一个空项目

springBoot-Dubbo和Zookeeper集成_第11张图片

2、在项目中创建module

springBoot-Dubbo和Zookeeper集成_第12张图片
(在idea中项目有可能会文件夹有问题,需要自己在下面这个项目控制中管理文件)
点击:springBoot-Dubbo和Zookeeper集成_第13张图片出现:
springBoot-Dubbo和Zookeeper集成_第14张图片

项目步骤:

一.提供者提供服务

springBoot-Dubbo和Zookeeper集成_第15张图片

1.导入依赖

pom文件

   
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>2.7.3version>
        dependency>
        <dependency>
            <groupId>com.github.sgroschupfgroupId>
            <artifactId>zkclientartifactId>
            <version>0.1version>
        dependency>

        
        <dependency>
            <groupId>org.apache.curatorgroupId>
            <artifactId>curator-frameworkartifactId>
            <version>2.12.0version>
        dependency>
        <dependency>
            <groupId>org.apache.curatorgroupId>
            <artifactId>curator-recipesartifactId>
            <version>2.12.0version>
        dependency>
        <dependency>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
            <version>3.4.14version>
            
            <exclusions>
                <exclusion>
                    <groupId>org.slf4jgroupId>
                    <artifactId>slf4j-log4j12artifactId>
                exclusion>
            exclusions>
        dependency>

代码展现:
UserService接口

package com.kuang.w.service;

/**
 * @ClassName : UserService  //类名
 * @Description : user测试的1的接口  服务提供者//描述
 * @Author : W //作者
 * @Date: 2021/6/1  21:26
 */
public interface UserService {
    /**
     * class getUser
     *
     * @return string
     **/
    String getUser();
}

UserServiceImpl实现UserService接口

package com.kuang.w.service;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

/**
 * @ClassName : UserServiceImpl  //类名
 * @Description :   //描述
 * @Author : W //作者
 * @Date: 2021/6/1  21:28
 */

/**
 * zookeeper 注册发现
 *
 * @author W
 * @Service 可以被扫描到,在项目启动就自动注册到注册中心
 * * @Service 这里导入是 org.apache.dubbo.config.annotation.Service中的包 是注册到dubbo中
 * @Component 使用了Dubbo后尽量不要Service注解
 */
@Service
@Component
public class UserServiceImpl implements UserService {

    @Override
    public String getUser() {
        return "jxy";
    }
}

2.配置注册中心的地址,以及服务发现名,和要扫描的包-

server.port=8082
#当前应用名字
dubbo.application.name=providers-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#扫描指定包下服务 注册
dubbo.scan.base-packages=com.kuang.w.service

3.在想要被注册的服务.上面~增加一-个注解@Service

就是在UserServiceImpl实现UserService接口中

package com.kuang.w.service;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

/**
 * @ClassName : UserServiceImpl  //类名
 * @Description :   //描述
 * @Author : W //作者
 * @Date: 2021/6/1  21:28
 */

/**
 * zookeeper 注册发现
 *
 * @author W
 * @Service 可以被扫描到,在项目启动就自动注册到注册中心
 * * @Service 这里导入是 org.apache.dubbo.config.annotation.Service中的包 是注册到dubbo中
 * @Component 使用了Dubbo后尽量不要Service注解
 */
@Service
@Component
public class UserServiceImpl implements UserService {

    @Override
    public String getUser() {
        return "jxy";
    }
}

让项目跑起来 这时候在访问http://localhost:7001/ 可以看到:
在这里插入图片描述

springBoot-Dubbo和Zookeeper集成_第16张图片
再项目中创建module写一个springboot项目

二 .消费者如何消费
1.导入依赖(跟提供服务的导入了的maven依赖一样)

        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>2.7.3version>
        dependency>
        <dependency>
            <groupId>com.github.sgroschupfgroupId>
            <artifactId>zkclientartifactId>
            <version>0.1version>
        dependency>

        
        <dependency>
            <groupId>org.apache.curatorgroupId>
            <artifactId>curator-frameworkartifactId>
            <version>2.12.0version>
        dependency>
        <dependency>
            <groupId>org.apache.curatorgroupId>
            <artifactId>curator-recipesartifactId>
            <version>2.12.0version>
        dependency>
        <dependency>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
            <version>3.4.14version>
            
            <exclusions>
                <exclusion>
                    <groupId>org.slf4jgroupId>
                    <artifactId>slf4j-log4j12artifactId>
                exclusion>
            exclusions>
        dependency>

代码展示:

package com.kuang.w.service;

/**
 * @ClassName : UserService  //类名
 * @Description : user测试的2的接口  服务提供者//描述
 * @Author : W //作者
 * @Date: 2021/6/1  21:26
 */
public interface UserService {
    /**
     * class getUser
     *
     * @return string
     **/
    String getUser();
}

想拿到provider-server提供的票要去注册中心拿到服务
*
* @Reference //引用,有两种方式
* 第一种:Pom坐标,
* 第二种:可以定义路经相同的接口名 第二种:可以定义路经相同的接口名

package com.kuang.w.service;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

/**
 * @ClassName : UserServiceImpl  //类名
 * @Description :   //描述
 * @Author : W //作者
 * @Date: 2021/6/2  9:38
 * @Service 引入的是org.springframework.stereotype.Service;包 这里是为注册到spring容器中
 */
@Service
public class UserServiceImpl {
    /**
     * 想拿到provider-server提供的票要去注册中心拿到服务
     *
     * @Reference //引用,
     * 第一种:Pom坐标,
     * 第二种:可以定义路经相同的接口名
     */
    @Reference
    UserService userService;

    public void byGetUser() {
        String user = userService.getUser ();
        System.out.println ("在注册中心拿到user = " + user);
    }
}

2.配置注册中心的地址,以及服务发现名,和要描的包

server.port=8081
#消费者去哪里拿服务
dubbo.application.name=consumer-server
#去注册中心地址拿服务
dubbo.registry.address=zookeeper://127.0.0.1:2181

测试

package com.kuang.w;

import com.kuang.w.service.UserServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ConsumerServerApplicationTests {
    /**
     *
     */
    @Autowired
    UserServiceImpl userService;

    @Test
    void contextLoads() {
        userService.byGetUser ();
    }
}

测试结果:

......
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.0)
......
在注册中心拿到user = jxy
Process finished with exit code 0

你可能感兴趣的:(springBoot,版本管理工具,zookeeper,java,分布式)