Nginx
nginx
nginx火的原因
一个线程内程序交替执行 select、poll、epoll select: 1)能够监视文件描述符的数量存在最大限制 2)线性扫描效率低 epoll: linux内核2.6以后对select进行的优化 1)每当FD就绪采用系统的回调函数将FD放入、效率高 2)最大连接数无限制
1)内置功能模块少 2)代码模块化 之所以轻量级,就是因位内置少,但是官方有很多插件
worker进程和cpu绑定,减少cpu切换的cache miss
为什么nginx处理静态文件有优势呢? 因为当请求到来时,一般是 file -----> kernol space ---> user space | socket <----kernol space<-----user space 而是直接 file -----> kernol space | socket <----kernol space
Mainline version 开发版
Stable version 稳定版
Legacy version 历史版本
安装方式
方式一:
wget http://nginx.org/download/nginx-1.14.1.tar.gz tar zxvf nginx-1.14.1.tar.gz cd nginx-1.14.1 yum -y install zlib zlib-devel yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake yum -y install wget httpd-tools vim ./configure --prefix=/usr/local/nginx make && make install
方式二(官方推荐):
vim /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1
yum list |grep nginx

文件所在路径
操作系统centos7.2
yum ------->安装的rpm包 rpm -ql nginx 已经安装的服务的一些配置文件的所在目录
| 路径 | 类型 | 作用 |
| /usr/lib/systemd/system/nginx-debug.service | 配置文件 |
用于配置出系统 守护进程管理器 管理方式 |
| /usr/lib/systemd/system/nginx.service | ||
| /etc/sysconfig/nginx | ||
| /etc/sysconfig/nginx-debug | ||
| /etc/nginx/nginx.conf |
nginx的主配置文件 |
|
| /etc/nginx/conf.d/default.conf | ||
| /etc/nginx/fastcgi_params | php专用 | |
| /etc/nginx/uwsgi_params | ||
| /etc/nginx/scgi_params | ||
| /etc/logrotate.d/nginx | nginx日志轮转 | |
| /etc/nginx/mime.types | 设置Content-type与扩展名的关系 | |
|
/etc/nginx/koi-utf /etc/nginx/modules /usr/lib64/nginx |
||
nginx -v 版本 nginx -V 编译时的一些信息
# 安装目的目录或路径
--prefix=/etc/nginx
--sbin-path=/usr/sbin/nginx
--modules-path=/usr/lib64/nginx/modules
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--ock-path=/var/run/nginx.lock
# 安装编译的参数 (执行对应模块式,Nginx所保留的临时性文件)
--http-client-body-temp-path=/var/cache/nginx/client-temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx 设定Nginx进程启动的用户和组用户
--group=nginx
--with-cc-opt=parameters 设置额外的参数将被添加到CFLAGS变量
(存入一些编译过程中优化的参数;比如说我们nginx使用的select,在这里可配置最大FD数)
--with-ld-opt=parameters 设置附加的参数,链接系统库 例如pcre
配置语法
yum install curl curl http://www.baidu.com 拿到返回的字符串
user 设置nginx服务的系统使用用户
worker_processes 工作进程数
error_log nginx错误日志
pid nginx服务启动时候pid
events worker_connections 每个进程允许最大连接数
最大65535,一般10000
use 工作进程数
nginx 日志格式参数 :可以分为3种 1)http请求变量 arg_PARAMETER、http_HEADER、sent_http_HEADER 在配置时需, - 变成_ 大写变小写 nginx -t -c /etc/nginx/nginx.conf 检查配置文件是否正确, 路径检查 2)内置变量 因为比较多,看官网 http://nginx.org/en/docs/http/ngx_http_core_module.html#var_status 3)自定义变量
信号量
nginx的信号量: # kill -INT master的PID TERM,INT 紧急杀掉,轻易不要用 nginx -s stop QUIT 优雅的关闭,请求完毕后杀 nginx -s quit HUP 重读配置文件,开启新的worker,杀死旧的worker nginx -s reload USE1 重读日志,在日志按月、日分割时有用 nginx -s reopen 实际在linux里一个文件是一个inode;名字只是表象罢了; 当日志备份时mv **.log **.log.bat不行,因为此文件一直在被nginx打开,就算改了名字依然指向对应的内存空间;就算删了也不管用
(文件系统的特殊性,一直向对应的inode写数据,文件名无关) --->备份1 mv **.log **.log.bat ;2 kill -USE1 进程pid USE2 平滑的升级, WINCH 和USE2配合使用,优雅的关闭旧的进程 nginx -t 测试配置是否正确
日志的定时切割 需要shell #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 logs/access.log main; date -s '2018-11-16 08:45:30' clock -w ------->写shell脚本runlof.sh #!/bin/shell LOGPATH=/usr/local/nginx/logs/access.log BASEPATH=/usr/local/nginx/bak/$(date -d yesterday +"%Y%m") mkdir -p $BASEPATH bak=$BASEPATH/$(date -d yesterday +"%d%H%M").access.log mv $LOGPATH $bak touch $LOGPATH kill -USE1 `cat /usr/local/nginx/logs/nginx.pid` # 分 时 日 月 周 # 创建定时任务 crontab -e * * */1 * * sh /usr/local/nginx/runlog.sh
模块
1)官方
源码包内包含的 以及不包含但官方支持的模块
2)第三方
--with-http_stub_status_module 展示nginx当前连接的一个状态 syntax;stub_status; Context;server,location location /xxx{ stub_status; }
--with-http_random_index_module 主目录中选择一个随机主页 但不包括以。开头的隐藏文件
Syntax: random_index on|off;
Default: random_index off;
Context: location
location /{
root /opt/ap/code;
random_index on;
}
--with-http_sub_module s--->c HTTP内容替换 ()
Syntax : sub_filter string replacement; Default : -- Context :http,server,location
location / {
root /opt/app/code;
index index.html index.htm
sub_filter '<a>imooc</a>' '<a>IMOOC</a>'
}
Syntax :sub_filter_last_modified on|off;
Default :sub_filter_last_modified off;
Context :http,server,location
# last_modified 校验服务端返回数据较上一次是否发生变换;请求头;缓存;
Syntax :sub_filter_once on|off; Default :sub_filter_once on; # 只匹配第一个/指定的内容都进行一次匹配 Context:http,server,location
limit_conn_module 链接频率限制 limit_req_module 请求频率限制 区别:连接 请求上不同 http1.0 TCP不能复用 http1.1 顺序性tcp复用 http2.0 多路复用tcp复用 http请求建立在一次tcp连接基础上 一次tcp请求至少产生一次http请求 Systax :limit_conn_zone key zone=name:size; Default :-- Context :http Systax : limit_conn zone number; Default :-- Context : http,server,location
Systax : limit_req_zone key zone=name:size rate=rate;
Default :--
Context : http
Systax : limit_req zone key zone=name [burst=number] [nodelay];
Default :--
Context : http,server,location
limit_conn_zone $binanry_remote_addr zone=conn_zone:1m; limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
limit_conn conn_zone 1;
limit_req zone=req_zome burst=3 nodelay; 超出限制的请求,会有3个请求,在下一秒执行
limit_req
精度的限制,连接限制-请求限制,多次请求可以建立在一次的连接基础上
yum install htppd -y
ab -n 40 -c 20 http://192.162.22.150/1.html
访问控制
基于ip的访问控制 http_access_module
Syntax :allow address |CIDR|unix:|all; Default :-- Context :http,server,location,limit_except
--------------------------------------------------
Syntax : deny address |CIDR|unix:|all;
Default :--
Context :http,server,location,limit_except
--------------------------------------------------
location ~ ^/admin.html {
root /opt/app/code;
allow 222.128.189.0/24;
deny all;
index index.html,index.htm;
}
方式一: http_x_forwarded_for = Client IP, Proxy(1) IP,Proxy(2) IP,..
局限; x_forwarded_for 是一个协议要求的,但不是强制的;代理厂商并一定会照做,还存在被修改的可能性,
方式二;结合geo模块
方式三、通过http自定义变量传递
再头信息里自定义一个我们规定的http的变量,联系上一层的设备,把客户端remote_addr的信息携带到我们规定变量里,
一层一层的携带到我们后端,既能避免x_forwarded_for 被改写,也能在后端准确的读到ip
基于用户的信任登录 http_auth_basic_module
局限性:当用户使用代理访问,remote_addr显示的是代理的IP,并不是真正的客户所使用的IP
Syntax :auth_basic string |off; # string 即表示了开启,也可以显示在前端 Default :auth_basic off; Context :http,server,location,limit_except
Syntax :auth_basic_user_file file; # 路径 Default :-- Context :http,server,location,limit_except
# comment name1:password1 name2:password2:comment name3:password3
提供了htpasswd加密方式 一般有 yum install httpd-tools -y
htpasswd -c ./auth_conf zhangsan
new password: *****
zhangsan:$apr1$pIH0Y1zJ$yUzMeK2su7LihULhqcPta1c
相同密码--->加密后不同
location ~ ^/admin.html{
root /opt/app/code;
auth_basic "Auth access test! input your password!";
auth_basic_user_file /etc/nginx/auth_conf;
index index.html index.htm;
}
再访问时,会提示要输入用户名和密码
局限性:
- 用户信息依赖文件方式
- 操作管理机械,效率低下
解决方案;
- nginx结合LUA实现高效验证
- nginx和LDAP打通,利用nginx-auth-ldap模块,yum安装不自带
proxy_set_header Host $http_host;
proxy_set_header X-Readl-Ip $remoter_addr;
静态资源
处理静态文件的优势讲解
Syntax : sendfile on |off; Default : sendfile off; Context : http,server,location,if in location 引读: --with-file-aio异步文件读取 目前效果不是特别好
Syntax :tcp_nopush on|off;
Default :tcp_nopush off;
Context :http,server,location
资源打包发送(),对报文的处理,提高了网络的传输速度,(推荐大文件)
作用:sendfile 开启的情况下,提高网络包的传输效率
Syntax :tcp_nodelay on|off;
Default :tcp_nodelay on;
Context :http,server,location
数据包不等待,实时性发送
作用: 在keep-alive连接下,提高网络包的传输实时性
Syntax : gzip on|off; Default :gzip off; Context :http,server,location,if in location
Syntax :gzip_comp_level level;
Default :gzip_comp_level 1;
Context :http,server,location
Syntax : gzip_http_version 1.0|1.1; Default : gzip_http_version 1.1; Context :http,server,location
http_gzip_static_module 预读gzip功能
Syntax : gzip_static on;
手动压缩 gzip ./test.img 会生成一个test.img.gz,原文件不存在
浏览器缓存 校验过期机制
- 校验是否过期 1.0 Expires、1.1Cache-Control(max-age) 依然会发请求
- 协议中Etag头信息教研 Etag (优先校验, 一串字符串)
- Last-Modified头信息教研 Last-Modified

nginx相关设置
Syntax : expires [modified] time; Default : expires off; Context : http,server,location,if in location
状态码304,数据从缓存中获取的。
nginx的csrf
Syntax : add_header name value [always]; Default : -- Context : http,server,location,if inlocation
add_header Access-Control-Allow-Origin http://www.jesonc.com;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
防盗链;
希望规矩的用户,合法的用户访问,
大部分没用的用户来访问,势必会对系统性能和请求造成了一定的损耗
目的:防止资源被盗用
首要方式:区别哪些请求是非正常的用户请求
基于http_refer防盗链配置模块
Syntax :valid_referers none | blocked |server_names|string;
Default :--
Context :server,location
location ~.*\.(jpg|gif|png)${
valid_referers none blocked 192.168.0.1 ~/google\./;
if ($valid_referer) {
retutrn 403;
}
root /opt/app/code/images;
}

反向代理
正向代理 与反向代理的区别:
区别在于代理的对象不一样
正向代理 代理的对象是 客户端
反向代理 代理的对象是 服务端
Syntax : proxy_pass URL; Default : -- Context :location,if in location,limit_except
http://localhost:8000/uri/ https://192.168.1.1:8000/uri/ http://unix:/tmp/backend.socket:/uri/;
正向代理
resolver 8.8.8.8; # 谷歌的dns服务器 locaion / { proxy_pass http://$http_host$request_uri; }
反向代理 : 通过80端口去访问其他端口
一个server代表一个虚拟主机
server{
listen 80;
server_name localhoost www.shuoiliu.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
缓冲区 Syntax :proxy_buffering on|off; Default :proxy_buffering on; Context :http,server,location 扩展 :proxy_buffer_size、proxy_buffers、proxy_busy_buffers_size
跳转重定向 Syntax :proxy_redirect default; proxy_redorect off;proxy_redirect redirect replacement; Default :proxy_redirect default; Context :http,server,location
头信息
Syntax :proxy_set_header field value;
Default :proxy_set_header Hosy $proxy_host;
proxy_set_header Connection close;
Context :http,server,location
扩展:proxy_hide_header、proxy_set_body
超时 Syntax :proxy_connection_timeout time; Default :proxy_connection_timeout 60s; Context :http,server,location 扩展:proxy_read_timeout、proxy_send_timeout
处理的时间
企业常用
resolver 8.8.8.8; # 谷歌的dns服务器 locaion / { proxy_pass http://$http_host$request_uri; proxy_redirect default; proxy_set_header Host $http_host; proxy_set_header X-Readl-Ip $remoter_addr; proxy_connection_timeout 30; proxy_read_timeout 60; proxy_write_timeout 60; proxy_buffer_size 32k; proxy_buffering on; # 可以减少频繁的IO proxy_buffers 4 128k; # 内存 proxy_busy_buffers_size 256k; # 内存 proxy_max_temp_file_size 256k; # 硬盘 }
缓冲区临时文件存放的地点看编译过程的信息,里面有
负载均衡
随着企业业务的增长,以及带来的客户的海量的请求,给服务端造成了海量的并发,使响应不能及时。
---> 扩容后端服务,前端需要一个负载均衡来均分请求,以提升整体的吞吐率。
单点的方式访问,如果一个点荡吊了,整体也就荡吊了。
但是有了负载均衡,一个挂掉了,其他的点也可以正常使用,剔除就可以了。
默认的负载均衡的算法: 是设置计数器,轮流请求N台服务器. 可以安装第3方模式,来利用uri做hash等等. 如http://wiki.nginx.org/NginxHttpUpstreamConsistentHash 这个模块就是用一致性hash来请求后端结节,并且其算法,与PHP中的memcache模块的一致性hash算法,兼容. 安装该模块后: Nginx.conf中 upstream memserver { consistent_hash $request_uri; server localhost:11211 weight=3 max_fails=3 fail_timeout=10s; server localhost:11212 weight=1 max_fails=3 fail_timeout=10s; }
按照范围分类,GSLB,SLB
全局负载均衡(范围比较大),


nginx就是一个SLB,往往企业不会大规模部署GSLB而是用到云的服务以及第三方的整体设备。 按照osi可以分为 四层负载均衡 和七层负载均衡 物理 链路 网络 传输(tcp/ip) 会话 表示 应用 四层已经支持TCP/ip控制,只需要对客户端的请求进行tcp/ip协议的包转发,性能非能快,只需要对底层的应用处理 七层可以完成很多应用方面的协议的请求;(http信息改写,安全应用规则的控制,转发 ,重写)nginx就是

upstream server 服务单元s 默认依次轮训, (一致性哈希)
Syntax :upstream name {...} Default :-- Context :http
不对外提供8002端口的服务
iptables -I INPUT -p tcp --dport 8002 -j DROP
upstream backend { server backend1.example.com weight=5; # 权重 server backend2.example.com:8080; server unix;/tmp/backend3; server backup1.example.com:8080 backup; # 备份节点 server backup2.example.com:8080 backup; }
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器,默认不分发,只有当其他忙不过来时,帮忙分发,ip_hash 不支持
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后,服务暂停的时间,默认10秒
max_conns 限制最大的接受的连接数
基于host分发
基于开发语言的分发
基于请求头的分发
基于源IP的分发

轮询 按时间顺序桌椅分配到不同的后端服务器
加权轮询 weight值越大,分配到的访问几率越高
least_conn 最少链接数,那个机器连接少就分发
ip_hash 每个请求访问IP的hash结果分配,这样来自同一个ip的 固定访问一个后端服务器 remote_addr(无法基于同一台服务器 代理)
第三方
url_hash 按照访问的url的hash结果来分配请求,是每个url丁香岛同一个后端服务器
hash 关键数值 hash自定义的key
内置,http_header,自定义
fair 第三方;安后端服务器的响应时间来分配请求,响应式夹断的优先分配
Syntax :hash key [consistent]; #$request_url; Default :-- Context :upstream this directive appeared in version 1.7.2
缓存服务
减少后端压力,尽量让所有请求都能在前端获得数据,处理掉。
服务端缓存;redis,memcache
代理缓存; nginx
客户端缓存:
proxy_cache 配置语法 必须 Syntax :proxy_cache_path path [levels=levels(1:2)][use_temp_path=on|off] keys_zone=name:size [incative=time] [max_size=size(10g)] [manager_files=number][manager_sleep=time] [manager_threshold=time]
[loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time][purger_threshold=time];
Default :-- Context :http
Syntax :proxy_cache zone |off; Default :proxy_cache off; Context :http,server,location
缓存过期周期 Syntax :proxy_cache_valid [code ...] time; # 状态码 Default :-- Context :http,server,location
缓存维度 Syntax :proxy_cache_key string; Default :proxy_cache_key $scheme$proxy_host$request_uri; # 协议主机url Context :http,server,location
部分页面不缓存
Syntax :proxy_no_cache string ...;
Default :--
Context :server,http,location
if ($request_uri ~ ^/(url3|login|register|password\/reset){
set $cookie_nocache 1;
}

proxy_next_upstream
防止后端其中一台服务器,出现问题,则跳过这一台
如何清理指定缓存
官方没有提供
用第三方扩展模块 ngx_cache_purge (编译\安装)
清理所有缓存:
rm -rf /opt/app/cache/
大文件分片请求 Syntax :slice size; Default ;slice 0; Context :http,server,location 1.9以后出现
优势:每个自请求收到的数据都会形成一个独立文件,一个请求断了,其他请求不受影响
缺点:当文件很大或者slice很小的时候,可能会导致文件描述符耗尽的情况
rewirte 实现url重写以及重定向 应用场景 1) url 访问跳转,支持开发设计 页面跳转。兼容性支持。展示效果 2) SEO优化, 方便搜索引擎的录入 3)维护 后台维护。流量转发 4)安全 将真实的页面伪装
Syntax : rewrite regex replacement [flag]; Default : -- Context :server,location,if
flag
last 停止rewrite检测
break 停止rewrite检测
redirect 返回302临时重定向,地址栏会显示跳转后的地址
permanent 返回301永久重定向,地址栏会显示跳转后的地址
rewrite ^ http://www.baidu.com$request_uri?;
rewrite ^(.*)$ /index$1.html break; # 内容重定向一次
last 与 break的区别:
break 找不到index$1文件会返回404
last 会重新访问一次 只不过url变成了/index$1.html
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break;
if (!-f $request_filename){
rewrite ^/(.*)$ http://www.baidu.com/ redirect;
}
! 取反, -f 判断路径是否存在


浙公网安备 33010602011771号