nginx是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。它主要有以下优点:
- 高并发连接: 官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接数。
- 内存消耗少: 在3万并发连接下,开启的10个Nginx 进程才消耗150M内(15M*10=150M)。
- 配置文件非常简单:风格跟程序一样通俗易懂。
- 成本低廉: Nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币。
- 支持Rewrite重写规则:能够根据域名、URL的不同,将 HTTP 请求分到不同的后端服务器群组。
- 内置的健康检查功能: 如果 Nginx Proxy 后端的某台 Web 服务器宕机了,不会影响前端访问。
- 节省带宽: 支持 GZIP 压缩,可以添加浏览器本地缓存的 Header 头。
- 稳定性高: 用于反向代理,宕机的概率微乎其微
由于nginx的性能很好,因此国内很多大公司都在使用,最主要的原因也是nginx是开源免费的。除了上面描述的一系列功能,项目中主要用nginx来实现以下三个功能:
- 动静分离
- 反向代理
- 负载均衡
动静分离
动静分离的原理非常简单,我们可以将一些静态资源html文件、图片等交给nginx来处理,将后台请求转发给后台服务器处理,由于nginx会有缓存作用,因此这样不仅仅加快了访问速度,而且也减小了tomcat服务器的负载。
反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连的客户端,此时代理服务器对外就表现为一个服务器。
需要注意的是代理服务器可以作为前端服务器来处理前端等请求处理静态资源,但是不能处理后端服务器的请求。
nginx反向代理主要有以下特点:
反向代理又称为Web服务器加速,是针对Web服务器提供加速功能的。它作为代理Cache,但并不针对浏览器用户,而针对一台或多台特定Web服务器(这也是反向代理名称的由来)。代理服务器可以缓存一些web的页面,降低了web服务器的访问量,所以可以降低web服务器的负载。web服务器同时处理的请求数少了,响应时间自然就快了。同时代理服务器也存了一些页面,可以直接返回给客户端,加速客户端浏览。
负载均衡
负载均衡主要是为了解决服务器负载过大,在有的时候,系统的并发量过大,一台服务器无法负担的起用户发送的请求,因此我们需要搭建服务器集群,而nginx负载均衡就是接收用户的请求将其转发给后台服务器集群上的每一台机器。
负载均衡主要有以下特点:
- 分散后台服务器的负载
- 自动去掉后台宕机的服务器
- 缓存后台请求内容,加速请求速度
nginx负载均衡主要有以下五种策略:
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、 weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
默认情况下是轮询的策略,但是这种方式的使用有一个问题,分布式session不一致的问题,不过我们可以使用ip_hash来将同一ip地址上的请求分配到一台服务器中处理,这样就不会出现session不一致的问题。这个问题不是我们这篇文章讨论的重点,感兴趣的读者可以自行查询资料。
Nginx下载安装
Nginx官方下载地址
下载安装比较简单,直接解压即可运行,具体操作查看下面文章
Nginx安装与命令(Linux)
Nginx 从安装到配置,看这篇教程就够了
验证是否安装成功
nginx -V
如果需要任何地方都可以执行,直接在系统环境上添加安装目录即可
验证成功
查看nginx进程
tasklist /fi "imagename eq nginx.exe"
杀掉nginx进程
taskkill /f /pid 11044 /pid 7092
需要管理员权限,用管理员权限打开CMD,然后再次输入上面的命令
启动Nginx
start nginx.exe
注意需要先进入安装目录,在执行start命令
cd C:\MyProgram\nginx-1.19.4
访问localhost:80 测试 ngnix 是否正常运行
返回 nginx 欢迎页表示正常运行
window下Nginx启动bat脚本
对于常用的命令,可以写成脚本的方式,这样会更加方便。
@echo off
rem 提供Windows下nginx的启动,重启,关闭功能
echo ==================begin========================
cls
::ngxin 所在的盘符
set NGINX_PATH=C:
::nginx 所在目录
set NGINX_DIR=C:\MyProgram\nginx-1.19.4\
color 0a
TITLE Nginx 管理程序增强版
CLS
echo.
echo. ** Nginx 管理程序 ***
echo.
:MENU
echo. ***** nginx 进程list ******
::tasklist|findstr /i "nginx.exe"
tasklist /fi "imagename eq nginx.exe"
echo.
if ERRORLEVEL 1 (
echo nginx.exe不存在
) else (
echo nginx.exe存在
)
echo.
::*************************************************************************************************************
echo.
echo. [1] 启动Nginx
echo. [2] 关闭Nginx
echo. [3] 重启Nginx
echo. [4] 刷新控制台
echo. [5] 重新加载Nginx配置文件
echo. [6] 检查测试nginx配置文件
echo. [7] 查看nginx version
echo. [0] 退 出
echo.
echo.请输入选择的序号:
set /p ID=
IF "%id%"=="1" GOTO start
IF "%id%"=="2" GOTO stop
IF "%id%"=="3" GOTO restart
IF "%id%"=="4" GOTO MENU
IF "%id%"=="5" GOTO reloadConf
IF "%id%"=="6" GOTO checkConf
IF "%id%"=="7" GOTO showVersion
IF "%id%"=="0" EXIT
PAUSE
::*************************************************************************************************************
::启动
:start
call :startNginx
GOTO MENU
::停止
:stop
call :shutdownNginx
GOTO MENU
::重启
:restart
call :shutdownNginx
call :startNginx
GOTO MENU
::检查测试配置文件
:checkConf
call :checkConfNginx
GOTO MENU
::重新加载Nginx配置文件
:reloadConf
call :checkConfNginx
call :reloadConfNginx
GOTO MENU
::显示nginx版本
:showVersion
call :showVersionNginx
GOTO MENU
::*************************************************************************************
::底层
::*************************************************************************************
:shutdownNginx
echo.
echo.关闭Nginx......
taskkill /F /IM nginx.exe > nul
echo.OK,关闭所有nginx 进程
goto :eof
:startNginx
echo.
echo.启动Nginx......
IF NOT EXIST "%NGINX_DIR%nginx.exe" (
echo "%NGINX_DIR%nginx.exe"不存在
goto :eof
)
%NGINX_PATH%
cd "%NGINX_DIR%"
IF EXIST "%NGINX_DIR%nginx.exe" (
echo "start '' nginx.exe"
start "" nginx.exe
)
echo.OK
goto :eof
:checkConfNginx
echo.
echo.检查测试 nginx 配置文件......
IF NOT EXIST "%NGINX_DIR%nginx.exe" (
echo "%NGINX_DIR%nginx.exe"不存在
goto :eof
)
%NGINX_PATH%
cd "%NGINX_DIR%"
nginx -t -c conf/nginx.conf
goto :eof
::重新加载 nginx 配置文件
:reloadConfNginx
echo.
echo.重新加载 nginx 配置文件......
IF NOT EXIST "%NGINX_DIR%nginx.exe" (
echo "%NGINX_DIR%nginx.exe"不存在
goto :eof
)
%NGINX_PATH%
cd "%NGINX_DIR%"
nginx -s reload
goto :eof
::显示nginx版本
:showVersionNginx
echo.
%NGINX_PATH%
cd "%NGINX_DIR%"
nginx -V
goto :eof
安装Tomcat
基本的安装运行请查看下方文章
SpringBootServletInitializer (Tomcat)启动spring boot项目
Tomcat多实例部署
Tomcat 中比较重要的概念(通常也是两个系统变量)CATALINA_HOME
和 CATALINA_BASE
- CATALINA_HOME:即指向Tomcat安装路径的系统变量(安装目录)
- CATALINA_BASE:即指向活跃配置路径的系统变量(工作目录)
通过设置这两个变量,就可以将Tomcat的安装目录和工作目录分离,从而实现Tomcat多实例的部署。
复制tomcate
复制tomcate安装文件夹,本例在本地模拟三台tomcat服务器(一个home和两个base)和一台nginx服务器
三个 Tomcat,它们的作用分别是:
目录 | 作用 |
---|---|
tomcat-home | 作为 CATALINA_HOME ,即只需要保留 bin 和 lib 两个文件夹 |
tomcat-8080 | 作为 CATALINA_BASE ,需要保留除了 bin 和 lib 之外的其他文件夹,使用 8080 端口 |
tomcat-9090 | 同 tomcat-8080,使用 9090 端口 |
Tomcat 的基本目录结构,以及对应的作用:
目录 | 简介 |
---|---|
bin | 存放脚本文件,例如比较常用的启动和关闭脚本 startup.sh、shutdown.sh 等 |
conf | 存放配置文件,如server.xml它是 tomcat 的主要配置文件 |
lib | Tomcat 运行需要的依赖包 |
log | 存放日志文件 |
temp | 存放运行时产生的临时文件 |
webapps | web 应用的默认目录,通常war包会部署到这里 |
work | 主要存放由JSP文件生成的servlet(Java文件以及最终编译生成的class文件) |
Tomcat官方文档上说明了 CATALINA_HOME
路径下需要包含 bin 和 lib 目录,也就是两个支持 tomcat 运行的目录,而 CATALINA_BASE
可以包含所有目录,但是 bin 和 lib 不是必须的,缺省时会使用 CATALINA_HOME
中的 bin 和 lib。
因此我们就可以使用一个 CATALINA_HOME
和多个 CATALINA_BASE
部署多个实例,这样的好处是便于管理和升级 Tomcat。
按照上面的要求删除三个tomcat目录下无用的文件夹:
tomcat-home 保留 bin 和 lib 目录,删除其他目录
omcat-8080 保留除了 bin 和 lib 之外的其他文件夹,使用 8080 端口
tomcat-9090 保留除了 bin 和 lib 之外的其他文件夹,使用 9090 端口
修改 Tomcat 配置文件
这一步主要是修改conf目录下的 server.xml 中端口的配置,在 server.xml 中配置了四个监听端口,分别是:
- Server port(默认8005): 监听关闭 tomcat 的 shutdown 命令
- Connector port(默认8080):监听 http 请求
- AJP Connector port(默认8009):监听 AJP 请求
- redirectPort(默认8443):重定向端口,出现在Connector配置中,如果该Connector仅支持非SSL的普通http请求,那么该端口会把https的请求转发到这个Redirect Port指定的端口
了解了监听的各个端口的作用之后就可以开始修改 server.xml 了,如果不使用 AJP 请求,那么我们只需要保证多实例中的 Server port 和 Connector port 不同即可:
# tomcat-8080 保持默认配置即可
# 修改 tomcat-9090 的配置,修改后的 /tomcat-9090/conf/server.xml 内容如下:
...
...
...
# tomcat-8080 保持默认配置即可
# 修改 tomcat-9090 的配置,修改后的 /tomcat-9090/conf/server.xml 内容如下:
...
...
...
大概有3个地方休要修改
编写脚本
前面的准备工作做完之后就可以启动 Tomcat 了,但是现在只有 tomcat-home/bin 目录下有 startup.sh 和 shutdown.sh,而我们要启动的 8080 和 9090 两个实例,因此我们就需要编写一段脚本,修改 CATALINA_BASE 来达到分别操作两个实例的目的:
启动脚本start.sh:
#!/bin/sh
CUR_DIR=`dirname $BASH_SOURCE`
export CATALINA_BASE=`readlink -f $CUR_DIR`
export CATALINA_HOME="/usr/local/tomcat-home"
if [ -f $CATALINA_HOME/bin/startup.sh ]; then
$CATALINA_HOME/bin/startup.sh
else
echo "$CATALINA_HOME/bin/startup.sh not exist"
fi
windows
@REM 启动 tomcat-8080
echo 启动 tomcat-8080
set "CATALINA_BASE=%cd%"
set "CATALINA_HOME=C:\Program Files\Apache Software Foundation\tomcat-home"
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
call "%EXECUTABLE%" start
pause
停止脚本stop.sh:
#!/bin/sh
CUR_DIR=`dirname $BASH_SOURCE`
export CATALINA_BASE=`readlink -f $CUR_DIR`
export CATALINA_HOME="/usr/local/tomcat-home"
if [ -f $CATALINA_HOME/bin/shutdown.sh ]; then
$CATALINA_HOME/bin/shutdown.sh
else
echo "$CATALINA_HOME/bin/shutdown.sh not exist"
fi
windows
@REM 关闭 tomcat-8080
echo 关闭 tomcat-8080
cd C:\Program Files\Apache Software Foundation\tomcat-home\bin
call shutdown.bat
pause
当然关闭和开启也可以使用前面提及的tasklist taskkill等
然后将这两个脚本文件放在 tomcat-8080 和 tomcat-9090 的根目录下:
[root@localhost tomcat-8080]# ls
conf logs RELEASE-NOTES start.sh temp work
LICENSE NOTICE RUNNING.txt stop.sh webapps
测试两个 Tomcat 是否同时正常运行
在 tomcat-8080/webapps/ROOT
和 tomcat-9090/webapps/ROOT
目录下分别新建一个 index.html
文件,内容分别为 “8080” 和 “9090” 便于我们区分。
完成之后使用 start.sh 启动两个实例
直接浏览器输入localhost:9090 和localhost:8080
我们还可以使用 curl 访问来测试:
# 访问 9090 端口,获取到 9090 的数据
[root@localhost tomcat-9090]# curl localhost:9090
9090
# 访问 8080 端口,获取到 8080 的数据
[root@localhost tomcat-8080]# curl localhost:8080
8080
Nginx 与 Tomcat 进行负载均衡
打开nginx安装目录,找到conf目录下的nginx.conf
# 进入 ngnix 配置文件的目录
# 默认配置文件是 ngnix.conf
http {
include /etc/nginx/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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_types text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
include /etc/nginx/conf.d/*.conf;
# Tomcat 服务器集群
upstream app_server {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:9080 weight=1;
}
...
server {
listen 80;
server_name api.xxx.com;
location / {
...
# 请求转发给 Tomcat 集群处理
proxy_pass http://app_server;
}
}
nginx -s reload
不同的系统配置文件位置不一样