nginx学习 安装、配置、反向代理、负载均衡、动静分离、前后端分离

一、Nginx简单了解

Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的免费开源Web和 反向代理服务器,也是一个 IMAP/POP3/SMTP   代理服务器。在高并发访问的情况下,Nginx是Apache服务器不错的替代品。官网数据显示每秒TPS高达50W左右。

Nginx是目前负载均衡技术中的主流方案,Nginx是一个轻量级的高性能HTTP反向代理服务器,同时它也是一个通用类型的代理服务器,支持绝大部分协议,如TCP、UDP、SMTP、HTTPS等。

Nginx与Redis相同,都是基于多路复用模型构建出的产物,因此它与Redis同样具备 「「资源占用少、并发支持高」」 的特点,在理论上单节点的Nginx同时支持5W并发连接,而实际生产环境中,硬件基础到位再结合简单调优后确实能达到该数值。

原理:原本客户端是直接请求目标服务器,由目标服务器直接完成请求处理工作,但加入Nginx后,所有的请求会先经过Nginx,再由其进行分发到具体的服务器处理,处理完成后再返回Nginx,最后由Nginx将最终的响应结果返回给客户端。


 

二、Nginx环境搭建

window环境安装nginx

01、下载

在nginx的官网地址进行下载,其官网地址如下所示:

http://nginx.org/

点击当前最新版本nginx1.19.6版本链接,然后跳转至如下Linux和Windows操作系统下的1.19.6版本的nginx下载地址

我们需要在windows环境安装nginx,因此单击“nginx/Windows-1.19.6”,然后如下图所示,在浏览器窗口底部出现nginx下载进度小页签显示,等待nginx下载完毕。

02、安装

解压缩下载文件nginx-1.19.6.zip。将解压缩文件nginx-1.19.6剪切到非系统盘。

如下所示,是nginx的目录结构,nginx.exe是nginx的启动工具,nginx的配置文件在conf目录下,logs目录下存放的是nginx的日志文件

03、启动

启动方式很多,可以双击nginx解压目录下的nginx.exe启动nginx,出现一闪而过的窗口,是正常的,表示nginx服务器已经启动;

也可以在cmd命令窗口输入命令nginx,使用命令到达nginx的加压缩后的目录,然后输入nginx命令,如下所示:

在浏览器地址框输入地址:

然后浏览器出现如下信息,说明nginx启动成功

04、配置

(1)修改端口号

conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。

注意:

  • 检查80端口是否被占用的命令是:netstat -ano | findstr “80”
  • 当我们修改了nginx的配置文件nginx.conf时,不需要关闭nginx后重新启动nginx,只需要执行重新启动nginx命令 nginx -s reload 即可让改动生效。

(2)配置静态资源

在解压缩的nginx目录下新建static目录,在该目录下拷贝粘贴一张图片资源1.jpg:

然后在nginx.conf配置文件中,root修改相对路径为static,如下所示:

然后执行命令 nginx -s reload 即可实现修改生效,然后在浏览器地址栏输入访问地址:http://localhost/1.jpg

05、停止

如果使用cmd命令窗口启动nginx,关闭cmd窗口是不能结束nginx进程的,可使用如下三种方法关闭nginx:

  • 输入nginx命令
    nginx -s stop (快速停止nginx) 或nginx -s quit(完整有序的停止nginx)。
  • 使用taskkill
    taskkill /f /t /im nginx.exe
  • 任务管理器中结束nginx任务

以上是windows环境下常用的下载、安装、启动、配置、停止等操作步骤。

Linux环境:

首先创建 Nginx的目录并进入:

[xiaoming@localhost]# mkdir /soft && mkdir /soft/nginx/  
[xiaoming@localhost]# cd /soft/nginx/

下载 Nginx的安装包,可以通过 FTP工具上传离线环境包,也可通过 wget命令在线获取安装包:

[xiaoming@localhost]# wget https://nginx.org/download/nginx-1.21.6.tar.gz

没有 wget命令的可通过 yum命令安装:

[xiaoming@localhost]# yum -y install wget

解压 Nginx的压缩包:

[xiaoming@localhost]# tar -xvzf nginx-1.21.6.tar.gz

下载并安装 Nginx所需的依赖库和包:

[xiaoming@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ gcc-c++  
[xiaoming@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ pcre pcre-devel4  
[xiaoming@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ zlib zlib-devel  
[xiaoming@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ openssl openssl-devel

也可以通过 yum命令一键下载(推荐上面那种方式):

[xiaoming@localhost]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

执行完成后,然后 ls查看目录文件,会看一大堆依赖

紧接着通过 rpm命令依次将依赖包一个个构建,或者通过如下指令一键安装所有依赖包:

[xiaoming@localhost]# rpm -ivh --nodeps *.rpm

进入解压后的 nginx目录,然后执行 Nginx的配置脚本,为后续的安装提前配置好环境,默认位于 /usr/local/nginx/目录下(可自定义目录):

[xiaoming@localhost]# cd nginx-1.21.6  
[xiaoming@localhost]# ./configure --prefix=/soft/nginx/

编译并安装 Nginx

[xiaoming@localhost]# make && make install

最后回到前面的 /soft/nginx/目录,输入 ls即可看见安装 nginx完成后生成的文件。

修改安装后生成的 conf目录下的 nginx.conf配置文件

[xiaoming@localhost]# vi conf/nginx.conf  
    修改端口号:listen    80;  
 修改IP地址:server_name  你当前机器的本地IP(线上配置域名);

制定配置文件并启动 Nginx

[xiaoming@localhost]# sbin/nginx -c conf/nginx.conf  
[xiaoming@localhost]# ps aux | grep nginx

Nginx其他操作命令:

sbin/nginx -t -c conf/nginx.conf # 检测配置文件是否正常  
sbin/nginx -s reload -c conf/nginx.conf # 修改配置后平滑重启  
sbin/nginx -s quit # 优雅关闭Nginx,会在执行完当前的任务后再退出  
sbin/nginx -s stop # 强制终止Nginx,不管当前是否有任务在执行

开放 80端口,并更新防火墙:

[root@localhost]# firewall-cmd --zone=public --add-port=80/tcp --permanent  
[root@localhost]# firewall-cmd --reload  
[root@localhost]# firewall-cmd --zone=public --list-ports

Windows/Mac的浏览器中,直接输入刚刚配置的 IP地址访问 Nginx

三、Nginx反向代理-负载均衡

再简单修改一下nginx.conf的配置即可:

upstream nginx_boot{  
   # 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2  
   server 192.168.0.000:8080 weight=100 max_fails=2 fail_timeout=30s;   
   server 192.168.0.000:8090 weight=200 max_fails=2 fail_timeout=30s;  
   # 这里的IP请配置成你WEB服务所在的机器IP  
}  

server {  
    location / {  
        root   html;  
        # 配置一下index的地址,最后加上index.ftl。
        index  index.html index.htm index.jsp index.ftl;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        # 请求交给名为nginx_boot的upstream上  
        proxy_pass http://nginx_boot;  
    }  
}
至此,所有的前提工作准备就绪,紧接着再启动Nginx,然后再启动两个web服务,第一个WEB服务启动时,在application.properties配置文件中,将端口号改为8080,第二个WEB服务启动时,将其端口号改为8090

Nginx请求分发原理:

客户端发出的请求192.168.12.129最终会转变为:http://192.168.12.129:80/,然后再向目标IP发起请求,流程如下:

  1. 由于Nginx监听了192.168.12.129的80端口,所以最终该请求会找到Nginx进程;
  2. Nginx首先会根据配置的location规则进行匹配,根据客户端的请求路径 /,会定位到location /{}规则;
  3. 然后根据该location中配置的proxy_pass会再找到名为nginx_boot的upstream;
  4. 最后根据upstream中的配置信息,将请求转发到运行WEB服务的机器处理,由于配置了多个WEB服务,且配置了权重值,因此Nginx会依次根据权重比分发请求。

四、Nginx动静分离

动静分离应该是听的次数较多的性能优化方案,那先思考一个问题: 为什么需要做动静分离呢?它带来的好处是什么?

其实这个问题也并不难回答,当你搞懂了网站的本质后,自然就理解了动静分离的重要性。先来以淘宝为例分析看看: 当浏览器输入www.taobao.com访问淘宝首页时,打开开发者调试工具可以很明显的看到,首页加载会出现100+的请求数,而正常项目开发时,静态资源一般会放入到resources/static/目录下:

在项目上线部署时,这些静态资源会一起打成包,那此时思考一个问题: 假设淘宝也是这样干的,那么首页加载时的请求最终会去到哪儿被处理?

答案毋庸置疑,首页100+的所有请求都会来到部署WEB服务的机器处理,那则代表着一个客户端请求淘宝首页,就会对后端服务器造成100+的并发请求。毫无疑问,这对于后端服务器的压力是尤为巨大的。

但此时不妨分析看看,首页100+的请求中,是不是至少有60+是属于 .js、.css、 .html、.jpg.....这类静态资源的请求呢?答案是Yes。 既然有这么多请求属于静态的,这些资源大概率情况下,长时间也不会出现变动,那为何还要让这些请求到后端再处理呢?能不能在此之前就提前处理掉?当然OK,因此经过分析之后能够明确一点:做了动静分离之后,至少能够让后端服务减少一半以上的并发量。到此时大家应该明白了动静分离能够带来的性能收益究竟有多大。

先在部署Nginx的机器,Nginx目录下创建一个目录static_resources:

mkdir static_resources

将项目中所有的静态资源全部拷贝到该目录下,而后将项目中的静态资源移除重新打包。

稍微修改一下nginx.conf的配置,增加一条location匹配规则:

location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){  
    root   /soft/nginx/static_resources;  
    expires 7d;  
}

然后照常启动nginx和移除了静态资源的WEB服务,你会发现原本的样式、js效果、图片等依旧有效

最后解读一下那条location规则:

location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)
  • ~代表匹配时区分大小写
  • .*代表任意字符都可以出现零次或多次,即资源名不限制
  • \.代表匹配后缀分隔符.
  • (html|...|css)代表匹配括号里所有静态资源类型

综上所述,简单一句话概述:该配置表示匹配以.html.css为后缀的所有资源请求。

「最后提一嘴,也可以将静态资源上传到文件服务器中,然后location中配置一个新的upstream指向。」

五、通过Nginx实现前后分离调试

现在很多项目都是前后端分离,在前端与后端不是一个人开发,或者本身并非相同的项目。以前项目较小时,前端的资源文件和后台代码都是放在一块,进行 调试基本上都是启动后台服务就可以进行前端访问。但随着前端技术的成熟与庞大,更多的项目都有一套完整的开发工具与环境,而前端的项目往往都会有一套比较完整的体系,不可能将其拷贝到后台的模块中进行访问,这样调试起来非常不方便,同时会有很多依赖的环境无法满足。

现在可以通过nginx去实现前后端分离时,前端代码对后台的访问。在没有nginx时,我们可能会将前端代码部署到一个类似于apache的服务器中,通过配置端口访问,比如http://localhost:8080进行访问,而后台代码又要启动,此时不可能使用相同的端口,比如8082,那么在前台调用后台接口时,由于ip相同端口不同,则存在跨域问题。

通过nginx配置:

server{
    listen 80;
    server_name localhost;
    location / {
        root   D:/file/front-proj;#前端静态页面路径
        index  index.html index.htm;#默认起始页
    }
    location /api { #后台接口
         proxy_pass   http://localhost:8081/;
    }
}

这样我们在前端调地址变成了:localhost/xxx,调用后台的接口变成了localhost/api/xxx

六、常用配置

upstream标签

upstream zlj_jhpt {
ip_hash; //负载均衡策略:ip_hash,ip_url,轮询,权重,fails
server XXXX.70:443 weight=1 max_fails=10 fail_timeout=120s;
server XXXX.70:6443 weight=1 max_fails=10 fail_timeout=120s;
#server XXXX.72:8080 weight=1 max_fails=10 fail_timeout=120s;
keepalive 64;
}

server标签

server {

listen 7443 ssl;#监听的端口
server_name XXXX:7443;#监听ip及端口
ssl_certificate D:/zlj_ssl/_.XXXX_bundle.crt;#ssl证书
ssl_certificate_key D:/zlj_ssl/.XXXX_RSA.XXXX_RSA.key;#ssl证书

ssl_session_cache shared:SSL:1m; #所有工作进程之间共享缓存
ssl_session_timeout 5m;

#ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

charset ISO-88509-1;

#前端页面:https://XXXX:7443/zhejiang-social-assistance/zhejiang-social-assistance.html#/five-help/how-help
#接口地址:https://XXXX:7443/zlj_jhpt/api/five-help/help-how-going/count


#接口地址映射
location /api/ {
proxy_pass https://XXXX:7443/zlj_jhpt/api/; 
proxy_set_header X-Real-IP $remote_addr;
}

#前端页面地址映射
location /zhejiang-social-assistance/ {
root D:\working\yw_szzfdp\web;
expires 12h;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

}

#静态资源反向代理配置,比如将项目中的图片放到nginx服务器上

location /stwx/happyCode/images {
alias D:\zly_cache\stwx\happlyCode\images;
expires 12h;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}


#Tomcat项目映射及跨域问题解决
location /zlj_jhpt {
proxy_pass https://zlj_jhpt;   #写死一个的话配置:ip地址+端口号+项目名称 ;负载均衡的话就用upsteam标签
include proxy.conf;
# 配置html以文件方式打开
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}

}

其他配置分析

#user nobody;
#worker_processes: CPU核心数,(双核4线程,可以设置为4,但是我这台服务器还有一个tomcat所以我配置3)
worker_processes 3;

#debug | info | notice | warn | error | crit
error_log logs/error.log warn;

pid logs/nginx.pid;

#worker_rlimit_nofile 65535;

#单个工作进程可以允许同时建立外部连接的数量
events {
worker_connections 8192;
}

http {
include mime.types;

default_type application/octet-stream;

fastcgi_intercept_errors on;

log_format main '"$upstream_addr" $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;
access_log off;
open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;

server_names_hash_bucket_size 128;

large_client_header_buffers 4 64k;

client_header_buffer_size 32k;

client_body_buffer_size 5120k;

client_max_body_size 100m;

server_tokens off;

ignore_invalid_headers on;
recursive_error_pages on;

server_name_in_redirect off;

sendfile on;

tcp_nopush on;

tcp_nodelay on;

keepalive_requests 3000;

keepalive_timeout 120;

client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;

autoindex off;

include gzip.conf;

map_hash_bucket_size 64;

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#upstream模块:配置所映射的服务器项目地址及端口号,5种负载均衡策略:轮询(默认),权重(weight),ip_haph,ip_url,fairs
upstream stwx {
ip_hash;
server XXXX.206:8080 weight=1 max_fails=10 fail_timeout=120s;
#server XXXX.72:8080 weight=1 max_fails=10 fail_timeout=120s;
keepalive 64;
}


upstream zlj_jhpt {
ip_hash;
#交换平台地址
server XXXX.70:443 weight=1 max_fails=10 fail_timeout=120s;
#server XXXX.70:8088 weight=1 max_fails=10 fail_timeout=120s;
#server XXXX.72:8080 weight=1 max_fails=10 fail_timeout=120s;
keepalive 64;
}

#server模块 配置监听的端口,一个server监听一个端口,配置客户端所访问的路径
server {
# 监听了7443端口号
listen 7443 ssl;
# 访问项目的ip地址及端口号
server_name XXXX:7443;
ssl_certificate D:/zlj_ssl/_.XXXX_bundle.crt;
ssl_certificate_key D:/zlj_ssl/.XXXX_RSA.XXXX_RSA.key;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

#ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

charset ISO-88509-1;
# 访问项目根路径 比如:https://XXXX:7443/zlj_jhpt就访问到了XXXX.70:443的项目名称位zlj_jhpt的项目
location /zlj_jhpt {
proxy_pass https://zlj_jhpt;
include proxy.conf;
# 配置html以文件方式打开,解决跨域问题
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}


location /st {
proxy_pass https://st;
include proxy.conf;
# 配置html以文件方式打开
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}

}

server {
listen 80;
server_name localhost XXXX;

charset ISO-88509-1;

location /stwx {
proxy_pass http://stwx;
include proxy.conf;
}

location /nginxstatus {
stub_status on;
access_log on;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

error_page 404 /404.html;
}


server {
listen 80;
server_name localhost shzz.XXXX;

charset ISO-88509-1;

location /switch_stshzz {
proxy_pass http://switch_stshzz;
include proxy.conf;
}

location /nginxstatus {
stub_status on;
access_log on;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

error_page 404 /404.html;
}
server {
listen 8800;
server_name localhost XXXX.206;

return 301 http://XXXX:8089/st;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高亚奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值