概述
nginx常用版本主要分为4大阵营
开源版本是最小的版本,只有一些基本功能,好处是开源免费。
后面的都加的有个自己的功能插件,但是收费。
我们学习阶段使用开源版本就行。
下载和安装
(1)去官网下载nginx的源码安装包,将软件安装包传到linux系统
(2)将安装包解压
tar -zxvf xxx.tar.gz
(3)进入解压目录,里边有一个configure的文件,那是一个安装脚本,可以直接执行它
./configure --prefix=/usr/local/nginx
–prefix参数可以指定我们软件安装的位置。
注:安装nginx需要保证linux系统中有gcc编译器、pcre库、zlib库,下面有相关安装方法:
安装gcc
yum install -y gcc
安装perl
yum install -y pcre pcre-devel
安装zlib库
yum install -y zlib zlib-devel
(4)最后,依次执行如下两个命令
make
make install
(5)安装完成后就会在/usr/local/目录下生成一个nginx目录。
启动与关闭
找到nginx的安装目录内的sbin目录,里边有个可执行文件“nginx”,运行如下命令可以启动和关闭nginx。
./nginx 启动nginx
./nginx -s stop 快速停止
./nginx -s quit 在关闭前完成已经接受的连接请求
./nginx -s reload 重新加载配置(重启)
常用参数:
-c 指定配置文件的位置,不配置会去默认的位置找
-t 测试配置文件语法是否正确(不运行)
启动nginx可以在浏览器访问一下
http://你的IP
访问出现如下页面即是启动成功
注:访问不成功可能是防火墙的问题,将防火墙关掉或者新建防火墙规则。
创建nginx服务,让它开机自启(了解)
在linux的/usr/lib/systemd/system/目录下创建nginx.service文件,在里面写上如下内容
[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
服务文件创建成功后,就可以使用“systemctl"命令控制nginx的启动和关闭了。
软件目录
nginx的安装目录内,主要有如下几个重要的目录:
- conf:配置文件,主配置文件为nginx.conf
- sbin:一些命令,里面只有一个nginx启动命令
- log:日志
- html:网页、静态的资源。我们访问的欢迎页(index.html)就放在这里面
- xxx_temp:放一些临时文件,不重要
运行原理
nginx启动会开启两个进程,master和worker,主要工作都是worker进程做的,worker也叫工作进程。
最小配置文件解析
打开conf目录中的配置文件nginx.conf,将一些注释去掉,如下是能启动nginx的最小配置文件
#启动nginx时工作进程数。一个CPU内核对应1个processes
worker_processes 1;
#事件驱动模块
events {
#每个工作进程的最大连接数
worker_connections 1024;
}
#http模块
http {
#引入别的配置文件。这里引入了mime.types文件,这个文件定义了许多返回类型和文件的对应关系(content-type)
include mime.types;
#默认的返回类型,如果mime.types定义的没有,就使用这个
default_type application/octet-stream;
#数据零拷贝。能加快文件的发送速度,减少复制的过程。
sendfile on;
#保持连接的超时时间
keepalive_timeout 65;
#server模块。一个server模块代表一个主机(虚拟主机)
server {
#监听的端口号
listen 80;
#主机名、域名
server_name 192.168.100.101;
#location后跟一个uri,如果访问的uri符合这个绑定的uri就会去它下面找资源
location / {
#主目录,所有资源会去主目录内找
root html;
#默认的欢迎页
index index.html index.htm;
}
#格式:error_page 错误码 请求路径。当服务器内部发生错误后,会发送对应的请求
error_page 500 502 503 504 /50x.html;
#当收到/50x.html请求时,去下面找
location = /50x.html {
#去这个目录中找50x.html
root html;
}
}
}
虚拟主机
虚拟主机,就是把一台物理服务器划分成多个“虚拟”的服务器,这样我们的一台物理服务器就可以当做多个服务器来使用,从而可以配置多个网站。Nginx提供虚拟主机的功能,就是为了让我们不需要安装多个Nginx,就可以运行多个域名不同的网站。
Nginx下,一个server标签就是一个虚拟主机。nginx的虚拟主机就是通过nginx.conf中server节点指定的,想要设置多个虚拟主机,配置多个server节点即可。
创建虚拟主机
虚拟主机技术可以在一台物理主机上模拟多台主机效果。举例模拟创建两台虚拟主机。
首先在服务器中创建两个目录server1和server2,每个目录代表一台虚拟主机,每个目录中都创建一个index.html,内容如下:
/server1/index.html
/server2/index.html
实现虚拟主机可以有如下两种方式:
监听不同端口
使每台虚拟主机监听不同的端口,配置文件内容如下
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#虚拟主机server1
server {
#监听80端口
listen 80;
server_name 192.168.100.101;
location / {
#修改目录
root /server1;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#虚拟主机server2
server {
#监听8080端口
listen 8080;
server_name 192.168.100.101;
location / {
#修改目录
root /server2;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
修改配置文件后重启nginx,在浏览器中访问
访问80端口
访问8080端口
访问不同端口就可以访问不同的主机。
设置不同的主机名
本地模拟需要修改windows的hosts文件,在hosts文件中添加两条映射。
IP地址都是我们nginx服务器的地址,但是有不同的域名。
再次修改nginx的配置文件,这次让它们监听的端口相同,但是主机名不同(主机名设置为域名)
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#虚拟主机server1
server {
listen 80;
#对应域名www.server1.com
server_name www.server1.com;
location / {
root /server1;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#虚拟主机server2
server {
listen 80;
#对应域名www.server2.com
server_name www.server2.com;
location / {
root /server2;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
在windows浏览器分别访问设置的不同域名
根据域名的不同去访问不同的虚拟主机。
注:多台虚拟主机的主机名和监听的端口号不能完全都相同,至少要有一个不一样。
server_name 匹配规则
(1)精准匹配
直接输入一个完整的域名或主机名
server_name www.server.com;
(2)匹配多个
支持匹配多个域名或主机,使用一个空格隔开
server_name www.server.com www.server2.com;
(3)通配符匹配
支持使用通配符“*”
#匹配所有以".server.com"结尾的域名
server_name *.server.com;
#匹配所有以"www.server."开始的域名
server_name www.server.*;
注:通配符“*”只支持头匹配和尾匹配,不能在中间
(4)正则匹配
正则使用"~"开始
server_name ~^www\.\w+\.com$;
反向代理
反向代理就是客户端(浏览器)将请求发送给反向代理服务器(nginx),然后代理服务器将请求转发给响应的后端服务器,并将后端服务器的响应返回给客户端,如上图。
在这个过程中,客户端对于后端服务器的信息是无感知的,nginx代理了后端服务器。
普通代理
代理的配置
在location模块下使用proxy_pass配置即可实现反向代理配置,满足location路径匹配后,就会将请求转发到proxy_pass配置的路径。
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 www.mypc.com;
location / {
#反向代理配置
proxy_pass http://www.baidu.com;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
注:proxy_pass和root配置二选一,配置了proxy_pass就不再需要root了。
负载均衡
在请求很多的情况下,通常会启用多个服务,将请求按照某种算法分散到这些服务器中,以缓解服务器压力。
nginx的负载均衡配置由upstream模块和proxy_pass配合使用。upstream模块用于定义需要负载均衡的后端服务组,通常由两个或以上的服务器url组成,proxy_pass指向配置的后端服务组。
基本负载均衡
基本负载均衡配置会将请求轮流分发到定义的后端服务组中,也就是轮询。
#中括号“[]”表示可选的配置
http {
#定义一个名为backend的后端服务组
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
# 配置健康检查(每 10 秒检查一次服务器状态,如果连续 3 次失败则标记为不健康,连续 2 次通过则标记为健康),只有健康的服务器才会被分发请求
[health_check interval=10s fails=3 passes=2];
}
server {
listen 80;
location / {
#负载均衡到名为backend的后端服务组
proxy_pass http://backend;
}
}
}
基于权重的负载均衡
在后端服务组中为每个url指定一个权重,权重高的分发的请求数量多。
http {
upstream backend {
#backend1接收3个请求时backend2会接收2个请求,同理backend3只会接收一个请求。也就是backend1会接收3倍于backend3的请求数量。
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
#健康检查
health_check interval=10s fails=3 passes=2
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
基于IP哈希的负载均衡
使用 IP 哈希可以确保同一个IP地址的客户端的请求始终分配到同一台服务器上。
http {
upstream backend {
#使用IP哈希算法分发请求
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
URL重写
使用rewrite关键字可以在转发请求时重写URL。
rewrite <regex> <replacement> [flag]
#regex-一个正则表达式,符合正则的请求URL将会被重写
#replacement-重写后的URL
#flag由如下四个选择:
#last-本条匹配结束后,继续向下匹配新的location;
#break-本条匹配完成后立即终止,跳向新的URL;
#redirect-返回302临时重定向,浏览器会显示重写后的URL;
#permanent-返回301永久重定向,浏览器会显示重写后的URL。
简单的URL重写
location / {
rewrite ^/page$ /newPage break;
proxy_pass http://192.168.0.108:3036;
}
上述配置会将“/page”请求重写为“/newPage”。
捕获路径中的变量
如果想要捕获路径中的值在重写后的URL中使用,可以使用小括号配合正则捕获路径变量,然后使用$1、$2…引用。
location / {
rewrite ^/page/([0-9]*)/([0-9]*)$ /newPage?p1=$1&p2=$2 break;
proxy_pass http://192.168.0.108:3036;
}
上述配置会将“/page/666/777”重写为“/newPage?p1=666&p2=777”。
处理请求和响应
nginx可以对http的请求和响应进行处理,然后再进行转发。
添加或修改请求头
在location 模块下使用”proxy_set_header“配置可以添加和修改请求头中的值。
proxy_set_header <自定义请求头> <值>;
简单的添加和修改
server {
listen 80;
server_name www.mypc.com;
location / {
proxy_pass http://192.168.242.1:3036;
#设置请求头
proxy_set_header X-Custom-Header 666;
proxy_set_header user-agent nginx;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
引用原始请求头的值
server {
listen 80;
server_name www.mypc.com;
location / {、
proxy_pass http://192.168.242.1:3036;
#添加一个新的请求头Host2,并引用原始请求的Host请求头
proxy_set_header Host2 $http_host;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
引用的请求头格式都满足$http_<header-name-in-lower-case-with-dashes-replaced-by-underscores>的模式。但是,如果你的请求头名称包含连字符(-),Nginx会自动将它们转换为下划线(_)来构造变量名。
防盗链配置
防盗链是一种保护网站资源不被其他网站未经授权而直接链接到其服务器上的措施。通过配置 Nginx,验证Referer请求头可以确保只有来自特定域名的请求才能访问你的资源。
#一、定义有效的引用站点
valid_referers none blocked server_names
*.example.com example.com
~\.google\. ~\.bing\. ~\.baidu\.;
#valid_referers 指令用于定义哪些引用是有效的。
#none 表示没有 Referer 头部;blocked 表示 Referer 头部被防火墙或代理服务器移除;
#server_names 表示直接访问服务器的域名;*.example.com 表示任何以 example.com 结尾的域名;~\.google\. 使用正则表达式匹配 Google 的引用。
#二、不满足引用站点则驳回请求
if ($invalid_referer) {
# 如果请求不是来自有效的引用站点,则返回 403 Forbidden 错误
return 403;
}
举例
server {
listen 80;
server_name www.mypc.com;
location / {
proxy_pass http://192.168.242.1:3036;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
# 防盗链配置,定义有效的引用站点
valid_referers none blocked server_names
*.mypc.com mypc.com
~\.google\. ~\.bing\. ~\.baidu\.;
#如果请求不是来自有效的引用站点,则返回 403 Forbidden 错误
if ($invalid_referer) {
return 403;
}
root html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
添加和删除响应头
使用add_header指令可以添加新的响应头,注意,这并不会修改原始的响应头,而是会添加一个新的响应头。使用方式和proxy_set_header指令一样。
add_header <自定义响应头> <值>;
proxy_hide_header指令可以删除后端响应的某个响应头。多个使用逗号分隔。
proxy_hide_header <响应头1>(,<响应头2>...);