在网上大多数是关于tomcat7与redis结合实现session会话共享,完全不符合现在的实际要求,由于在工作中需要完成过tomcat8负载均衡的项目,结合项目总结把实现的过程展现出来。废话不多说了,直接上干货,为了保护客户的权益,在此全部以内网IP来代替。本文先把Nginx代理功能与Tomcat8+Redis4实现session会话共享展示出来,关于数据库、Redis主从等方面下个博文会详细写出来的。

一、        项目简单需求如下

1、 此项目是一个电商的网络商城的网站,网站是用jdk-1.8编写的

2、 实现tomcat8负载均衡的功能,一台Tomcat服务器挂掉不影响客户的正常访问

3、 商城有登录功能需要实现session会话共享

4、 数据库用mariadb+galera来实现高可用

5、 用proxysql来实现数据库的读写分离

6、 Nginx代理通过Keepalived实现高可用

说明:使用Nginx作为Tomcat的负载平衡器,Tomcat的会话Session数据存储在Redis,能够实现零宕机的7x24效果。因为将会话存储在Redis中,因此Nginx就不必配置成stick粘贴某个Tomcat方式,这样才能真正实现后台多个Tomcat负载平衡。

二、        项目实施中的改进

1、 第一次项目实施研讨会中准备使用nginx基于访问ip的hash策略

2、 第二次项目实施研讨会中准备使用是tomcat8的cluster会话保持功能

3、 第三次项目实施研讨会中准备使用的是基于memcache会话保持功能

4、 最后确定用Tomcat8+Redis4实现session会话共享

说明:关于memcache与redis的区别请大家自行上网查询,在此不浪费大家时间了

 

三、        网络架构简单介绍如下

主机名称

操作系统

IP地址分配

Nginx1.12

CentOS7.5

192.168.101.71

Tomcat-1

192.168.101.72

Tomcat-2

192.168.101.73

Redis4.06

192.168.101.74

 

四、        Nginx负载均衡功能实现

1、        centos7操作系统优化,以上是实际生产环境使用

1)vim /etc/security/limits.conf

最后添加

*               soft     nofile           102400

*               hard    nofile           102400

*               soft     nproc                    102400

*               hard    nproc           102400

2) vim /etc/security/limits.d/20-nproc.conf

#加大普通用户限制 也可以改为unlimited

*    soft       nproc   102400

*    hard      nproc   102400

root soft     nproc   unlimited

3) vim /etc/sysctl.conf加入内容如下:

net.ipv6.conf.all.disable_ipv6 = 1

net.ipv6.conf.default.disable_ipv6 = 1

net.ipv4.icmp_echo_ignore_broadcasts = 1

net.ipv4.icmp_ignore_bogus_error_responses = 1

net.ipv4.ip_forward = 0

net.ipv4.conf.all.send_redirects = 0

net.ipv4.conf.default.send_redirects = 0

net.ipv4.conf.all.rp_filter = 1

net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.all.accept_source_route = 0

net.ipv4.conf.default.accept_source_route = 0

kernel.sysrq = 0

kernel.core_uses_pid = 1

net.ipv4.tcp_syncookies = 1

kernel.msgmnb = 65536

kernel.msgmax = 65536

kernel.shmmax = 68719476736

kernel.shmall = 4294967296

net.ipv4.tcp_max_tw_buckets = 6000

net.ipv4.tcp_sack = 1

net.ipv4.tcp_window_scaling = 1

net.ipv4.tcp_rmem = 4096 87380 4194304

net.ipv4.tcp_wmem = 4096 16384 4194304

net.core.wmem_default = 8388608

net.core.rmem_default = 8388608

net.core.rmem_max = 16777216

net.core.wmem_max = 16777216

net.core.netdev_max_backlog = 262144

net.ipv4.tcp_max_orphans = 3276800

net.ipv4.tcp_max_syn_backlog = 262144

net.ipv4.tcp_timestamps = 0

net.ipv4.tcp_synack_retries = 1

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_mem = 94500000 915000000 927000000

net.ipv4.tcp_fin_timeout = 1

net.ipv4.tcp_keepalive_time = 30

net.ipv4.ip_local_port_range = 1024 65000

net.netfilter.nf_conntrack_max = 655350

net.netfilter.nf_conntrack_tcp_timeout_established = 1200

net.ipv4.conf.all.accept_redirects = 0

net.ipv4.conf.default.accept_redirects = 0

net.ipv4.conf.all.secure_redirects = 0

net.ipv4.conf.default.secure_redirects = 0

vm.overcommit_memory=1

4) 最后 sysctl  -p   生效

5)修改主机名以区分各机器功能

2、nginx安装配置

1)    上传nginx-1.12.2.tar.gz到/usr/local/src

2)    yum -y install gcc gcc-c++ make libtool zlib zlib-devel pcre pcre-devel openssl openssl-devel

3)    useradd -s /sbin/nologin www

4)    cd /usr/local/src

5)    tar -zxvf nginx-1.12.2.tar.gz -C /usr/local/

6)    cd /usr/local/nginx-1.12.2/

7)    ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module  --with-http_gzip_static_module  --with-pcre  --with-http_flv_module

8)    make && make install

9)    ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx

10) vim /etc/init.d/nginx 内容如下:

#!/bin/bash

# nginx Startup script for the Nginx HTTP Server

# chkconfig: - 85 15

# pidfile: /usr/local/nginx/logs/nginx.pid

# config: /usr/local/nginx/conf/nginx.conf

nginxd=/usr/local/nginx/sbin/nginx

nginx_config=/usr/local/nginx/conf/nginx.conf

nginx_pid=/usr/local/nginx/logs/nginx.pid

RETVAL=0

prog="nginx"

# Source function library.

. /etc/rc.d/init.d/functions

# Start nginx daemons functions.

start() {

if [ -f $nginx_pid ] ; then

echo "nginx already running...."

exit 1

fi

echo -n "Starting $prog: "

   $nginxd -c ${nginx_config}

   RETVAL=$?

[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx

}

# Stop nginx daemons functions.

stop() {

echo -n "Stopping $prog: "

        $nginxd -s stop

        RETVAL=$?

[ $RETVAL = 0 ] &&rm -f /var/lock/subsys/nginx

}

# reloadnginx service functions.

reload() {

echo -n "Reloading $prog: "

    $nginxd -s reload

}

# statusngnx service functions

status() {

if [ -f $nginx_pid ] ; then

echo  "$prog is running"

else

echo  "$prog is stop"

fi

}

case "$1" in

start)

start

        ;;

stop)

stop

        ;;

reload)

reload

        ;;

restart)

stop

start

        ;;

status)

status

        ;;

*)

echo "Usage: $prog {start|stop|restart|reload|status}"

exit 1

        ;;

esac

11) chmod +x /etc/init.d/nginx

12) chkconfig --add nginx  && chkconfig nginx on

13) systemctl daemon-reload

14) mv /usr/local/nginx/conf/nginx.conf  /usr/local/nginx/conf/nginx.conf.bak

15) vim /usr/local/nginx/conf/nginx.conf 内容如下:

user  www www;

worker_processes  4;

worker_cpu_affinity 0001 0010 0100 1000;

error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

worker_rlimit_nofile 102400;

pid        logs/nginx.pid;

events {

       use epoll;

       worker_connections  102400;

}

http {

       include mime.types;

       default_type  application/octet-stream;

       log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

       access_log  logs/access.log  main;

       server_tokens off;

       sendfile        on;

       tcp_nopush     on;

           #keepalive_timeout  0;

       keepalive_timeout  65;

           #Compression Settings

       gzip on;

       gzip_comp_level 6;

       gzip_http_version 1.1;

       gzip_proxied any;

       gzip_min_length 1k;

       gzip_buffers 16 8k;

       gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;

       gzip_vary on;

    #end gzip

    # http_proxy Settings

       client_max_body_size   10m;

       client_body_buffer_size   128k;

       proxy_connect_timeout   75;

       proxy_send_timeout   75;

       proxy_read_timeout   75;

       proxy_buffer_size   4k;

       proxy_buffers   4 32k;

       proxy_busy_buffers_size   64k;

       proxy_temp_file_write_size  64k;

    #load balance Settings

upstream backend_tomcat {

       server 192.168.101.72:8080 weight=1 max_fails=2 fail_timeout=10s;

       server 192.168.101.73:8080 weight=1 max_fails=2 fail_timeout=10s;

    }

    #virtual host Settings

       server {

              listen       80;

              server_name  www.benet.com;

              charset utf-8;

       location / {

              root html;

              index  index.jsp index.html index.htm;

        }

       location ~* \.(jsp|do)$ {

              proxy_pass  http://backend_tomcat;

              proxy_redirect off;

              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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

        }

       location /nginx_status {

              stub_status on;

              access_log off;

              allow 192.168.101.0/24;

              deny all;

        }

    }

}

16) service  nginx restart 如果第一失败就再执行一次,

17) Nginx代理服务器配置是4核8G主机

18) ss -tunlp  可以查看到80端口已经对外提供服务了

3安装、配置 tomcat

jdk版本:jdk1.8.0_131

tomcat版本: apache-tomcat-9.0.2

1)所需软件:(tomcat8.5和tomcat9 都可以,此处以tomcat9为例)

apache-tomcat-8.5.20.tar.gz 或 apache-tomcat-9.0.2.tar.gz

———————————————————————————-

jdk-8u131-linux-x64.tar.gz

———————————————————————————-

commons-pool2-2.4.2.jar

jedis-2.9.0.jar

tomcat85-session-redis-1.0.jar

———————————————————————————-

下载地址:

链接:https://pan.baidu.com/s/1c1P6Nzq 密码:13f5

参考配置:

context.xml

2)解压tomcat、jdk到指定的目录

# mkdir  /app

# tar -xvf apache-tomcat-9.0.2.tar.gz  -C  /app/

# tar -xvf jdk-8u131-linux-x64.tar.gz  -C  /app/

3)指定jdk或者修改jdk环境变量:

3.1)指定JDK版本以便tomcat与jdk联接

vim /app/apache-tomcat-9.0.2/bin/catalina.sh

添加如下内容:

export JAVA_HOME=/app/jdk1.8.0_131

export JRE_HOME=/app/jdk1.8.0_131/jre

位置如下图:

3.2修改java环境变量

(a)

在/etc/profile.d/目录下,创建一个.sh结尾的文件,

比如:

vim /etc/profile.d/jdk180.sh

添加如下内容:

export JAVA_HOME=/app/jdk1.8.0_131

export PATH=$JAVA_HOME/bin:$PATH

export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

(b)

执行该脚本文件,是JAVA环境变量生效

source /etc/profile.d/jdk180.sh

3.3)拷贝Tomcat需要的3个jar文件

将下边的三个文件拷贝至:${TOMCAT_HOME}/lib目录下

commons-pool2-2.4.2.jar、jedis-2.9.0.jar、tomcat85-session-redis-1.0.jar

$ cp ./*.jar /app/apache-tomcat-9.0.2/lib/

3.4)修改context.xml文件

$ vim /app/apache-tomcat-9.0.2/conf/context.xml

添加如下内容:参考下载文件中的context.xml文件

————————————————– 分割线 ————————————————–

<Valve className=”com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve” />

<Manager className=”com.orangefunction.tomcat.redissessions.RedisSessionManager”

host=”192.168.101.74″

port=”6379″

database=”0″

maxInactiveInterval=”60″ />

因在word文档编辑模式,此处的内容复制到context.xml文件后需要在英文输入法上把引号重新替换下

————————————————– 分割线 ————————————————–

3.5)创建测试文件:

cd /app/apache-tomcat-9.0.2/webapps/

mkdir test

vim test/index.jsp

以tomcat-1机器为例index.jsp内容如下:tomcat-2机器则直接替换相应的名称就可以了(把tomcat-1换成tomcat-2)

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>

<head>

<title>tomcat-1</title>

</head>

<body>

<h1><font color="red">Session serviced by tomcat-1</font></h1>

<table aligh="center" border="1">

<tr>

<td>Session ID</td>

<td><%=session.getId() %></td>

<% session.setAttribute("abc","abc");%>

</tr>

<tr>

<td>Created on</td>

<td><%= session.getCreationTime() %></td>

</tr>

</table>

</body>

<html>

3.6)启动tomcat

/app/apache-tomcat-9.0.2/bin/startup.sh

4、安装、配置 Redis(此处只是redis的简单安装配置)

4.1、下载、解压、编译:

yum  -y install wget  &&  wget http://download.redis.io/releases/redis-4.0.6.tar.gz

tar  -zxvf      redis-4.0.6.tar.gz -C /app/

cd /app/redis-4.0.6/

make  && make install

默认配置文件位于:

/app/redis-4.0.6/redis.conf

二进制文件是编译完成后在src目录下,通过下面的命令启动Redis服务:

#ll  src/redis-server

注意:这里直接执行Redis-server 启动的Redis服务,是在前台直接运行的(效果如上图),也就是说,执行完该命令后,如果Lunix关闭当前会话,则Redis服务也随即关闭。正常情况下,启动Redis服务需要从后台启动,并且指定启动配置文件。

4.2、修改配置文件,让redis以守护进程的形式后台运行

Avim redis.conf,将daemonize属性改为yes(表明需要在后台运行)

daemonize  yes

B、默认是只监听在本机的本地IP地址:127.0.0.16379端口,

注意:#####################################

redis4.0.6 如果注释掉默认的绑定地址 #bind 127.0.0.1

有时会导致客户端无法链接redis-server

###########################################

添加要监听的本地IP地址:

bind 127.0.0.1 192.168.101.74

可以根据需要,修改监听端口

4.3、启动、停止 redis

启动:

格式:redis-server 配置文件

src/redis-server  redis.conf

关闭指定redis

src/redis-cli -p 6379 shutdown

停止:

# src/redis-cli -p 端口 shutdown

src/redis-cli -p 6379 shutdown

或者

pkill redis-server

4.4启动Redis

格式:redis-server 配置文件

cd /app/redis-4.0.6/  &&  src/redis-server  redis.conf

 

五、访问测试页:

刷新页面,分别访问到不同的tomcat主机,但获取的session ID相同,

说明:用Redis,实现tomcat session共享 测试成功

http://192.168.101.71/test  不断刷新可以看到session ID号是相同


参考以下文档链接:

https://blog.51cto.com/yw666/1910451

http://www.enunix.com/