haproxy+nginx+tomcat+memcache实现动静分离、会话同步集群

一、实验说明

  1. haproxy在前端做负载均衡调度,后端实现动静分离
  2. 静态资源server为nginx
  3. 动态内容使用nginx&tomcat做app server,集成于单机,两台
  4. 使用两台memcache服务器做高可用session缓存,实现app server宕机时会话不中断

以上组合使用实现业务、session、session缓存均为高可用的集群。

二、实验准备

  1. haproxy server:192.168.0.168
  2. nginx server(静态):192.168.0.68
  3. nginx+tomcat-1:192.168.0.69
  4. nginx+tomcat-2:192.168.0.70
  5. memcache-1 192.168.0.71
  6. memcache-2:192.168.0.101

IP\hosts\clock zone配置统一

简要拓扑:

三、nginx静态:

1、解决依赖关系

编译安装nginx需要事先需要安装开发包组"Development Tools"和 "Development Libraries"。同时,还需要专门安装pcre-devel包:

# yum -y install pcre-devel

2、安装

首先添加用户nginx,实现以之运行nginx服务进程:

# groupadd -r nginx

# useradd -g nginx -s /sbin/nologin nginx

接着开始编译和安装:

# ./configure \

--prefix=/usr/local/nginx \

--sbin-path=/usr/local/nginx/sbin/nginx \

--conf-path=/etc/nginx/nginx.conf \

--error-log-path=/var/log/nginx/error.log \

--http-log-path=/var/log/nginx/access.log \

--pid-path=/var/run/nginx/nginx.pid  \

--lock-path=/var/lock/nginx.lock \

--user=nginx \

--group=nginx \

--with-http_ssl_module \

--with-http_flv_module \

--with-http_stub_status_module \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/tmp/nginx/client/ \

--http-proxy-temp-path=/var/tmp/nginx/proxy/ \

--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \

--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \

--http-scgi-temp-path=/var/tmp/nginx/scgi \

--with-pcre

# make && make install

3、为nginx提供SysV init脚本:

新建文件/etc/rc.d/init.d/nginx,内容如下:

#!/bin/sh

#

# nginx - this script starts and stops the nginx daemon

#

# chkconfig:   - 85 15

# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \

#               proxy and IMAP/POP3 proxy server

# processname: nginx

# config:      /etc/nginx/nginx.conf

# config:      /etc/sysconfig/nginx

# pidfile:     /var/run/nginx.pid

# Source function library.

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

# Source networking configuration.

. /etc/sysconfig/network

# Check that networking is up.

[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"

prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {

# make required directories

user=`nginx -V 2>&1 | grep "configure arguments:" | sed ‘s/[^*]*--user=\([^ ]*\).*/\1/g‘ -`

options=`$nginx -V 2>&1 | grep ‘configure arguments:‘`

for opt in $options; do

if [ `echo $opt | grep ‘.*-temp-path‘` ]; then

value=`echo $opt | cut -d "=" -f 2`

if [ ! -d "$value" ]; then

# echo "creating" $value

mkdir -p $value && chown -R $user $value

fi

fi

done

}

start() {

[ -x $nginx ] || exit 5

[ -f $NGINX_CONF_FILE ] || exit 6

make_dirs

echo -n $"Starting $prog: "

daemon $nginx -c $NGINX_CONF_FILE

retval=$?

echo

[ $retval -eq 0 ] && touch $lockfile

return $retval

}

stop() {

echo -n $"Stopping $prog: "

killproc $prog -QUIT

retval=$?

echo

[ $retval -eq 0 ] && rm -f $lockfile

return $retval

}

restart() {

configtest || return $?

stop

sleep 1

start

}

reload() {

configtest || return $?

echo -n $"Reloading $prog: "

killproc $nginx -HUP

RETVAL=$?

echo

}

force_reload() {

restart

}

configtest() {

$nginx -t -c $NGINX_CONF_FILE

}

rh_status() {

status $prog

}

rh_status_q() {

rh_status >/dev/null 2>&1

}

case "$1" in

start)

rh_status_q && exit 0

$1

;;

stop)

rh_status_q || exit 0

$1

;;

restart|configtest)

$1

;;

reload)

rh_status_q || exit 7

$1

;;

force-reload)

force_reload

;;

status)

rh_status

;;

condrestart|try-restart)

rh_status_q || exit 0

;;

*)

echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"

exit 2

esac

而后为此脚本赋予执行权限:

# chmod +x /etc/rc.d/init.d/nginx

添加至服务管理列表,并让其开机自动启动:

# chkconfig --add nginx

# chkconfig nginx on

4.配置文件基础配置及参数优化:

vim /etc/nginx/nginx.conf

做一下修改:

user nginx nginx;

error_log  /var/log/nginx/error.log info;

access_log /var/log/nginx/access.log info;

pid  /var/run/nginx/nginx.pid;

worker_rlimit_nofile  20480;

events {

use epoll;

worker_connections  10240;

}

http {

include       mime.types;

default_type  application/octet-stream;

sendfile        on;

server {

listen 80;

servername www.a.com;

root /www/nginx/a.com/;

index index.html;

allow 192.168.0.0/16;

deny all;

}

}

*注释:

worker_rlimit_nofile  20480;单个worker最大可以打开的句柄数,至少要>=worker—connection的数目,  当nginx做反向代理时,要>=worker——connection的数目的两倍

保存退出而后,创建相应目录文件就可以启动服务并测试了:

# service nginx start

echo "<h1>test.a.com_192.168.0.68</h1>" > /www/nginx/a.com/index.html

浏览器测试打开http://192.168.0.68正常访问

四、haproxy配置

yum -y install haproxy

vim /etc/haproxy/haproxy.cfg

frontend  main *:80

acl url_static       path_beg       -i /static /images /javascript /stylesheets

acl url_static       path_end       -i .jpg .gif .png .css .js .html .htm

acl url_jsp          path_end       -i .jsp .do

use_backend static          if url_static

use_backend app             if url_jsp

default_backend             static

#---------------------------------------------------------------------

# static backend for serving up images, stylesheets and such

#---------------------------------------------------------------------

backend static

balance     roundrobin

server      static 192.168.0.68:80 check

#---------------------------------------------------------------------

# round robin balancing between the various backends

#---------------------------------------------------------------------

backend app

balance     roundrobin

server  app1 192.168.0.69:80 check

server  app2 192.168.0.70:80 check

保存退出

service haproxy start

测试:http://192.168.0.168,打开静态nginx页面成功:

五、tomcat部署安装

1.官方版JDK下载:

http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

tomcat是基于java语音开发的程序,需要运行在jvm中。java是跨平台语言,java的运行基于各种类库,java早先用于B/S架构上的是applet,在客户端运行,后期发展为servlet,在server端运行,但是servlet是硬编码进html中的,因此程序员在开发servlet程序时,又必须将其与html语言结合开发,在php类的嵌入式编程语言出现了之后,servlet也研发了一种全新的嵌入式语言jsp,而tomcat即是jsp的一个web容器,与之类似的开源方案还有Jboss等。

这里使用官方的jdk套件:

rpm -ivh jdk-8u131-linux-x64.rpm

cat > /etc/profile.d/java.sh << EOF

export JAVA_HOME=/usr/java/default

export PATH=$JAVA_HOME/bin:$PATH

EOF

. /etc/profile.d/java.sh

测试:# java -version

java version "1.8.0_131"

Java(TM) SE Runtime Environment (build 1.8.0_131-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

java部署成功

2.tomcat部署

unzip apache-tomcat-7.0.78.zip -d /usr/local/

cd /usr/local

ln -sv apache-tomcat-7.0.78/  tomcat   #软链接,方便以后升级

cat > /etc/profile.d/tomcat.sh << EOF

> export CATALINA_HOME=/usr/local/tomcat

> export PATH=$CATALINA_HOME/bin:$PATH

> EOF

. /etc/profile.d/tomcat.sh

cd /usr/local/tomcat/bin/

chmod +x *

#catalina.sh -version  #测试

Using CATALINA_BASE:   /usr/local/tomcat

Using CATALINA_HOME:   /usr/local/tomcat

Using CATALINA_TMPDIR: /usr/local/tomcat/temp

Using JRE_HOME:        /usr/java/default

Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

Server version: Apache Tomcat/7.0.78

Server built:   May 10 2017 15:02:19 UTC

Server number:  7.0.78.0

OS Name:        Linux

OS Version:     2.6.32-642.el6.x86_64

Architecture:   amd64

JVM Version:    1.8.0_131-b11

JVM Vendor:     Oracle Corporation

tomcat部署成功

浏览器测试:http://192.168.0.69:8080,tomcat测试页显示成功

3.安装nginx

tomcat的http并发能力比较弱,因此在生产环境中,一般在在单机中集成tomcat和一个httpd服务,常见的是nginx

nginx编译安装过程同上,只是配置文件需修改,nginx将所有请求反代至tomcat,需添加一个location:

location / {

proxy_pass http://127.0.0.1:8080;

index  index.jsp index.htm;

}

http://192.168.0.69,Tomcat测试页显示成功,代理部署完成

这里再简单描述一下tomcat上web应用部署的方法:

  1. 最简单的方法,将程序员写好的app放入tomcat_home下的webapps目录中
  2. 修改tomcat_home/conf/server.xml配置文件,在host容器中添加<context>组件
  3. 在tomcat_home/conf/Catalina/localhost目录下创建.xml结尾的单独配置文件,配置文件中添加<context>组件,此方法无需重启tomcat服务,推荐使用

部署演示:

添加test.xml配置文件

cd /usr/local/tomcat/conf/Catalina/localhost

vim test.xml

<Context  path ="/test"  docBase ="/usr/local/tomcat/webapps/test"

debug ="0"  privileged ="true"  reloadable ="ture"  >

</Context>

注释:

path:是访问时的根地址,表示访问的路径;如上述例子中,访问该应用程序地址如下:http://192.168.0.69/test

reloadable:表示可以在运行时在classes与lib文件夹下自动加载类包。其中reloadable="false"表示当应用程序 中的内容发生更改之后服务器不会自动加载,这个属性在开发阶段通常都设为true,方便开发,在发布阶段应该设置为false,提高应用程序的访问速度。

docbase:表示应用程序的路径, 可以使用绝对路径,也可以使用相对路径,相对路径相对于webapps。

创建访问路径、类库、及一个简单的jsp文件:

mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{class,lib}

vim /usr/local/tomcat/webapps/test/index.jsp

<%@ page language="java" %>

<html>

<head><title>TomcatA</title></head>

<body>

<h1><font color="red">Tomcatapp.test.com</font></h1>

<table align="centre" border="1">

<tr>

<td>Session ID</td>

<% session.setAttribute("tomcatapp","by_ywq"); %>

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

</tr>

<tr>

<td>Created on</td>

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

</tr>

</table>

</body>

</html>

浏览器测试:http://192.168.0.69/test部署成功

另一台tomcat节点部署过程一致,过程不再赘述,测试页面标题做修改以示区别:

两台tomcat部署完毕后,从前端访问haproxy地址测试代理是否生效:http://192.168.0.168/index.jsp

页面显示异常,捕获响应报文如下:

status code为404,动静分离导致haproxy将css样式表、图片文件路由至静态主机获取,但静态主机没有相应的页面资源

scp /usr/local/tomcat/webapps/ROOT  192.168.0.68:/www/nginx/a.com/

chown -R nginx:nginx /www/nginx/a.com/ROOT

再次刷新页面,解决:

测试haproxy roundrobin效果:

http://192.168.0.168/test/index.jsp,反复刷新,页面在tomcat1和tomcat2之间切换

负载均衡成功,但是可以发现session ID一直是在变化的,为了实现app server之一宕机,其上的连接再转移至其他app server后仍然保持会话不中断,需要引入session共享机制。

默认情况下,tomcat将session保存在本地,tomcat自带有DeltaManager会话管理器,可以实现在一个集群中的tomcat主机,按指定的频率,使用组播地址,与各节点相互分享session数据,这种方式实现起来比较简单,但是对资源的消耗较大,当cluster内的成员数量在3 4台以上时,一般使用另一种方案,即所有成员将session保存在同一台缓存服务器中,缓存服务器可以是memcache、redis等,这里用的是memcache session manager,这个项目最早是在谷歌的开源网站上出现的,现在项目地址已经转移到了GitHub上。

参考地址:https://code.google.com/archive/p/memcached-session-manager/

https://github.com/magro/memcached-session-manager

六、memcache安装部署

1.安装libevent

memcached依赖于libevent API,因此要事先安装之,项目主页:http://libevent.org/,读者可自行选择需要的版本下载。本文采用的是目前最新版本的源码包libevent-2.0.21-stable.tar.gz。安装过程:

# tar xf libevent-2.0.21-stable.tar.gz

# cd libevent-2.0.21-stable

# ./configure --prefix=/usr/local/libevent

# make && make install

将库文件导入系统库中

# echo "/usr/local/libevent/lib" > /etc/ld.so.conf.d/libevent.conf

# ldconfig

2.安装配置memcached

1、安装memcached

# tar xf memcached-1.4.18.tar.gz

# cd memcached-1.4.18

# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

# make && make install

安装完成后启用memcache:

/usr/local/memcached/bin/memcached -d 11211 -u nobody -c 1024 -m 128

3、memcached SysV的startup脚本代码如下所示,将其建立为/etc/init.d/memcached文件:

#!/bin/bash

#

# Init file for memcached

#

# chkconfig: - 86 14

# description: Distributed memory caching daemon

#

# processname: memcached

# config: /etc/sysconfig/memcached

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

## Default variables

PORT="11211"

USER="nobody"

MAXCONN="1024"

CACHESIZE="64"

OPTIONS=""

RETVAL=0

prog="/usr/local/memcached/bin/memcached"

desc="Distributed memory caching"

lockfile="/var/lock/subsys/memcached"

start() {

echo -n $"Starting $desc (memcached): "

daemon $prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE -o "$OPTIONS"

RETVAL=$?

[ $RETVAL -eq 0 ] && success && touch $lockfile || failure

echo

return $RETVAL

}

stop() {

echo -n $"Shutting down $desc (memcached): "

killproc $prog

RETVAL=$?

[ $RETVAL -eq 0 ] && success && rm -f $lockfile || failure

echo

return $RETVAL

}

restart() {

stop

start

}

reload() {

echo -n $"Reloading $desc ($prog): "

killproc $prog -HUP

RETVAL=$?

[ $RETVAL -eq 0 ] && success || failure

echo

return $RETVAL

}

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

restart

;;

condrestart)

[ -e $lockfile ] && restart

RETVAL=$?

;;

reload)

reload

;;

status)

status $prog

RETVAL=$?

;;

*)

echo $"Usage: $0 {start|stop|restart|condrestart|status}"

RETVAL=1

esac

exit $RETVAL

使用如下命令配置memcached成为系统服务:

# chmod +x /etc/init.d/memcached

# chkconfig --add memcached

# service memcached start

4、使用telnet命令测试memcached的使用

# telnet 127.0.0.1 11211

七、msm部署

原理参考步骤五底部的链接

这里使用javolution的序列化工具,准备以下java类库:

编辑$CATALINA_HOME/conf/context.xml,添加以下内容:

<Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"

memcachedNodes="n1:192.168.0.71:11211,n2:192.168.0.101:11211"

failoverNodes="n1"

requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"

transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"

/>

</Context>

另一台tomcat上配置相同,修改failoverNodes="n2"

再次在前端访问haproxy代理地址:http://192.168.0.168/test,重复刷新页面,可以发现页面在tomcat-A和Tomcat-B之间轮换,但session ID与session创建时间不会改变:

至此,实验成功。

总结:

实验过程前段进行顺利,最后的msm部署非常头疼,花了两个晚上才搞定,碰到的有缺少jar类库、context字段不生效导致页面404、两台tomcat相同配置文件和环境却一台正常一台跑不起来等奇葩问题,以上问题全部搞定后还是发现session不能同步。无奈了,甚至怀疑到是不是haproxy代理的问题,马上开干停用haproxy编译安装nginx做代理,问题依旧。。。。。今天回来试着把jdk从1.8回滚到1.7后,问题居然解决了。事实证明,谷歌是个好东西,要去翻墙,推荐一个我用了一年活好免费的VPN:green

欢迎讨论纠错,

Over!

时间: 2024-10-01 22:23:58

haproxy+nginx+tomcat+memcache实现动静分离、会话同步集群的相关文章

【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Webserver集群

额.博客名字有点长.. . 前言 最终到这篇文章了,心情是有点激动的. 由于这篇文章会集中曾经博客讲到的全部Nginx功能点.包含主要的负载均衡,还有动静分离技术再加上这篇文章的重点.通过Keepalived实现的HA(High Available).为什么要实现高可用呢?曾经在搭建的时候仅仅用了一台Nginxserver,这种话假设Nginxserver宕机了,那么整个站点就会挂掉.所以要实现Nginx的高可用,一台挂掉还会有还有一台顶上去.从而保证站点能够持续的提供服务. 关于负载均衡和动静

nginx+tomcat负载均衡+动静分离

1.服务器A安装ng,服务器B.C安装tomcat: 2.服务器A建立/data/www目录,用于发布静态文件: 3.ng无动静分离配置: user root root; worker_processes 8; pid /usr/local/nginx/nginx.pid; worker_rlimit_nofile 102400; events { use epoll; worker_connections 102400; } http { include mime.types; default

nginx实现动静分离负载均衡集群

LB 负载均衡集群分两类: LVS (四层)和 nginx 或 haproxy (七层) 客户端通过访问分发器的 VIP 来访问网站 | 现在应用更复杂,比如现在网站页面有: .php .html .png .jpeg .jsp 等, 有劢态页面有静 态页面.静态页面一般是丌变的,想访问更快些,前面学习过 SQUID. | 但是前面的 LVS 是四层的.基于 IP 的.现在需要在应用层基于丌同的应用迚行分发. | 七层 LB , Nginx / Haproxy 都可以支持 7 层 LB 现在实现

Nginx+Keepalived+Tomcat之动静分离的web集群

#vi /etc/nginx/nginx.conf############################################user nginx nginx;worker_processes 4;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on;up

(总结)Nginx与Apache、Tomcat、Resin动静分离核心配置

PS:近来有几个刚使用nginx的新童鞋老问我,nginx+fastcgi不够稳定,偶尔出现502错误,怎么解决?本人使用nginx也有3年多了,也认为php-fpm模块不够稳定,在访问量不大的时候没事,访问量增大时易出现502,当然这个还跟nginx的一些缓存设置和超时设置有关,设置不合理就易出现.php-fpm动态生成大型页面也没有优势,有时候会使php-cgi进程变成僵尸进程.据说php 5.4版本已自带php-fpm模块,稳定性是否有改进?太新还没用过,不评论.其实本人比较喜欢nginx

haproxy 基础详解 及 动静分离的实现

haproxy 介绍 1 工作在ISO 七层 根据http协议(或者工作在ISO四层 根据tcp协议) 提供web服务的负载均衡调度器 负载均衡调度器分类 工作在四层: # lvs 工作在七层: # nginx (web,http reverse proxy,cache) # haproxy (http reverse proxy,tcp proxy) # tcp: 实现MySQL的读写中读的负载均衡 # ats (apache traffic server) # perlbal # pound

Nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第三部分

Nginx反向代理.动静分离.负载均衡及rewrite隐藏路径详解 (Nginx Apache MySQL Redis) 楓城浪子原创,转载请标明出处! 更多技术博文请见个人博客:https://fengchenglangzi.000webhostapp.com 微信bh19890922 QQ445718526.490425557 三.Nginx动静分离及负载均衡 3.1 Nginx安装 请参考:https://fengchenglangzi.000webhostapp.com/?p=511 亦

CentOS 6.5 HAProxy+apache实现web服务动静分离

HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理.HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接.并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露

HAProxy+apache实现web服务动静分离

HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理.HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接.并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露