注意这几点,轻轻松松配置 Nginx + Tomcat 的集群和负载均衡
Tomcat 集群是当单台服务器达到性能瓶颈,通过横向扩展的方式提高整体系统性能的有效手段。Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,可以通过简单的配置实现 Tomcat 集群的负载均衡。
本文使用的 Tomcat 是 8.5.35 版本,Nginx 是 1.14.2 版本。接下来看下配置的过程以及可能会遇到的问题,首发于微信公众号「顿悟源码」。
1. 概述
对于 Web 应用来说,集群最大的问题就是 Session 信息的共享,一般有以下解决方法:
- 使用粘性会话,比如,使用 IP Hash 的负载均衡策略,将当前用户的请求都集中到一台服务器上;缺点是单点故障,会话丢失
- 使用 Session 复制,使用 Tomcat 自带的 Session 复制策略,将会话信息同步到集群的各个节点;缺点是消耗更多内存和带宽,适用于小型集群
- 使用第三方缓存中间件缓存整个集群会话信息,比如 Redis 缓存,可由应用程序控制与 Session 的关联,也可以适配 Tomcat
- 当然了,也可以把会话信息存到共享文件系统或者数据库
在配置 Nginx 的过程中,可能会遇到以下问题:
- 配置 upstream 名称时不能使用下划线,比如 tomcat_ha,否则 Tomcat 会抛出 The character [_] is never valid in a domain name 的异常
- 在 windows 上杀掉所有的 nginx.exe 进程,
taskkill /fi "imagename eq nginx.exe" /f
- 在 windows 上有个 pid 为 4 的系统进程会占用 80 端口,所以这里将 nginx 改为了 8000
在配置 Tomcat 集群的过程中,需要注意的问题:
- 确保 web.xml 配置了 <distributable/> 元素
- 确保 Context 的 Manager 别被替换成了标准会话管理器
- Receiver.address 不要配置成 auto,因为默认可能会绑定 127.0.0.1;Receiver.port 可改也可不改,Tomcat 会自行检测 4000-4100 范围内的可用端口,自动处理冲突
- 如果在不同服务器上,需要关闭防火墙或开端口,还有时间同步
2. Nginx 核心配置
Nginx 使用的是默认配置,添加和修改的核心配置如下:
http {
...
#gzip on;
#设置负载均衡的服务器列表和权重
upstream tomcat-ha {
#ip_hash;
server 172.31.1.41:8080 weight=1;
server 172.31.1.42:8080 weight=1;
}
server {
listen 8000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
#转发请求
proxy_pass http://tomcat-ha;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
...
}
}
3. Tomcat 集群配置
启用集群配置,在 <Engine> 元素中添加以下配置:
<!-- channelSendOptions=6 同步复制 -->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6">
<!-- 集群 Session 管理器 -->
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
-->
<!-- 集群内部通信配置 -->
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.10.2"
port="5000"
selectorTimeout="100"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<!-- 此 vavle 拦截请求,并将 Session 信息发给内部节点 -->
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
简单描述下工作原理:
- nginx 将请求转发给 Tomcat1,请求登录认证,创建会话,生成 Cookie,在响应返回之前,将 Session 信息复制到 Tomcat2
- 再次请求时,nginx 将带着会话 Cookie 的请求转发给了 Tomcat2,Tomcat2 发现内部 Session 池中有关联的已认证成功的 Session 对象,不再认证返回请求资源
4. 验证负载均衡和 Session 复制
4.1 测试环境
- 使用两台 PC 部署 Tomcat,对应关系是:172.31.1.41-Tomcat1,172.31.1.42-Tomcat2
- 部署基于使用 Tomcat 自带的 SessionExample 程序,编写了一个 tomcat-benchmark 的 web 应用
- 结合 Tomcat 自带的 Manager 应用,查看已部署应用内部 Session 池
4.2 负载均衡
修改 tomcat-benchmark 部署描述符文件中的 context-param 为 "I'm Tomcat 1/2" 用于区分两个 Tomcat,启动 Nginx 和 Tomcat,在浏览器访问 172.31.1.42:8080 可以看到请求在两个服务器间切换:
4.3 Session 复制
为了方便理解,这里先把 Nginx 的负载均衡策略设置成 ip_hash:
- 假设 Nginx 始终将请求定位到 Tomcat1 上,然后在 Tomcat1 上创建会话,往会话中添加一些属性
- 关闭 Tomcat1 模拟故障,此时 Nginx 会带着之前的会话 Cookie 将请求转发到 Tomcat2,上
- 查看 Tomcat2 上是否存在与 Cookie(JSESSIONID) 关联的 Session 信息,若有表示复制成功
整个过程如下:
动图正好与上述描述的相反,可以看到 Session 信息从 Tomcat2 复制到了 Tomcat1 中。
5. 小结
搜索微信号「顿悟源码」,回复「Tomcat」后,可获取本文测试使用的工程以及 Nginx 和 Tomcat 的配置文件。
注意这几点,轻轻松松配置 Nginx + Tomcat 的集群和负载均衡的更多相关文章
- 在Linux上使用Nginx为Solr集群做负载均衡
在Linux上使用Nginx为Solr集群做负载均衡 在Linux上搭建solr集群时需要用到负载均衡,但测试环境下没有F5 Big-IP负载均衡交换机可以用,于是先后试了weblogic的proxy ...
- 结合Apache和Tomcat实现集群和负载均衡 JK 方式 2 (转)
本文Apache+Tomcat集群配置 基于最新的Apache和Tomcat,具体是2011年4月20日最新的Tomcat和Apache集群和负载均衡配置. 准备环境 Apache Apa ...
- 结合Apache和Tomcat实现集群和负载均衡 JK 方式
本文基本参考自 轻松实现Apache,Tomcat集群和负载均衡,经由实操经历记录而成,碰到些出入,以及个别地方依据个人的习惯,所以在一定程度上未能保持原文的完整性,还望原著者海涵. 因原文中有较多的 ...
- 结合Apache和Tomcat实现集群和负载均衡
http://fableking.iteye.com/blog/360870 TomcatApacheJSP应用服务器Web 本文基本参考自 轻松实现Apache,Tomcat集群和负载均衡,经由实 ...
- 用apache和tomcat搭建集群,实现负载均衡
型的企业应用每天都需要承受巨大的访问量,在着巨大访问量的背后有数台服务器支撑着,如果一台服务器崩溃了,那么其他服务器可以使企业应用继续运行,用户对服务器的运作是透明化的,如何实现这种透明化呢?由如下问 ...
- Tomcat服务器集群与负载均衡实现
一.前言 在单一的服务器上执行WEB应用程序有一些重大的问题,当网站成功建成并开始接受大量请求时,单一服务器终究无法满足需要处理的负荷量,所以就有点显得有 点力不从心了.另外一个常见的问题是会产生单点 ...
- nginx与tomcat搭建集群,负载均衡
--------------------------------------------------- 搭建环境(在桌面上即可完成测试) 先准备2个tomcat服务器 解压tomcat压缩包 得到 把 ...
- 用Nginx搭建IIS集群实现负载均衡
长话短说,我们用Nginx来搭建一个简单的集群,实现Web应用的负载均衡,架构图如下: 两台Web服务器,一台静态资源服务器,因为是演示,我们以网站形式部署在本机IIS中 一台Nginx代理服务器,安 ...
- 实战Apache+Tomcat集群和负载均衡
实战Apache+Tomcat集群和负载均衡 目录 1. 什么是J2EE集群... 3 1.1. 序言... 3 1.2. 基本术语... 3 伸缩性(Scalability): ...
随机推荐
- SPFA - Luogu 3385 【模板】负环
[模板]负环 描述 找负环 输入 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 接下来M行,每行三个整数a b w,表示a->b有一条权值为w ...
- [网站公告]11月26日00:00-04:00阿里云RDS升级
大家好,11月26号00:00-04:00(今天夜里),阿里云将对我们所用的SQL Server RDS实例所在的物理主机做升级操作(目前博客园整站运行于阿里云上),升级期间RDS实例会有2次闪断,每 ...
- Careercup - Microsoft面试题 - 24308662
2014-05-12 07:31 题目链接 原题: I have heard this question many times in microsoft interviews. Given two a ...
- Python框架之Django学习笔记(十一)
话说上次说到数据库的基本访问,而数据库我们主要进行的操作就是CRUD,也即是做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete),俗 ...
- mongo命令
安装mongo http://docs.mongodb.org/master/tutorial/install-mongodb-on-redhat-centos-or-fedora-linux/ 启动 ...
- python - 接口自动化测试 - HttpRequest - 接口测试类封装
# -*- coding:utf-8 -*- ''' @project: ApiAutoTest @author: Jimmy @file: http_request.py @ide: PyCharm ...
- jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒
sp中/el表达式中将后台传来的时间戳格式化为年月日时分秒1.引入相关标签库 <%@taglib prefix="c" uri="http://java.sun.c ...
- AngularJs 特性 之 双向数据绑定
<!DOCTYPE html> <html lang="en" ng-app> <head> <meta charset="UT ...
- 十一黄(xun)金(lian)周感想
实际上并没有训整整一周-_-|| 只训了三天 听说纪中全员没过节(ΩДΩ)好可怕 这三天考了5场模拟赛,一场初赛模拟 让我感觉我和开学时比起来还是有很大的提升的 最主要就是在dp方面. 经过整个九月疯 ...
- 百度地图API 根据地址查询经纬度
html页面.引用上API: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> ...