当前位置: 首页 > news >正文

案例:Nginx + Tomcat集群(负载均衡 动静分离)

目录

案例

案例环境

案例步骤

部署Tomcat服务器

部署Nginx服务器

实现负载均衡和读写分离

日志控制


案例

案例环境

操作系统

IP 地址

角色

CentOS

192.168.10.101

Nginx服务器(调度器)

CentOS

192.168.10.102

Tomcat服务器①

CentOS

192.168.10.103

Tomcat服务器②

Windows虚拟机或宿主机

浏览器测试

需求:静态请求交给Nginx解析,动态请求交给2个Tomcat服务器实现动静分离和负载均衡

以及日志的控制

假如有DDOS等网络攻击,服务器的连接数会被耗尽,需要获取真实客户端的地址

DDOS:分布式拒绝服务攻击


案例步骤

部署Tomcat服务器

因为102和103都是作为Tomcat服务器,部署的大致步骤相同,这里我们只开启102和103的会话同步

分别导入tomcat源码软件包到102和103主机

在102(Tomcat服务器①)操作

为了方便实验关闭防火墙和内核安全机制

tomcat是java开发的,这里我们需要在系统上安装java,确保开发环境一致

这里yum安装的java没有指定版本,安装的java版本是1.8的,可能仅适用于本次案例

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install java

tomcat是解压即用的,不需要编译和安装。

移动到/usr/local/下方便使用

[root@localhost ~]# tar zxvf apache-tomcat-9.0.8.tar.gz
[root@localhost ~]# mv apache-tomcat-9.0.8 /usr/local/tomcat9

在根目录下创建一个用来存放网页文件的目录

在该目录下添加动态内容和静态内容,以达到更好的测试效果

[root@localhost webapps]# mkdir -p /web/webapp1
[root@localhost webapps]# cd /web/webapp1/
[root@localhost webapp1]# vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP test1 page</title>   </head><body><% out.println("动态页面 1,http://www.test1.com");%></body><body><div>动态页面的图片 1</div><br><img src="logo.jpg"></body>
</html>

在103(Tomcat服务器②)操作

为了实现调度的效果,暂时关闭会话同步,来到103把其中的文本内容改一下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 
<html>   
<head><title>JSP test2 page</title>
</head><body><% out.println("动态页面 2,http://www.test2.com");%></body> <body> <div>动态页面的图片 2</div><br><img src="logo.jpg"> </body> 
</html>

在102(Tomcat服务器①)操作

开启会话同步

打开tomcat配置文件

在第150行,Host单元中添加Context标签,指定网页文件的位置

[root@localhost tomcat9]# vim /usr/local/tomcat9/conf/server.xml
<Context docBase="/web/webapp1" path="" />

保存并退出,启动tomcat

[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh

使用宿主机的浏览器测试,访问两个Web服务器的IP+端口号。结果如下,动态和静态的内容都显示出来了

图像、音频、视频之类的资源我们交给Nginx去解析,所以现在看不到图片是正常的


部署Nginx服务器

在101(Nginx服务器)操作

首先导入Nginx的源码软件包,准备安装

为了方便实验,关闭防火墙和内核安全机制

再安装Nginx依赖软件包,创建程序用户

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install pcre-devel zlib-devel gcc*
[root@localhost ~]# useradd -M -s /sbin/nologin nginx

解压Nginx源码包,进入解压目录,运行configure脚本,指定安装参数,编译(make)、安装(make install

[root@localhost ~]# tar zxvf nginx-1.12.0.tar.gz
[root@localhost ~]# cd nginx-1.12.0
[root@localhost nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
[root@localhost nginx-1.12.0]# make && make install

优化调用命令的方式,创建软链接到命令目录下,然后使用nginx -t测试是否能正常调用命令

[root@localhost nginx-1.12.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

cd进入Nginx存放网页文件的目录,删除index.html文件中的内容,替换为下方代码块的内容

[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# vim index.html
<body>
<h1>静态页面</h1>
</body>

因为我们的网页有中文,所以打开Nginx配置文件,在第39行指定字符集为utf8,然后保存并退出

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
charset utf8;

启动nginx服务,结果如下图

[root@localhost ~]# nginx


实现负载均衡和读写分离

刚才说了在这个案例的环境中,图像等静态资源由Nginx负责解析,那么相应的要实现动静分离

cd进入Nginx存放网页文件的目录,在该目录下创建一个存放图片资源的子目录,进入该目录,把之前在tomcat指定的logo.jpg导入进该目录下

[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir img
[root@localhost html]# cd img/

除此之外,还需要修改配置文件来实现动静分离

返回上一级目录知道nginx根目录,打开配置文件

[root@localhost img]# cd ..
[root@localhost html]# cd ..
[root@localhost nginx]# vim conf/nginx.conf

在第34行,添加upstream单元来配置负载均衡

再往下隔一个location单元,添加2个location单元实现读写分离(看下图)

下方代码表示nginx会将到达的请求按照权重分发到两台Tomcat服务器上,权重值(weight)越高,处理的请求越多

    upstream mytomcat {server 192.168.10.102:8080;server 192.168.10.103:8080;}# 省略...location ~ .*\.jsp$ {proxy_set_header HOST $host;proxy_pass http://mytomcat;}location ~ .*\.(jpg|png|gif)$ {root /usr/local/nginx/html/img;expires 30d;}

参数

说明

proxy_set_header HOST $host;

把原http请求中的Header中的Host字段放到转发的请求报文里,后端的web服务器利用这个host判断请求的是哪个虚拟主机

  • ~:不区分大小写
  • .*.\.jsp$:nginx匹配所有以.jsp结尾的请求,并将它们转发到定义的mytomcat后端服务器组中的某个Tomcat服务器处理。
  • .*\.(jpg|png|gif)$:这个配置用于处理静态图片文件。对于这些文件的请求,nginx会直接从指定的目录中提供,并设置响应头以便客户端进行缓存。
  • expires 30d:缓存时间为30天

由于修改了配置文件,需要重启服务使其生效,使用宿主机的浏览器访问192.168.10.101/index.jsp,此时就可以解析图片了,效果如下图

[root@localhost nginx]# nginx -s stop
[root@localhost nginx]# nginx


日志控制

在102(Tomcat服务器①)操作

如果此时查看Tomcat的访问日志,可以看到访问的IP都是代理服务器的IP

那么我们需要把这些源IP改为客户端的真实IP,以便Tomcat的访问日志能够详细记录

[root@localhost ~]# tail /usr/local/tomcat9/logs/localhost_access_log.2024-08-08.txt 
192.168.10.101 - - [08/Aug/2024:10:10:17 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.101 - - [08/Aug/2024:10:10:18 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.101 - - [08/Aug/2024:10:10:19 +0800] "GET /index.jsp HTTP/1.0" 200 215

在101(Nginx服务器)操作

打开配置文件,可以在location单元中设置对应参数来改变tomcat访问日志中的源IP

location ~ .*\.jsp$ {proxy_set_header HOST $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header Client-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass  http://myTomcat;}

参数

说明

proxy_set_header X-Real-IP $remote_addr;

使用$remote_addr变量获得用户的真实ip

如果有多个代理,$remote_addr一般设置在第一个代理服务器上。

当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖

proxy_set_header Client-IP $remote_addr;

获取客户端ip地址

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

从客户的真实ip为起点,穿过多层代理的proxy ,最终到达web服务器,都会记录下来。

所以在获取用户真实ip的时候,最后一个nginx配置此变量,用来获取客户端的ip地址

适合多层代理的场景

在102、103(Tomcat服务器①②)操作

打开Tomcat配置文件

在第162行添加代理服务器定义的变量

[root@localhost ~]# vim /usr/local/tomcat9/conf/server.xml
pattern="%{X-Real-IP}i %h %l %u %t &quot;%r&quot; %s %b" />

  • i:请求头

然后重启Tomcat服务

[root@localhost ~]# /usr/local/tomcat9/bin/shutdown.sh 
[root@localhost ~]# /usr/local/tomcat9/bin/startup.sh 

然后查看访问日志,就可以看到客户端的真实IP被加到开头了

[root@localhost ~]# tail /usr/local/tomcat9/logs/localhost_access_log.2024-08-08.txt 192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215
192.168.10.1 192.168.10.101 - - [08/Aug/2024:11:02:52 +0800] "GET /index.jsp HTTP/1.0" 200 215

相关文章:

案例:Nginx + Tomcat集群(负载均衡 动静分离)

目录 案例 案例环境 案例步骤 部署Tomcat服务器 部署Nginx服务器 实现负载均衡和读写分离 日志控制 案例 案例环境 操作系统 IP 地址 角色 CentOS 192.168.10.101 Nginx服务器&#xff08;调度器&#xff09; CentOS 192.168.10.102 Tomcat服务器① CentOS 1…...

【密码学】密码协议的分类:②认证协议

密码协议的分类有很多种方式&#xff0c;这里我采取的是基于协议实现的目的来分类。可以将密码协议分成三类&#xff1a;认证协议、密钥建立协议、认证密钥建立协议。 一、认证协议是什么&#xff1f; 认证协议都在认证些什么东西呢&#xff1f;认证一般要认证三个东西&#x…...

异步编程(Promise详解)

目录 异步编程 回调函数 回调地狱 Promise 基本概念 Promise的特点 1.Promise是一种构造函数 2.Promise接收函数创建实例 3.Promise对象有三种状态 4.Promise状态转变不可逆 5.Promise 实例创建即执行 6.Promise可注册处理函数 7.Promise支持链式调用 Promise的静…...

DjangoORM注入分享

DjangoORM注入 简介 ​ 这篇文章中&#xff0c;分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 ​ 攻击效果同数据库注入 从Django-Orm开始 开发角度 ​ Django ORM&#xff08;Object-Relational Mapping&#xff09;是Django框架中用于处理数…...

【HBZ分享】Redis各种类型的数据结构应用场景

String(字符串类型) 计数器&#xff1a; incr / decr, 比如商品库存&#xff0c;业务号的发号器业务数据key-value缓存&#xff0c; 缓存结果数据&#xff0c;提高网站性能&#xff0c;缓解DB压力分布式session会话&#xff0c; 集群环境下存储token鉴权信息分布式锁&#xff…...

anaconda创建并且配置pytorch(完整版)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 ** &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍** ❤️如遇文章付费&#xff0c;可先看看我公众号中是否发布免费文章❤️ &#x1f64f;笔者水平有限&#xff0c;欢迎各位大…...

高级java每日一道面试题-2024年8月10日-网络篇-你对跨域了解多少?

如果有遗漏,评论区告诉我进行补充 面试官: 你对跨域了解多少? 我回答: 跨域问题&#xff0c;即Cross-Origin Resource Sharing&#xff08;CORS&#xff09;&#xff0c;是现代Web开发中一个非常重要的概念&#xff0c;涉及到浏览器的安全策略——同源策略&#xff08;Same…...

AtCoder Beginner Contest 365 A~E

A.Leap Year&#xff08;思维&#xff09; 题意&#xff1a; 给你一个介于 1583 1583 1583和 2023 2023 2023之间的整数 Y Y Y。 求公历 Y Y Y年的天数。 在给定的范围内&#xff0c; Y Y Y年的天数如下&#xff1a; 如果 Y Y Y不是 4 4 4的倍数&#xff0c;则为 365 365 …...

多机部署, 负载均衡-LoadBalance

目录 1.负载均衡介绍 1.1问题描述 1.2什么是负载均衡 1.3负载均衡的一些实现 服务端负载均衡 客户端负载均衡 2.Spring Cloud LoadBalancer 2.1快速上手实现负载均衡 2.2负载均衡策略 自定义负载均衡策略 3.服务部署&#xff08;Linux&#xff09; 3.1服务构建打包…...

(回溯) LeetCode 78. 子集

原题链接 一. 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集 &#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&…...

DQL数据查询语言(多表处理)—/—<7>

一、多表处理 当前有两个表&#xff0c;一个是学生表student&#xff0c;一个是分数表score student表字段名表示如下&#xff08;共1000条数据&#xff09;&#xff1a; score表字段表示如下&#xff08;共6000条数据&#xff09;&#xff1a; 1、求每个学生的总分 SELECT …...

力扣刷题总结

去年有段时间一直在刷题&#xff0c;进步神速&#xff0c;解决了以往刷完就忘的问题&#xff0c;这里总结下经验&#xff0c;给有需要的人参考下&#xff0c;核心观点就仨&#xff1a; 1. 打好数据结构与算法基础 2. 多刷题多练习 3. 形成自己的知识体系 下图是我梳理的知识体…...

BLDC ESC 无刷直流电子调速器驱动方式

BLDC ESC 无刷直流电子调速器驱动方式 1. 源由2. 驱动方法2.1 Trapezoidal 1202.2 Trapezoidal 1502.3 Sinusoidal 1802.4 Field-Orientated Control (FOC) 3. FOC&#xff08;Field-Oriented Control&#xff09;3.1 引入坐标系3.2 Clarke and Park变换Clarke 变换&#xff08…...

解决 IntelliJ IDEA 编译错误 “Groovyc: Internal groovyc error: code 1” 及 JVM 内存配置问题

在使用 IntelliJ IDEA 进行开发时&#xff0c;我们可能会遇到各种编译和运行错误&#xff0c;其中之一就是 Groovy 编译器错误&#xff08;Groovyc: Internal groovyc error: code 1&#xff09;或 JVM 内存不足错误。这类错误可能会影响开发效率&#xff0c;但通过调整 JVM 内…...

LeetCode.2940.找到Alice和Bob可以相遇的建筑

友情提示&#xff1a;这个方法并没有通过案例&#xff0c;只通过了944个案例&#xff08;很难受&#xff09;&#xff0c;超时了&#xff0c;但是想着还是分享出来吧 题目描述&#xff1a; 给你一个下标从 0 开始的正整数数组 heights &#xff0c;其中 heights[i] 表示第 i …...

OFD板式文件创建JAVA工具-EASYOFD 四、文字 Text

JAVA版本的OFD板式文件创建工具easyofd. 功能包含了图像、 图像、 文字、和模版页功能。同时也支持OFD文件的数字签名及验签&#xff0c;电子签章及验签。 本JAVA版本的easyofd使用原生方式创建板式文件&#xff0c;不依赖JAVA的SWT库。 项目地址&#xff1a;http://…...

【概念速通】李群 lie group

李群 lie group 概念速通 快速示例介绍&#xff1a;【引入】单位复数 (The unit complex numbers) 是李群 (lie group) 最简单的例子之一【进一步】SO(2): The 2D rotation matrices【Typical uses】SE(2): Pose of a robot in the plane Group & Lie Group 定义&#xff1…...

day_39

198. 打家劫舍 class Solution:def rob(self, nums: List[int]) -> int:if len(nums) 1:return nums[0]dp [0] * len(nums)dp[0], dp[1] nums[0], max(nums[0], nums[1])for i in range(2, len(nums)):dp[i] max(dp[i - 1], dp[i - 2] nums[i])return dp[len(nums) - …...

计算机系统层次结构

1.计算机系统的组成 计算机系统的组成硬件系统软件系统 2.计算机的硬件部分 2.1冯诺依曼机的结构特点&#xff1a; 图示&#xff1a; 1.五大部分由运算器(ALU)&#xff0c;控制器(CU)&#xff0c;存储器(主存辅存)&#xff0c;输入设备&#xff0c;输出设备五大部分组成2.指…...

java语言特点

Java语言是一种广泛使用的编程语言&#xff0c;它具有以下几个显著的特点&#xff1a; 面向对象&#xff1a;Java是一种纯面向对象的语言&#xff0c;它支持类的封装、继承和多态等特性。面向对象的设计使得Java程序更加模块化&#xff0c;易于维护和扩展。 平台无关性&#xf…...

单元测试注解:@ContextConfiguration

ContextConfiguration注解 ContextConfiguration注解主要用于在‌Spring框架中加载和配置Spring上下文&#xff0c;特别是在测试场景中。 它允许开发者指定要加载的配置文件或配置类的位置&#xff0c;以便在运行时或测试时能够正确地构建和初始化Spring上下文。 基本用途和工…...

大数据-72 Kafka 高级特性 稳定性-事务 (概念多枯燥) 定义、概览、组、协调器、流程、中止、失败

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

MySQl 中对数据表的增删改查(基础)

MySQl 中对数据表的增删改查&#xff08;基础&#xff09; 新增演示插入一条数据插入多条数据 查询全列查询部分列查询查询关于列名的表达式查询时用别名查询去重后的结果查询排序后的结果条件查询比较运算符和逻辑运算符 分页查询 修改删除 黑白图是在命令行里的&#xff0c;彩…...

LVS知识点整理及实践

LVS知识点整理及实践 LVSlvs集群概念lvs概念lvs集群类型lvs-nat模型数据逻辑: lvs-DR模式数据传输和过程:特点: lvs-tun模式数据传输过程:特点: lvs-fullnet模式数据传输过程 lvs调度算法lvs调度算法类型lvs静态调度算法lvs动态调度算法4.15版本内核以后新增调度算法 ipvsadm命…...

Ubuntu gnome WhiteSur-gtk-theme类mac主题正确安装和卸载方式

目录 摘要目的安装和卸载特别说明 Ubuntu gnome WhiteSur-gtk-theme类mac主题正确安装和卸载方式 摘要 Ubuntu版本&#xff1a;ubuntu24.04 主题下载地址&#xff1a;https://github.com/vinceliuice/WhiteSur-gtk-theme 参考的安装教程&#xff1a;https://blog.51cto.com/u_…...

计算机毕业设计选题推荐-办公用品管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

计算机毕业设计选题推荐-网上考试系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

白骑士的Matlab教学基础篇 1.4 函数与脚本

系列目录 上一篇&#xff1a;白骑士的Matlab教学基础篇 1.3 控制流 函数和脚本是 MATLAB 编程中的基本组成部分&#xff0c;它们使得代码更加模块化、可重用和组织化。通过理解函数的定义与调用、参数与返回值&#xff0c;以及 MATLAB 脚本与批处理&#xff0c;可以显著提高编…...

Qt——多线程

一、QThread类 如果要设计多线程程序&#xff0c;一般是从QThread继承定义一个线程类&#xff0c;并重新定义QThread的虚函数 run() &#xff0c;在函数 run() 里处理线程的事件循环。 应用程序的线程称为主线程&#xff0c;创建的其他线程称为工作线程。主线程的 start() 函数…...

技术周总结 08.05-08.11周日(scala git回滚)

文章目录 一、08.06 周二1.1) 问题01 mac安装 scala:1. 使用 Homebrew2. 使用 SDKMAN!其他注意事项1. 确认 Scala 安装位置2. 设置 PATH 环境变量对于 zsh (macOS Catalina 及更高版本默认使用 zsh):对于 bash (如果您使用的是 bash shell): 3. 验证安装 二、08.09 周五2.1&…...