Dubbo+Zookeeper+SpringBoot
分布式系统
分布式系统(distributed system)
是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。因为,分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议,带来更多的问题。。。
Dubbo
产生背景
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构(让多个计算机提供同一个服务)已无法应对,分布式服务架构以及流动计算架构势在必行,急需一个治理系统确保架构有条不紊的演进。
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
流动计算架构(云端)
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
RPC
RPC
(Remote Procedure Call) 远程过程调用,在了解RPC前,我们先认识什么是LPC ?
本地过程调用(LPC)LPC用在多任务操作系统中,使得同时运行的任务能互相会话。这些任务共享内存空间使任务同步和互相发送信息。远程过程调用(RPC)RPC类似于LPC,只是在网上工作。RPC开始是出现在Sun微系统公司和HP公司的运行UNⅨ操作系统的计算机中。简单理解就是程序中的一个方法调用另外一个方法。
然而相对于
RPC 来说调用的方法不在本地,是在另外一台电脑。通过网络来调取其电脑上的方法,这就是RPC
RPC
的核心:通讯(类似于HTTP的通讯),序列化(有助于数据的传输)
RPC 运行原理图
Dubbo 概述
[Dubbo官网](Apache Dubbo)
dubbo
是一款高性能、轻量级的基于Java
开发的开源 RPC
框架,它提供了三大核心功能:面向接口的远程方法调用
、智能容错和负载均衡
、服务自动注册和发现
dubbo
的架构:
节点角色说明
节点 | 角色说明 |
---|---|
Provider |
暴露服务的服务提供方 |
Consumer |
调用远程服务的服务消费方 |
Registry |
服务注册与发现的注册中心 |
Monitor |
统计服务的调用次数和调用时间的监控中心 |
Container |
服务运行容器 |
服务提供者(Provider):服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer):服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo 架构具有以下几个特点,分别是连通性
、健壮性
、伸缩性
、以及向未来架构的升级性
。 详情查看官网
在Dubbo
官网中服务的注册与发现
推荐我们使用Zookeeper
那么什么是Zookeeper呢?
Zookeeper
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
Zookeeper:专门做服务的注册于与发现
安装Zookeeper
安装之前需要先安装 jdk
,因为它运行需要Java的运行环境jre
1、下载安装包,点击下载 这里提供的是 Zookeeper 3.7.0
版本
2、将下载的文件上传到 liunx
服务器中的 /opt/ 下 上传可以有很多更具比如 putty
xftp
等。
3、解压文件
tar -xzvf apache-zookeeper-3.7.0-bin.tar.gz
4、修改文件夹名称并进入配置文件目录
# 修改文件名
mv apache-zookeeper-3.7.0-bin apache-zookeeper-3.7.0
# 进入配置文件目录
cd apache-zookeeper-3.7.0/conf
5、复制 zoo_sample.cfg
文件并重新命名为 zoo.cfg
cp zoo_sample.cfg zoo.cfg
6、编辑zoo.cfg
文件修改数据目录和日志目录
# 修改文件命令
vim zoo.cfg
# 在文件中修改以下两条数据
dataDir=/tmp/zookeeper/data # 数据存放目录
dataLogDir=/tmp/zookeeper/log # 日志存放目录
注意:如果想配置集群的话,请在clientPort下面添加服务器的ip。如
server.1=192.168.180.132:2888:3888
server.2=192.168.180.133:2888:3888
server.3=192.168.180.134:2888:3888
如果电脑内存比较小,zookeeper还可以设置成伪集群。也就是全部服务器采用同一个ip,但是使用不同的端口。
7、创建配置文件中需要的目录
mkdir /tmp/zookeeper
mkdir /tmp/zookeeper/data
mkdir /tmp/zookeeper/log
注意:如果是配置集群,还需要在前面配置过的dataDir路径下新增myid文件
# 进入 dataDir目录
cd /tmp/zookeeper/data
touch myid
vim myid
在data目录下创建文件,文件名为“myid”, 编辑该“myid”文件,并在对应的IP的机器上输入对应的编号。
如在192.168.180.132
上,“myid”文件内容就是1
。在192.168.180.133
上,内容就是2
。
8、配置环境变量
vim /etc/profile
在文件最后添加以下内容
export ZOOKEEPER_HOME=/opt/apache-zookeeper-3.7.0
export ZOOKEEPER_HOME
export PATH=$PATH:$ZOOKEEPER_HOME/bin
# 让新定义的环境变量生效
source /etc/profile
9、启动 Zookeeper
# 进入启动目录
cd /opt/apache-zookeeper-3.7.0
# 启动程序 注意,Java环境必须正确,且启动前面的 . 不可以省略
./zkServer.sh start
启动成功
效果如下:
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.7.0/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
10、启动客户端
./zkCli.sh
如果是连接多个不同的主机节点,可以使用如下命令:
./zkCli.sh -server 192.168.180.132:2888
查看启动状态
[root@localhost bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.7.0/bin/../conf/zoo.cfg
Mode: standalone
11、基本使用命令
1、创建节点
使用create命令,可以创建一个zookeeper节点。
create [-s] [-e] path data acl
其中-s表示顺序节点,-e表示临时节点。默认情况下,创建的是持久节点。
path是节点路径,data是节点数据,acl是用来进行权限控制的。
# 创建一个叫做/wyx 的节点,内容是"123" [zk: localhost:2181(CONNECTED) 0] create /wyx 123 Created /wyx
2、获取节点内容
使用 get 获取指定节点的内容
[zk: localhost:2181(CONNECTED) 1] get /wyx 123
3、查看指定节点下面的内容
使用 ls 查看指定节点下面的所有内容
[zk: localhost:2181(CONNECTED) 2] ls / [wyx, zookeeper]
4、更新节点内容
使用 set 更新节点内容
[zk: localhost:2181(CONNECTED) 3] set /wyx 111 [zk: localhost:2181(CONNECTED) 4] get /wyx 111
5、删除节点
使用 delete 命令删除节点
[zk: localhost:2181(CONNECTED) 5] delete /wyx [zk: localhost:2181(CONNECTED) 6] ls / [zookeeper]
window下只需要解压安装包,然后修改配置文件的conf下的配置文件将 zoo_sample.cfg
修改为 zoo.cfg
文件即可,然后依次启动 bin
目录下的 zkServer.cmd
在启动 zkCli.cmd
即可
安装 Dubbo-Admin
dubbo
就是一个jar包,能帮助你的 Java
程序连接 Zookeeper
,并利用 zookeeper
消费提供服务。但是为了提供用户更好的管理监控众多的 dubbo
服务,官方提供了一个可视化的监控程序 dubbo-admin,不过这个监控即使不装也不影响使用
1、下载 Dubbo-Admin
2、解压压缩包
解压完成后进入压缩包的目录下的 \dubbo-admin-master\dubbo-admin\src\main\resources
目录下,编辑application.properties
文件
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# 该服务启动的端口
server.port=7001
# 缓存控制
spring.velocity.cache=false
# 编码控制
spring.velocity.charset=UTF-8
# 模板控制
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
# 国际化控制
spring.messages.basename=i18n/message
# 配置登录的用户名和密码 默认都是 root root
spring.root.password=root
spring.guest.password=guest
# 配置启动zookeeper的启动路径,一般使用本机(127.0.0.1),我这里用来虚拟机,所有使用了这个地址
dubbo.registry.address=zookeeper://192.168.137.129:2181
3、打包程序
使用管理员方式运行CMD
进入\dubbo-admin-master\
目录下执行下面代码
mvn clean package -Dmaven.test.skip=true
等待它打包完成
我是在windows打包然后上传到虚拟机,如果没有使用虚拟机直接在windows 上运行打包出来jar
包即可
4、上传到虚拟机并执行 jar
包
注意点,执行jar包前,必须保证 zookeeper 服务已经启动
# 执行jar包 执行前注意上传上来的jar包位置
[root@localhost home]# java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.2.RELEASE)
2021-05-06 18:44:36.919 INFO 2057 --- [ main] c.a.dubboadmin.DubboAdminApplication : Starting DubboAdminApplication v0.0.1-SNAPSHOT on localhost.localdomain with PID 2057 (/home/dubbo-admin-0.0.1-SNAPSHOT.jar started by root in /home)
5、因为使用的虚拟机,这里要开启防火墙
# 开启防火墙
[root@localhost home]# systemctl start firewalld.service
# 设置开机自动开启防火墙
[root@localhost home]# systemctl enable firewalld.service
# 查看防火墙状态
[root@localhost home]# firewall-cmd --state
running
# 开启防火墙端口 7001端口
[root@localhost home]# firewall-cmd --zone=public --add-port=7001/tcp --permanent
success
# 重启防火墙
[root@localhost home]# systemctl restart firewalld.service
# 关闭防火墙端口
firewall-cmd --permanent --zone=public --remove-port=7001/tcp
# 查看已开启端口
firewall-cmd --list-ports
6、测试访问
这里访问的位置和上面第2步
配置文件中配置的的访问路径有关,我的这里访问的路径是:http://192.168.137.129:7001/
需要输入用户名和密码,默认都是 root 配置文件中说过
至此 Dubbo-Admin 安装完成。
window直接执行jar包 然后访问 http://127.0.0.1:7001 即可
Dubbo zookeeper SpringBoot 整合
创建空的项目
1、添加俩个模块(SpringBoot的web模块)分别是,服务提供者(Provider)
和 消费者(Consumer)
开始编写 Provider
模块
导入依赖
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.7.0</version>
<exclusions>
<exclusion>
<!--不排除会报错-->
<!--排除slf4j-log4j12 日志-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
编写接口
package com.wyx.service;
// 物流服务模块
public interface Logistics {
String getInfo();
}
编写接口实现类
package com.wyx.service;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;
@DubboService //代表该类可以被 dubbo 扫描到,项目启动就注册到注册中心
@Component // 代表该组件会被注入 Spring 容器中
public class LogisticsImpl implements Logistics{
@Override
public String getInfo() {
return "获取物流信息";
}
}
配置启动配置文件
# 服务提供者,需要配置 名字 注册中心地址 注册的服务,使用包扫描的方式
# 修改端口
server.port=8001
# 服务提供者的名称
dubbo.application.name=provider-service
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 注册哪些服务
dubbo.scan.base-packages=com.wyx.service
启动测试
启动前必须先开启 zookeeper
服务 否则必然报错
然后我们接着运行 Dubbo-Admin
查看服务是否已经注册 访问 http://localhost:7001
接着编写 Consumer
模块
导入依赖
和 Provider
模块依赖相同
编写实现类
package com.wyx.service;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class UserService {
// 想要拿到远程的 provider-service 提供的服务,就要取注册中心拿
// 使用远程注入的注解
//想要注入远程的服务有两种方法 1、使用Pom坐标 2、可以定义路径相同接口名
@DubboReference
Logistics logistics;
public String getLogistics(){
String info = "在注册中心中拿到。。。。"+logistics.getInfo();
return info;
}
}
上一步的
@DubboReference 我们这里使用的是路径相同的接口名方法,使用需要与 Provider
提供接口相同的接口
实现如下
package com.wyx.service;
// 物流服务模块
public interface Logistics {
String getInfo();
}
编写测试类
package com.wyx;
import com.wyx.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ConsumerApplicationTests {
@Autowired
UserService userService;
@Test
void contextLoads() {
System.out.println(userService.getLogistics());
}
}
到此所有方法编写完成,运行查看结果(必须开启zookeeper 和 Provider程序不能停止
)
查看控制台输出结果
在注册中心中拿到。。。。获取物流信息