nginx

Posted fina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx相关的知识,希望对你有一定的参考价值。

nginx

nginx

--prefix=/usr/local/nginx 设置nginx安装路径
--conf-path=/etc/nginx/nginx.conf 设置nginx主配置文件路径
--user=nginx --group=nginx 设置nginx普通用户运行
--error-log-path=/var/log/nginx/error_log 错误日志输入路径
--http-log-path=/var/log/nginx/access_log 访问日志输出路径
--pid-path=/var/run/nginx/nginx.pid 设置PID路径
--lock-path=/var/lock/nginx.lock 设置lock路径
--with-http_ssl_module 开启SSL模块
--with-http_stub_status_module 开启状态页面
--with-http_gzip_static_module 开启gz模块,压缩静态页面
--with-http_flv_module 开启流媒体
--with-http_mp4_module 开启MP4模块

编译安装

yum install -y pcre-devel openssl-devel
useradd -r ngix
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --error-log-path=/var/log/nginx/error_log --http-log-path=/var/log/nginx/access_log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_mp4_module
make -j4
make install
ln -s /usr/local/

/usr/local/nginx/sbin/nginx
ss -tnlp|grep 80

主配置段的指令:

正常运行的必备配置:

1、user USERNAME[GROUPNAME];
指定运行worker进程的用户和组;user nginx nginx;

2、pid/path/to/pid_file;
指定nginx守护进程的pid文件;pid/var/run/nginx/nginx.pid;

3、worker_rlimit_nofile#;
指定所有worker进程所能够持开的最大文件句柄数;

性能相关优化相关配置

1、worker_processes #;
worker进程的个数;通常应该略少于CPU物理核心数;
#通常值为物理CPU核心数-1或-2
#常用

2、worker_cpu_affinity cpumask.…;
#一个CPU核心只运行一个NGINX进程,一个进程专用一个CPU核心
优点:提升缓存的命中率;
context switch:会产生CPU的不必要的消耗;
cpumask: 0000 0000
0000 0001
0000 0010
0000 0100
0000 1000
worker_cpu affinity 00000001 00000010 00000100;
#常用
#worker_cpu affinity auto;

3、timer_resolution
计时器解析度:降低此值,可减少gettimeofday()系统调用的次数:
#解析次数越高,精度越高,资源消耗越大,
#解析次数越低,精度越低,若要求不是特别是高的话,可减少解析数

4、worker_priority number;
指明worker进程的nice值;
-20,19
100,139
数字越小,优先级高
#必须时,可降低
#worker_priority -10;

事件相关的配置:

1、accept_mutex {off|on};
master调度用户请求至各worker进程时使用的负载均衡锁;
on表示能让多个worker轮流地、序列化地去响应新请求:
#当一个新的用户请求到达时,主控进程必须重多个worker进程挑选一个回应请求
#若开启,公平的,轮流,序列的分配,若关闭,则随机

2、lock_file file;
accept_mutex用到的锁文件路径;
#利用这个函数,要对文件进行读写的一个应用程序可将文件的某一部分锁定起来,使其不能由其他应用程序访问。这样便避免了同时读写时发生的冲突。

3、use [epoll|rtsig|select|poll];
指明使用的事件模型:建议让nginx自行选择;

4、worker_connections #:
设定单个worker进程所能够处理的最大并发连接数量;

#worker_connections 10240;
#承受最大并发数worker_connections * work_processes
#大于65535,就无效,若想有效,修改内核参数
#此选项一般必须设置的;

用户调试、定位问题

#编译时添加此选项,才可以调试
--with-debug

1、daemon {on|off};
是否以守护进程方式运行nginx;调试时应该设置为off
#关闭时,可在控制台看到调试输出信息

2、master_process {on|off};
是否以master/worker模型来运行nginx;高度时可以设置为off

3、error_log file | syslog:server=address[,parameter=value]| memory:size [debug | info | notice | warn | error | crit | alert | emerg];
error_log 位置 级别;
若要使用debug级别,需要在编译nginx时使用了--with-debug选项:

总结:经常需要进行调整的参数

worker_processes
worker_connections
worker_cpu_affinity
worker_priority

新改动配置生效的方式:
nginx -s reload
stop,quit,reopen

nginx作为web服务器时使用的配置
http {}:由ngx_http_core_module模块所引入
配置框架
http {
upstream {
...
}

server {
	location URL{
		root "/path/to/somedir";
		...
	} # 类似于http中的<Location>,用于定义url与本地文件系统的映射关系
	location URL {
		if ...{
			...
		}
		...
	}
	...
} #每个server 类似于http中的一个<VirtualHost>

server {
	...
}

}

注意:与http相关的指令仅能够旋转于http、server、location、upstream、if上下文,但有些指令仅应用于这5种上下文中的某些种;

配置指令:

1、server { }
定义一个虚拟主机

示例
server{
1isten 8080;
server_name www.test.com;
root"/vhosts/web1";
}

2、listen
指定监听的地址和端口:
以下两种方式都可以
listen address [:port];
listen port;

3、server_name NAME [...];
后面可以跟多个主机名[域名]:名称还可以使用正则表达式(~)或通配符;

(1)精确匹配优先 www.test.com
(2)左侧通配符匹配检查: .test.com
(3)右侧通配符匹配检查: mail.
(4)正则表达式匹配检查: ~^.
.test.com$
(5)default_server;

4、root path;
设置资源路径映射:用于指明请求的url所对应资源所在文件系统上的起始路径
root "/var/www/html";

5、location [ = | ~ | ~* | ~~ ] uri { … }
location @name {...}
功能:允许根据用户请求的URI来匹配定义的各location:匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制访问控制等功能;

=:精确匹配检查;
~:正则表达式模式匹配检查,区分字符大小写;
~*:正则表达式模式匹配检查,不区分字符大小写;
^~:URI的前半部分匹配,不支持正则表达式;

匹配的优先级:精确匹配=、^、~*、不带任务符号的

server {
    listen 80;
    server_name www.test.com;
    location / {
        root "/var/www/html/web1";
    }
    
    location /images {
        root "/var/www/html/images";
    }
    
    location ~* .php$ {
        fagipass ;
    }
}
server{
listen 8080; 
server_name www.test.com;

 location/{
root "/vhosts/webl";
}

 location /images/{
root "/vhosts/images";
}

 location ~* .(txtltext)${
root "/vhosts/text";
}

6、alias path;
用于location配置段,定义路径别名

1ocation /images/ {
root"/vhosts/web1";
}

 http://ww.test.com/images/a.jpg<--/vhosts/web1/images/a.jpg 
 
location /images/ {
alias"/www/pictures/"; 
}
http://www.test.com/images/a.jpg<--/ww/picuter/a.jpg

注意:root表示指明路径为对应的location "/" URL;alias表示路径映射,即1ocation指令后定义的URL是相对于alias所指明的路径而言:
#使用alias右侧一定要加/

7、index file;
默认主页面

index index.php index.html;

8、error_page code [...] =code URI | @name
根据http响应状态码来指明我用的错误页面;

error_page 404 /404_customed.html

示例 404报错打开404.html, =200修改响应码

error_page 404 =200 /404.html;

9、基于IP的访问控制
allow IP/Network;
deny IP/Network;

示例

allow 192.168.2.0/24;
deny all;

#deny 192.168.2.254;

10、基于用户的访问控制
basic,digest;

auth_basic "heloo vip";
auth_basic_user_file "/path/to/password_file";
账号密码文件建议使用htpasswd来创建;
mkdir /etc/nginx/users
htpasswd -c -m /etc/nginx/users/.htpasswd admin

11、https服务
生成私钥,生成请收签署请求,并获得证书;

cd /etc/pki/CA/
`umask 077;openssl genrsa -out private/cakey.pem 2048`
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
touch serial index.txt
echo 01 > serial 

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
`umask 077; openssl genrsa -out nginx.key 1024`
openssl req -new -key nginx.key -out nginx.csr
openssl ca -in nginx.csr -out nginx.crt -days 365

server {
        listen       443 ssl;
        server_name  www.test.com;
        ssl_certificate      /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key  /etc/nginx/ssl/nginx.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

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

12、stub_status { on|off };
仅能用于location上下文

  location /status {
      stub_status on;
      allow 192.168.2.0/24;
      deny all;
		}

示例
Active connections: 1 #当前所有打开状态的连接数
server accepts handled requests
30 30 53
#已经接受的连接数
#已经处理过的连接数
#处理连接的请求,在保持连接模式下,请求数量可能会多于连接数量
Reading: 0 Writing: 1 Waiting: 0
#Reading:正处于接收请求状态的连接数:
#Writing:请求已经接收完成,正处于处理请求或发送响应的过程中的连接数:
#Waiting:保持连接模式,且处于活动状态的连接数:

13、rewrite regex replacement flag;
flag
last:一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理;而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break:一旦此rewrite规则重写完成后,由User Agent对新的URL重新发起请求,且不再会被当前1ocatrion内的任何rewrite规则所检查:
redirect:以302响应码(临时重定向)返回新的URL:
permanent:以301响应码(永久重定向)返回新的URL:

14、if
语法:if(condition) {...}
应用环境:server,location
condition:
变量名:
变量值为空串,或者以"0"开始,则为false,其它的均为true;

以变量为操作数构成的比较表达式
可使用=,!=类似的比较操作符进行测试:

正则表达式的模式匹配操作
~:区分大小写的模式匹配检查
*:不区分大小写的模式匹配检查!和l~*:对上面两种测试取反
#影响CPU性能

测试路径为文件存在性:-f,!-f

测试指定路径为目录的可能性:-d,!-d

测试文件的存在性:-e,!-e

检查文件是否有执行权限:-x,!-x

示例
if ($http_user_agent ~* MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}

15、防盗链

location ~* `.(jpg|gif|jpeg|png$) {
    valid_referer none blocked www.test.com;
    if ($invalid_referer) {
        rewrite ^/ http://www.test.com/403.html;
    }
}

16、定制访问日志格式

log_format main $server_addr $remote_addr [$time_local] $msec+$connection
                ‘"$request" $status $connection $request time $body_bytes_sent "$http_referer"‘
                ‘"$http_user_agent" "$http_x_forwarded_for"‘;

access_log  logs/access.log  main;

注意:此处可用变量为nginx各模块内建变量:

网络连接相关的配置:
1、keepalive_timeout#;
长连接的超时时长,默认75s;
2、keepalive_requests#;
在一个长连接上所能够允许请求的最大资源数:
3、keepalive_disable[msie6lsafarilnone];
为指定类型的User Agent禁用长连接:
4、tcp_nodelay onloff;
是否对长连接使用TCP_NODELAY选项:
#将小的包合并成一个包
#影响用户体验
5、client_header_timeout#;
读取http请求报文首部的超时时长;
6、client_body_timeout#;
读取http请求报文body部分的超时时长:
7、send_timeout#;
发送响应报文的超时时长:

nginx代理

#ngx_http_proxy_module,ngx_http_upstream_module
#ngxhttp_proxy_module:实现反向代理及缓存功能
#proxy_pass http://{SERVER_IP|UPSTREAM_NAME}/uri

l

ocation / {
proxy_pass http://192.168.2.254; 
proxy_set_header Host $host; 
#记录客户端的主机,不记录代理服务器的主机
proxy_set_header X-Real-IP $remote_addr;
#记录客户端的IP地址,不记录代理服务器的IP
}

代理缓存

mkdir -pv /nginx/cache
chown -R nginx.nginx /nginx/cache

proxy_cache_path /nginx/cache levels=1:2 keys_zone=mycache:500m inactive=1d max_size=10g;
#proxy_cache_path path [levels=levels] keys_zone=name:size [Inactive=time] [max size=size]
#在http{} 缓存存放路径 levels参数定义高速缓存的层次结构级别:从1到3,每个级别接受值1或2. 缓存名字和内存空间大小 缓存的数据超过1天没有被访问就自动清除 访问的缓存数据,硬盘缓存空间大小为10G

proxy_cache mycache;
proxy_cache_valid 200 1d;
proxy_cache_valid 301 302 10m;
proxy_cache_valid any 1m; 
proxy_cache_use_stale error timeout
#在http,server,location{}中
#proxy_cache zone_name
#设置缓存名称
proxy_cache_valid [code] time;
#响应码缓存的时间
proxy_cache_method GET | HEAD | POST
#如果此指令中列出了客户端请求方法,则将缓存响应。
#设置缓存哪些 HTTP 方法, 默认缓存 HTTP GET/HEAD 方法, 不缓存 HTTP POST 方法
proxy_cache_use_stale
#确定在与代理服务器通信期间可以在哪些情况下使用过时的缓存响应
#error如果无法选择代理服务器来处理请求,则该参数还允许使用陈旧的缓存响应。
#此外,updating如果当前正在更新,该参数允许使用过时的缓存响应。这允许在更新缓存数据时最小化对代理服务器的访问次数
proxy_cache_min_uses number
#某响应被请求多少次后,才清除缓存
proxy_cache_bypass string
#定义不从缓存中获取响应的条件。如果字符串参数的至少一个值不为空且不等于 “0”,则不会从缓存中获取响应:
#设置在何种情形下nginx将不从cache取数据的;
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
proxy_set_header
location / {
proxy_pass http://192.168.2.254; 
proxy_set_header Host $host; 
#记录客户端的主机,不记录代理服务器的主机
proxy_set_header X-Real-IP $remote_addr;
#记录客户端的IP地址,不记录代理服务器的IP
}
#允许将字段重新定义或附加到传递给代理服务器的请求标头该value可以包含文本,变量,以及它们的组合。当且仅当proxy_set_header在当前级别上没有定义指令时,这些指令才从先前级别继承

ngx_http_upstream_module
定义服务器组
proxy_pass,fastcgi_pass,uwsgi_pass
#默认情况下,使用加权循环平衡方法在服务器之间分配请求

upstream back1 {
    server back1.test.com;
    server 192.168.2.100:8080;
}

snat模式的大量client
基于sticky实现session绑定
#nginx版本1.5.7之前用 sticky_cookie_insert;之后用sticky
cookie
#使用该cookie方法时,有关指定服务器的信息将在 nginx 生成的 HTTP

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

route
#使用该route方法时,代理服务器会在收到第一个请求时为客户端分配路由。来自此客户端的所有后续请求将在 cookie 或 URI 中携带路由信息。将此信息与服务器指令的 “ route” 参数进行比较,以标识应将请求代理到的服务器。如果未指定 “ ” 参数,则路由名称将是 IP 地址和端口的 MD5 哈希值或 UNIX 域套接字路径的十六进制表示形式。如果指定的服务器无法处理请求,则配置的平衡方法将选择新服务器,就好像请求中没有路由信息一样。

upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;
    sticky route $route_cookie $route_uri;
}

learn
#当使用learn方法(1.7.1)时,nginx 分析上游服务器响应并学习通常在HTTP cookie 中传递的服务器启动的会话。
这种性能较好

upstream backend {
   server backend1.example.com:8080;
   server backend2.example.com:8081;

   sticky learn
          create=$upstream_cookie_examplecookie
          lookup=$cookie_examplecookie
          zone=client_sessions:1m;
}

least_conn:高度方法,最少连接

keepalive
upstream memcached_backend {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;
    keepalive 32;
}

短链接模式,拿到数据断开连接
不建议开启

health_check;
#状态检测
建议:关闭访问日志;

http {
    server {
    ...
        location / {
            proxy_pass http://backend;
            health_check match=welcome;
        }
    }

    match welcome {
        status 200;
        header Content-Type = text/html;
        body ~ "Welcome to nginx!";
    }

#status is not one of 301, 302, 303, or 307, and header does not have "Refresh:"

match not_redirect {
    status ! 301-303 307;
    header ! Refresh;
}
# status ok and not in maintenance mode
match server_ok {
    status 200-399;
    body !~ "maintenance mode";
}

自定义响应首部

add_header X-Via $server_addr;
add_header test $server_addr;
add_header X-Cache $upstream_cache_status;

curl -I [domain|IP]

fastcgi的相关配置
lnmp:php启用fpm模型

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;
}

注意:Nginx 访问 PHP 文件的 File not found 错误处理,两种情况
这个错误很常见,原有有下面两种几种
php-fpm 找不到 SCRIPT_FILENAME 里执行的 php 文件
php-fpm 不能访问所执行的 php,也就是权限问题

  • 第一种情况
更改配置文件 nginx.conf 
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 
替换成下面
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
然后重新加载 nginx 配置文件 
/etc/init.d/nginx reload
  • 第二种情况
两种解决方法: 
第一种,就是把你 root 文件夹设为其他用户允许 
第二种,找到你的 php-fpm 的配置文件,找到下面这段,把 apache 替换成你要的用户组
; RPM: apache Choosed to be able to access some dir as httpd 
user = apache 
; RPM: Keep a group allowed to write in log dir. 
group = apache

php测试页面

<?php
phpinfo();
?>

php-mysql测试页面

<?php
$conn =mysql_connect(‘127.0.0.1‘,‘root‘,‘‘);
if ($conn)
   echo succ;
else
   echo error;
 mysql_close();
?>

三个问题
1、root为同一路径
2、root为不同的路径
3、fpm server为另一主机
fastcgi_pass fastcgi://192.168.2.254:9000

http://nginx.org
http://tengine.taobao.org

user nobody nobody;
worker_processes  auto;
worker_rlimit_nofile 51200;
error_log  /var/log/nginx/error_log;
access_log /var/log/nginx/access_log;
pid        /var/run/nginx/nginx.pid;
events {
    use epoll;
    worker_connections  51200;
}
http {
    server_tokens off;
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main     ‘$server_addr $remote_addr [$time_local] $msec+$connection‘ 
                        ‘"$request" $status $connection $request time $body_bytes_sent "$http_referer"‘
                    	‘"$http_user_agent" "$http_x_forwarded_for"‘;
    open_log_file_cache max=1000 inactive=20s min_users=1 valid=1m;
    sendfile        on;
    tcp_nopush     on;
    gzip  on;
    gzip_comp_level 6;
    keepalive_timeout  35;
    server{
          listen 80;
          server_name www.web1.com;
          location / {
          root html;
          index index.php index.html;
          }
 		
 		  location ~ .php$ {
          root           /var/www/html/web1/;
          fastcgi_pass   127.0.0.1:9000;
          fastcgi_index  index.php;
          fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include        fastcgi_params;
          }
        }
        
    server{
          listen 8888;
          server_name nginx-status;
          location / {
          access_log off;
          deny all;
          return 503;
          }
          
          location /status {
          stub_status on;
          access_log off;
            #error_page 404 =200 /404.html;
            #auth_basic "welcome vip";
            #auth_basic_user_file /etc/nginx/users/.htpasswd;
            allow 127.0.0.1;
            allow 192.168.2.0/24;
            access_log off;
            deny all;
             }
        }
#HTTPS server
    server {
                listen       443 ssl;
                server_name  www.test.com;
                ssl_certificate      /etc/nginx/ssl/nginx.crt;
                ssl_certificate_key  /etc/nginx/ssl/nginx.key;
                ssl_session_cache    shared:SSL:1m;
                ssl_session_timeout  5m;
                ssl_ciphers  HIGH:!aNULL:!MD5;
                ssl_prefer_server_ciphers  on;
 
            location / {
                 root   html;
                 index  index.html index.htm;
                 }
        }
}

服务脚本

#! /bin/bash
# chkconfig: - 85 15
PATH=/usr/local/nginx
DESC="nginx daemon"
NAME=nginx
DAEMON=$PATH/sbin/$NAME
CONFIGFILE=/etc/$NAME/$NAME.conf
PIDFILE=/var/run/$NAME/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# source function library
. /etc/rc.d/init.d/functions

set -e
[ -x "$DAEMON" ] || exit 0
do_start() {
$DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}
do_stop() {
$DAEMON -s stop || echo -n "nginx not running"
}
do_reload() {
$DAEMON -s reload || echo -n "nginx can‘t reload"
}
case "$1" in
start)
    echo -n "Starting $DESC: $NAME"
    do_start
    echo "."
;;
stop)
    echo -n "Stopping $DESC: $NAME"
    do_stop
    echo "."
;;
reload|graceful)
    echo -n "Reloading $DESC configuration..."
    do_reload
    echo "."
;;
restart)
    echo -n "Restarting $DESC: $NAME"
    do_stop
    do_start
    echo "."
;;
*)
    echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
exit 3
;;
esac
exit 0

关于证书

cd /etc/pki/CA/
`umask 077;openssl genrsa -out private/cakey.pem 2048`

openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HA
Locality Name (eg, city) [Default City]:ZZ
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:OPS
Common Name (eg, your name or your server‘s hostname) []:CA.TEST.COM
Email Address []:[email protected]

touch serial index.txt
echo 01 > serial 

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
`umask 077; openssl genrsa -out nginx.key 1024`

openssl req -new -key nginx.key -out nginx.csr
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HA
Locality Name (eg, city) [Default City]:ZZ
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:OPS
Common Name (eg, your name or your server‘s hostname) []:WWW.TEST.COM 
Email Address []:[email protected]  

Please enter the following ‘extra‘ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

openssl ca -in nginx.csr -out nginx.crt -days 3650




































































































































































以上是关于nginx的主要内容,如果未能解决你的问题,请参考以下文章

将 nginx rtmp 片段发送到 WebRTC

text 有用的nginx命令和片段

linux学习:Nginx--常见功能配置片段与优化-06

HLS NGINX-RTMP [错误] 1281#0:* 58 hls:强制片段拆分:10.002 秒

Nginx 跨域

Nginx配置文件详细介绍