Nginx

372 阅读7分钟

主要功能

  • 静态资源服务
  • 反向代理
  • api接口服务(权限控制、缓存)

一般检查

  • vi /etc/sysconfig/network-scripts/ifcfg-ens33(看网卡的配置信息,或者直接setup)
  • systemctl stop firewalld.service(临时关闭防火墙)
  • systemctl disable firewalld.service(永久关闭防火墙)

依赖包

  • yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
  • yum -y install wget httpd-tools(待会压力测试使用) vim

安装

yum install gcc gcc-c++ perl -y
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.43.tar.gz依赖包
wget http://prdownloads.sourceforge.net/libpng/zlib-1.2.11.tar.gz依赖包
wget https://www.openssl.org/source/openssl-1.0.2n.tar.gz依赖包
wget http://nginx.org/download/nginx-1.10.1.tar.gz依赖包
tar -zxvf nginx-1.10.1.tar.gz
tar -zxvf openssl-1.0.2h.tar.gz
tar -zxvf pcre-8.43.tar.gz
tar -zxvf zlib-1.2.11.tar.gz

cd nginx-1.10.1
./configure --prefix=/usr/local/nginx \
--pid-path=/usr/local/nginx/nginx.pid \
--error-log-path=/usr/local/nginx/error.log \
--http-log-path=/usr/local/nginx/access.log \
--with-http_ssl_module \
--with-mail --with-mail_ssl_module \
--with-stream --with-threads \
--user=comex --group=comexgroup \
--with-pcre=/root/package/pcre-8.43 \
--with-zlib=/root/package/zlib-1.2.11 \
--with-openssl=/root/package/openssl-1.0.2n
make && make install

sudo /home/www/nginx/sbin/nginx -t
nginx: [emerg] getpwnam("comex") failed
vi /home/www/nginx/conf/nginx.conf
user  www;
sudo /home/www/nginx/sbin/nginx

日志切割(具体查询linux、logrotate.d的语法了)

cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 `cat /var/run/nginx.pid`
                fi
        endscript
}

缓存目录

/var/cache/nginx

主配置文件

user  nginx;   设置nginx服务的系统使用用户  
worker_processes  1;  工作进程数,一般和CPU数量相同 

error_log  /var/log/nginx/error.log warn;   nginx的错误日志  
pid        /var/run/nginx.pid;   nginx服务启动时的pid

events {
    worker_connections  1024;每个进程允许的最大连接数 10000
}

http {
    include       /etc/nginx/mime.types;//文件后缀和类型类型的对应关系
    default_type  application/octet-stream;//默认content-type

    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;//默认访问日志

    sendfile        on;//启用sendfile
    #tcp_nopush     on;//懒发送

    keepalive_timeout  65;//超时时间是65秒

    #gzip  on; # 启用gzip压缩

    include /etc/nginx/conf.d/*.conf;//包含的子配置文件
}
//最外层是全局的配置然后就是http下面可以配置多个server(一个server对应一个应用服务)
//一个server下也可以配置多个location

server {
    listen       80;  //监听的端口号
    server_name  localhost;  //用域名方式访问的地址

    #charset koi8-r; //编码
    #access_log  /var/log/nginx/host.access.log  main;  //访问日志文件和名称

    location / {
        root   /usr/share/nginx/html;  //静态文件根目录
        index  index.html index.htm;  //首页的索引文件
    }

    #error_page  404              /404.html;  //指定错误页面

    # redirect server error pages to the static page /50x.html
    # 把后台错误重定向到静态的50x.html页面
    error_page   500 502 503 504  /50x.html; 
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    # 代理PHP脚本到80端口上的apache服务器
    location ~ \.php$ {
        proxy_pass   http://127.0.0.1;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    # 把PHP脚本9000端口上监听的FastCGI服务
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    # 不允许访问.htaccess文件
    location ~ /\.ht {
        deny  all;
    }
}

监控nginx客户端的状态

http://192.171.207.104/status

Active connections: 2   当前nginx正在处理的活动连接数         
server accepts---总共处理的连接数 handled---成功创建握手数 requests---总共处理请求数 
 3 3 10 
Reading---读取到客户端的Header信息数: 0 
Writing---返回给客户端的Header信息数: 1 
Waiting---开启keep-alive的情况下,这个值等于 active – (reading + writing): 1 

限制同一个ip限制请求频次

#limit_req_zone
// 可以以IP为key zone为空间的名称 size为申请空间的大小
Syntax: limit_req_zone key zone=name:size rate=rate;   
Default: --
Context: http(定义在server以外)
-----------------------------------------------------------------------
#limit_req
# zone名称 number限制的数量
Syntax: limit_req  zone=name [burst=number] [nodelay];
Default: --
Context: http,server,location
-----------------------------------------------------------------------
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
server {
  location /{
      limit_req req_zone;
      # 缓存区队列burst=3个,不延期,即每秒最多可处理rate+burst个.同时处理rate个
      limit_req zone=req_zone burst=3 nodelay;
  }
}
- $binary_remote_addr 表示远程的IP地址
- zone=req_zone:10m 表示一个内存区域大小为10m,并且设定了名称为req_zone
- rate=1r/s 表示请求的速率是11个请求
- zone=req_zone 表示这个参数对应的全局设置就是req_zone的那个内存区域
- burst=3 表示请求队列的长度
- nodelay 表示不延时

限制连接数limit_conn_zone

# 可以以IP为key zone为空间的名称 size为申请空间的大小
Syntax: limit_conn_zone key zone=name:size;   
Default: --
Context: http(定义在server以外)

# imit_conn
# zone名称 number限制的数量
Syntax: limit_conn  zone number;
Default: --
Context: http,server,location

# 案例
limit_conn_zone $binanry_remote_addr zone=conn_zone:1m;
server {
  location /{
      limit_conn conn_zone 1;
  }
}
表明以ip为key,来限制每个ip访问文件时候,最多只能有一个在线,否则其余的都要返回不可用

http_access_module 访问权限控制

Syntax: allow address|all;
Default: --
Context: http,server,location,limit_except
Syntax: deny address|CIDR|all;

Default: --
Context: http,server,location,limit_except

# demo
server {
  location ~ ^/admin.html{
       deny 192.171.207.100;
       allow all;
  }
}    
server {
  location ~ ^/admin.html{
     if ($http_x_forwarded_for !~* "^8\.8\.8\.8") {
        return 403;
     }
}

常见配置项

 sendfile(不经过用户内核发送文件)、 
 tcp_nopush(在sendfile开启的情况下,合并多个数据包,提高网络包的传输效率)、 
 tcp_nodelay(在keepalive连接下,提高网络包的传输实时性)、 
 gzip、gzip_comp_level 、
 gzip-static(先找磁盘上找同名的.gz这个文件是否存在,节约CPU的压缩时间和性能损耗)
(nginx天生已经设置了静态资源的缓存 If-Modified-Since: Tue, 04 Dec 2018 15:03:06 GMT,If-None-Match: "5c06972a-264", Cache-Control: max-age=0)
 expires是没有设置的
 demo:
 
    location ~ .*\.(jpg|png|gif)$ {
        gzip off;#关闭压缩
        root /data/www/images;
    }

    location ~ .*\.(html|js|css)$ {
        gzip on; #启用压缩
        gzip_min_length 1k;    #只压缩超过1K的文件
        gzip_http_version 1.1; #启用gzip压缩所需的HTTP最低版本
        gzip_comp_level 9;     #压缩级别,压缩比率越高,文件被压缩的体积越小
        gzip_types  text/css application/javascript;#进行压缩的文件类型
        root /data/www/html;
    }

    location ~ ^/download {
        gzip_static on; #启用压缩
        tcp_nopush on;  # 不要着急发,攒一波再发
        root /data/www; # 注意此处目录是`/data/www`而不是`/data/www/download`
    } 

添加header

location ~ .*\.json$ {
        add_header Access-Control-Allow-Origin http://localhost:3000;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        root /data/json;
}

防止盗链valid_referers

 # none没有refer ---blocked非正式HTTP请求 ----特定IP  这些都有效
 valid_referers none blocked 47.104.184.134;
 if ($invalid_referer) { # 验证通过为0,不通过为1
	return 403;
 }

正向代理

$http_host 要访问的主机名 $request_uri请求路径
proxy_pass http://$http_host$request_uri;

反向代理

location ~ ^/api {
    proxy_set_header Host $host:$server_port;  #设置头
    proxy_set_header X-Real-IP $remote_addr;   #设置头
    proxy_pass http://localhost:3000;
    proxy_redirect default; #重定向

    proxy_set_header Host $http_host;        #向后传递头信息
    proxy_set_header X-Real-IP $remote_addr; #把真实IP传给应用服务器

    proxy_connect_timeout 30; #默认超时时间
    proxy_send_timeout 60;    # 发送超时
    proxy_read_timeout 60;    # 读取超时


    proxy_buffering on;             # 在proxy_buffering 开启的情况下,Nginx将会尽可能的读取所有的upstream端传输的数据到buffer,直到proxy_buffers设置的所有buffer们 被写满或者数据被读取完(EOF)
    proxy_buffers 4 128k;           # proxy_buffers由缓冲区数量和缓冲区大小组成的。总的大小为number*size
    proxy_busy_buffers_size 256k;   # proxy_busy_buffers_size不是独立的空间,他是proxy_buffers和proxy_buffer_size的一部分。nginx会在没有完全读完后端响应的时候就开始向客户端传送数据,所以它会划出一部分缓冲区来专门向客户端传送数据(这部分的大小是由proxy_busy_buffers_size来控制的,建议为proxy_buffers中单个缓冲区大小的2倍),然后它继续从后端取数据,缓冲区满了之后就写到磁盘的临时文件中。
    proxy_buffer_size 32k;          # 用来存储upstream端response的header
    proxy_masx_temp_file_size 256k; # response的内容很大的 话,Nginx会接收并把他们写入到temp_file里去,大小由proxy_max_temp_file_size控制。如果busy的buffer 传输完了会从temp_file里面接着读数据,直到传输完毕。
}

负载均衡

upstream lrj {
  server 127.0.0.1:3000 weight=10;
  server 127.0.0.1:4000;
  server 127.0.0.1:5000;
}

server {
    location / {
        proxy_pass http://lrj;
    }
}

#一些配置项
down	当前的服务器不参与负载均衡
backup	当其它节点都无法使用时的备份的服务器
max_fails	允许请求失败的次数,到达最大次数就会休眠
fail_timeout	经过max_fails失败后,服务暂停的时间,默认10秒
max_conns	限制每个server最大的接收的连接数,性能高的服务器可以连接数多一些
upstream xxx {
  server localhost:3000 down;
  server localhost:4000 backup;
  server localhost:5000 max_fails=1 fail_timeout=10s;
}

#分配方式
轮询(默认)------每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
weight(加权轮询)------指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
ip_hash------每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题
least_conn------哪个机器上连接数少就分发给谁
url_hash(第三方)------按访问的URL地址来分配 请求,每个URL都定向到同一个后端 服务器上(缓存)
fair(第三方)------按后端服务器的响应时间来分配请求,响应时间短的优先分配
正定义hash------hash自定义key


location优先级

  • = 最高
  • ^~ 次之
  • ~(大小写敏感) ~*(大小写不敏感)
  • 直接写路径的

匹配执行的逻辑是:

  • 首先执行所有的直接写路径的,跟^~,记录下最长前缀。
  • 如果过程中碰到=号,且匹配成功,则直接使用=的规则,不再继续。
  • 存储最长匹配的前缀字符串。
  • 从上到下,测试正则,返回true的就匹配上了(如果最长匹配的前缀字符串是 ^~ 规则匹配出来的,则不检查正则表达式,直接使用^~的配置)
  • 如果没有匹配的正则表达式,存储最长匹配的前缀字符串的规则

一句话就是等号直接返回,如果没有匹配到等号,就检查非=号的所有location的最长公共前缀(备用),测试正则,适用第一个返回true的

cenos 7

# Systemd
系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其他进程,根据管理,字母d是守护进程(daemon)的缩写

# 配置目录	用途
/usr/lib/systemd/system	每个服务最主要的启动脚本设置,类似于之前的/etc/initd.d
/run/system/system	系统执行过程中所产生的服务脚本,比上面的目录优先运行
/etc/system/system	管理员建立的执行脚本,类似于/etc/rc.d/rcN.d/Sxx类的功能,比上面目录优先运行,在三者之中,此目录优先级最高
# systemctl
# 监视和控制systemd的主要命令是systemctl
# 该命令可用于查看系统状态和管理系统及服务
命令:systemctl  command name.service
启动:service name start –>systemctl start name.service
停止:service name stop –>systemctl stop name.service
重启:service name restart–>systemctl restart name.service
状态:service name status–>systemctl status name.service