文章目录
一、简介:
1、Nginx简介
Nginx是一款免费且开源的Web服务器项目,常用来做、Web服务器、反向代理服务器、负载均衡服务器。特点如下:
- 免费且开源:免费试用,开放源代码。
- 轻量级且模块化:消耗内存少、保留核心模块、不需要全部安装、支持第三方模块。
- 高性能:Nginx支持很高的并发 。
- 热部署:在不重启Web服务器时升级、或者添加新模块等。
2、常用四大发行版
Openresty:是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。
Tengine:是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。
二、Nginx编译安装:
1、Nginx编译安装
1、依赖环境安装
yum -y install pcre-devel pcre gcc gcc-c++ zlib zlib-devel openssl openssl-devel
# gcc: C语言编辑器 nginx是C语言编写的 所以需要C环境
# pcre: 支持正则表达式
# openssl: 支持HTTPS加密协议
# zlib: 支持数据包头压缩
2、编译安装
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar xf nginx-1.18.0.tar.gz -C /usr/src/
cd /usr/src/nginx-1.18.0/
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make && make install
3、启动
cd /usr/local/nginx/sbin/
./nginx
netstat -anput | grep 80
4、防火墙设置
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-service=http --add-service=https --permanent
firewall-cmd --reload
5、验证
浏览器访问 自己的IP地址即可!
2、Nginx目录结构
/usr/local/nginx # 服务安装目录
/usr/local/nginx/sbin # 服务主程序目录
/usr/local/nginx/sbin/nginx # 服务程序文件
/usr/local/nginx/conf # 服务主配置文件目录
/usr/local/nginx/logs/ # 服务日志文件目录
/usr/local/nginx/logs/nginx.pid # 服务pid文件
/usr/local/nginx/logs/error.log # 服务错误日志文件
/usr/local/nginx/logs/access.log # 服务访问日志文件
3、Nginx 相关命令
/usr/local/nginx/sbin/nginx # 启动nginx
/usr/local/nginx/sbin/nginx -v # 小写v查看nginx版本信息
/usr/local/nginx/sbin/nginx -V # 大写V除版本信息外还显示配置参数信息
/usr/local/nginx/sbin/nginx -t # 检查nginx配置文件是否正确
/usr/local/nginx/sbin/nginx -s reload # 重新加载nginx
/usr/local/nginx/sbin/nginx -s quit # 正常关闭nginx
/usr/local/nginx/sbin/nginx -s stop # 快速关闭nginx
quit 和 stop 的区别:
- quit:当nginx服务已经启动,想要停止服务可以使用quit信号正常停止服务,quit信号并不会立即停止 服务,而是先不接收新的请求,但是会先处理完已经接收的连接后在停止服务,这种停止的方式被称为 ”优雅 的停止“
- stop:当nginx服务已经启动,想要停止服务可以使用stop信号快速停止服务,stop信号会立即停止服 务,这种停止服务的方式被称为 ”暴力停止“
三、Nginx配置文件解析
1、最小配置
去除Nginx配置文件中的注释等内容 -r 支持正则 -i.bak备份
sed -r -i.bak '/(^$|^#|#)/d' nginx.conf
worker_processes 1; # worker工作进程数
events {
worker_connections 1024; # 每个worker进程可以创建的连接数
}
http {
include mime.types; # 解析类型定义
default_type application/octet-stream; # 默认解析类型
sendfile on; # 减少Copy的过程
keepalive_timeout 65; # 保持连接超时时间
server { # 虚拟主机 vhost
listen 80; # 监听端口号
server_name localhost; # 主机名、域名
location / { # 根据规则匹配URL
root html; # 网页主目录 nginx根目录中的html
index index.html index.htm; # 默认页
}
error_page 500 502 503 504 /50x.html; # 错误网页指定
location = /50x.html {
root html;
}
}
}
2、虚拟主机
原本一台服务器只能对应一个站点、通过虚拟主机技术可以虚拟化多个站点对外提供服务。
每一段 server 中就是一个虚拟主机 如下:
server {
.. ..
}
实验:通过不同端口 设置多实例虚拟主机
创建不同的 index.html文件
mkdir /www
cd /www/
mkdir www video
echo "This is the www site." > /www/www/index.html
echo "This is the video site." > /www/video/index.html
http {
.. ..
server {
listen 80;
server_name localhost;
location / {
root /www/www; # 设置80端口网页主目录
index index.html index.htm;
}
}
server {
listen 88;
server_name localhost;
location / {
root /www/video; # 设置88端口网页主目录
index index.html index.htm;
}
}
}
/usr/local/nginx/sbin/nginx -s reload
测试:
curl 127.0.0.1
This is the www site.
curl 127.0.0.1:88
This is the video site.
3、匹配正则表达式
= # 开头表示精确匹配
~ # 区分大小写匹配
~* # 不区分大小写匹配
!~和!~* # 分别为区分大小写不匹配及不区分大小写不匹配的正则
^ # 以什么字符开头
$ # 以什么字符结尾
^~ # 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可
* # 任意字符
/ # 通用匹配,任何请求都会匹配到
举例:
通用匹配 任何请求都会匹配到
location / {
}
严格区分大小写,匹配.php结尾
location ~ \.php$ {
fastcgi_pass http://127.0.0.1:9000;
}
严格区分大小写,匹配.jsp结尾
location ~ \.jsp$ {
proxy_pass http://127.0.0.1:8080;
}
不区分大小写匹配
location ~* "\.(sql|bak|tgz|tar.gz|.git)$ {
default_type text/html;
return 403 "启用访问控制";
}
四、Nginx反向代理
1、理论
反向代理 记住 proxy_pass 一个词即可
反向代理的工作原理是,代理服务器来接受客户端的网络访问连接请求,然后服务器将请求有策略的转发给网络中实际工作的业务服务器,并将从业务服务器处理的结果,返回给网络上发起连接请求的客户端。
2、实践:Nginx反代代理Tomcat
1、部署安装Tomcat (两台同步操作)
安装JDK环境 并验证
yum install -y java-1.8.0-openjdk-devel.x86_64
java -version
下载Tomcat 并解压启动
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.62/bin/apache-tomcat-9.0.62.tar.gz --no-check-certificate
tar xf apache-tomcat-9.0.62.tar.gz -C /usr/local/
cd /usr/local/apache-tomcat-9.0.62/bin/
./startup.sh
ps -aux |grep java
防火墙配置
# 开启8080端口
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
# 开启8081端口
firewall-cmd --add-port=8081/tcp --permanent
firewall-cmd --reload
2、更改其中一台的端口号为 8081
cd /usr/local/apache-tomcat-9.0.62/conf/
vim server.xml
.. ..
<Connector port="8081" protocol="HTTP/1.1"
重启 Tomcat
./shutdown.sh
./startup.sh
netstat -anput |grep 8081
3、插入不同的页面
# 101 操作
mv /usr/local/apache-tomcat-9.0.62/webapps/ROOT/index.jsp{,.bak}
cd /usr/local/apache-tomcat-9.0.62/webapps/ROOT
echo "This is 101" > index.jsp
# 105 操作
mv /usr/local/apache-tomcat-9.0.62/webapps/ROOT/index.jsp{,.bak}
cd /usr/local/apache-tomcat-9.0.62/webapps/ROOT
echo "This is 105" > index.jsp
测试
curl 10.10.14.101:8081
This is 101
curl 10.10.14.105:8080
This is 105
4、Nginx 反代配置
http {
.. ..
server {
listen 8888;
server_name 10.10.14.100;
location = /8080/ {
proxy_pass http://10.10.14.105:8080/;
}
location = /8081/ {
proxy_pass http://10.10.14.101:8081/;
}
}
}
验证
curl 10.10.14.100:8888/8080/
This is 105
curl 10.10.14.100:8888/8081/
This is 101
五、Nginx负载均衡
负载均衡是基于 反向代理之上的 需要配合proxy_pass一起来使用,可以通过配置负载均衡策略 将请求转发到 后端集群中。
所谓的集群定义 是多台服务器提供相同服务,在客户端开来好像就只有一台服务器。
1、实践:Nginx负载均衡Tomcat
1、配置Tomcat 参考 四、Nginx反向代理
最终效果如下:
curl 10.10.14.101:8080
This is 101
curl 10.10.14.105:8080
This is 105
2、Nginx 配置
upstream 负载均衡配置 需要在http 字段下定义
http {
.. ..
upstream tomcat {
server 10.10.14.101:8080 weight=8;
server 10.10.14.105:8080 weight=2;
# server 10.10.14.101:8080 weight=8 down;
# server 10.10.14.105:8080 weight=2 backup;
}
.. ..
}
weight 权重值 此值越高 被分配的优先级也就越高
down 不使用此服务器
backup 备份服务器 当没有一台可以提供服务时自动启动
虚拟主机配置:
http {
.. ..
server {
listen 8888;
server_name localhost;
location / {
proxy_pass http://tomcat;
# 当使用proxy_pass 就需要注释掉下面内容
# root /www/www;
# index index.html index.htm;
}
}
}
3、防火墙配置
在外网不能访问后端Tomcat 只能通过Nginx访问 如下图:
Tomcat服务器上配置防火墙:
systemctl start firewalld.service
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.10.14.100" port protocol="tcp" port="8080" accept"
firewall-cmd --reload
移除规则:
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="10.10.14.100" port protocol="tcp" port="8080" accept"
firewall-cmd --reload
4、重启Nginx并验证
curl 10.10.14.100:8888
This is 101
curl 10.10.14.100:8888
This is 105
2、负载均衡策略
目前为止 内置策略有3中 分别是:轮询策略、加权策略和ip_hash策略,默认使用轮询策略。
1、轮询策略
默认使用 轮询策略 逐一转发 适用于无状态请求。
2、加权策略(weight)
设置优先级 weight的大小和访问率成正比。
3、ip_hash策略
根据客户端ip地址转发同一台服务器,可以保持回话。
4、least_conn
最少连接访问。
5、url_hash
根据用户访问url定向转发请求。
六、Nginx + Keepalived 高可用
1、环境说明
环境:
IP地址 | 说明 | 备注 |
---|---|---|
10.10.14.100 | Nginx_Master节点 | Master和Backup配置文件保持一致 |
10.10.14.102 | Nginx_Backup节点 | Master和Backup配置文件保持一致 |
10.10.14.105 | Tomcat 节点1 | |
10.10.14.101 | Tomcat 节点2 |
2、实践
1、Nginx_Master节点 和 Nginx_Salve节点 配置保持一致 nginx配置文件如下
http {
.. ..
upstream tomcat {
server 10.10.14.101:8080;
server 10.10.14.105:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcat;
}
}
.. ..
}
2、keepalived 安装配置(两台Nginx 都需要操作)
yum -y install openssl-devel libnl libnl-devel libnfnetlink-devel
wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz --no-check-certificate
tar zxf keepalived-2.0.20.tar.gz
cd keepalived-2.0.20/
./configure --sysconf=/etc
make && make install
# --sysconf 指定配置文件路径
3、Master keepalived配置:
[root@nginx1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id 111
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.14.200
}
}
4、Slave keepalived配置:
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id 102
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 50
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.14.200
}
}
5、启动验证
systemctl restart keepalived.service
ip a
# 配置正确应该 Master上可以看到200IP地址 Backup则不能
# 在Master上停止keepalived 看VIP是否可以票到Backup主机上
6、防止脑裂配置
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
7、 监控脚本
监控本地Nginx是否正常 如果不正常 则停止keepalived
cat keep_nginx.sh
#!/bin/bash
if ! (which killall);then
(yum install psmisc -y) &>/dev/null
fi
killall -0 nginx
if [ $? -ne 0 ];then
systemctl stop keepalived
fi
# killall -0 nginx: 判断Nginx进程是否存在 存在则返回0
添加脚本追踪模块到keepalived配置文件
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id 111
}
vrrp_script keep_nginx.sh {
script "/root/keep_nginx.sh"
interval 2
weight 5
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.14.200
}
track_script {
keep_nginx.sh
}
}
七、Nginx证书认证
1、SSL证书配置
# CA:证书颁发机构
# RA:证书注册机构
证书配置:
mkdir /usr/local/nginx/ssl_key
cd /usr/local/nginx/ssl_key
创建私钥:
[root@loaclhost ssl_key]# openssl genrsa -idea -out server.key 2048
Generating RSA private key, 2048 bit long modulus
......................................+++
.....+++
e is 65537 (0x10001)
Enter pass phrase for server.key: # 密码
Verifying - Enter pass phrase for server.key: # 密码
生成证书 去除私钥密码:
openssl req -days 3650 -x509 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
ls /usr/local/nginx/ssl_key
server.crt server.key
Nginx配置:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/ssl_key/server.crt; # 指定证书位置
ssl_certificate_key /usr/local/nginx/ssl_key/server.key; # 指定私钥位置
ssl_session_timeout 5m;
}
防火墙配置:
firewall-cmd --add-service=https --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
启动测试:
echo "Test Service SSL" > html/index.html
nginx -t
nginx
浏览器访问:https://NginxIP
若涉及到本地域名等信息需要修改hosts文件:C:\Windows\System32\drivers\etc\hosts
- 格式:域名 IP地址
2、rewrite地址重写
server {
listen 80;
server_name https.benet.com;
# rewrite .* https://https.benet.com; #重定向任选其一
# rewrite .* https://$host$request_uri redirect;
# rewrite .* https://$server_name$request_uri redirect;
rewrite .* https://$server_name$1 redirect;
}
八、Nginx平滑升级
1、Nginx平滑升级原理
一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块。
Nginx平滑升级其原理简单概括:
- (1)在不停掉老进程的情况下,启动新进程。
- (2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
- (3)新进程接受新请求。
- (4)老进程处理完所有请求,关闭所有连接后,停止。
信号说明:
信号 | nginx内置shell | 说明 |
---|---|---|
HUP | nginx -s reload | 重载配置文件 |
USR1 | nginx -s reopen | 重新打开日志文件,配置mv,用做日志切割 |
USR2 | - | 热升级nginx程序 |
WINCH | - | 优雅的关闭相关的worker进程 |
QUIT | nginx -s squit | 优雅的停止nginx |
TERM,INT | nginx -s stop | 立即停止nginx |
2、实践:1.16版本 升级到 1.18版本
nginx -v
nginx version: nginx/1.16.1
按照原来的编译参数安装 nginx 的方法进行安装,只需要到 make,千万不要 make install 。如果make install 会将原来的配置文件覆盖
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar zxvf nginx-1.18.0.tar.gz -C /usr/local/src
cd /usr/local/src/nginx-1.18.0
./configure --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
make
备份替换nginx命令:
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date +%F)
cp /usr/local/src/nginx-1.18.0/objs/nginx /usr/local/nginx/sbin/
测试新版本:
/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -v
查找nginx.pid文件位置
find / -name nginx.pid
/usr/local/nginx/logs/nginx.pid
发送平滑迁移信号 USR2: 启动新的主进程,实现热升级
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
发送WINCH信号给旧版主进程,旧版主进程就开始从容关闭
kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
3、升级失败 回滚操作
1、替换原来的 nginx命令
cd /usr/local/nginx/sbin/
mv nginx_2022-03-21 nginx
2、kill -HUP 旧版本的Master进程号
//不重载 配置文件下 启动旧的worker进程
kill -HUP `cat /usr/local/nginx/logs/nginx.pid.oldbin`
3、kill -USR2 新版本的主进程号
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
4、kill -WINCH 新版本的主进程号
kill -WINCH `cat /usr/local/nginx/logs/nginx.pid`
4、遇到问题
**问题:**执行完成 “发送平滑迁移信号 USR2” 没有出现新的Master进程信息
查看日志 报错内容为: 大致意思是 找不到 nginx 目录
execve() failed while executing new binary process "nginx" (2: No such file or directory)
原因: Nginx平滑升级是根据环境变量来进行的 ,找不到 nginx目录 是因为上次启动nginx不是 使用完全路径启动的 而环境变量中并没有 nginx这个目录 所以导致 这个问题!
**解决:**使用正确的启动方法
/usr/local/nginx/sbin/nginx
九、Nginx 优化方案
十、扩展
1、网站返回码
200 # 请求成功
201 # 上传文件成功
301 # 永久重定向(redirect)
302,307 # 临时重定向(redirect)
304 # 浏览器缓存
403 # 请求不到首页,没有权限
404 # 请求的资源在前端查明不存在
405 # 请求方法不支持
500 # 服务器的内部错误,程序错误
502 # 请求的资源前端有记录指向后端数据库,却找不到后端资源
503 # 服务暂时不可用
504 # 请求超时
2、URL和URI的区别
URL:统一资源定位符
格式:https://www.baidu.com/?tn=98010089_dg&ch=12
URL和URI的区别:
URI:可以理解成一个网站的首页
URL:可以理解成资源的具体路径
3、F12网络返回参数
General(大致信息):
Request URL: http://10.10.14.100/index.html # 请求的URL地址
Request Method: GET # 请求的方法
Status Code: 304 OK # 状态码
Remote Address: 10.10.14.100:80 # 请求地址(ipv4/ipv6)
Referrer Policy: no-referrer-when-downgrade # 降级(从https降级到http)
Request Headers(请求头部信息):
Accept: text/html # 请求的类型
Accept-Encoding: gzip, deflate, br # 是否进行压缩
Accept-Language: zh-CN,zh;q=0.9 # 请求的语言
Connection: keep-alive # TCP长连接
cache-control:max-age=0 # 缓存时间
Cookie: # 客户端缓存,用户密码等网站信息
Host:www.baidu.com/ # 请求的域名
Upgrade-Insecure-Requests: 1 # 启用升级https访问
User-Agent: Mozilla/5.0 # 客户端浏览器(可以理解xxx浏览器是基于什么内核开发出开的)
Response Headers(服务器响应头部信息):
Cache-Control: private # 缓存类型非公开(公开:pubLic)
Connection: keep-alive # 长连接
Content-Encoding: gzip # 压缩格式gzip
Content-Type: text/html;charset=utf-8 # 文档类型
Date: Sat, 14 Mar 2020 08:48:02 GMT # 响应时间
Expires: Sat, 14 Apr 2022 08:47:42 GMT # 失效时间
Server: BWS/1.1 # 网站服务器软件
status:200 # 状态码
4、curl 常用测试参数
-I 参数: 只显示响应内容
curl -I 127.0.0.1:8080
HTTP/1.1 200
Set-Cookie: JSESSIONID=CA2EC2BDA2C9E6A0BE3EB87FDEEFA8FA; Path=/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Sat, 09 Apr 2022 06:27:19 GMT
-i 参数:显示响应内容 + 整体内容
curl -i 127.0.0.1:8080