SpringBoot、SpringCloud微服务 学习集群高可用
学习目标
- 理解集群流程(Nginx+Tomcat)
- 理解分布式概念->SOA->微服务
- 能实现Eureka集群[集群配置]
- 能实现Redis集群[Redis集群配置、哨兵策略、Redis击穿问题]
- RabbitMQ集群
1.集群概述
1.1什么是集群
1.1.1集群概念
集群是一种计算机系统, 它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作。在某种意义上,他们可以被看作是一台计算机。集群系统中的单个计算机通常称为节点,通常通过局域网连接,但也有其它的可能连接方式。集群计算机通常用来改进单个计算机的计算速度和/或可靠性。一般情况下集群计算机比单个计算机,比如工作站或超级计算机性能价格比要高得多。
1.1.2集群的特点
集群拥有以下两个特点:
- 可扩展性:集群的性能不限制于单一的服务实体,新的服务实体可以动态的添加到集群,从而增强集群的性能。
- 高可用性:集群当其中一个节点发生故障时,这台节点上面所运行的应用程序将在另一台节点被自动接管,消除单点故障对于增强数据可用性、可达性和可靠性是非常重要的。
1.1.3集群的两大能力
集群必须拥有以下两大能力:
- 负载均衡:负载均衡把任务比较均匀的分布到集群环境下的计算和网络资源,以提高数据吞吐量。
- 错误恢复:如果集群中的某一台服务器由于故障或者维护需要无法使用,资源和应用程序将转移到可用的集群节点上。这种由于某个节点的资源不能工作,另一个可用节点中的资源能够透明的接管并继续完成任务的过程,叫做错误恢复。
负载均衡和错误恢复要求各服务实体中有执行同一任务的资源存在,而且对于同一任务的各个资源来说,执行任务所需的信息视图必须是相同的。
1.2集群与分布式的区别
说到集群,可能大家会立刻联想到另一个和它很相近的一个词----“分布式”。那么集群和分布式是一回事吗?有什么联系和区别呢?
相同点:
分布式和集群都是需要有很多节点服务器通过网络协同工作完成整体的任务目标。
不同点:
分布式是指将业务系统进行拆分,即分布式的每一个节点都是实现不同的功能。而集群每个节点做的是同一件事情。
如下图,每个人都有不同的分工,一起协作干一件事,叫做“分布式”
再看下图:每个划桨人干的都是一样的活,叫做集群。
分布式的每一个节点也可以做成集群。其实这个赛龙舟的图,总整体来看属于分布式,包括打鼓和划桨两个分布式节点,而划桨的节点又是集群的形态。
Nginx:反向和正向代理服务器,轻量级的web服务器,也是邮件服务器。占用资源小,运行稳定。
命令:
启动命令:start nginx
停止命令:nginx -s quit
停止命令:nginx -s stop
重新加载:nginx -s reload
Nginx+Tomcat集群/高可用
#负载均衡池
upstream itheimaStream {
server 127.0.0.1:18081;
server 127.0.0.1:18082;
server 127.0.0.1:18083;
}
#配置虚拟机 处理www.itheima.com
server {
#侦听端口
listen 80;
#当前虚拟机所配置的域名信息[所有该域名访问都遵循该配置规则]
server_name www.itheima.com;
#charset koi8-r;
#access_log logs/host.access.log main;
#针对用户请求路径而言
#位置方位的意思
#根据用户的请求,决定如何路由用户的请求
#/所有请求
location / {
#所有www.itheima.com的请求都交给itheimaStream负载均衡池处理
#proxy_pass http://itheimaStream;
proxy_pass http://127.0.0.1:18081;
}
}
Nginx静态网站发布
#所有静态页访问
server {
#侦听端口
listen 80;
#当前虚拟机所配置的域名信息[所有该域名访问都遵循该配置规则]
server_name resource.itheima.com;
#charset koi8-r;
#access_log logs/host.access.log main;
#针对用户请求路径而言
#位置方位的意思
#根据用户的请求,决定如何路由用户的请求
#/所有请求
location / {
#所有的请求全部到D:\project-changgou-portal-fis3-master目录下找对应文件
root D:/project-changgou-portal-fis3-master;
}
}
Nginx实现动静分离
#配置虚拟机 处理www.itheima.com
server {
#侦听端口
listen 80;
#当前虚拟机所配置的域名信息[所有该域名访问都遵循该配置规则]
server_name www.itheima.com;
#charset koi8-r;
#access_log logs/host.access.log main;
#所有以.jpg,.png。。。都遵循该配置路由规则
location ~ \.(jpg|png|gif|js|css)$ {
#都直接到D盘的images目录找文件
root D:/images;
}
#针对用户请求路径而言
#位置方位的意思
#根据用户的请求,决定如何路由用户的请求
#/所有请求
location / {
#所有www.itheima.com的请求都交给itheimaStream负载均衡池处理
#proxy_pass http://itheimaStream;
proxy_pass http://127.0.0.1:18081;
}
}
2 Eureka集群
2.1 Eureka简介
2.1.1什么是Eureka
Eureka是一种基于REST(Representational State Transfer)的服务,主要用于AWS,用于定位服务,以实现中间层服务器的负载平衡和故障转移。我们将此服务称为Eureka Server。Eureka还附带了一个基于Java的客户端组件Eureka Client,它使与服务的交互变得更加容易。客户端还有一个内置的负载均衡器,可以进行基本的循环负载均衡。在Netflix,一个更复杂的负载均衡器包装Eureka,根据流量,资源使用,错误条件等多种因素提供加权负载平衡,以提供卓越的弹性。
理解:
Eureka是一个服务注册与发现的注册中心。类似于dubbo中的zookeeper.
官网地址:
https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance
2.1.2Eureka的架构
application Service :相当于服务提供者
application Client :相当于服务消费者
make remote call :服务调用过程
us-east-1c d e 都是region:us-east-1 的可用区域。
简单可以理解为:
每一个erurak都是一个节点,默认启动时就是以集群的方式。
2.2 搭建Eureka集群
配置host文件C:\Windows\System32\drivers\etc\hosts
文件,添加映射
127.0.0.1 eureka-server1
127.0.0.1 eureka-server2
127.0.0.1 eureka-server3
2.2.1 application.yml配置
第1台application.yml:
server:
port: 8761
eureka:
instance:
hostname: eureka-server1
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka-server2:8762/eureka/,http://eureka-server3:8763/eureka/
第2台application.yml
server:
port: 8762
eureka:
instance:
hostname: eureka-server2
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka-server1:8761/eureka/,http://eureka-server3:8763/eureka/
第3台application.yml配置:
server:
port: 8763
eureka:
instance:
hostname: eureka-server3
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka-server1:8761/eureka/,http://eureka-server2:8762/eureka/
2.2.2 效果
项目中使用的时候,将多个写到一起,隔开即可,代码如下:
上图代码如下:
eureka:
client:
service-url:
defaultZone: http://eureka-server1:8761/eureka/,http://eureka-server2:8761/eureka/,http://eureka-server3:8763/eureka/
3 Redis Cluster
4.1 Redis-Cluster简介
4.1.1 什么是Redis-Cluster
为何要搭建Redis集群。Redis是在内存中保存数据的,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据,适合存储大数据的是Hadoop生态系统的Hbase或者是MogoDB。Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。
Redis集群搭建的方式有多种,例如使用客户端分片、Twemproxy、Codis等,但从redis 3.0之后版本支持redis-cluster集群,它是Redis官方提出的解决方案,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster架构图如下:
客户端与 redis 节点直连,不需要中间 proxy 层.客户端不需要连接集群所有节点连接集群中任何一个可用节点即可。
所有的 redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽.
4.1.2分布存储机制-槽
(1)redis-cluster 把所有的物理节点映射到[0-16383]slot 上,cluster 负责维护
node<->slot<->value
(2)Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
例如三个节点:槽分布的值如下:
SERVER1: 0-5460
SERVER2: 5461-10922
SERVER3: 10923-16383
4.1.3容错机制-投票
(1)选举过程是集群中所有master参与,如果半数以上master节点与故障节点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作. 故障节点对应的从节点自动升级为主节点
(2)什么时候整个集群不可用(cluster_state:fail)?
如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完成时进入fail状态.
4.2搭建Redis-Cluster
4.2.1搭建要求
需要 6 台 redis 服务器。搭建伪集群。
需要 6 个 redis 实例。
需要运行在不同的端口 7001-7006
4.2.2准备工作
(1)安装gcc 【此步省略】
Redis 是 c 语言开发的。安装 redis 需要 c 语言的编译环境。如果没有 gcc 需要在线安装。
yum install gcc-c++
(2)使用yum命令安装 ruby (我们需要使用ruby脚本来实现集群搭建)【此步省略】
yum install ruby
yum install rubygems
----- 知识点小贴士 -----
Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby(Java平台)、IronRuby(.NET平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名
RubyGems简称gems,是一个用于对 Ruby组件进行打包的 Ruby 打包系统
(3)将redis源码包上传到 linux 系统 ,解压redis源码包
(4)编译redis源码 ,进入redis源码文件夹
make
看到以下输出结果,表示编译成功
(5)创建目录/usr/local/redis-cluster目录, 安装6个redis实例,分别安装在以下目录
/usr/local/redis-cluster/redis-1
/usr/local/redis-cluster/redis-2
/usr/local/redis-cluster/redis-3
/usr/local/redis-cluster/redis-4
/usr/local/redis-cluster/redis-5
/usr/local/redis-cluster/redis-6
以第一个redis实例为例,命令如下
make install PREFIX=/usr/local/redis-cluster/redis-1
出现此提示表示成功,按此方法安装其余5个redis实例
(6)复制配置文件 将 /redis-3.0.0/redis.conf 复制到redis下的bin目录下
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-1/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-2/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-3/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-4/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-5/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-6/bin
4.2.3配置集群
(1)修改每个redis节点的配置文件redis.conf
修改运行端口为7001 (7002 7003 …)
将cluster-enabled yes 前的注释去掉(632行)
集群:
6个节点
3主
3从
1)创建6个节点 7001-7006
2)开启集群
3)串联集群[将集群链接到一起]
(2)启动每个redis实例
以第一个实例为例,命令如下
cd /usr/local/redis-cluster/redis-1/bin/
./redis-server redis.conf
把其余的5个也启动起来,然后查看一下是不是都启动起来了
[root@localhost ~]# ps -ef | grep redis
root 15776 15775 0 08:19 pts/1 00:00:00 ./redis-server *:7001 [cluster]
root 15810 15784 0 08:22 pts/2 00:00:00 ./redis-server *:7002 [cluster]
root 15831 15813 0 08:23 pts/3 00:00:00 ./redis-server *:7003 [cluster]
root 15852 15834 0 08:23 pts/4 00:00:00 ./redis-server *:7004 [cluster]
root 15872 15856 0 08:24 pts/5 00:00:00 ./redis-server *:7005 [cluster]
root 15891 15875 0 08:24 pts/6 00:00:00 ./redis-server *:7006 [cluster]
root 15926 15895 0 08:24 pts/7 00:00:00 grep redis
(3)上传redis-3.0.0.gem ,安装 ruby用于搭建redis集群的脚本。
[root@localhost ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0...
Installing RDoc documentation for redis-3.0.0...
(4)使用 ruby 脚本搭建集群。
进入redis源码目录中的src目录 执行下面的命令 redis-trib.rb
ruby工具,可以实现Redis集群,create
创建集群,--replicas
创建主从关系 1