Linux-Manual

Nginx 安装和配置

Nginx 说明

来自网络上的一个好介绍

Nginx 的 Docker 部署

worker_processes      1;

events {
  worker_connections  1024;
}

http {
  include             mime.types;
  default_type        application/octet-stream;

  sendfile on;

  keepalive_timeout   65;

  server {
    listen            80;
    server_name       localhost 127.0.0.1 193.112.221.203 youmeek.com;

    location / {
      root            /usr/share/nginx/html;
      index           index.html index.htm;
    }
  }
}

YUM 安装(版本一般滞后半年左右)


Nginx 源码编译安装(带 Prometheus 模块)

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/local/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--with-http_ssl_module \
--with-http_stub_status_module \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--add-module=/usr/local/nginx-module-vts

Nginx 源码编译安装(带监控模块)

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/local/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--with-http_ssl_module \
--with-http_stub_status_module \
--http-scgi-temp-path=/var/temp/nginx/scgi
drwxr-xr-x. 2 root root 4096 3月  22 16:21 conf
drwxr-xr-x. 2 root root 4096 3月  22 16:21 html
drwxr-xr-x. 2 root root 4096 3月  22 16:21 sbin
nginx version: nginx/1.8.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --pid-path=/usr/local/nginx/run/nginx.pid --lock-path=/usr/local/nginx/lock/nginx.lock --with-http_ssl_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module

把 Nginx 添加到系统服务中

#!/bin/bash


#nginx执行程序路径需要修改
nginxd=/usr/local/nginx/sbin/nginx

# nginx配置文件路径需要修改
nginx_config=/usr/local/nginx/conf/nginx.conf

# pid 地址需要修改
nginx_pid=/var/local/nginx/nginx.pid


RETVAL=0
prog="nginx"

# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -x $nginxd ] || exit 0

# Start nginx daemons functions.
start() {
if [ -e $nginx_pid ];then
   echo "nginx already running...."
   exit 1
fi

echo -n $"Starting $prog: "
daemon $nginxd -c ${nginx_config}
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
return $RETVAL
}

# Stop nginx daemons functions.
# pid 地址需要修改
stop() {
	echo -n $"Stopping $prog: "
	killproc $nginxd
	RETVAL=$?
	echo
	[ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx /var/local/nginx/nginx.pid
}

# reload nginx service functions.
reload() {
	echo -n $"Reloading $prog: "
	#kill -HUP `cat ${nginx_pid}`
	killproc $nginxd -HUP
	RETVAL=$?
	echo
}

# See how we were called.
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	reload)
		reload
		;;
	restart)
		stop
		start
		;;
	status)
		status $prog
		RETVAL=$?
		;;
	*)

	echo $"Usage: $prog {start|stop|restart|reload|status|help}"
	exit 1

esac
exit $RETVAL

Nginx 无缝升级

为 Nginx 添加 basic_auth

yum install httpd-tools  

htpasswd -c /opt/nginx-auth/passwd.db myusername,回车之后输入两次密码


server {
    ...

    location / {
        auth_basic   "please input you user name and password";
        auth_basic_user_file    /opt/nginx-auth/passwd.db;
        ....
    }
}

Nginx 全局变量

Nginx 配置

Nginx 在 1.8.1 版本下的默认配置(去掉注释)

user root;#我这里习惯使用 root,所以这里需要这样设置。如果你有为你的 nginx 专门配置一个用户,这里需要改为你的用户
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

HTTP 服务,虚拟主机

user root;#我这里习惯使用 root,所以这里需要这样设置。如果你有为你的 nginx 专门配置一个用户,这里需要改为你的用户
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 一个 server 代表一个虚拟主机
    server {
        listen       80;
        server_name  localhost;

        location / {
            # 虚拟机根目录是 /usr/local/nginx/html 目录
            root   html;
            # 虚拟机首页是 /usr/local/nginx/html 目录下这两个文件
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    
    server {
        # 第二个虚拟机的端口是 90,服务地址还是本地
        listen       90;
        server_name  localhost;

        location / {
            root   html90;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
user root;#我这里习惯使用 root,所以这里需要这样设置。如果你有为你的 nginx 专门配置一个用户,这里需要改为你的用户
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 一个 server 代表一个虚拟主机
    server {
        listen       80;
        # 两个虚拟主机都使用 80 端口,设置不同域名
        server_name  code.youmeek.com;

        location / {
            # 虚拟机根目录是 /usr/local/nginx/html 目录
            root   html;
            # 虚拟机首页是 /usr/local/nginx/html 目录下这两个文件
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    
    server {
        listen       80;
        # 两个虚拟主机都使用 80 端口,设置不同域名
        server_name  i.youmeek.com;

        location / {
            root   html-i;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

反向代理和负载均衡

user root;#我这里习惯使用 root,所以这里需要这样设置。如果你有为你的 nginx 专门配置一个用户,这里需要改为你的用户
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 自己定义的两个 tomcat 请求地址和端口
    # 也就是当浏览器请求:tomcat.youmeek.com 的时候从下面这两个 tomcat 中去找一个进行转发
    upstream tomcatCluster {
        server 192.168.1.114:8080;
        server 192.168.1.114:8081;
        
        # 添加 weight 字段可以表示权重,值越高权重越大,默认值是 1,最大值官网没说,一般如果设置也就设置 3,5,7 这样的数
        # 官网:https://www.nginx.com/resources/admin-guide/load-balancer/#weight
        # server 192.168.1.114:8080 weight=2;
        # server 192.168.1.114:8081 weight=1;
    }

    server {
        listen       80;
        server_name  tomcat.youmeek.com;

        location / {
            proxy_pass   http://tomcatCluster;
            index  index.html index.htm;
        }
    }
}

配置 HTTPS 服务(SSL 证书配置)

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    
    # 如果访问 http 也直接跳转到 https
    server {
        listen       80;
        server_name sso.youmeek.com;
        return 301 https://$server_name$request_uri;
    }
    
    # crt 和 key 文件的存放位置根据你自己存放位置进行修改
    server {
        listen       443;
        server_name  sso.youmeek.com;
        ssl  on;
        ssl_certificate     /opt/ssl/certificate.crt;
        ssl_certificate_key /opt/ssl/private.key;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

listen 443 ssl;

ssl_certificate     /opt/jar/ssl/server.crt;
ssl_certificate_key /opt/jar/ssl/server.key;

ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

Nginx 压力测试

ab -n 1000 -c 100 http://www.baidu.com/

-n  总的请求数
-c  单个时刻并发数
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking juejin.im (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        nginx
Server Hostname:        juejin.im
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

Document Path:          /
Document Length:        271405 bytes

Concurrency Level:      100(并发数:100)
Time taken for tests:   120.042 seconds(一共用了 120 秒)
Complete requests:      1000(总的请求数:1000)
Failed requests:        0(失败的请求次数)
Write errors:           0
Total transferred:      271948000 bytes
HTML transferred:       271405000 bytes
Requests per second:    8.33 [#/sec] (mean)(QPS 系统吞吐量,平均每秒请求数,计算公式 = 总请求数 / 总时间数)
Time per request:       12004.215 [ms] (mean)(毫秒,平均每次并发 100 个请求的处理时间)
Time per request:       120.042 [ms] (mean, across all concurrent requests)(毫秒,并发 100 下,平均每个请求处理时间)
Transfer rate:          2212.34 [Kbytes/sec] received(平均每秒网络流量)

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       57  159 253.6     77    1002
Processing:  1139 11570 2348.2  11199   36198
Waiting:      156 1398 959.4   1279   22698
Total:       1232 11730 2374.1  11300   36274

Percentage of the requests served within a certain time (ms)
  50%  11300
  66%  11562
  75%  11863
  80%  12159
  90%  13148
  95%  15814
  98%  18882
  99%  22255
 100%  36274 (longest request)

Nginx 常规优化

增加工作线程数和并发连接数

events {
	# 每一个进程可以打开的最大连接数(这个参数是受限制于系统参数的,默认是 1024)(进程数是上面 worker_processes 决定的)
    worker_connections  1024;
    # 可以一次建立多个连接
    multi_accept on;
    # epoll 模式效率最高
    use epoll;
}

启动长连接

http {
  sendfile on; # 减少文件在应用和内核之间的拷贝
  tcp_nopush on; # 当数据包达到一定大小再发送
  
  keepalive_timeout   65;
  
  upstream tomcatCluster {
      server 192.168.1.114:8080;
      server 192.168.1.114:8081;
      keepalive 300; # 300 个长连接
  }
  
}

启用缓存和压缩

http {
    gzip on;
    gzip_buffers 8 16k; # 这个限制了nginx不能压缩大于128k的文件
    gzip_min_length 512; # 单位byte
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";
    gzip_http_version 1.1; # 1.0 的版本可能会有问题
    gzip_types   text/plain text/css application/javascript application/x-javascript application/json application/xml;
}

操作系统优化(机器好点的时候)

修改 sysctl 参数
net.ipv4.tcp_fin_timeout = 10           #保持在FIN-WAIT-2状态的时间,使系统可以处理更多的连接。此参数值为整数,单位为秒。
net.ipv4.tcp_tw_reuse = 1              #开启重用,允许将TIME_WAIT socket用于新的TCP连接。默认为0,表示关闭。
net.ipv4.tcp_tw_recycle = 0            #开启TCP连接中TIME_WAIT socket的快速回收。默认值为0,表示关闭。
net.ipv4.tcp_syncookies = 1            #开启SYN cookie,出现SYN等待队列溢出时启用cookie处理,防范少量的SYN攻击。默认为0,表示关闭。
net.core.somaxconn = 1024             #定义了系统中每一个端口最大的监听队列的长度, 对于一个经常处理新连接的高负载 web服务环境来说,默认值为128,偏小。
修改 limits 参数
* soft nofile 262144
* hard nofile 262144
* soft core unlimited
* soft stack 262144

Nginx 监控模块

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/local/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--with-http_ssl_module \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--with-http_stub_status_module
location /nginx_status {
    allow 127.0.0.1;
    deny all;
    stub_status on;
    access_log   off;
}
Active connections: 1
server accepts handled requests
 3 6 9   
Reading: 0 Writing: 5 Waiting: 0   

Nginx 配置文件常用配置积累

location 配置

= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,不是正则匹配
~ 开头表示区分大小写的正则匹配;
~* 开头表示不区分大小写的正则匹配
/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到

location / {

}

location /user {

}

location = /user {

}

location /user/ {

}

location ^~ /user/ {

}

location /user/youmeek {

}

location ~ /user/youmeek {

}

location ~ ^(/cas/|/casclient1/|/casclient2/|/casclient3/) {

}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico|woff|woff2|ttf|eot|txt)$ {

}

location ~ .*$ {

}

链接 aa 下,查询参数包含 bb

location /aa/ {
	if ( $args ~* '(.*bb.*)' ) {
		return 601;
	}
}
location /aa/ {
	if ($args ~ tag=bb){
		return 601;
	}
}

HTTP 服务,绑定多个域名

安装第三方模块

生成规格图

启用 Gzip 压缩

防盗链

Nginx 禁止特定用户代理(User Agents)访问,静止指定 IP 访问

Nginx 缓存

Nginx 自动分割日志文件

Nginx 处理跨域请求

安全相预防

在配置文件中设置自定义缓存以限制缓冲区溢出攻击的可能性 client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k;

  1. 将timeout设低来防止DOS攻击 所有这些声明都可以放到主配置文件中。 client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10;

  2. 限制用户连接数来预防DOS攻击 limit_zone slimits $binary_remote_addr 5m; limit_conn slimits 5;

使用 logrotate 做 nginx 日志轮询分割


/var/log/nginx/access.log /var/log/nginx/error.log {
	create 644 root root
	notifempty
	daily
	rotate 15
	missingok
	dateext
	sharedscripts
	postrotate
	    if [ -f /var/local/nginx/nginx.pid ]; then
	        kill -USR1 `cat /var/local/nginx/nginx.pid`
	    fi
	endscript
}

//每天02点10分执行一次
10 02 * * *  /usr/sbin/logrotate -f /etc/logrotate.d/nginx

杂七杂八

资料