本文讲解我们如何使用Nginx做反向带服务器,实现nginx与tomcat服务器集群做负载均衡。

一、nginx与tomcat实现负载均衡

1、在/usr/local/ngnix/conf  创建文件 nginx-tomcat.conf

文件内容:

user  nobody;
worker_processes 2;
events {
worker_connections 1024;
}
http{
# upstream 配置一组后端服务器,
# 请求转发到upstream后,nginx按策略将请求指派出某一服务器
# 即配置用于负载均衡的服务器群信息
upstream tomcats{
fair;
server 121.42.41.143:8080;
server 219.133.55.36;
}
server {
listen 80;
server_name 121.42.41.143;
access_log logs/tomcat-nginx.access.log combined;
# 反向代理设置,将所有/路径下请求发给本机上的tomcat
location / {
#root html;
index index.html index.htm;
#==========Nginx提供的代理============
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://tomcats;
}
}
}

2、使用该配置文件启动nginx (启动前先关闭nginx)

[root@iZ28b4kreuaZ bin]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx-tomcat.conf

二、配置文件详解:

worker_processes  2;

events {
worker_connections 1024;
} http {
include mime.types;
default_type application/octet-stream; # upstream 配置一组后端服务器,
# 请求转发到upstream后,nginx按策略将请求指派出某一服务器
# 即配置用于负载均衡的服务器群信息
upstream backends {
#=========均衡策略=============
#none 轮询(权重由weight决定)
#ip_hash 通过hash算法将用户的请求与第一次请求的服务器进行绑定,后续该用户所有的请求都将被分配到该服务器上。除非该服务器挂掉。
#============== 第三方 均衡策略===========
#fair 根据各个服务器的性能的不同,自动选择使用响应能力强的服务器。
#url_hash 根据url选择服务器。 #===============服务器集==============
server 192.168.1.62:8080;
server 192.168.1.63; #==========weight权重策略:权重值越高负载越大==========
# server 192.168.1.64 weight=5; #===============backup:备份机,只有非备份机都挂掉了才启用===============
server 192.168.1.64 backup; #==============down: 停机标志,不会被访问(对临时维护的服务器设置)=============
server 192.168.1.65 down; # max_fails:达到指定次数认为服务器挂掉;
# fail_timeout:挂掉之后过多久再去测试是否已恢复
server 192.168.1.66 max_fails=2 fail_timeout=60s;
} 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_test/路径下请求发给本机上的tomcat
location /proxy_test/ {
proxy_pass http://localhost:8080;
} # 负载均衡设置,将所有jsp请求发送到upstream backends指定的服务器群上
location ~ \.jsp$ {
proxy_pass http://backends; # 真实的客户端IP
proxy_set_header X-Real-IP $remote_addr;
# 请求头中Host信息
proxy_set_header Host $host;
# 代理路由信息,此处取IP有安全隐患
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 真实的用户访问协议
proxy_set_header X-Forwarded-Proto $scheme;
# 默认值default,
# 后端response 302时 tomcat header中location的host是http://192.168.1.62:8080
# 因为tomcat收到的请求是nginx发过去的, nginx发起的请求url host是http://192.168.1.62:8080
# 设置为default后,nginx自动把响应头中location host部分替换成当前用户请求的host部分
# 网上很多教程将此值设置成 off,禁用了替换,
# 这样用户浏览器收到302后跳到http://192.168.1.62:8080,直接将后端服务器暴露给浏览器
# 所以除非特殊需要,不要设置这种画蛇添足的配置
proxy_redirect default;
} # 一个url重写的例子,浏览器请求 /page.go时,url被重写成/test/page.jsp
location ~ \.go$ {
rewrite ^(.*)\.go$ /test/$1\.jsp last;
} #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;
} }
}

三、fair策略的安装

fair策略:根据各个服务器的性能的不同,自动选择使用响应能力强的服务器。该策略是第三方提供的,所以要先安装。

安装步骤

1、下载 gnosek-nginx-upstream-fair-a18b409.tar.gz

2、解压  tar zxvf gnosek-nginx-upstream-fair-a18b409.tar.gz

3、将解压后的文件移动到 /usr/local目录下并 改名为 nginx-upstream-fair

4、将该模块添加到我们安装的nginx中

a、首先进入nginx-1.8.1源文件目录下在执行:

[root@iZ28b4kreuaZ nginx-1.8.1]# ./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx-upstream-fair/

b、执行:make    进行编译

c、进入 nginx-1.8.1/objs/下将最新的nginx启动项 覆盖原来的 /usr/local/nginx/sbin/nginx启动项。

[root@iZ28b4kreuaZ objs]# cp nginx /usr/local/nginx/sbin

d、开启Nginx 看看是可以使用

 四、在分布式服务器集群中session共享问题

问题:当我们的用户在tomcat1服务器上登录后,tomcat1会保存用户的登录信息,但当用户的请求被代理服务器分配给tomcat2/tomcat3服务器时,这时就会出现tomcat2/tomcat3无法获取用户登录信息,从而导致用户需要重新登录的现象。我们有三种解决方案:

1、同一个用户的请求锁定在同一台服务器上,这样就不会存在session在不同服务器之间共享问题。这种方案简单,但缺乏容错性(一旦服务器故障,那用户的请求将被分配给其他服务器,这时就需要重新登录)

实现方式:设置集群策略为 ip_hash ;

 upstream tomcats{
ip_hash;
}

2、session复制方式: 当任何服务器中session值发生改变,他都会将该改变广播给其他服务器,当其他服务器收到广播后也做相应的改变,从而实现session在所有服务器中一直。缺点 当集群中tomcat服务器很多时会增加网络负荷,性能低下。实现方式:

a、在tomcat的server.xml中配置session广播

      <!-- 基于网络广播的策略,一个节点session变化,其它节点同步复制,节点多或数据量大时性能低下 -->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.6.223"
port="8080"/>
</Channel>
</Cluster>

b、在我们的分布式应用的web.xml 中添加 <distributable/>标签

<distributable/>:作用是公告我们的应用可以处于集群环境中。

3、通过创建额外的共享空间用来管理session,一般我们使用分布式缓存技术redis、memcached缓存技术,在这里我么使用memcached。

  a、memcached的安装:http://www.cnblogs.com/jalja/p/6121978.html

  b、memcached 的 session共享原理

  粘性共享:

  非粘性:

c、tomcat访问memcached的相关环境(我们使用的是tomcat7)

  1. 复制jar包到tomcat/lib目录,jar分三类

    1)spymemcached.jar memcached java客户端

    2)memcached相关的包  memcached-session-manager-{version}.jar       核心包         memcached-session-manager-tc{tomcat-version}-{version}.jar   Tomcat版本相关的包

    3)序列化工具包,有多种可选方案,不设置时使用jdk自带序列化,其它可选kryo,javolution,xstream,flexjson等   msm-{tools}-serializer-{version}.jar  其它序列化工具相关包  一般第三方序列化工具不需要实现serializable接口

d、配置Context,加入处理session的Manager  MemcachedBackupSessionManager
 Context配置查找顺序:
        1)conf/context.xml 全局配置,作用于所有应用
        2) conf/[enginename]/[hostname]/context.xml.default 全局配置,作用于指定host下全部应用
        3) conf/[enginename]/[hostname]/[contextpath].xml 只作用于contextpath指定的应用
        4) 应用META-INF/context.xml 只作用于本应用
        5) conf/server.xml <Host>下 作用于Context docBase指定的应用
         如果只希望session管理作用于特定应用,最好用3,4方式设置,希望作用全体,可用1,2,5设置

conf/context.xml的配置:

 <?xml version="1.0" encoding="UTF-8"?>

 <Context>

     <WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource> <!-- sticky session 最小配置-->
<!-- className 管理器类名 -->
<!-- memcachedNodes memcached服务器节点,以节点名:主机:端口形式表示,其中节点名随意命名,但不同tomcat间要一致 -->
<!-- sticky隐含默认值为true,此时为sticky session模式 -->
<!-- failoverNodes 仅适用于sticky模式, n1表示主要将session备份到n2,如果n2不可用,再用n1-->
<!-- 另一台服务器配置正好相反,这样保证将session保存到其它机器,避免整个机器崩溃时tomcat与session一起崩溃-->
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
failoverNodes="n1"
/> <!-- 经常用到的生产环境sticky(粘性)模式配置 -->
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(jpg|png|css|js)$"
memcachedProtocol="binary"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/> <!-- 经常用到的生产环境non-sticky(非粘性模式)模式配置 -->
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
sticky="false"
sessionBackupAsync="false"
lockingMode="auto"
requestUriIgnorePattern=".*\.(jpg|png|css|js)$"
memcachedProtocol="binary"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/> <!--
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211" #sticky模式,默认true
sticky="false" #仅适用于sticky模式,n1表示主要将session备份到n2,如果n2不可用,再用n1
failoverNodes="n1" #忽略的请求类型,这些类型请求不处理session
requestUriIgnorePattern=".*\.(jpg|png|css|js)$" #例如context中设置sessionPath=/时,一个host下多个应用可能有相同session_id,
#此时向memcached写入时会造成混乱,可通过以下方式加前缀区分不同应用
storageKeyPrefix="static:name|context|host|webappVersion|context.hash|host.hash|多项组合,以,间隔" #设置mecached协议数据传输方式,默认text,设为binary有助力性能提升
memcachedProtocol="binary" #是否异步存储session变化,默认true,性能好,适用于sticky模式,
#non-sticky时建议设置为false,避免延迟造成信息不一致
sessionBackupAsync="false" #仅适用于non-sticky模式,为避免同步编辑冲突,在修改session时锁定
#同步编辑一种可能发生的情况是在ajax请求时,同一页多个请求同时发起,可能会访问不同后端
#auto 读模式不锁写模式锁
#uriPattern模式,将URI+"?"+queryString与模式Regex匹配,如果匹配则锁定
lockingMode="none|all|auto|uriPattern:Regex" #使用第三方序列化工具,提高序列化性能
#常用的第三方工具kryo, javolution, xstream等
#此时需要向tomcat/lib下添加相关jar包
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
--> </Context>

四、集群环境开发注意事项

1、实体类要序列化( implements Serializable)

private static final long serialVersionUID = 3349238980725146825L;

2、获取客户端请求地址的方式 。在nginx-tomcat.conf中添加如下配置:

   server {
location / {
proxy_set_header X-Real-IP $remote_addr; # 真实的客户端IP
}
}

java代码:

public static String  getIp(HttpServletRequest request){
String remoteIp =request.getRemoteAddr();
String headIp=request.getHeader("X-Real-IP");
return headIp==null?remoteIp:headIp;
}

3、动静分离
  把静态文件放在nginx服务器中(css、js、图片)

Nginx 服务器 之Nginx与tomcat实现负载均衡的更多相关文章

  1. Nginx服务器的使用与反向代理负载均衡

    目录 Nginx服务器 一:什么是Nginx? 什么是Nginx - Nginx与其他服努器的性能比较 二:如何在Linux中搭建Nginx服务器? 常见的错误 三:Nginx的反向代理和负载均衡 什 ...

  2. Nginx安装使用及与tomcat实现负载均衡

    1. 背景 基于nginx强大的功能,实现一种负载均衡,或是不停机更新程序等.nginx相比大家基本上都知道是什么来头了,具体的文章大家可以去搜索相关文章学习阅读,或是可以查看Nginx中文文档和Ng ...

  3. Nginx+Tomcat+Memcached负载均衡集群服务搭建

    操作系统:CentOS6.5  本文档主要讲解,如何在CentOS6.5下搭建Nginx+Tomcat+Memcached负载均衡集群服务器,Nginx负责负载均衡,Tomcat负责实际服务,Memc ...

  4. nginx+tomcat+redis负载均衡及session共享

    概述 本文档是用来详细描述 nginx+tomcat+redis负载均衡实现session共享 所需软件及下载地址 软件名称 下载地址 功能说明 Nginx-v1.6.0 http://nginx.o ...

  5. Tomcat(五):nginx/httpd + tomcat及负载均衡tomcat

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  6. 使用 Nginx + Tomcat 搭建负载均衡

    负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称为Load Balance, ...

  7. nginx+tomcat实现负载均衡集群

    一台tomcat站点由于可能出现单点故障及无法应付过多客户复杂多样的请求等问题,不能单独应用于生产环境下 所以需要一套可靠的解决方案来完善web站点架构 而Nginx只能访问静态页面,如果需要动态需要 ...

  8. Docker + Nginx + Tomcat 实现负载均衡简单演示

    Docker + Nginx + Tomcat 实现负载均衡 环境 [root@pinyoyougou-docker ~]# docker -v Docker version 1.12.6, buil ...

  9. nginx+tomcat实现负载均衡以及双机热备

    还记得那些年吗? 还记得更新代码之后,服务器起不来被领导训斥吗?还记得更新代码,需要停机过多的时间被渠道部们埋怨吗?还记得更新代码,代码出错时自己吓个半死吗?于是我们聪明勤快的程序员,看着电影待到夜深 ...

随机推荐

  1. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  2. CodeSimth - .Net Framework Data Provider 可能没有安装。解决方法

    今天想使用CodeSimth生成一个sqlite数据库的模板.当添加添加数据库的时候发现: .Net Framework Data Provider 可能没有安装. 下面找到官方的文档说明: SQLi ...

  3. iOS逆向工程之KeyChain与Snoop-it

    今天博客的主题是Keychain, 在本篇博客中会通过一个登陆的Demo将用户名密码存入到KeyChain中,并且查看一下KeyChain中存的是什么东西,把这些内容给导出来.当然本篇博客的重点不是如 ...

  4. Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)

    Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...

  5. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  6. 深入浅出Redis-redis哨兵集群

    1.Sentinel 哨兵 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所 ...

  7. npm 使用小结

    本文内容基于 npm 4.0.5 概述 npm (node package manager),即 node 包管理器.这里的 node 包就是指各种 javascript 库. npm 是随同 Nod ...

  8. 基于Composer Player 模型加载和相关属性设置

    主要是基于达索软件Composer Player.的基础上做些二次开发. public class ComposerToolBarSetting { public bool AntiAliasingO ...

  9. AEAI DP V3.6.0 升级说明,开源综合应用开发平台

    AEAI DP综合应用开发平台是一款扩展开发工具,专门用于开发MIS类的Java Web应用,本次发版的AEAI DP_v3.6.0版本为AEAI DP _v3.5.0版本的升级版本,该产品现已开源并 ...

  10. 使用Nginx反向代理 让IIS和Tomcat等多个站点一起飞

    使用Nginx 让IIS和Tomcat等多个站点一起飞 前言: 养成一个好习惯,解决一个什么问题之后就记下来,毕竟“好记性不如烂笔头”. 这样也能帮助更多的人 不是吗? 最近闲着没事儿瞎搞,自己在写一 ...