微服务01 ZooKeeper, Kafka

1.4 微服务

1.4.6 Spring Cloud

JAVA 微服务技术

Dubbo是2014年之前阿里退出的分布式系统的技术(不属于微服务)。现在主流是 Spring Cloud

Spring Cloud

 

官网地址: https://spring.io/projects/spring-cloud 
官网上实现方法有很多种,目前主流是阿里巴巴实现的方法

Spring Boot 和 Spring cloud

Spring Boot用于单体开发; Spring cloud基于Spring Boot开发,关注多个小服务开发

1.5 服务网格 Mesh

k8s里每个pod里放一个公用容器, 用于连数据库, 服务配置, 限流等功能, 叫边车。开发无需关注这些功能

1.6 无服务架构 Serverless

用于云端,用户只要写业务代码。其他买云服务,交给云厂商

1.7 微服务还是单体

单体在绝大部分时候是更好的选择,即单体优先

 

2 ZooKeeper

2.2 ZooKeeper 工作原理

2.2.1 ZooKeeper 功能

2.2.1.1 命名服务  #实现服务发现, 服务注册

2.2.1.2 状态同步

2.2.1.3 配置中心

2.2.1.4 集群管理

zookeeper自身也有集群功能, 保证自身高可用

2.2.2 ZooKeeper 服务流程

 ZooKeeper没monitor功能, 没提供图形web界面,无法监控程序之间调用关系,nacos解决了这一问题

2.3 ZooKeeper 安装

zookeeper基于java开发

2.3.1 ZooKeeper 单机部署

2.3.1.2 部署 ZooKeeper

2.3.1.2.1 包安装

范例:包安装

#不要求版本,直接安装
[root@ubuntu2204 ~]#apt list zookeeper
zookeeper/jammy 3.4.13-6ubuntu4 all
[root@ubuntu2204 ~]#apt -y install zookeeper    #如果没java会把java安装了

#启动
[root@ubuntu2204 ~]#/usr/share/zookeeper/bin/zkServer.sh start
#查看状态
[root@ubuntu2204 ~]#/usr/share/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /etc/zookeeper/conf/zoo.cfg
Mode: standalone    #单机模式

[root@ubuntu ~]#ss -lntp    #打开2181端口
LISTEN  0       50                   *:2181               *:*      users:(("java",pid=3810,fd=27)) 

如果要安装最新版本,就下载最新的包二进制安装

2.3.1.2.2 二进制安装

#可以从apache基金会官网进入
https://zookeeper.apache.org/
#版本: stable 和 current ,生产建议使用stable版本
#有source release是源码要编译,没有表示编译好了

#历史版本下载
https://archive.apache.org/dist/zookeeper/
#下载带bin表示二进制版,如apache-zookeeper-3.9.2-bin.tar.gz  

[root@ubuntu ~]#wget https://archive.apache.org/dist/zookeeper/current/apache-zookeeper-3.9.2-bin.tar.gz

#先装java环境,否则zookeeper起不来
[root@ubuntu ~]#apt update && apt -y install openjdk-11-jdk
#检查下版本
[root@ubuntu ~]#java -version

#解压zookeeper安装包
[root@ubuntu ~]#tar xf apache-zookeeper-3.9.2-bin.tar.gz -C /usr/local/
[root@ubuntu local]#cd apache-zookeeper-3.9.2-bin/
[root@ubuntu local]#ln -s apache-zookeeper-3.9.2-bin/ zookeeper
#准备配置文件
[root@ubuntu local]#cd zookeeper/conf/
[root@ubuntu conf]#cp zoo_sample.cfg zoo.cfg

#默认配置可不做修改
[root@ubuntu1804 ~]#vim /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000  #"滴答时间",用于配置Zookeeper中最小的时间单元长度,单位毫秒,是其它时间配置的基础  
initLimit=10   #初始化时间,包含启动和数据同步,其值是tickTime的倍数
syncLimit=5    #正常工作,心跳监测的时间间隔,其值是tickTime的倍数
dataDir=/usr/local/zookeeper/data/ #配置Zookeeper服务存储数据快照的目录(把目录创建出来),基于安全 (默认tmp目录ubuntu一重启会清空)
dataLogDir=/usr/local/zookeeper/logs  #指定日志路径,默认与 dataDir 一致,事务日志对性能影响非常大,强烈建议事务日志目录和数据目录分开,如果后续修改路径,需要先删除中dataDir中旧的事务日志,否则可能无法启动
clientPort=2181 #配置当前Zookeeper服务对外暴露的端口,用户客户端和服务端建立连接会话

autopurge.snapRetainCount=3 #3.4.0中的新增功能:启用后,ZooKeeper 自动清除功能,会将只保留此最新3个快照和相应的事务日志,并分别保留在dataDir 和dataLogDir中,删除其余部分,默认值为3,最小值为3
autopurge.purgeInterval=24  #3.4.0及之后版本,ZK提供了自动清理日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个1或更大的整数,默认是 0,表示不开启自动清理功能

#修改PATH变量
[root@ubuntu ~]#echo 'PATH=/usr/local/zookeeper/bin:$PATH' > /etc/profile
[root@ubuntu ~]#. /etc/profile

#启动(默认会读取配置文件zoo.cfg)
[root@ubuntu ~]#zkServer.sh start
#查看状态
[root@ubuntu ~]#zkServer.sh status
#查版本
[root@ubuntu ~]#zkServer.sh version
#停止
[root@ubuntu ~]#zkServer.sh stop

2.3.1.5 service 文件

[root@ubuntu2204 ~]#cat > /lib/systemd/system/zookeeper.service <<EOF
[Unit]
Description=zookeeper.service
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/zookeeper/bin/zkServer.sh start
ExecStop=/usr/local/zookeeper/bin/zkServer.sh stop
ExecReload=/usr/local/zookeeper/bin/zkServer.sh restart

[Install]
WantedBy=multi-user.target
EOF

[root@ubuntu2204 ~]#systemctl daemon-reload
[root@ubuntu2204 ~]#systemctl enable --now zookeeper.service

2.4 ZooKeeper 客户端访问

2.4.1 命令行客户端访问 ZooKeeper (了解)

#访问zookeeper
[root@ubuntu ~]#zkCli.sh    #默认连到本机2181端口
#按tab键查看命令列表
#查看文件
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /zookeeper 
[config, quota]
#zookeeper和文件系统区别:zookeeper的文件夹自身也可以存放文件,即文件夹也可同时作为文件
#获取zookeeper文件夹自己的数据
[zk: localhost:2181(CONNECTED) 2] get /zookeeper
#创建文件夹
[zk: localhost:2181(CONNECTED) 3] create /app1
[zk: localhost:2181(CONNECTED) 5] ls /
[app1, zookeeper]
[zk: localhost:2181(CONNECTED) 7] create /app1/name
#对app1文件夹存放数据
[zk: localhost:2181(CONNECTED) 8] set /app1 myapp
#获取数据
[zk: localhost:2181(CONNECTED) 11] get /app1 
myapp
#app1路径下的内容保持不变
[zk: localhost:2181(CONNECTED) 12] ls /app1 
[name]
#查看已知节点元数据
[zk: 10.0.0.103:2181(CONNECTED) 9] stat /zookeeper
#删除
[zk: 10.0.0.103:2181(CONNECTED) 7] delete /app1
#退出
quit

2.4.3 图形化客户端 ZooInspector

github链接

https://github.com/zzhang5/zooinspector
https://gitee.com/lbtooth/zooinspector.git

注意:此软件因年代久远不再更新,当前只支持在Ubuntu18.04和Rocky8编译安装,不支持更高版本,如Ubuntu20.04等

#注意:只支持JDK8,不支持JDK11
[root@ubuntu ~]#apt update && apt install -y openjdk-8-jdk
[root@ubuntu ~]#apt install maven -y    #如果没有java,会装jdk11

#镜像加速
[root@ubuntu ~]#vim /etc/maven/settings.xml
 <mirrors>
   <!--阿里云镜像-->
   <mirror>
       <id>nexus-aliyun</id>
       <mirrorOf>*</mirrorOf>
       <name>Nexus aliyun</name>
       <url>http://maven.aliyun.com/nexus/content/groups/public</url>
   </mirror>
 </mirrors>

#国内镜像
[root@zookeeper-node1 ~]#git clone https://gitee.com/lbtooth/zooinspector.git
#编译,此步骤需要较长时间下载,可能数分钟
[root@ubuntu ~]#cd zooinspector/
[root@ubuntu zooinspector]#mvn clean package -Dmaven.test.skip=true
#把target下大的jar包拷贝走,需要里面的脚本
[root@ubuntu zooinspector]#cp target/zooinspector-1.0-SNAPSHOT-pkg.tar /opt
[root@ubuntu zooinspector]#cd /opt/
[root@ubuntu opt]#tar xf zooinspector-1.0-SNAPSHOT-pkg.tar
#里面两个脚本,linux下用和windows下用
[root@ubuntu opt]#ls zooinspector-1.0-SNAPSHOT/bin/
zooinspector.bat  zooinspector.sh
[root@ubuntu zooinspector-1.0-SNAPSHOT]#bin/zooinspector.sh

#把zooinspector-1.0-SNAPSHOT-pkg.tar传到windows上,解压
[root@ubuntu opt]#sz zooinspector-1.0-SNAPSHOT-pkg.tar
#运行zooinspector.bat即可
#这个工具以后一直能用

2.4.4 Python 访问 ZooKeeper

[root@zookeeper-node1 ~]#apt update && apt -y install python3 python3-kazoo
[root@zookeeper-node1 ~]#cat zookeepe_test.py 
#!/usr/bin/python3
from kazoo.client import KazooClient

zk = KazooClient(hosts='10.0.0.101:2181')
zk.start()
# 创建节点(并写数据):makepath设置为True,父节点不存在则创建,其他参数不填均为默认
zk.create('/zkapp/test',b'this is a test',makepath=True)
# 操作完后关闭zk连接
data=zk.get('/zkapp/test')
print(data)
zk.stop()

[root@zookeeper-node1 ~]#chmod +x ./zookeepe_test.py
[root@zookeeper-node1 ~]#./zookeepe_test.py

2.4.2 nc 访问 ZooKeeper

[root@ubuntu ~]#telnet 10.0.0.151 2181
#常见命令列表
conf #输出相关服务配置的详细信息
cons #列出所有连接到服务器的客户端的完全的连接/会话的详细信息
envi #输出关于服务环境的详细信息
dump #列出未经处理的会话和临时节点
stat #查看哪个节点被选择作为Follower或者Leader
ruok #测试是否启动了该Server,若回复imok表示已经启动
mntr #输出一些运行时信息
reqs #列出未经处理的请求
wchs #列出服务器watch的简要信息
wchc #通过session列出服务器watch的详细信息
wchp #通过路径列出服务器watch的详细信息
srvr #输出服务的所有信息
srst #重置服务器统计信息
kill #关掉Server,当前版本无法关闭
isro #查看该服务的节点权限信息

#可以管道直接传输
[root@ubuntu ~]#echo conf | nc 10.0.0.200 2181

命令的安全限制

#默认情况下,这些4字命令有可能会被拒绝,提示如下报错
xxxx is not executed because it is not in the whitelist.

#解决办法:在 zoo.cfg文件中添加如下配置,如果是集群需要在所有节点上添加下面配置
# vim conf/zoo.cfg
4lw.commands.whitelist=*    #允许所有4字命令
#在服务状态查看命令中有很多存在隐患的命令,为了避免生产中的安全隐患,要对这些"危险"命令进行一些安全限制,只需要编辑服务的zoo.cfg文件即可

# vim conf/zoo.cfg
4lw.commands.whitelist=conf,stat,ruok,isro

[root@ubuntu ~]#systemctl restart zookeeper.service

2.3.2 ZooKeeper 集群部署

2.3.2.1 ZooKeeper 集群介绍

zookeeper不需要设定谁是主谁是从,会自动选举主节点,从节点

2.3.2.1.1 集群结构

 对于n台server,每个server都知道彼此的存在。只要有>n/2台server节点可用,整个zookeeper系统保持可用。因此zookeeper集群通常由 奇数台Server节点组成

集群中节点数越多,写性能越差,读性能越好。节点越少写性能越好,读性能越差

2.3.2.1.2 集群角色

2.3.2.1.3 选举过程

节点角色状态:

LOOKING:寻找 Leader 状态,处于该状态需要进入选举流程
LEADING:领导者状态,处于该状态的节点说明是角色已经是Leader 
FOLLOWING:跟随者状态,表示 Leader已经选举出来,当前节点角色是follower 
OBSERVER:观察者状态,表明当前节点角色是 observer

选举 ID:

1.ZXID(zookeeper transaction id):每个改变 Zookeeper状态的操作都会自动生成一个对应的zxid。ZXID最大的节点优先选为Leader
2.myid:服务器的唯一标识(SID),通过配置 myid 文件指定,集群中唯一,当ZXID一样时,myid大的节点优先选为Leader

2.3.2.2 ZooKeeper 集群部署

2.3.2.2.1 环境准备

#三台ubuntu18.04,20.04,22.04
zookeeper-node1.wang.org 10.0.0.151
zookeeper-node2.wang.org 10.0.0.152
zookeeper-node3.wang.org 10.0.0.153
#在三个节点都安装JDK8或JDK11
#在三个节点都安装zookeeper
[root@ubuntu ~]#bash install_zookeeper_single_node.sh    #装完是单机版,要改配置为集群版

2.3.2.2.3 准备配置文件

#3台机器修改配置文件 (追加下面3行)
[root@ubuntu ~]#vim /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000  #服务器与服务器之间的单次心跳检测时间间隔,单位为毫秒
initLimit=10  #集群中leader 服务器与follower服务器初始连接心跳次数,即多少个 2000 毫秒
syncLimit=5  #leader 与follower之间连接完成之后,后期检测发送和应答的心跳次数,如果该follower在设置的时间内(5*2000)不能与leader 进行通信,那么此 follower将被视为不可用。
dataDir=/usr/local/zookeeper/data #自定义的zookeeper保存数据的目录
dataLogDir=/usr/local/zookeeper/logs
clientPort=2181 #客户端连接 Zookeeper 服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求
maxClientCnxns=128 #单个客户端IP 可以和zookeeper保持的连接数
autopurge.snapRetainCount=3 #3.4.0中的新增功能:启用后,ZooKeeper 自动清除功能,会将只保留此最新3个快照和相应的事务日志,并分别保留在dataDir 和dataLogDir中,删除其余部分,默认值为3,最小值为3
autopurge.purgeInterval=24  #3.4.0及之后版本,ZK提供了自动清理日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个1或更大的整数,默认是 0,表示不开启自动清理功能

#格式: server.MyID服务器唯一编号=服务器IP:Leader和Follower的数据同步端口(只有leader才会打开):Leader和Follower选举端口(L和F都有)
server.1=10.0.0.151:2888:3888
server.2=10.0.0.152:2888:3888
server.3=10.0.0.153:2888:3888
#如果添加节点,只需要在所有节点上添加新节点的上面形式的配置行,在新节点创建myid文件,并重启所有节点服务即可


#创建dataDir文件
[root@ubuntu ~]#mkdir -p /usr/local/zookeeper/data

2.3.2.2.4 在各个节点生成ID文件

注意: 各个myid文件的内容要和zoo.cfg文件相匹配

#10.0.0.151
[root@zookeeper-node1 ~]#echo 1 > /usr/local/zookeeper/data/myid
#10.0.0.152
[root@zookeeper-node2 ~]#echo 2 > /usr/local/zookeeper/data/myid
#10.0.0.153
[root@zookeeper-node3 ~]#echo 3 > /usr/local/zookeeper/data/myid

2.3.2.2.5 各服务器启动 Zookeeper

#3台机器都停止
[root@ubuntu ~]#systemctl stop zookeeper.service
#3台机器都启动
[root@ubuntu ~]#systemctl start zookeeper.service
#查看集群角色
[root@ubuntu ~]#zkServer.sh status

#测试,reboot其中一台,查看两外两台,其中一台变为主节点

2.3.3 容器化部署

范例: 单实例

docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper

范例: 集群部署

#基于docker-compose部署集群(部署在同一台机器,坏了就崩了,这样部署也就玩一玩)
version: '3.1'
services:
 zoo1:
   image: zookeeper
    restart: always
   hostname: zoo1
   ports:
      - 2181:2181
   environment:
     ZOO_MY_ID: 1
     ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
     
 zoo2:
   image: zookeeper
    restart: always
   hostname: zoo2
   ports:
      - 2182:2181
   environment:
     ZOO_MY_ID: 2
     ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
     
 zoo3:
   image: zookeeper
    restart: always
   hostname: zoo3
   ports:
      - 2183:2181
   environment:
     ZOO_MY_ID: 3
     ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181

Zookeeper作为配置中心,也可以作为注册中心。具体怎么用,那就是java程序写代码了

 

3 Kafka

3.2 Kafka 介绍

java写的

3.3 常用消息队列对比

kafka动态扩容依赖zookeeper,但是最新版不依赖它了

3.5 Kafka 角色和流程

3.5.1 Kafka 概念

Producer:Producer即生产者,消息的产生者,是消息的入口。负责发布消息到Kafka broker。

Consumer:消费者,用于消费消息,即处理消息

Broker:Broker是kafka实例,每个服务器上可以有一个或多个kafka的实例,假设每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,
如: broker
-0、broker-1等…… Controller:是整个 Kafka 集群的管理者角色,任何集群范围内的状态变更都需要通过 Controller 进行,在整个集群中是个单点的服务,可以通过选举协议进行故障转移,
负责集群范围内的一些关键操作:主题的新建和删除,主题分区的新建、重新分配,Broker的加入、退出,触发分区 Leader 选举等,每个Broker里都有一个Controller实例,
多个Broker的集群同时最多只有一个Controller可以对外提供集群管理服务,Controller可以在Broker之间进行故障转移,Kafka 集群管理的工作主要是由Controller来完成的,
而 Controller 又通过监听Zookeeper 节点的变动来进行监听集群变化事件,Controller 进行集群管理需要保存集群元数据,监听集群状态变化情况并进行处理,
以及处理集群中修改集群元数据的请求,这些主要都是利用 Zookeeper 来实现 Topic :消息的主题,可以理解为消息的分类,一个Topic相当于数据库中的一张表,一条消息相当于关系数据库的一条记录,或者一个Topic相当于Redis中列表数据类型的一个Key,
一条消息即为列表中的一个元素。kafka的数据就保存在topic。在每个broker上都可以创建多个topic。 虽然一个 topic的消息保存于一个或多个broker 上同一个目录内, 物理上不同 topic 的消息分开存储在不同的文件夹,但用户只需指定消息的topic即可生产或消费数据而不必
关心数据存于何处,topic 在逻辑上对record(记录、日志)进行分组保存,消费者需要订阅相应的topic 才能消费topic中的消息。 Consumer group: 每个consumer 属于一个特定的consumer group(可为每个consumer 指定 group name,若不指定 group name 则属于默认的group),
同一topic的一条消息只能被同一个consumer group 内的一个consumer 消费,类似于一对一的单播机制,但多个consumer group 可同时消费这一消息,
类似于一对多的多播机制
Partition :是物理上的概念,每个 topic 分割为一个或多个partition,即一个topic切分为多份, 当创建 topic 时可指定 partition 数量,
partition的表现形式就是一个一个的文件夹,该文件夹下存储该partition的数据和索引文件,分区的作用还可以实现负载均衡,提高kafka的吞吐量。
同一个topic在不同的分区的数据是不重复的,一般Partition数不要超过节点数,注意同一个partition数据是有顺序的,但不同的partition则是无序的。 Replication: 同样数据的副本,包括leader和follower的副本数,基本于数据安全,建议至少2个,是Kafka的高可靠性的保障,和ES的副本有所不同,
Kafka中的副(leader
+follower)数包括主分片数,而ES中的副本数(follower)不包括主分片数 #副本放的位置kafka自己实现

3.5.2 Kafka 工作机制

注意:Kafka 2.8.0版本开始,增加了KRaft(KRaft是Kafka Raft协议模式的简称)模式,这个模式下Kafka不再需要ZooKeeper,而是使用内 置的Raft协议来进行元数据的管理和领导者选举。Raft协议是一种为分布式系统提供一致性的算法,它更易于理解和实施,同时也保证了系 统的可用性和数据的一致性。

 

posted @ 2024-10-14 19:07  战斗小人  阅读(23)  评论(0编辑  收藏  举报