Nginx
使用场景
1.静态资源服务,通过本地文件系统提供服务
2.反向代理服务,延伸出包括缓存,负载均衡
3.API服务 Openresty
一.简单请求和非简单请求
简单请求
请求方法是Head,get,post 三种之一
请求头不超过 Accept、Accept-Language、Content-Language、Last-Event-ID
Content-Type 只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain
简单请求会在头信息添加Origin字段直接发送,用来说明来自哪个源(协议+域名+端口)
如果服务器发现Origin 不在许可范围内,会返回一个正常的Http响应,浏览器取的回应之后发现头信息没有Access-Control-Allow-oRIGIN 就抛出一个错误XHR的 error事件
如果存在就会多出一个Access-Control- 开头的头信息字段
非简单请求
是对服务器有特殊要求的请求,比如请求方法书put delete 或者Content-Type 值为application/json 浏览器会在正式通信之前,发送一次HTTP预检测OPTIONS请求,先询问服务器 当前网页所在的域名是否在服务器的许可名单中,以及可以使用那些http请求方法和同信息,只有得到肯定的答复,浏览器才会发出正式的XHR请求
1.跨域
在浏览器上当前访问的网站向另一个网站发送请求获取数据的过程就是跨域请求。
跨域是浏览器的同源策略决定的,是一个重要的浏览器安全策略,用于限制一个 origin 的文档或者它加载的脚本与另一个源的资源进行交互,它能够帮助阻隔恶意文档,减少可能被攻击的媒介,可以使用 CORS 配置解除这个限制。
# 不同源的例子
http://example.com/app1 # 协议不同
https://example.com/app2
http://example.com # host 不同
http://www.example.com
http://myapp.example.com
http://example.com # 端口不同
http://example.com:8080
2.正向代理反向代理
正向代理 就是 客户端和NG在一起 ,服务端不知道谁是真正的客户端
反向代理就是 NG和服务都安在一起,客户端不知道谁是真正的服务端
3.负载均衡
分摊压力
4.动静分离
将动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力
一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。
使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。
5.操作
systemctl start firewalld # 开启防火墙
systemctl stop firewalld # 关闭防火墙
systemctl status firewalld # 查看防火墙开启状态,显示running则是正在运行
firewall-cmd --reload # 重启防火墙,永久打开端口需要reload一下
systemctl enbale nginx 开机启动
# 添加开启端口,--permanent表示永久打开,不加是临时打开重启之后失效
firewall-cmd --permanent --zone=public --add-port=8888/tcp
# 查看防火墙,添加的端口也可以看到
firewall-cmd --list-all
nginx -s reload
nginx -s reopen
nginx -s quit 等待工作进程处理完成后关闭
nginx -t -c <配置路径>
6.配置语法
main 全局
events 配置影响服务器或与用户的网络连接
http 配置代理,缓存,日志定义等大多数功能和第三方模块配置
upstream 配置后段服务器具体izhi, 负载军和配置不可或缺的一部分
server 配置虚拟主机的相关参数 一个http可以有多个server块
location
每条指令以;结尾 指令与参数之间以空格符号分割
# 注释 $使用变量
典型配置
user nginx; # 运行用户,默认即是nginx,可以不进行设置
worker_processes 1; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}
http { # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
# 设置日志模式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # Nginx访问日志存放位置
sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
include /etc/nginx/conf.d/*.conf; # 加载子配置项
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44;# 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
location 指令用于匹配uri 语法
location [ = | ~ | ~* | ^~] uri {
...
}
= 精确匹配,用于不含正则表达式的uri 如果匹配成功,不再进行后续的查找
^~ 用于不含正则表达式的uri钱,标识如果该符号后面的字符是最佳匹配,采用该柜则
~ 标识用该符号否面的正则去匹配路径 区分大小写
~* 用该符号后面的正则去匹配路径,不区分大小写,跟~ 优先级都比较低,如果有多个location的正则能匹配的话,则使用正则表达式最长的哪个
如果 uri 包含正则表达式,则必须要有 ~ 或 ~* 标志。
全局变量
全局变量名 功能
$host 请求信息中的 Host,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口
$request_method 客户端请求类型,如 GET、POST
$remote_addr 客户端的 IP 地址
$args 请求中的参数
$arg_PARAMETER GET 请求中变量名 PARAMETER 参数的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer...
$content_length 请求头中的 Content-length 字段
$http_user_agent 客户端agent信息
$http_cookie 客户端cookie信息
$remote_addr 客户端的IP地址
$remote_port 客户端的端口
$http_user_agent 客户端agent信息
$server_protocol 请求使用的协议,如 HTTP/1.0、HTTP/1.1
$server_addr 服务器地址
$server_name 服务器名称
$server_port 服务器的端口号
$scheme HTTP 方法(如http,https)
设置二级域名虚拟主机
配置反向代理
在 http模块中server块中得location /
增加proxy_pass
反向代理其他指令
proxy_set_header 将客户端请i去发送给后端服务器之前,更改来自客户端得请求头信息
proxy_connect_timeout 配置Nginx与后后端代理服务器尝试建立连接超时时间
proxy_reader_timeout:配置 Nginx 向后端服务器组发出 read 请求后,等待相应的超时时间;
proxy_send_timeout:配置 Nginx 向后端服务器组发出 write 请求后,等待相应的超时时间;
proxy_redirect :用于修改后端服务器返回的响应头中的 Location 和 Refresh。
使用反向代理解决跨域
location / {
proxy_pass
}
配置header解决跨域
server {
listen 80;
server_name be.sherlocked93.club;
add_header 'Access-Control-Allow-Origin'$http_origin; # 全局变量获得当前请求origin,带cookie的请求不支持*
add_header 'Access-Control-Allow-Credentials''true'; # 为 true 可带上 cookie
add_header 'Access-Control-Allow-Methods''GET, POST, OPTIONS'; # 允许请求方法
add_header 'Access-Control-Allow-Headers'$http_access_control_request_headers; # 允许请求的 header,可以为 *
add_header 'Access-Control-Expose-Headers''Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
add_header 'Content-Type''text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # 200 也可以
}
location / {
root /usr/share/nginx/html/be;
index index.html;
}
}
开启gzip压缩
gzip on; # 默认off,是否开启gzip
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
配置负载均衡
http {
upstream myserver {
# ip_hash; # ip_hash 方式
# fair; # fair 方式
server 127.0.0.1:8081; # 负载均衡目的服务地址
server 127.0.0.1:8080;
server 127.0.0.1:8082 weight=10; # weight 方式,不写默认为 1
}
server {
location / {
proxy_pass http://myserver;
proxy_connect_timeout 10;
}
}
}
负载方式
1.轮询
2weight 权重分配
3.ip_hash
4.fair 第三方 依赖nginx-upstram-fair
动静分离
server {
location /www/ {
root /data/;
index index.html index.htm;
}
location /image/ {
root /data/;
autoindex on;
}
}
配置高可用集群 双机热备
yum install keepalived -y
然后编辑 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定义一个外围检测机制,并在 vrrp_instance 中通过定义 track_script 来追踪脚本执行过程,实现节点转移:
global_defs{
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30// 上面都是邮件配置,没卵用
router_id LVS_DEVEL // 当前服务器名字,用hostname命令来查看
}
vrrp_script chk_maintainace { // 检测机制的脚本名称为chk_maintainace
script "[[ -e/etc/keepalived/down ]] && exit 1 || exit 0"// 可以是脚本路径或脚本命令
// script "/etc/keepalived/nginx_check.sh" // 比如这样的脚本路径
interval 2 // 每隔2秒检测一次
weight -20 // 当脚本执行成立,那么把当前服务器优先级改为-20
}
vrrp_instanceVI_1 { // 每一个vrrp_instance就是定义一个虚拟路由器
state MASTER // 主机为MASTER,备用机为BACKUP
interface eth0 // 网卡名字,可以从ifconfig中查找
virtual_router_id 51 // 虚拟路由的id号,一般小于255,主备机id需要一样
priority 100 // 优先级,master的优先级比backup的大
advert_int 1 // 默认心跳间隔
authentication { // 认证机制
auth_type PASS
auth_pass 1111 // 密码
}
virtual_ipaddress { // 虚拟地址vip
172.16.2.8
}
}
其中检测脚本 nginx_check.sh,这里提供一个:
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
/usr/sbin/nginx # 尝试重新启动nginx
sleep 2 # 睡眠2秒
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
killall keepalived # 启动失败,将keepalived服务杀死。将vip漂移到其它备份节点
fi
fi
复制一份到备份服务器,备份 Nginx 的配置要将 state 后改为 BACKUP,priority 改为比主机小。
设置完毕后各自 service keepalived start 启动,经过访问成功之后,可以把 Master 机的 keepalived 停掉,此时 Master 机就不再是主机了 service keepalived stop,看访问虚拟 IP 时是否能够自动切换到备机 ip addr。
再次启动 Master 的 keepalived,此时 vip 又变到了主机上。
server {
listen 80;
server_name fe.sherlocked93.club;
location / {
root /usr/share/nginx/html/pc;
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root /usr/share/nginx/html/mobile;
}
index index.html;
}
}
配置https
server {
listen 443 ssl http2 default_server; # SSL 访问端口号为 443
server_name sherlocked93.club; # 填写绑定证书的域名
ssl_certificate /etc/nginx/https/1_sherlocked93.club_bundle.crt; # 证书文件地址
ssl_certificate_key /etc/nginx/https/2_sherlocked93.club.key; # 私钥文件地址
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #请按照以下协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
add_header X-Frame-Options DENY; # 减少点击劫持
add_header X-Content-Type-Options nosniff; # 禁止服务器自动解析资源类型
add_header X-Xss-Protection 1;
静态服务
listen 80;
server_name static.sherlocked93.club;
charset utf-8; # 防止中文文件名乱码
location /download {
alias /usr/share/nginx/html/static; # 静态资源目录
autoindex on; # 开启静态资源列目录
autoindex_exact_size off; # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
autoindex_localtime off; # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
}
}
图片防盗链
server {
listen 80;
server_name *.sherlocked93.club;
# 图片防盗链
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked 192.168.0.2; # 只允许本机 IP 外链引用
if ($invalid_referer){
return 403;
}
}
}
请求过滤
# 非指定请求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
return 403;
}
location / {
# IP访问限制(只允许IP是 192.168.0.2 机器访问)
allow 192.168.0.2;
deny all;
root html;
index index.html index.htm;
}
HTTP转到https
server {
listen 80;
server_name www.sherlocked93.club;
# 单域名重定向
if ($host = 'www.sherlocked93.club'){
return 301 https://www.sherlocked93.club$request_uri;
}
# 全局非 https 协议时重定向
if ($scheme != 'https') {
return 301 https://$server_name$request_uri;
}
# 或者全部重定向
return 301 https://$server_name$request_uri;
# 以上配置选择自己需要的即可,不用全部加
}