企业网站建设培训,重庆市建设工程信息网打不开是怎么回事,wordpress vip会员插件,百度用户服务中心人工24小时电话一、什么是微服务架构
1、单体架构
顾名思义一个软件系统只部署在一台服务器上。 在高并发场景中#xff0c;比如电商项目#xff0c;单台服务器往往难以支撑短时间内的大量请求#xff0c;聪明的架构师想出了一个办法提高并发量#xff1a;一台服务器不够就加一台比如电商项目单台服务器往往难以支撑短时间内的大量请求聪明的架构师想出了一个办法提高并发量一台服务器不够就加一台如果还不够就再加一台。所以衍生出了集群架构。
2、集群架构 当服务器的数量增多以后需要一个【负载均衡】的功能来协调进来的请求将请求分发给不同的服务器。
但是当集群中的服务器数量越来越多的时候维护集群的成本也在攀升不利于长期发展。
所以聪明的架构师又想到可以把单台web服务器的完整功能拆分成许多小模块比如订单模块、商品模块根据不同模块所承担的请求数量决定服务器的数量。
这种方式叫分布式架构。
3、分布式架构 将不同功能模块拆分灵活部署服务器。但是这样不是很极致一些类似权限校验的功能还没有剥离出来。
所以聪明的架构师在分布式架构的基础上提取公共系统模块形成了微服务架构。
4、微服务架构
核心思想就是需要什么功能就从什么系统中获取。
比如电商系统中客户想要购买一个商品就得先创建一个订单但是订单系统不能独立实现发货和配送这时候就需要调用商品系统和物流系统。出现了系统之间互相调用的情况。 二、为什么要使用ZooKeeper
前面提到在微服务架构中出现了系统之间互相调用的情况。
那么如何实现系统之间的相互调用呢
RPC框架可以帮助我们实现系统之间的调用。
1、RPC框架 RPC框架一般有两个选择 Spring Cloud Netflix - Ribbon Apache - Dubbo 这里我们先来认识Dubbo Dubbo微服务架构 以上是 Dubbo 的工作原理图从抽象架构上分为两层服务治理抽象控制面 和 Dubbo 数据面 。
服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中心、流量管控策略、Dubbo Admin 控制台等如果采用了 Service Mesh 架构则还包含 Istio 等服务网格控制面。Dubbo 数据面。数据面代表集群部署的所有 Dubbo 进程进程之间通过 RPC 协议实现数据交换Dubbo 定义了微服务应用开发与调用规范并负责完成数据传输的编解码工作。 服务消费者 (Dubbo Consumer)发起业务调用或 RPC 通信的 Dubbo 进程服务提供者 (Dubbo Provider)接收业务调用或 RPC 通信的 Dubbo 进程 在上面的例子中订单系统想要调用商品系统的时候就需要知道商品系统的 IP端口。但是商品系统可能是一个集群架构如果某一个节点掉线或新增一个节点调用方是无法获取最新消息的也就是不知道商品系统有哪些节点可用。 这时候就需要使用注册中心统一管理RPC框架中的节点。
2、注册中心
当RPC框架中某一个集群的节点上线或掉线时就通知注册中心。这样当订单系统需要调用商品服务的时候就从注册中心获取提供商品服务的 IP端口。
在Dubbo中官方推荐使用的注册中心是ZooKeeper。 我们想构建微服务架构可以借助RPC框架Dubbo来构建但是Dubbo需要一个注册中心Dubbo官方推荐的注册中心是ZooKeeper。 三、ZooKeeper介绍
1、概述
是一个分布式程序的协调服务是Hadoop和Hbase的重要组件。提供的功能包括配置维护、域名服务、分布式同步、组服务等。
2、ZooKeeper集群机制
ZooKeeper是为其他程序提供服务的所以其本身不能挂掉。ZooKeeper集群机制采用的是半数存活机制有一半以上的节点存活才可用所以在一般情况下集群节点最好是奇数个。
3、ZooKeeper中的角色 Leader - 主节点
唯一能处理事务请求的节点保证集群事务处理的顺序性。
集群内部各服务的调度者。
Follower - 从节点
处理非事务请求将接收到的事务请求转发给主节点处理。
参与事务请求Proposal的投票。
参与Leader选举投票。
Observer - 观察者
处理非事务请求将接收到的事务请求转发给主节点处理。
不参与任何投票。
四、准备ZooKeeper集群环境
1、准备3个节点
准备3个centos 7.0 的虚拟机节点并且安装配置好 JDK 1.8。 我使用VM Ware创建了1个虚拟机节点是 192.168.0.1 创建快照后复制两个节点分别修改ip地址 # 修改网络配置文件
vim /etc/sysconfig/network-scripts/ifcfg-ens33 192.168.0.2 192.168.0.3 2、节点关系的映射
每个节点设置相应的ip和主机名的映射关系方便集群环境的部署。
修改hosts配置文件中的信息。 # 修改 hosts 文件
vim /etc/hosts 192.168.0.1 allwe01 192.168.0.2 allwe02 192.168.0.3 allwe03 3、免密登录配置
关于ZooKeeper集群环境的搭建可以先在一个节点安装且配置好相关配置文件然后再分发到其他的节点上再到各个节点上做一些个性化配置即可。相对于给每一个节点单独安装高效一些。
但是在使用脚本分发这些配置的时候需要登录到其他的节点这样有些繁琐所以我们来配置一下免密登录。
① 生成公钥 私钥
ssh-keygen
集群服务器的每一个节点都生成自己的公钥 私钥
② 发送公钥给目标节点
发送公钥给需要免密登录的节点。
ssh-copy-id allwe01
ssh-copy-id allwe02
ssh-copy-id allwe03 ③ 创建工作目录
cd /
mkdir allwe01
在每一个节点都创建一个工作目录。
④ 测试向其他节点发送文件功能
先登录 allwe01 服务器执行下面的命令。
scp -r a.txt allwe02:/allwe02# a.txt 目标文件
# allwe02 目标服务器
# :/allwe02 目标服务器的目标目录 再登录 allwe02 服务器查看接收的文件。 发送成功
4、关闭防火墙
# 查看防火墙状态
firewall -cmd --state我的虚拟机没安装防火墙。
5、安装 JDK
java java -version 五、动手搭建ZooKeeper集群
1、安装ZooKeeper
从官网下载安装包apache-zookeeper-3.6.4-bin.tar.gz
# 解压文件
tar -zxvf apache-zookeeper-3.6.4-bin.tar.gz 2、修改配置
① 修改zoo_sample.cfg文件名称为 zoo.cfg
# 修改文件名称
mv zoo_sample.cfg zoo.cfg ② 修改配置文件内容
tickTime2000 # zookeeper内部最小单位时间 - 2000msinitLimit10 # follower在启动过程中从Leader同步数据的时间syncLimit5 # 心跳检查间隔时间 - 5sdataDir/opt/zookeeper/data # zookeeper缓存的数据存储目录clientPort2181 # 客户端端口号# 集群环境 - 配置相关节点信息
# 2888 - 心跳端口
# 3888 - 数据端口server.1 allwe01:2888:3888
server.2 allwe02:2888:3888
server.3 allwe03:2888:3888
③ 配置myid文件
需要在zookeeper的数据存储目录创建一个myid文件文件内容仅一行信息表示当前节点在集群中的标识范围是1 ~ 255每个节点的myid数字和在zoo.cfg中配置的数字对应。 3、分发文件
配置好一个ZooKeeper节点后就可以将这个ZooKeeper文件夹分发给其他节点服务器。分别修改myid文件即可。 scp -r zookeeper allwe02:/opt/scp -r zookeeper allwe03:/opt/
4、启动测试
sh /bin/zkServer.sh start 这里打印启动成功了。但是只启动一个节点会报错原因是zookeeper采用半数存活机制我们这里有3个节点如果只有一个节点启动报错是正常的等半数以上的节点启动后就好了。
# 查看执行状态sh zkServer.sh status 可以看到有的是Leader有的是Follower。
六、ZooKeeper的Leader选举策略
半数存活机制只有超过半数的节点存活时集群才可用。我在上面搭建了一个3节点的集群分别命名为allwe01、allwe02、allwe03。
1、为什么要做Leader选举
Leader的主要作用是保证分布式数据一致性也就是分布式事务。Leader节点具有读和写的功能但是Follower节点和Observer节点只有读的功能。
所以在ZooKeeper中必须有且只有一个Leader节点一旦掉线必须选一个新的Leader节点接替工作。
2、面试问题
① 服务器初始化时的选举策略
集群中的节点在挨个启动时当allwe02启动后集群可用这时如何确定哪个是Leader
请看VCR每个节点都投票将票发送给其他节点且接收其他节点的票。选出自己认为最新的节点并且投票给它一旦超过半数票指向同一个节点选举成功。
等allwe03启动时已经存在Leader节点了所以不用选举直接成为Follower就行了。 ② 集群运行期间Leader掉线后的选举策略
集群成功启动后当Leader节点掉线了剩下两个节点如何确定哪个为Leader
ZooKeeper运行期间如果有Leader掉线此时集群停止对外服务开始在内部选举新的Leader。
1变更状态。不是观察者的节点都将自己的状态修改为Looking开始进入Leader选举。
2和上面画的流程图一样事务id越大的节点优先级越高。如果事务id一样就比较myidmyid越大的优先级越高。
3选出Leader节点后集群恢复对外服务。
七、ZooKeeper的使用
1、配置ZooKeeper的环境变量
为了简化每次操作ZooKeeper而不用进入ZooKeeper的安装目录。将ZooKeeper的bin目录配置到环境变量中。
这样可以在服务器上的任意目录使用ZooKeeper啦
2、连接客户端
通过 /bin 目录下的 zkCli.sh 连接。
# 默认连接本机zookeeper
sh zkCli.sh # 连接其他节点
sh zkCli.sh -timeout 5000 -server allwe02:2181
连接上客户端就可以使用ZooKeeper操作数据了。
3、ZooKeeper的数据结构 ZooKeeper内部是文件目录结构根目录是【/】可以在根目录下创建新的目录以此来保存数据。
4、ZooKeeper的常用命令
ZooKeeper作为Dubbo的注册中心用来保存我们各个服务的节点信息说明ZooKeeper是支持保存数据和查询操作的。
命令作用create [-s] [-e] [-c] [-t ttl] path [data] [acl]创建持久化节点(目录)-s创建持久化节点自动生成节点名-e创建临时节点客户端退出时临时节点被删除ls [-s] [-w] [-R] path查询某个节点下的节点信息和属性信息加上 -sget [-s] [-w] path查询某个节点下的数据信息和属性信息加上 -sset [-s] [-v version] path data给某个节点设置数据delete [-v version] path 删除没有子节点的节点 使用deleteall删除有子节点的节点
5、属性信息解析
属性含义cZxid创建事务idctime创建时间mZxid修改事务idmtime修改时间pZxid上级节点事务idcversion创建版本号dataVersion数据版本号aclVersion权限版本号ephemeralOwner临时拥有者 0x0表示没有dataLength数据长度numChildren子节点个数
6、节点的分类
代码含义 PERSISTENT 持久化节点 PERSISTENT_SEQUENTIAL 持久化有序节点 EPHEMERAL 临时节点 EPHEMERAL_SEQUENTIAL 临时有序节点
1临时节点下不允许创建任何节点。 7、ZooKeeper的事件监听
1监听数据的改变
# 获取app1的数据且开启对app1的监听
get -w /app1
使用allwe01客户端开启监听某个节点的数据内容变化。
但是只能触发一次监听如果想要实现持续监听那么需要在下次读取数据时再次使用监听命令。 allwe02客户端修改/app1节点的数据 allwe01接收到监听动态 2监听子节点的改变
# 开启监听 /app1 的子节点变化
ls -w /app1
在allwe01的客户端节点开启对 /app1 的子节点的监听。
但是只能触发一次监听如果想要实现持续监听那么需要在下次读取节点信息时再次使用监听命令。 在allwe02的客户端修改 /app1 的子节点。 allwe01的客户端收到监听。 8、关于注册中心的使用思路 八、Java API操作ZooKeeper
package zookeeper;import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.jupiter.api.Test;import java.io.IOException;
import java.util.List;/*** zookeeper连接客户端** Author: AllWe* Date: 2024/09/19/19:25*/
public class Test01 {/*** 客户端地址*/private static String ip 192.168.0.1:2181, 192.168.0.2:2181, 192.168.0.3:2181;/*** 连接超时时间*/private static int outTime 50000;/*** zookeeper连接对象*/private static ZooKeeper zooKeeper null;/*** 创建连接*/static {try {zooKeeper new ZooKeeper(ip, outTime, new Watcher());System.out.println(创建连接成功!连接信息: zooKeeper);} catch (IOException e) {throw new RuntimeException(e);}}/*** 连接zookeeper客户端 - 测试增删改查*/Testpublic void crud() throws Exception {// 删除目标节点zooKeeper.delete(/app1/app1.4, -1);// 判断目标节点是否存在Stat exists zooKeeper.exists(/app1/app1.4, true);if (exists ! null) {System.out.println(节点存在);} else {System.out.println(节点不存在);// 创建节点String s zooKeeper.create(/app1/app1.4, hello world.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println(s);// 修改节点数据zooKeeper.setData(/app1/app1.4, lalala.getBytes(), -1);}System.out.println();// 获取目标节点的子节点ListString children zooKeeper.getChildren(/app1, true);System.out.println(children);for (String child : children) {// 查询节点的数据byte[] data zooKeeper.getData(/app1/ child, false, null);if (data ! null) {System.out.println(new String(data));}}}/*** 连接zookeeper客户端 - 测试子节点监听*/Testpublic void nodeChildrenChange() throws Exception {ListString children zooKeeper.getChildren(/app1, new Watcher());System.out.println(children: children);Thread.sleep(Integer.MAX_VALUE);}/*** 连接zookeeper客户端 - 测试节点数据监听*/Testpublic void nodeDataChange() throws Exception {byte[] data zooKeeper.getData(/app1, new Watcher(), null);if (data ! null)System.out.println(----- new String(data));Thread.sleep(Integer.MAX_VALUE);}
}package zookeeper;import org.apache.zookeeper.WatchedEvent;/*** zookeeper 监听器** Author: AllWe* Date: 2024/09/19/19:29*/
public class Watcher implements org.apache.zookeeper.Watcher {/*** 触发监听器回调方法* param watchedEvent*/Overridepublic void process(WatchedEvent watchedEvent) {System.out.println(触发了监听器回调方法);System.out.println(watchedEvent.type: watchedEvent.getType());}
}