一、redis 哨兵模式
1.1 redis 安装启动
$ yum install redis
# 启动报错
$ systemctl start redis
Job for redis.service failed because the control process exited with error code.
See "systemctl status redis.service" and "journalctl -xe" for details.
# 查看报错信息,显示无权限
$ journalctl -xe
Jan 12 11:22:24 localhost.localdomain redis-server[1613]: >>> 'logfile /var/log/redis/redis.log'
Jan 12 11:22:24 localhost.localdomain redis-server[1613]: Can't open the log file: Permission denied
# 查看服务文件配置
$ cat /lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
# 说明这个服务系统启动后是redis组的,所以改文件权限为redis组即可
$ chown redis:redis /var/log/redis/redis.log
1.2 配置文件修改
master 配置文件修改
$ vim /etc/redis.conf
# 后台守护程序运行
daemonize yes
# 远程访问
bind 0.0.0.0
# 设置密码
requirepass mall@rw
# 使用了redis 哨兵集群,由于在切换master的时候,原本的master可能变成slave,故也需要在原本redis master上配置masterauth:
masterauth mall@rw
slave 配置文件修改
# 修改配置文件
$ vim /etc/redis.conf
# 后台守护程序运行
daemonize yes
# 远程访问
# bind 127.0.0.1
# 设置密码
requirepass mall@rw
# 由于slave需要和master交互,在slave上需配置master的密码验证
masterauth mall@rw
# slave 节点指定master地址和端口
replicaof 10.0.5.101 6379
防火墙开放6379端口,否则远程主机无法连接redis服务
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
firewall-cmd --zone=public --query-port=6379/tcp
启动服务,先启动 master 再启动 slave
$ systemctl enable redis
$ systemctl start redis
# 查看节点信息
$ redis-cli
127.0.0.1:6379> auth mall@rw
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.5.102,port=6379,state=online,offset=28,lag=0
master_replid:5015ca82b639009a10d4dce16d234117b2449b37
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
1.3 哨兵配置文件修改
$ vim /etc/redis-sentinel.conf
# 后台守护程序运行
daemonize yes
# mymaster是主节点的别名,当前Sentinel节点监控 10.0.5.101:6379 这个主节点,1代表判断主节点失败至少需要2个Sentinel节点同意
sentinel monitor mymaster 10.0.5.101 6379 2
# 配置master密码,注意该行一定要在 sentinel monitor mymaster 10.0.5.101 6379 1 之下,否则报错:no such master with specified name
sentinel auth-pass mymaster mall@rw
注意:sentinel monitor mymaster 10.0.5.101 6379 1 切记即使监控的是本机也不要用 127.0.0.1,被坑好惨
防火墙开放26379端口,否则远程主机无法连接redis-sentinel服务
firewall-cmd --zone=public --add-port=26379/tcp --permanent
firewall-cmd --reload
firewall-cmd --zone=public --query-port=26379/tcp
启动服务
$ systemctl enable redis-sentinel.service
$ systemctl start redis-sentinel.service
# 查看日志
$ vim /var/log/redis/sentinel.log
注意:哨兵至少配置3台服务器,如果只有两台服务器那么当一台宕机则单个哨兵无法选举。
1.4 Spring Boot项目配置redis哨兵
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
配置文件
spring:
redis:
password: mall@rw # Redis服务器连接密码(默认为空)
timeout: 300ms # 连接超时时间(毫秒)
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认为8
max-active: 8
# 连接池中的最大空闲连接 默认为8
max-idle: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认为-1
max-wait: -1ms
# 连接池中的最小空闲连接 默认为 0
min-idle: 0
sentinel:
# 主节点的别名
master: mymaster
# sentinel服务的ip和端口
nodes: 10.0.101:26379,10.0.102:26379,10.0.103:26379
config
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ReadMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import java.util.ArrayList;
import java.util.List;
@Configuration
@Slf4j
public class RedissonConfig {
@Autowired
private RedisProperties redisProperties;
/**
* 单个服务
* @return
*/
@Profile({"dev", "test"})
@Bean
public RedissonClient redissonSingle() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://"
+ redisProperties.getHost()
+ ":"
+ redisProperties.getPort())
;
return Redisson.create(config);
}
/**
* 哨兵模式
* @return
*/
@Profile("prod")
@Bean
public RedissonClient redissonSentinel() {
Config config = new Config();
List<String> nodes = redisProperties.getSentinel().getNodes();
List<String> clusterNodes = new ArrayList<>(nodes.size());
for (String address : nodes) {
clusterNodes.add("redis://" + address);
}
config.useSentinelServers()
.addSentinelAddress(clusterNodes.toArray(new String[0]))
.setMasterName(redisProperties.getSentinel().getMaster())
.setReadMode(ReadMode.SLAVE)
.setTimeout(redisProperties.getTimeout().getNano())
.setPassword(redisProperties.getPassword());
return Redisson.create(config);
}
}
二、RabbitMQ 镜像模式
1.2.1 安装服务
# 安装依赖
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
# 下载并安装 rabbitmq
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.9/rabbitmq-server-3.8.9-1.el8.noarch.rpm
yum install rabbitmq-server-3.8.9-1.el8.noarch.rpm
# 安装web管理插件
rabbitmq-plugins enable rabbitmq_management
# 开机启动并启动服务
systemctl enable rabbitmq-server.service
systemctl start rabbitmq-server.service
# 添加用户 rabbitmqctl add_user <username> <password>
rabbitmqctl add_user mall mall
# 设置用户角色为管理员
rabbitmqctl set_user_tags mall administrator
# 查看用户列表
rabbitmqctl list_users
# 添加vhost
rabbitmqctl add_vhost /mall
rabbitmqctl list_vhosts
# 分配访问权限
rabbitmqctl set_permissions -p /mall mall ".*" ".*" ".*"
1.2.2 搭建镜像集群
有两台服务器
10.0.5.101
10.0.5.102
# 修改每个服务器的hosts
$ vim /etc/hosts
10.0.5.101 mq1
10.0.5.102 mq2
# mq对主机名非常的敏感,即使使用hostnamectl set-hostname m1主机名之后不重启的话也是造成集群的不通信的问题
$ reboot
# .erlang.cookie是erlang分布式的token文件,集群内所有设备要持有相同的.erlang.cookie文件才允许彼此通信。将mq2的替换为mq1的
# 查看mq1的.erlang.cookie
$ cat /var/lib/rabbitmq/.erlang.cookie
YTAWDSEAFUODRDHTLKMD
# 将mq2的替换
$ vim /var/lib/rabbitmq/.erlang.cookie
YTAWDSEAFUODRDHTLKMD
# 在mq2服务器上执行下面的命令将与mq1服务器进行复制
# 暂停服务
$ rabbitmqctl stop_app
# 加入到m1的集群
$ rabbitmqctl join_cluster rabbit@mq1
# 启动服务
$ rabbitmqctl start_app
# 验证集群结果
$ rabbitmqctl cluster_status
# 镜像模式依赖 policy 模块,启动镜像模式
# ha-all:为策略名称。
# ^:为匹配符,只有一个 ^ 代表匹配所有
# -p vhost:指定vhost;ha-mode:为匹配类型,他分为 3 种模式:all-所有(所有的 queue),exctly-部分(需配置 ha-params 参数,此参数为 int 类型比如 3,众多集群中的随机 3 台机器),nodes-指定(需配置 ha-params 参数,此参数为数组类型比如["rabbit@mq1","rabbit@mq2","rabbit@mq3"]这样指定为 3 台机器。);ha-sync-mode:镜像队列中消息的同步方式,其值可为”automatic”或”manually”.
$ rabbitmqctl set_policy -p /mall ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
1.2.3 Spring Boot项目配置RabbitMQ集群
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置
//RabbitMQ单机
spring:
rabbitmq:
host: localhost
port: 5672
username: your_username
password: your_password
//或者 RabbitMQ单机,只使用addresses
spring:
rabbitmq:
addresses:ip1:port1
username: your_username
password: your_password
//RabbitMQ集群,addresses一定要逗号分隔
spring:
rabbitmq:
addresses:ip1:port1,ip2:port2,ip3:port3
username: your_username
password: your_password