目录
一. Nginx快速入门
1. Nginx 概述
1.1 Nginx 介绍
Nginx 是一个轻量级、高性能的HTTP和反向代理web服务器。作为一个 HTTP Server ,其主要关心的是 HTTP 协议层面的传输和访问控制,监听相应的地址和端口,对客户端的HTTP资源请求进行响应、转发或处理,但是一个 HTTP Server 能做的始终只是把服务器上的静态资源如实的通过 HTTP 协议传输给客户端。相比于Nginx,我们常见的Tomcat也是一个web服务器,不过他是一个 Application Server,或者说是一个「Servlet/JSP」应用的容器,其可以处理动态请求,功能更加强大。Nginx和Tomcat各有侧重,且Nginx在近些年的发展中以其轻便灵活、高并发等优势在web服务器中脱颖而出,在反向代理、负载均衡、动静分离等应用方面占据了一席之地。
1.2 Nginx 功能应用
Nginx功能非常强大和丰富,使用起来也非常灵活。Nginx可以提供基本的HTTP服务,作为静态资源服务器处理静态文件;也可以作为HTTP代理服务器和反向代理服务器,支持通过缓存加速访问,完成简单的负载均衡和容错支持包过滤功能和SSL等。我们这里主要介绍其反向代理、负载均衡、动静分离方面的应用。
(1)反向代理
- 正向代理:代理客户端访问服务器,向服务器隐藏真实用户。正向代理类似于VPN,服务器不知道具体是哪个客户端访问了它。
- 反向代理:代理服务器接收处理客户端请求,向客户端隐藏真实服务器。客户端不知道具体访问的是哪个服务器。反向代理常与负载均衡密切相关。
(2)负载均衡
负载均衡是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行处理,从而协同完成工作任务,增加服务吞吐量、减少单台服务单元的压力。比如当网站的访问量达到一定程度后,单台服务器已不能满足需求,这时就需要多台服务器集群根据一定的策略来分摊和处理请求负载。在这个过程中,接收用户请求的过程是反向代理,使用策略分发请求到真实服务器的过程是负载均衡,负载均衡配置一般都需要同时配置反向代理。负载均衡的策略主要有两类,分别是内置策略和扩展策略。其中内置策略为已实现的内置算法,比如轮询(请求依次分发,默认),加权轮询(根据权重分发请求),IP hash(对客户端请求的ip进行hash操作,然后根据hash结果分发请求);而扩展策略是指自定义分发算法。
(3)动静分离
动静分离是指在web服务器架构中,将静态资源与动态处理请求或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务的访问性能和可维护性。简而言之,就是将动静资源分别进行拆分处理,根据静态资源的特点将其做缓存操作,提高资源响应的速度。
2. Nginx 安装与控制
在Linux中,Nginx的安装分为源码安装和yum安装两种方式,这两种安装方式的区别如下:
- 源码安装:源码安装是指手动安装nginx的安装包。它要求自行配置nginx所必需的gcc、PCRE、zlib、OpenSSL等环境,并指定编译参数进行自定义安装。该方法的灵活度较高,nginx的各种配置、文件位置均可定制。
- yum安装:yum安装是指通过yum工具自动安装nginx。它会自动安装并配置nginx所依赖的环境(gcc、PCRE、zlib、OpenSSL等),自动指定并分配默认编译参数和相关文件资源位置。该方法比较简单方便,只需一行命令即可完成,但是灵活度较低,受限较多。
2.1 Nginx Linux 源码安装
(1)Nginx 安装环境准备
- 安装GCC编译器:Nginx是使用C语言编写的应用服务,因此要想编译运行Nginx就必须基于一个编译工具,GCC就是一个开源的编译器集合。
yum install -y gcc #安装gcc
gcc --version #查看gcc版本,测试是否成功
- 安装PCRE库:PCRE是一个兼容正则表达式库。Nginx在Rewrite模块和HTTP核心模块都会用到正则表达式语法,需要PCRE来解析。因此需要安装其库及其源代码pcre、pcre-devel来提供支持。
yum install -y pcre pcre-devel #安装pcre库及其源代码
rpm -qa pcre pcre-devel #测试是否成功
- 安装zlib库:zlib 库提供了很多种压缩和解压缩的算法库。在Nginx的很多模块都需要对传输内容进行gzip压缩,因此需要安装其库及其源代码zlib、zlib-devel来提供支持。
yum install -y zlib zlib-devel #安装zlib库及其源代码
rpm -qa zlib zlib-devel #测试是否成功
- 安装OpenSSL库:OpenSSL是一个开源的安全通信软件库,其包含主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议等。Nginx在提供网页安全通信时需要用到OpenSSL,因此需要安装其库及其源代码openssl、openssl-devel来提供支持。
yum install -y openssl openssl-devel #安装openssl库及其源代码
rpm -qa openssl openssl-devel #测试是否成功
(2)Nginx 源码安装流程
- 下载Nginx安装包
下载Nginx安装包有两种方式:一是通过在Nginx官网下载好安装包后,通过FTP上传到云服务器上;二是在 Linux 云服务器上通过 wget 下载相应链接的安装包。我们这里主要使用方式二。
wget http://nginx.org/download/nginx-1.22.0.tar.gz #下载nginx安装包
- 进行包管理,安装解压缩
为了对Nginx相关安装文件进行统一管理,我们新建一个 nginx/core 用来存放和管理nginx的安装目录。然后对 nginx-1.22.0.tar.gz 安装包进行解压缩,解压缩后可以看到其安装目录如下。
mkdir -p nginx/core #新建文件目录
mv nginx-1.22.0.tar.gz nginx/core #移动压缩包
tar -zxf nginx-1.22.0.tar.gz #解压缩
- 执行编译配置
在安装目录中,比较重要的是 configure 编译配置脚本文件。该脚本可以给我们的Nginx安装指定一些编译参数,进行一些自定义的安装配置。其编译参数可以通过 ./configure --help 命令来查看,常见的一些参数说明如下:http://nginx.org/en/docs/configure.html
--prefix=PATH 指定nginx的安装目录,默认值为/usr/local/nginx
--sbin-path=PATH 指定nginx可执行文件位置,默认值为<prefix>/sbin/nginx
--modules-path=PATH 指定nginx动态模块安装目录,默认值为<prefix>/modules
--conf-path=PATH 指定nginx核心配置位置,默认为<prefix>/conf/nginx.conf
--error-log-path=PATH 指定nginx错误日志目录,默认为<prefix>/logs/error.log
--pid-path=PATH 指定进程ID文件位置,默认为<prefix>/logs/nginx.pid
--lock-path=PATH set nginx.lock pathname
--user=USER set non-privileged user for
worker processes
--group=GROUP set non-privileged group for
worker processes
--build=NAME set build name
--builddir=DIR set build directory
没有特殊需求的话,我们直接使用默认的编译配置即可,即在安装目录下执行 configure 编译配置脚本文件,不用加任何参数。
./configure
- 编译 & 安装
编译配置完成之后,我们在安装目录下进行最终的编译和安装操作,完成Nginx的源码安装过程。
make && make install
- 添加nginx服务
安装完成后我们通过 whereis nginx 命令可以看到,所有的nginx文件目录都被安装到了 /usr/local/nginx (默认路径)下(包括所有的配置、静态资源、日志、可执行文件等)。
我们到 sbin 目录下,执行 ./nginx 可以启动 nginx 应用进程,通过公网IP访问 nginx 服务可以到达 nginx 默认首页。但是这时我们通过 systemctl status nginx 是无法找到该服务的,并且只有在 sbin 目录下才能使用 nginx 命令。这是因为我们没有向系统添加nginx服务,或者说是环境变量(不是内部命令,系统无法识别)。我们参照网上的教程,将Nginx添加到系统服务中即可。
2.2 Nginx Linux yum安装
采用yum简单安装,安装过程可以参考官网:http://nginx.org/en/linux_packages.html#RHEL-CentOS
(1)安装yum-utils
yum-utils是一个与yum集成的实用程序集合,可通过多种方式扩展其本机功能,从而使其功能更强大、更易于使用,比如管理yum源。
sudo yum install yum-utils
(2)设置yum仓库源
配置 yum 的 nginx 安装源,主要包括stable(稳定版本)和mainline(主线/最新版本),默认为稳定版。
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
(3)自动安装配置nginx
yum会自动帮我们下载并安装所有的依赖包,以及进行系统环境和服务配置,安装方式比较简单。
sudo yum install nginx
(4)查看 nginx安装信息
- nginx -v:查看安装nginx的版本信息,此处为1.22.0版本
- whereis nginx:查看nginx的安装文件目录。可以看到,通过yum安装与源码安装不同的是,nginx的安装文件被默认拆分到了不同的目录下。
- nginx -V:查看nginx的安装编译信息。可以看到,在yum安装中 configure arguments默认指定了一系列的编译参数,比如 --sbin-path=/usr/sbin/nginx 的含义为nginx可执行脚本的安装目录默认为 /usr/sbin/nginx。
2.3 Nginx 控制命令
sbin/nginx 是nginx的二进制可执行文件,所有的nginx相关控制命令都需要直接通过该可执行文件进行。开启nginx服务后,可以以通过访问IP/IP:80来验证(显示nginx默认主页)。
systemctl start nginx #开启nginx服务
systemctl enable nginx #设置开机自启
./nginx #启动nginx
./nginx -s stop #强制停止nginx
./nginx -s quit #安全退出(等待nginx工作进程全部安全完成并保存后,再进行退出)
./nginx -s reload #重新加载配置文件(nginx配置文件更新后必须reload才可生效)
ps aux|grep nginx #查看nginx进程
注意:若连接不上,请检查云服务器安全组是否开放相关端口,或者服务器防火墙是否开放相关端口!
3. Nginx 结构分析与配置说明
3.1 Nginx 文件目录结构分析
在Nginx安装完成之后,虽然yum安装方式与源码安装方式的目录组织结构不同,但是文件目录内容大体相同,接下来我们来分析一下Nginx各主要目录结构的作用。
/usr/local/nginx
# 1.nginx 相关的配置文件
- conf
# CGI是通用网关接口规范,用于解决请求和数据的处理及响应。
# fastcgi、scgi、uwsgi均是对该接口规范的不同实现,供nginx调用。
- fastcgi.conf # cgi 配置文件
- fastcgi.conf.default # cgi 配置文件副本(用于配置文件备份)
- fastcgi_params # cgi 配置参数
- fastcgi_params.default # cgi 配置参数副本(用于配置参数备份),下同
- scgi_params
- scgi_params.default
- uwsgi_params
- uwsgi_params.default
# 编码与转换配置文件
- koi-utf
- koi-win
- win-utf
# 数据传输类型映射文件
- mime.types # mime.types 记录了HTTP数据传输的协议头与文件类型的映射
- mime.types.default # mime.types 映射文件的副本
# Nginx核心配置文件
- nginx.conf # nginx.conf 配置了nginx的绝大多数内容,我们也将重点学习该文件
- nginx.conf.default # nginx.conf 核心配置的副本
# 2. 静态资源目录
- html
# html 下放置一些nginx管理的静态资源
- 50x.html # nginx 默认错误页面
- index.html # nginx 默认主页
# 3.日志文件目录
- logs
- access.log # nginx 访问日志
- error.log # nginx 错误日志
- nginx.pid # nginx进程的PID记录
# 4.二进制脚本目录
- sbin
- nginx # nginx 的二进制可执行脚本
3.2 Nginx 配置说明
我们以源码安装后的Nginx为例。在上述Nginx文件目录结构中,我们最关心的就是Nginx的核心配置文件 nginx.conf,整个Nginx服务行为的配置内容都包含在其中。该文件的所在位置为 /usr/local/nginx/conf/nginx.conf。接下来我们将对Nginx的配置进行详细说明。
3.2.1 Nginx 配置结构
Nginx的整体配置由多个配置块组成,主要包括main块、events块、http块、upstream块、server块、location块。每个配置块都有自己的配置指令和作用,各个配置块协同作用完成Nginx的服务,各配置块的作用及结构关系如下:
- main块:main块是全局配置块,主要会配置一些影响Nginx服务器整体运行的配置指令。比如服务用户(组)、全局日志位置、配置文件引入,工作线程worker process数等。
- events块:events块主要会配置一些影响Nginx服务与网络行为的配置指令。比如处理请求的事件驱动模型、最大连接数worker_connections等。
- http块:http块是http服务器配置模块,这也是Nginx服务中配置最频繁最常用的部分。http块可由http全局配置模块、upstream模块和多个server块组成。主要会配置一些HTTP服务相关的配置指令,比如代理、缓存、负载均衡等。
- upstream块:Upstream模块主要会配置一些与服务集群、负载均衡相关的配置指令,实现一些简单的调度算法。
- server块:Server块是虚拟主机配置模块,每个 server 块就相当于一个虚拟主机服务,对特定的请求进行监听和处理。Server块可由Server全局配置模块和多个location块组成。主要会配置一些虚拟主机服务相关的配置指令,比如监听端口、域名、日志、路由等。
- location块:location块是路由管理配置模块,该模块主要是基于nginx服务器接收到的请求URL,对请求进行过滤、处理和响应等。主要会配置一些路由相关的配置指令,比如匹配URL、资源定位、代理转发等。
... #全局块,'#'为配置注释
events { #events块
...
}
http #http块
{
... #http全局块
upstream [PATH_NAME] { #upstream块
...
}
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
其中,Nginx安装后默认的 nginx.conf 配置文件内容说明如下,'#'表示配置注释:
#1.main块部分
#user nobody; #user指令 定义Nginx服务运行的用户和用户组
worker_processes 1; #worker_processes指令 Nginx worker进程的数量,一般与CPU内核数量有关
#error_log指令 定义全局错误日志
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid指令 定义Nginx 进程PID文件的位置
#pid logs/nginx.pid;
#2.events块部分
events {
worker_connections 1024; #worker_connections指令 定义每个worker进程所支持的最大连接数
}
#3.http块部分
http {
include mime.types; #include指令 引入文件类型映射表mime.types(相对路径)
default_type application/octet-stream; #默认的HTTP文件数据类型
# 自定义日志生成格式
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# main为此日志输出格式的名称,可以在下面的access_log指令中引用
#access_log logs/access.log main;
# 指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件
sendfile on;
# 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
#tcp_nopush on;
# 设置客户端连接保持长连接活动的超时时间(秒),在超过这个时间之后,服务器会关闭该连接。
#keepalive_timeout 0;
keepalive_timeout 65;
# 开启gzip压缩输出
#gzip on;
#4.server块部分
server {
listen 80; # 虚拟主机服务监听端口
server_name localhost; # 监听地址/域名/IP(可有多个,空格隔开)
#charset koi8-r; # 网页默认编码格式
#access_log logs/host.access.log main; #日志配置
#5.location块部分 路由管理
location / { # URI拦截规则:访问localhost:80/ -> html/index.html找资源
root html; # root指令 资源定位位置(相对目录html下)
index index.html index.htm; # 默认首页,html目录下的index.html/index.htm
}
#server的错误页面配置 500,502,503,504状态码->/50.html页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy_pass 指令 反向代理
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
}
#6.多个虚拟主机服务 server配置
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS 安全控制服务配置,要用到SSL
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
3.2.2 Nginx 配置指令
我们在实现Nginx应用服务时,最常用的就是server、upstream和location块的配置,其它部分的配置多用来进行服务调优,我们这里暂时不做介绍。接下来我们将先介绍一下Nginx的工作模式和域名解析相关的基础,然后介绍上述三部分块的配置指令。
(1)Nginx 配置基础
- 域名解析相关介绍
在网络中,我们通常使用IP地址来标识网络主机完成通信过程。但是IP地址是一串32位的数字协议,冗长复杂且在通信过程中难以记忆。为了方便计算机网络通信服务,人们提出一种字符串到IP地址的映射,称为域名,比如www.baidu.com。有了域名,使得网络通信服务变得更加简单方便。当然我们最终还是要将域名解析为对应的IP地址从而实现访问,这就需要借助域名解析服务器(DNS服务器)帮我们自动完成域名到IP地址的解析过程。
当我们访问请求域名时,会先从当前浏览器的缓存中查找域名映射关系,如果可以找到则直接从浏览器中解析映射IP访问;否则就去本机的 hosts 本地存储映射文件中(Windows为C:\\Windows\System32\drivers\etc;Centos为\etc\hosts)查找有无对应的域名映射关系记录,如果有则直接从hosts文件中解析映射IP访问;否则,请求就会发送到外网,通过一层一层的域名解析服务器(DNS服务器)去解析域名,然后将解析后的IP返回给浏览器访问并缓存。
域名要想在外网中访问,就要购买并进行域名备案才可以使用。我们在下面的测试和学习中没有那么多资源,因此我们只在本地 hosts 文件中配置只有本机可以识别解析的虚拟域名即可,这样只有本地可以访问,作为学习来说已经足够了。
- Nginx工作模式介绍
Nginx的工作模型由一个master进程和多个worker进程组成,master进程管理多个worker进程,每个worker进程分别处理多个连接请求。Nginx通常会配置多个server虚拟机服务,监听不同的端口,当有HTTP请求到达本机服务器时(1),相应的监听端口server会拦截请求(2),并根据其server_name(域名、IP等)和资源定位URI 使用相应的规则分配server处理(3)。
(2)server块主要配置指令
- listen 指令
语法 | listen address:port [default_server]...; listen port [default_server]...; |
---|---|
默认值 | listen *:80 (super user)| *:8000(normal user) |
位置 | server |
listen 指令表示当前server虚拟主机服务监听的本地端口。当不配置listen指令时,Nginx 若在以超级用户运行时则监听 80 端口,以非超级用户运行时则监听 8000 端口。listen 指令的配置比较灵活,我们看几个例子:
listen 127.0.0.1:8000; #listen IP:port 监听指定的IP和端口(无需配置server_name)
listen 127.0.0.1; #监听指定IP下的所有端口(无需配置server_name)
listen 8000; #监听指定端口上的连接
listen *:8000; #监听指定端口上的连接
default_server 属性是标识符,用来将此虚拟主机server设置成相应监听端口下的默认主机。所谓的默认主机指的是当请求到达本机服务器,并被相应端口监听的server拦截下进行匹配,如果没有匹配到则会默认执行的server主机。如果不指定默认使用的是该监听端口下的第一个server。
server { #监听8080端口下的 __ 域名匹配
listen 8080;
server_name __;
default_type text/plain;
return 200 'listen __ 8080 serever';
}
server { #监听8080端口下的 _ 域名匹配,8080端口下的默认server
listen 8080 default_server;
server_name _;
default_type text/plain;
return 200 'listen _ 8080 server default';
}
server { #监听80端口下的 _ 域名匹配,80端口下的默认server(第一个)
listen 80;
server_name _;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- server_name 指令
语法 | server_name name...; name可以提供多个值,中间用空格分隔 |
默认值 | server_name ""; |
位置 | server |
server_name 指令用于配置虚拟主机服务监听的主机名称,该名称可以是IP地址/域名/主机名,多与 listen 指令配合使用(listen+server_name的组合必须唯一)。当请求到达监听端口时,Nginx会将server_name与IP或请求头部中的Host字段内容(域名)进行匹配,匹配成功后才会将请求交由server处理。同时,server_name支持精确匹配、通配符匹配、正则表达式匹配三种方式。
server {
listen 80;
server_name www.example.com www.nginx.com; #精确匹配
}
server {
listen 80;
server_name *.example.com www.nginx.*; #通配符匹配(*只能放在首部或尾部)
}
server {
listen 80;
server_name ~^www\d+\.example\.com$; #正则表达式匹配
}
当一个请求同时能被多个server匹配处理时,三种匹配方式的匹配优先级如下:
- 精准域名匹配
- 通配符前置的最长域名匹配
- 通配符后置的最长域名匹配
- 第一个匹配到的正则表达式(在配置文件中配置的顺序先后)
(3)location块主要配置指令
- URI匹配规则
location 是 Nginx 对 HTTP 请求中的 URI 资源进行匹配处理的指令。在请求匹配到相应的server后,由location对请求中的URI资源进行处理。location 的语法形式如下:
语法 | location [ = | ~ | ~* | ^~ | @ ] UriPattern { ... } |
其中,[=|~|~*|^~|@] 部分称为 location 修饰语(Modifier),修饰语定义了与 URI 的匹配方式。UriPattern 为匹配项,可以是字符串或正则表达式。 不同匹配方式的说明如下:
#1.无修饰符:URI访问路径必须以指定模式开始,匹配项的内容只能是字符串。比如/ab,/abc,/ab/ccc
location /ab {
default_type text/plain;
return 200 "access success";
}
#2.'=' 修饰符:URI访问路径必须与指定模式精确匹配,匹配项的内容只能是字符串。比如 /ab
#注意:location 与 = 之间必须有空格隔开
location =/ab {
default_type text/plain;
return 200 "access success";
}
#3.'~' 修饰符:表示当前匹配URI中包含正则表达式,并且区分大小写。比如/abc,/abd
location ~^/ab\w$ {
default_type text/plain;
return 200 "access success";
}
#4.'~*' 修饰符:表示当前匹配URI中包含正则表达式,并且不区分大小写。比如/abc,/AbC
location ~*^/ab\w$ {
default_type text/plain;
return 200 "access success";
}
#5.'^~' 修饰符:表示当前匹配URI中包含正则表达式,并且区分大小写,匹配到后就不再继续搜索。
location ^~^/ab\w$ {
default_type text/plain;
return 200 "access success";
}
- root 和 alias 指令
root 和 alias 均用来设置请求资源的定位目录。当请求到来时,如果相关的 location 配置了root或alias指令,则请求会前往相应的目录下查找资源并返回数据。
root 语法 | root path; |
alias 语法 | alias path; |
既然都用来指定访问资源的路径,二者的区别主要如下:
#root指令:root指令的处理结果是 root路径+location路径
#访问地址 IP:images/mv.png => 资源目录 /usr/local/nginx/html + /images/mv.png
location /images{
root /usr/local/nginx/html;
}
#alias指令:alias指令的处理结果是 alias路径替换location路径
#访问地址 IP:images/mv.png => 资源目录 /usr/local/nginx/html + /mv.png
#注意:若location以'/'结尾,则alias也必须以'/'结尾,root则无此要求。
location /images{
alias /usr/local/nginx/html;
}
- index 指令
语法 | index file...; |
默认值 | index index.html; |
index 指令搭配 root/alias 指令来使用,用于设置默认的访问资源首页(root/alias目录下)。index后可跟多个资源名称,若访问时没有指定具体的资源,则会依次进行默认资源查找。
- proxy_pass 指令
proxy_pass指令用于实现Nginx反向代理,向客户端隐藏并代理真实服务器。该指令用于设置连接被代理服务器的协议、IP 地址或套接字,也可以是域名或 upstream 定义的服务器集群组(包含传输协议http/https、主机名称或IP地址加端口号、URI等要素)。
语法 | proxy_pass UrlPath; |
位置 | location |
注意 | 1.代理转发proxy_pass指令与资源定位root/alias指令不能同时使用。 2.被代理服务器地址必须是本机可以访问到的地址,比如可访问外网或本机服务及其子网(此处常用虚拟机模拟)。 |
#1.Nginx代理服务器(显示IP):http://192.168.200.133:8080
server {
listen 8080;
server_name localhost;
location /{
proxy_pass http://192.168.200.146:8081; #代理到真实服务器 146
}
}
#2.真实服务器(用户无感知):http://192.168.200.146:8081
server {
listen 8081;
server_name localhost;
location /{
default_type text/plain;
return 200 "146 server access success!";
}
}
除了基本的配置之外,proxy_pass指令还相当严格,表现在有无 '/' 都会使得访问结果大不相同。在Nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,则表示相对路径,把匹配的路径部分也给代理走。 具体说明如下:
- location 为 / 时:proxy_pass 后 url 加不加 / 效果相同。
proxy_pass http://192.168.200.146:8081; proxy_pass http://192.168.200.146:8081/;
- location 带有匹配URI,proxy_pass 后 url 不加 / 时:直接将请求的uri拼接到代理地址。
#访问请求 http://192.168.200.133:8080 + /server/index.html #代理请求 http://192.168.200.146:8081/svr + /server/index.html location /server{ proxy_pass http://192.168.200.146:8081/svr; }
- location 带有匹配URI,proxy_pass 后 url 加 / 时:将请求的uri中和location匹配的部分进行替换。
#访问请求 http://192.168.200.133:8080 + /server/index.html #代理请求 http://192.168.200.146:8081/svr + index.html location /server{ proxy_pass http://192.168.200.146:8081/svr/; }
- proxy_set_header 指令
语法 | proxy_set_header field value; |
作用 | 该指令用于在转发给被代理服务器前,修改或添加客户端的请求头属性字段。 |
# Nginx代理服务器
server{
listen 8080;
server_name localhost;
location /server{
proxy_pass http://192.168.200.146:8081/;
proxy_set_header username Tom; #修改请求头部的username字段
}
}
# 被代理服务器
server{
listen 8081;
server_name localhost;
default_type text/plain;
return 200 $http_username; #取http请求头部的username字段
}
(4)upstream 块主要配置指令
Nginx的负载均衡是在Nginx反向代理的基础上把用户的请求根据指定的算法分发到一组upstream虚拟服务池,这就涉及到了upstream指令块。该指令块用来定义一组服务器集群及其负载均衡策略,它们可以是监听不同连接和端口的服务器。指令块的语法以及 server 指令的部分主要参数介绍如下:
语法 | upstream name{ server name [paramerters] server ... } |
位置 | http |
参数名称 | 默认值 | 参数介绍 |
weight | 1 | 服务集群中每个server的轮询权重(加权轮询策略) |
backup | - | 将被代理服务器标为备份状态,当其他非备份被代理服务器不可用时,会把请求转发给备份被代理服务器 |
down | - | 将被代理服务器标为不可用状态 |
upstream块中的server与前述的server虚拟服务器不同,该处指令用于指定集群中后端服务器的名称和一些负载参数,可以使用域名、IP、端口或socket等,负载均衡的相关用例介绍如下:
http{
# upstream 服务集群配置(默认为从上到下依次轮询)
upstream backend {
server 192.168.200.146:8081;
server 192.168.200.146:8082;
server 192.168.200.146:8083;
}
server {
listen 8080;
server_name localhost;
location /{
proxy_pass http://backend; #代理到服务集群
}
}
}
二. Vue项目部署(Nginx)
Vue前端项目打包后的dist文件为经压缩后的静态资源文件,内部仅含有一个index.html单页面应用(Vue的核心思想),但该页面无法被直接访问和运行(因为其含有很多路由转发、异步请求、动态解析等非静态服务),所以就需要我们将该dist静态资源部署到相应的资源服务器上进行管理。
Vue项目的部署方式主要包括SpringBoot内置部署、Tomcat部署和Nginx部署三种方式,我们这里以主流的Nginx部署为主(前后端分离,耦合性最低),部署过程分为后端服务器部署、前端静态资源部署、后端接口访问配置三个阶段。
1. 部署SpringBoot后端服务器
SpringBoot后端项目开发完成后通过package打包为jar包(注意修改mybatis文件的连接信息为云服务器上的mysql信息),然后将打包后的jar包上传至远端云服务器,通过nohup指令进行后台启动。
#nohup指令 后台启动jar包,日志信息输出到log.file文件
nohup java -jar babyshark-0.0.1-SNAPSHOT.jar > log.file 2>&1 &
#查看java进程
ps -aux | grep java
#关掉/杀死java进程
kill -9 pid
2. 部署Vue前端项目资源
Vue前端项目通过 npm run build 指令打包为dist静态资源文件,然后上传至远端云服务器。dist文件为Vue项目压缩后的静态资源文件,无法直接运行,因此需要借助静态资源服务器来管理运行即Nginx。云服务器上Nginx的配置内容如下(访问 http://公网IP 即可访问到Nginx服务管理的Vue项目):
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
#这里修改为你的dist文件位置
root /usr/local/weblog/dist;
index index.html index.htm;
#放置重复刷新空白问题
try_files $uri $uri/ /index.html;
}
#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;
}
}
}
3. 后端接口访问配置
在整个项目运行过程中,前端需要通过Axios来异步请求后端的业务接口,完成前后端分离的功能交互。参与这个过程的对象主要包括前端页面、Nginx服务器、后端服务器三个部分,在前端Axios请求中我们直接使用后端的内网IP/localhost都是访问不到后端接口的, 因为此时这个请求是由当前浏览器Web页面所在的主机直接向我们的后端服务器内网IP发出的(不要误解为由Nginx直接发出请求,Nginx服务器只负责将资源渲染返回给相应主机的浏览器,再由相应的浏览器主机发起Axios请求),二者不在一个内网段内自然是访问不到的,解决方法主要包括以下两种:
(1)直接访问后端接口公网地址
最简单直接的方法是前端Axios直接访问后端接口的公网IP地址。但是这样的弊端是会将后端的接口直接暴露在浏览器中,且云服务器需要开放相应的端口才能访问。这种解决方式比较生硬且给服务安全带来很大的威胁和隐患,黑客很容易越过前端直接对后端发起攻击。
//创建默认实例,Axios直接请求后端接口公网IP
const instance = axios.create({
baseURL:'http://公网IP:8080',
timeout:5000
})
(2)Nginx反向代理
为了解决第一个方式不安全的弊端,我们可以使用Nginx的反向代理。服务器只对外暴露前端的IP和接口,将Axios的后端接口请求引到Nginx监听服务上,然后由Nginx将后端请求代理转发到SpringBoot后端服务器上(Nginx服务与SpringBoot服务在同一个主机/网段内,可以直接通过内网/localhost访问)。
#1.Vue Axios配置
//创建默认实例
const instance = axios.create({
baseURL:'/api',
timeout:5000
})
#2.Nginx conf 反向代理配置
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
#这里修改为你的dist文件位置
root /usr/local/weblog/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
#后端接口反向代理配置
location /api/ {
#反向代理路径(Nginx可直接访问SpringBoot接口)
proxy_pass http://localhost:8080/;
}
#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;
}
}
}
4. 最终结果
个人博客地址,感谢关注:http://blog.dreamahead-resource.site