在上一篇文章里,已经完成了基本环境的安装,本文继续。
ps:上篇文章的地址:http://blog.csdn.net/chaojicain/article/details/78029575
为了确保在测试过程中不会因为防火墙的原因导致测试失败,配置前先将防火墙关闭
## 查看防火墙状态
[root@localhost init.d]# service iptables status
## 关闭防火墙
[root@localhost init.d]# service iptables stop
nginx负载均衡
nginx.conf配置文件:
#user nobody;
#cpu quantity or quantity * 2
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 2048;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format logstash_json '{ "@timestamp": "$time_iso8601", '
'"client_ip": "$remote_addr", '
'"resp_len": "$body_bytes_sent", '
'"waster_time": "$request_time", '
'"status": "$status", '
'"request_path": "$request", '
'"request_method": "$request_method", '
'"upstream": "$upstream_addr", '
'"upstream_status": "$upstream_status", '
'"ups_resp_time": "$upstream_response_time" }';
access_log logs/access_json.log logstash_json;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#keepalive_timeout 0;
keepalive_timeout 120;
add_header X-Frame-Options SAMEORIGIN;
#gzip on;
#gzip_min_length 1k;
#gzip_buffers 4 16k;
#gzip_http_version 1.0;
#gzip_comp_level 2; #压缩等级
#gzip_types text/plain application/x-javascript text/css application/xml;
#gzip_vary on;
upstream ms{
server 10.200.188.240:8080 weight=1;
server 10.200.188.234:8080 weight=1;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_pass http://ms;
}
#error_page 404 /404.html
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /check-status {
check_status;
access_log off;
#allow SOME.IP.ADD.RESS;
##deny all;
}
}
}
新增index.jsp到234/240的tomcat的webapp下:
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
This is my JSP page MESserver-Appt1 <br><!-- 二个tomcat修改此处 -->
session Id :<%=session.getId()%>
</body>
</html>
启动234/240上的tomcat,浏览器上访问http://10.200.188.234
配置keepalived实现热备
keepalived.conf 配置文件,两台机器上的配置基本相同,不同的用红色标出
! Configuration File for keepalived
global_defs {
router_id Nginx
}
vrrp_script chk_nginx {
script "/usr/local/keepalived/check_nginx.sh" --nginx健康检查脚本
interval 2
weight -5
}
vrrp_instance VI_1 {
state BACKUP --MASTER(主),BACKUP(从)
interface eth0 --网卡名
virtual_router_id 58 --虚拟ID两台机器要配置一样
priority 90 --优先级,
nopreempt --优先竞争
advert_int 1
authentication { --两台配置一样
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { --虚拟ip
10.200.188.236
}
track_script {
chk_nginx
}
}
说明:我的方案中,nginx是没有主从之分的,一台挂掉了,另外一台接收服务,挂掉的重启了,也不会重新接管服务。如果要实现主从,则state 设置为MASTER, nopreempt 关闭优先级竞争,如果不关闭,即使两台都设置为BACKUP,优先级高的还是会抢占优先级低的
check_nginx.sh 脚本
1 #!/bin/sh
2 # check nginx server status
3
4 # Source Function Library
5
6 nginxPidNum=`ps -C nginx --no-header | wc -l`
7
8 if [ "$nginxPidNum" -eq 0 ];then
9
10 # /usr/local/nginx/sbin/nginx
11
12 # sleep 3
13 nginxPidNum=`ps -C nginx --no-header | wc -l`
14 if [ "$nginxPidNum" -eq 0 ];then
15 service keepalived stop
16 fi
17 fi
18
依次启动两台虚拟机上的tomcat、nginx、keepalived。
[root@localhost keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:24:ed:fd brd ff:ff:ff:ff:ff:ff
inet 10.200.188.240/24 brd 10.200.188.255 scope global eth0
inet 10.200.188.236/32 scope global eth0
inet6 fe80::20c:29ff:fe24:edfd/64 scope link
valid_lft forever preferred_lft forever
可以看到eth0网卡上出现了两个ip,关闭240上的keepalived服务,在234查看ip是否漂移过去。如果漂移过去则配置成功。浏览器访问10.200.188.236即可访问到index.jsp
页面。重启240后,发现240并没有重新接管ip,可见配置生效。当234上的nginx服务down掉时,检测脚本会自动关闭keepalive服务,ip自动漂移回到240
Redis+Tomcat实现Session 共享
实现redis+tomcat的session共享需要用到开源项目
https://github.com/jcoleman/tomcat-redis-session-manager,下载源码,编译打包生成jar文件。
由于项目是gradle的,没有环境,下载下来后直接改为了maven项目,下面贴出pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.orangefunction</groupId> <artifactId>com.orangefunction</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>com.orangefunction</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>7.0.57</version> </dependency> </dependencies> <build> <finalName>tomcat-redis-session-manager-master</finalName> </build> </project>
将打包生成的tomcat-redis-session-manager-master.jar、commons-pool2-2.2.jar、jedis-2.5.2.jar拷贝到234和240的tomcat的lib目录下。
编辑conf目录下的context.xml文件,新增如下:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="10.200.188.234"
port="6379"
password="123456" <!--redis 密码 没有可以不设置-->
database="0"
maxInactiveInterval="60" />
配置Redis:
#只列出了配置项
bind 0.0.0.0 #解决其他主机无法访问的问题
protected-mode yes #保护模式
daemonize yes #后台启动
requirepass "123456" --redis密码
masterauth "123456" --主从时使用
两台虚拟机上的redis使用相同的配置
启动234上的redis,在依次启动tomcat、nginx .访问234上的nginx,可以看到不管访问的是234或是240的tomcat,session值都是不变的。说明配置成功。
查看234的redis
[root@localhost redis]# redis-cli -a 123456
使用keys * 可以查看redis所有的键值
ps:这里遇到了一个问题,在没有任何访问的情况下,看到redis中的sessionId不停的增加,找了很久都没有发现问题,最后发现是nginx在检查后台tomcat的健康状态而不断的发出http请求导致。修改nginx配置如下:
upstream ms{
server 10.200.188.240:8080 weight=1;
server 10.200.188.234:8080 weight=1;
check interval=3000 rise=2 fall=5 timeout=1000 type=tcp; }
将type=http 改为tcp即可。具体细节参看
https://www.iyunv.com/thread-38535-1-1.html
Keepalived+Redis 实现redis双击热备
keepalived.conf:
! Configuration File for keepalived
global_defs {
router_id Nginx
}
vrrp_script chk_nginx {
script "/usr/local/keepalived/scripts/redis-check.sh" #同时检测redis和nginx,任何一个挂掉,直接切换到备机
interval 2
weight -5
# fail 2 失败次数,达到失败次数就转移ip,这里用脚本控制不设置,有主备的可以考虑
# timeout 2 超时时间
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 58
priority 88
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.200.188.236
}
track_script {
chk_nginx
}
notify_master /usr/local/keepalived/scripts/redis-master.sh #成为主的时候执行
notify_backup /usr/local/keepalived/scripts/redis-backup.sh #成为备的时候执行
notify_fault /usr/local/keepalived/scripts/redis-fault.sh #出现错误的时候执行
notify_stop /usr/local/keepalived/scripts/redis-stop.sh #停止的时候执行
}
主备设置除了priority基本一样。
redis-check.sh 主备一样:
#!/bin/bash
# Time 2017.9.18
# Desc 检查redis和nginx服务是否正常
password=123456
logfile=/usr/local/keepalived/logs/redis-keepalived.log
# ping reids
pingRs=`/usr/local/redis/bin/redis-cli -a $password PING`
#查看nginx进程id是否存在
nginxPidNum=`ps -C nginx --no-header | wc -l`
if [ "$pingRs" != "PONG" ] || [ "$nginxPidNum" -eq 0 ];then
echo "[`date`] nginx or redis is error! " >> $logfile
#等待2秒重试
sleep 2
pingRs=`/usr/local/redis/bin/redis-cli -a $password PING`
nginxPidNum=`ps -C nginx --no-header | wc -l`
if [ "$pingRs" != "PONG" ] || [ "$nginxPidNum" -eq 0 ];then
echo "[`date`] nginx or redis is error ! switch host" >> $logfile
service keepalived stop
fi
fi
redis-master.sh
#!/bin/bash
# Time 2017.9.18
# Desc redis 主服务启动脚本
password=123456
# redis 客户端绝对路径
redisCli=/usr/local/redis/bin/redis-cli
#日志路径
logfile=/usr/local/keepalived/logs/redis-keepalived.log
echo "[`date`] master " >> $logfile
# 设置主从关系 同步数据
echo "[`date`] begin slaveof ..." >> $logfile
$redisCli -a $password slaveof 10.200.188.234 6379 &>> $logfile
# 暂停5秒保证数据同步结束
sleep 5
echo "[`date`] slaveof done ..." >> $logfile
# 取消同步
$redisCli -a $password slaveof NO ONE &>> $logfile
主从的不同在于ip不同,修改即可
#/bin/bash
# Time 2019.9.18
# Desc 进入backup时执行的脚本
password=123456
redisCli=/usr/local/redis/bin/redis-cli
logfile=/usr/local/keepalived/logs/redis-keepalived.log
echo "[`date`] backup is start" >> $logfile
sleep 5
echo "begin to slaveof ..."
$redisCli -a $password slaveof 10.200.188.234 6379 &>>$logfile
echo "[`date`] slaveof done ..."
主从ip不同而已
redis-fault.sh
#!/bin/bash
# Time 2017.9.18
# Desc keepalived 异常
logfile=/usr/local/redis-keepalived.log
echo "[`date`] keepalived is fault" >> $logfile
redis-stop.sh
#!/bin/bash
# Time 2017.9.18
# Desc stop
logfile=/usr/local/redis-keepalived.log
echo "[`date`] keepalived is stop" >> $logfile
至此配置就算完成了,依次启动,redis、tomcat、nginx、keepalived 。测试。关闭其中一个redis,查看ip是否漂移,查看redis缓存是否同步、重启redis查看redis是否同步了正在提供服务的redis的数据。如果有则万事大吉。高可用的集群环境搭建完成。
第一次写博客,有点乱。如果有错漏之处,轻拍!以上用的配置文件和脚本稍后会上传到csdn上。