Nginx

nginx

nginx火的原因
一个线程内程序交替执行
select、poll、epoll
select:
1)能够监视文件描述符的数量存在最大限制
2)线性扫描效率低
epoll:
linux内核2.6以后对select进行的优化
1)每当FD就绪采用系统的回调函数将FD放入、效率高
2)最大连接数无限制
IO多路复用epoll
1)内置功能模块少
2)代码模块化


之所以轻量级,就是因位内置少,但是官方有很多插件
轻量级
worker进程和cpu绑定,减少cpu切换的cache miss
CPU亲和(affinity)
为什么nginx处理静态文件有优势呢?
因为当请求到来时,一般是
file -----> kernol space ---> user space 
                                                  |
socket  <----kernol space<-----user space

而是直接
file -----> kernol space  
                         |
socket  <----kernol space
sendfile
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/koi-win
/etc/nginx/win-utf

/etc/nginx/modules

/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.14.1
/usr/share/doc/nginx-1.14.1/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/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 判断路径是否存在

 

 

posted @ 2018-11-19 08:46  慕沁  阅读(203)  评论(0)    收藏  举报