文章目录
Nginx 是一个高性能的 Web 服务器和反向代理服务器,它广泛用于托管网站、服务 API 和负载均衡。1. Nginx安装
1. Linux安装Nginx
进入到/usr/local
目录下,执行命令:
yum install -y nginx
通过如下命令启动nginx服务
systemctl start nginx
通过如下命令,设置nginx开启自启动
systemctl enable nginx
nginx默认占用80端口。
访问ip:80
,可以看到如下页面
这个页面默认目录为/usr/share/nginx/html
。
2. Windows安装Nginx
官网下载nginx稳定版本:
- 启动nignx服务:解压下载的安装包,双击nginx.exe,会有一个黑色的弹窗一闪而过,启动成功。
- 停止nignx服务:任务管理器 -> 详细信息,找到 nginx.exe,右键,点击结束任务。
2. Nginx配置
2.1 配置文件简介
修改配置之前,一般我们都需要备份一下我们的配置文件,以防改错了。
Linux版本的nginx的配置文件在/etc/nginx
目录下,配置文件名称为nginx.conf
,Windows版本的nginx的配置文件在conf
目录下。nginx.conf.default
为nginx的默认配置文件,相当于一个初始文件的备份文件。
可以通过如下命令,删除配置文件中的注释以及换行。
grep -Ev '#|^$' nginx.conf > nginx.conf
去除多余内容后,剩下的内容如下:
worker_processes 1;
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 / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
目前我们可以删除第8行、第9行、17-20行的内容,只保留如下:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
}
这就是nginx的最小配置项。
修改保存配置文件后,我们想让配置文件生效,需要重启nginx服务。
systemctl restart nginx
ps -ef|grep nginx # 查看nginx进程
nginx -t # 检测配置文件是否存在错误
当工作进程出现问题或者被杀死后,nginx管理进程会自动创建新的工作进程。如果杀死nginx管理进程,相当于停止了nginx服务。
2.2 配置文件详解
最小配置详细配置
##
# 全局配置
##
user www-data; ## 配置 worker 进程的用户和组
worker_processes auto; ## 配置 worker 进程启动的数量,建议配置为 CPU 核心数
error_log logs/error.log; ## 全局错误日志
pid /run/nginx.pid; ## 设置记录主进程 ID 的文件
worker_rlimit_nofile 8192; ## 配置一个工作进程能够接受并发连接的最大数
##
# 工作模式及连接数上限
##
events {
# epoll 是多路复用 IO(I/O Multiplexing)中的一种方式,
# 仅用于 Linux 2.6 以上内核,可以大大提高 Nginx 性能
use epoll
# 单个后台 worker process 进程的最大并发链接数
# 并发总数 max_clients = worker_professes * worker_connections
worker_connections 4096; ## Defaule: 1024
# multi_accept on; ## 指明 worker 进程立刻接受新的连接
}
##
# http 模块
##
http {
##
# Basic Settings
##
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,
#以平衡磁盘与网络 I/O 处理速度,降低系统的 uptime.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; ## 连接超时时间
types_hash_max_size 2048; ## 指定散列类型表的最大大小
# server_tokens off;
# server_names_hash_bucket_size 64; # this seems to be required for some vhosts
# server_name_in_redirect off;
include /etc/nginx/mime.types; ## 设定 mine 类型
default_type application/octet-stream;
# 设定请求缓冲
client_header_buffer_size 128k; # 指定客户端请求头缓存大小,当请求头大于 1KB 时会用到该项
large_client_header_buffers 4 128k; # 最大数量和最大客户端请求头的大小
##
# SSL Settings
##
# 启用所有协议,禁用已废弃的不安全的SSL 2 和SSL 3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
# 让服务器选择要使用的算法套件
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log; ## 访问日志
error_log /var/log/nginx/error.log; ## 错误日志
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf; # 这个文件夹默认是空的
include /etc/nginx/sites-enabled/*; # 开启的 Server 服务配置
}
##
# mail 模块
##
mail {
# See sample authentication script at:
# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# auth_http localhost/auth.php;
# pop3_capabilities "TOP" "USER";
# imap_capabilities "IMAP4rev1" "UIDPLUS";
server {
listen localhost:110;
protocol pop3;
proxy on;
}
server {
listen localhost:143;
protocol imap;
proxy on;
}
}
2.3 路由匹配问题
location /api {
root /codewei;
index index.html index.htm;
}
当我们按照如上配置时。当请求 http://ip:81/api
时,Nginx会做以下几件事:
- 匹配到
location /api
块。 - 根据
root
指令,知道应该在文件系统的/codewei
目录下查找文件。 - 因为请求的是
/api
,所以Nginx会在/codewei
目录下查找名为api
的文件或目录。如果找到名为api
的目录,Nginx会进一步在这个目录中查找index
指令指定的文件(index.html
或index.htm
)。
如果我们的意图是让http://ip:81/api
直接访问/codewei
目录下的index.html
文件,而不是/codewei/api/index.html
,我们应该使用alias
指令而不是root
指令,如下所示:
location /api {
alias /codewei/; # 注意这里的斜杠,它表示/codewei目录
index index.html index.htm;
}
使用alias
指令后,Nginx就会知道/api
请求实际上应该对应到文件系统中的/codewei/
目录,而不是/codewei/api
目录。这样,当你访问http://ip:81/api
时,Nginx就会提供/codewei/
目录下的index.html
文件。
2.4 对于 root后的路径是否要以/结尾的问题
在Nginx的配置中,使用root
指令时,目录路径的末尾是否加/
(斜杠)是有区别的。这主要影响到Nginx如何拼接请求的路径和root
指定的目录路径。
如果你的root
指令后面没有加/
,Nginx会将其视为一个相对路径的起点,并将请求的URI路径完整地附加在这个起点后面。例如:
location /api {
root /codewei;
index index.html index.htm;
}
对于请求http://ip:81/api/some/path
,Nginx会在/codewei
目录下查找api/some/path
这个路径。注意,这里包括了api
部分,因为root
后面没有加/
。
然而,如果你的root
指令后面加了/
,Nginx会将其视为一个绝对路径的起点,并且只会将请求URI中location
匹配之后的部分附加在这个起点后面。例如:
location /api {
root /codewei/;
index index.html index.htm;
}
对于同样的请求http://ip:81/api/some/path
,Nginx现在会在/codewei/
目录下查找some/path
这个路径。注意,这里不包括api
部分,因为root
后面加了/
。
3. 部署SpringBoot+Vue
3.1 后端项目
后端仅一个Controller,无其他内容。
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*")
public class NginxController {
@GetMapping("/getName")
public String getName(){
return "小明";
}
@GetMapping("/getAgeById/{id}")
public String getAgeById(@PathVariable("id") Integer id){
return String.valueOf(id);
}
}
后端配置文件application.yaml
server:
port: 8080
使用maven build进行打包。
将打包好的jar包上传到服务器,使用nohup java -jar xxx.jar &
运行项目。
3.2 前端项目
前端页面
<template>
<div>
<button @click="getName">获取名字</button>
<button @click="getAgeById">根据ID获取年龄</button>
<div style="text-align: center;font-weight: 600;" v-cloak>{{result}}</div>
</div>
</template>
<script>
import {getAgeById, getName} from "@/api/user";
export default {
data() {
return {
result:""
}
},
methods: {
getName(){
getName().then((response) => {
this.result = response.data;
})
},
getAgeById(){
getAgeById(23).then((response) => {
this.result = response.data;
})
}
}
}
</script>
axios配置
import axios from "axios";
const request = (option) => {
const instance = axios.create({
baseURL: "/api", // 注意此处!
});
return instance(option);
};
export default request;
请求api
import request from '@/util/request'
export function getName() {
return request({
url: '/user/getName',
method: 'get'
})
}
export function getAgeById(id) {
return request({
url: '/user/getAgeById/'+ id,
method: 'get'
})
}
vue.config.js配置
module.exports = {
publicPath: '/',
outputDir: "dist",
devServer: {
port: 80,
proxy: {
'/api': {
target: "http://localhost:8080",
changOrigin: true,
ws: true,
secure: false,
pathRewrite: {
'^/api': ''
}
}
}
}
}
使用npm run build
进行打包。会生出一个dist目录。
3.3 nginx配置
将前端打包好的dist目录上传到服务器。
nginx配置
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80; # 访问 ip:80 即可访问
server_name localhost;
location / {
root /home/dist; # 刚刚打包好的dist的目录
index index.html index.htm;
}
location /api/ { # 注意 / 结尾
proxy_pass http://localhost:8080/; # 引文后端项目跑在同一个主机上,所以使用lcoalhost 注意 / 结尾
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
此时,我们访问http://ip:80
即可访问到前端项目。
4. Nginx各种代理配置
来源:https://blog.csdn.net/mingongge/article/details/139364019
4.1 基础配置说明
<pre data-index="18" class="set-code-show prettyprint" name="code"><code class="prism language-nginx has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"># 进程数量
worker_processes 1;
events {
# 最大连接数量
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre>
4.2 演示如何强制http跳转https
server {
listen 80;
server_name test.com;
# http强制跳转到https
rewrite ^(.*)$ https://$server_name$1 permanent;
}
4.3 演示如何配置微信支付的校验文件
server {
listen 80;
server_name localhost;
# 默认根路径
location / {
root index.html;
}
# 微信支付校验文件,可以直接配置访问名称
location ^~/MP_verify_2g3uEjrB5B2LIbNl.txt {
alias /home/MP_verify_2g3uEjrB5B2LIbNl.txt;
}
# 微信支付校验文件,也可以通过正则配置
location ~^/MP_verify_[a-zA-Z0-9]*\.(txt)$ {
root /home/;
rewrite ^/home/(.txt)$ /home/$1 last;
}
}
4.4 演示root和alias两种配置静态资源的区别
server {
listen 80;
server_name localhost;
# 用root方式,location中的路径会拼加到root的地址后面
# 请求路径为:http://localhost:8080/files/index.jpg 实际访问为:/home/files/index.jpg
location ~^/files/ {
root /home/;
index index.html index.htm;
}
# 用alias方式,location中的路径不会拼加到alias的地址后面
# 这请求路径为:http://localhost:8080/files/index.jpg 实际访问为:/home/index.jpg
location ~^/files/ {
alias /home/;
index index.html index.htm;
}
}
4.5 演示请求后台接口代理配置
server {
listen 8080;
server_name localhost;
#################### 第一种场景(代理地址不加斜杠) ####################
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/api/getUser
location ^~/api/ {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际指向为:http://127.0.0.1:8000/api/getUser
location ^~/api {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
#################### 第二种场景(代理地址+斜杠) ####################
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/getUser
location ^~/api/ {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000//getUser
location ^~/api {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
#################### 第三种场景(代理地址+后缀) ####################
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/user/getUser
location ^~/api {
proxy_pass http://127.0.0.1:8000/user;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/usergetUser
location ^~/api/ {
proxy_pass http://127.0.0.1:8000/user;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
#################### 第四种场景(代理地址+后缀+斜杠) ####################
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/user/getUser
location ^~/api/ {
proxy_pass http://127.0.0.1:8000/user/;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
# 请求路径为:http://127.0.0.1:8080/api/getUser 实际代理为:http://127.0.0.1:8000/user//getUser
location ^~/api {
proxy_pass http://127.0.0.1:8000/user/;
proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
}
}
4.6 演示前端项目如何部署nginx
server {
listen 8090;
server_name localhost;
# 默认访问
# 部署路径:/home/web/my_demo
# 访问路径为:http://localhost:8090/
location / {
try_files $uri $uri/ /index.html;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
root /home/web/my_demo/;
index index.html index.htm;
}
# 带前缀的访问
# 部署路径:/home/web/my_demo
# 访问路径为:http://localhost:8090/my_demo/
# 如果location路径最后没有配置斜杠,则浏览器输入访问地址后,路径最后会自动拼一个斜杠
location ^~/my_demo/ {
try_files $uri $uri/ /my_demo/index.html;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
root /home/web/;
index index.html index.htm;
}
}
}
5. Nginx常用命令
## 查看 Nginx 程序文件目录:/usr/sbin/nginx
$ ps -ef | grep nginx
## 查看 nginx.conf 配置文件目录:/etc/nginx/nginx.conf
$ nginx -t
$ vim /etc/nginx/nginx.conf
## 配置文件目录:/etc/nginx
## 虚拟主机配置文件目录:/etc/nginx/sites-available/
## 虚拟主机文件夹目录:/var/www/,详情可在 /etc/nginx/sites-available/ 中配置
## 默认网页文件目录:/usr/share/nginx/html
## 测试配置文件,只检查配置文件是否存在语法错误
$ nginx -t -c <path-to-nginx.conf>
$ sudo nginx -t -c /etc/nginx/nginx.conf
## 启动 Nginx 服务
$ nginx 安装目录 -c <path-to-nginx.conf>
$ sudo /etc/init.d/nginx start
## 停止 Nginx 服务
$ sudo /usr/sbin/nginx -s stop
## 重启 Nginx
$ sudo /usr/sbin/nginx -s reload # 0.8 版本之后的方法
$ kill -HUP pid # 向 master 进程发送信号从容地重启 Nginx,即服务不中断
$ sudo service nginx start
$ sudo service nginx stop
$ sudo service nginx restart
6. 正向代理、反向代理、负载均衡
6. 1正向代理
正向代理:内网服务器主动去请求外网的服务的一种行为
光看概念,可能有读者还是搞不明白:什么叫做“正向”,什么叫做“代理”,我们分别来理解一下这两个名词。
正向:相同的或一致的方向
代理:自己做不了的事情或者自己不打算做的事情,委托或依靠别人来完成。 借助解释,回归到nginx的概念,正向代理其实就是说客户端无法主动或者不打算完成主动去向某服务器发起请求,而是委托了nginx代理服务器去向服务器发起请求,并且获得处理结果,返回给客户端。
从下图可以看出:客户端向目标服务器发起的请求,是由代理服务器代替它向目标主机发起,得到结果之后,通过代理服务器返回给客户端。
正向代理的配置:
server {
#指定DNS服务器IP地址
resolver 114.114.114.114;
#指定代理端口
listen 8080;
location / {
#设定代理服务器的协议和地址(固定不变)
proxy_pass http://$http_host$request_uri;
}
}
正向代理的关键配置:
1.resolverDNS服务器IP地址
2.listen:主动发起请求的内网服务器端口
3.proxy_pass代理服务器的协议和地址
6. 2反向代理
反向代理:reverse proxy,是指用代理服务器来接受客户端发来的请求,然后将请求转发给内网中的上游服务器,上游服务器处理完之后,把结果通过nginx返回给客户端。
举个栗子:一个服务器的80端口只有一个,而服务器中可能有多个项目,如果A项目是端口是8081,B项目是8082,C项目是8083,假设指向该服务器的域名为www.xxx.com,此时访问B项目是www.xxx.com:8082,以此类推其它项目的URL也是要加上一个端口号,这样就很不美观了,这时我们把80端口给nginx服务器,给每个项目分配一个独立的子域名,如A项目是a.xxx.com,并且在nginx中设置每个项目的转发配置,然后对所有项目的访问都由nginx服务器接受,然后根据配置转发给不同的服务器处理。具体流程如下:
反向代理配置:
server {
#监听端口
listen 80;
#服务器名称,也就是客户端访问的域名地址
server_name a.xxx.com;
#nginx日志输出文件
access_log logs/nginx.access.log main;
#nginx错误日志输出文件
error_log logs/nginx.error.log;
root html;
index index.html index.htm index.php;
location / {
#被代理服务器的地址
proxy_pass http://localhost:8081;
#对发送给客户端的URL进行修改的操作
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
}
}
这样就可以通过a.xxx.com来访问a项目对应的网站了,而不需要带上难看的端口号。
反向代理的配置关键点是:
1.server_name:代表客户端向服务器发起请求时输入的域名
2.proxy_pass:代表源服务器的访问地址,也就是真正处理请求的服务器(localhost+端口号)。
6. 3负载均衡
负载均衡:将服务器接收到的请求按照规则分发的过程,称为负载均衡。负载均衡是反向代理的一种体现。
可能绝大部分人接触到的web项目,刚开始时都是一台服务器就搞定了,但当网站访问量越来越大时,单台服务器就扛不住了,这时候需要增加服务器做成集群来分担流量压力,而在架设这些服务器时,nginx就充当了接受流量和分流的作用了,当请求到nginx服务器时,nginx就可以根据设置好的负载信息,把请求分配到不同的服务器,服务器处理完毕后,nginx获取处理结果返回给客户端,这样,用nginx的反向代理,即可实现了负载均衡。
Nginx实现负载均衡有几种模式:
1.轮询:每个请求按时间顺序逐一分配到不同的后端服务器,也是nginx的默认模式。轮询模式的配置很简单,只需要把服务器列表加入到upstream模块中即可。
下面的配置是指:负载中有三台服务器,当请求到达时,nginx按照时间顺序把请求分配给三台服务器处理。
2.ip_hash:每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。3.url_hash:按访问url的hash结果来分配请求,相同的url固定转发到同一个后端服务器处理。
下面的配置是指:负载中有三台服务器,当请求到达时,nginx优先按照ip_hash的结果进行分配,也就是同一个IP的请求固定在某一台服务器上,其它则按时间顺序把请求分配给三台服务器处理。
而在每一种模式中,每一台服务器后面的可以携带的参数有:
- down: 当前服务器暂不参与负载
- weight: 权重,值越大,服务器的负载量越大。
- max_fails:允许请求失败的次数,默认为1。
- fail_timeout:max_fails次失败后暂停的时间。
- backup:备份机,只有其它所有的非backup机器down或者忙时才会请求backup机器。