一文读懂 nginx配置

一、文件说明

html:放静态文件
conf:配置文件
logs:日志
sbin:nginx 启动

二、命令

nginx  #启动
nginx -s stop  / nginx -s quit #停止服务
nginx -t 检查配置文件
nginx -s reload # 重启 nginx
nginx -c /usr/local/nginx/conf/nginx.conf #启动指定加载的配置文件

三、nginx.conf

user  nobody;       #主模块命令, 指定Nginx的worker进程运行用户以及用户组,默认由nobody账号运行。
worker_processes  1;     #指定Nginx要开启的进程数。
#用来定义全局错设日志文件的路径和日志名称。
#日志输出级别有debug,info,notice,warn,error,crit 可供选择,其中debug输出日志最为详细,面crit(严重)输出日志最少。默认是error
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;  #用来指定进程id的存储文件位置。当解开这个命令时,查看 nginx.pid 文件即可查看 nginx 运行的 pid

#use 其中参数use用来指定nginx的工作模式(这里是epoll,epoll是多路复用IO(I/O Multiplexing)中的一种方式),nginx支持的工作模式有select ,poll,kqueue,epoll,rtsig,/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,对于linux系统,epoll是首选。

#event.worker_connection   是设置nginx每个进程最大的连接数,默认是1024,所以nginx最大的连接数max_client=worker_processes * worker_connections。进程最大连接数受到系统最大打开文件数的限制,需要设置ulimit。
events {
    worker_connections  1024;
}

http {
    include       mime.types;  #主模块命令,对配置文件所包含文件的设定,减少主配置文件的复杂度,相当于把部分设置放在别的地方,然后在包含进来,保持主配置文件的简洁
    default_type  application/octet-stream; #默认文件类型,当文件类型未定义时候就使用这类设置的。

    #指定nginx日志的格式
    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路径 这里的 main 和log_format的 main 一致。
    #能access_log 使用 log_format的日志格式
    access_log  logs/access.log  main;

    sendfile        on;#开启高效文件传输模式(zero copy 方式),避免内核缓冲区数据和用户缓冲区数据之间的拷贝。
    #tcp_nopush     on;#开启TCP_NOPUSH套接字(sendfile开启时有用)

    #客户端连接超时时间
    keepalive_timeout  65;

    #设置是否开启gzip模块
    #gzip  on;

    server {
        #虚拟主机的服务端口
        listen       80;
        #用来指定ip或者域名,多个域名用逗号分开
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
         #地址匹配设置,支持正则匹配,也支持条件匹配,这里是默认请求地址,用户可以location命令对nginx进行动态和静态网页过滤处理
         
            #虚拟主机的网页根目录
            root   html;
            #默认访问首页文件
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #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
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


   
    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.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;
    #    }
    #}

}

四、 http

1.log_format 的格式参数:

image

五、 server

本机配置:

/usr/local/nginx/conf/nginx.conf 在 http 内层,与server同级添加

include /usr/local/nginx/conf/extra_conf/*.conf;

在/usr/local/nginx/conf/extra_conf 中添加 **.conf 文件,内配置单个 server 配置项

server{
    listen       80;
    server_name  localhost;
    location .......
}

1.location匹配

image

匹配规则
~     波浪线表示执行一个正则匹配,区分大小写
~*    表示执行一个正则匹配,不区分大小写
^~    ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
=      #进行普通字符精确匹配
1.精准匹配

访问地址必须为 url/a/。如果是 url/a 那么这个不匹配

location =/a/ {
        rewrite ^/  /a.html break;
        root   html/static/;
}
2.一般匹配

访问地址可为
url/b/a
url/b/a/
url/b/a/任何值…

但是下面不可
url/任何值/b/a

location /b/a {
        rewrite ^/  /c.html break;
	root   html/static/;
}

访问地址如果是直接访问 html
html 文件路径:html/static/a.html
浏览器路径:http://127.0.0.1:8003/static/a.html

location /static {
		#root声明,在html文件夹,查找/static/a.html文件

		root html/;
        }
3.正则匹配

访问地址可为:
url/b/c
url/b/c/
url/b/c/任何值…
url/任何值…/b/c/任何值…

location ~/b/c/* {
        rewrite ^/  /e.html break;
        root   html/static/;
}

地址会先匹配 一般匹配,如果一般匹配匹配上了,还会再走正则匹配。最终走正则匹配
如上面 那个location 与下面这个 location 并存,则下面这个会失效。

扫描二维码关注公众号,回复: 10728844 查看本文章
location /b/c/a {
	return 401;
}

url/b/d/a 访问 f.html
url/b/d/a/ 访问 g.html
url/b/d/a/ss 访问 g.html

location ^~ /b/d/a/ {
        rewrite ^/  /g.html break;
        root   html/static/;
}
location ~ /b/d/* {
        rewrite ^/  /f.html break;
        root  /usr/local/nginx/html/static/;
}

注:… 代表中间可以多级目录

2.nginx 指令

root

root 后的 test_html(默认是 html) 代表 nginx/html 文件夹

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

alias

寻址时/test 就相当于test_html文件夹的别称。如nginx 中有如下目录:test_html/test_static/a.html。
那么浏览器地址栏中输入如下地址即可找到a.html:/test/test_static/a.html

  location /test {
            alias   test_html;
            index  index.html index.htm;
        }

proxy_pass

反向代理
如原服务地址为:
http://127.0.0.1:9003/user/abc/bbc/select
nginx配置:
http://127.0.0.1:9003/user/abc/
最后浏览器访问地址:
http://127.0.0.1:8002/test/bbc/select
注:反向代理地址 有无『/』都不影响。只会对upstream 分发地址的时候有影响

    location /test {
       proxy_pass   http://127.0.0.1:9003/user/abc/;
    }

如果是如下配置,那么遵循下面 upstream 注2 的规则

    location /test {
       proxy_pass   http://127.0.0.1:9003;
    }

upstream

proxy_pass 后的 http://adminservice/; 对应upstream后的adminservice
注1:upstream 的被代理地址只能写到端口,不可127.0.0.1:9003/xx 这样,配置文件会不通过
注2:如果proxy_pass http://adminservice(不带"/"),那么最后拼接的地址会带上 location 中的/test。 如:浏览器地址为:http://127.0.0.1:8002/user/abc,那么最后的地址会为 127.0.0.1:9003/test/user/abc
如果 proxy_pass http://adminservice/(带"/"),那么最后的拼接地址就会不带 location 的 /test。如:浏览器地址为:http://127.0.0.1:8002/user/abc,那么最后的地址会为 127.0.0.1:9003/user/abc

因为请求接口时,端口后的域名段不可能都一样,所以实际中,proxy_pass必须带『/』
负载均衡
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。down 暂时不参与负载
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

http{
    upstream adminservice {
                    server 127.0.0.1:9003 weight=2;
                    server 127.0.0.1:9002;
            }


    server {
            listen       8002;
            server_name  127.0.0.1;
    
            location /test {
               proxy_pass   http://adminservice/;
            }
    
        }
}

3.rewrite

image
格式:
rewrite regex replacement [flag]; flag=【break/last/redirect/permanent】
regex 是正则表达式
replacement 是替换值,新值
flag – 是处理标志

简单例子

浏览器 url:http://127.0.0.1:80/aa.html
最终访问:html/a.html
正则:『^/』表示适配任何值。
location 匹配了aa.html 进入 location中。 rewrite 的正则匹配为任何值。所以最终访问的页面是 a.html.root 指向 html 所以最终访问的是 html/a.html

location /aa.html {
	rewrite ^/  a.html break;
	root  html;
}
rewrite没有命中

浏览器 url:http://127.0.0.1:80/aa.html
最终访问:html/aa.html
location 的匹配是 aa.html 的 url,而 rewrite 的匹配是 xx.js 的 url,所以 rewrite 会永远匹配不上。相当于没有 rewrite,所以最终访问的是html/aa.html ,html 下没有 aa.html 页面就会返回404

location /aa.html {
	rewrite /*.js  a.html break;
	root  html;
}
flag

/redirect(状态码302)/permanent(状态码301)
如果rewrite命中,发页面重定向,浏览器地址栏会变
浏览器初始地址栏:http://127.0.0.1:8004/bb
发送请求后地址栏:http://127.0.0.1:8004/b.html

location /bb {
    rewrite ^/  /b.html permanent;
	root   html/;
}

break/last 内部重定向,换path值
break标记,停止执行后续命令
浏览器 url:http://127.0.0.1:8004/aa.html
进入页面:html/static/b.html
当进入到当前 location 中后,首先匹配到 b.html,然后执行 break。那么后面 rewrite a.html 命令就不会再执行了。

location /aa.html {
	rewrite ^/  /b.html break;
	rewrite ^/  /a.html break;
	root   html/static/;
}

last标记,会引发location重新匹配
浏览器 url:http://127.0.0.1:8004/ab.html
最终结果:页面报错

当通过匹配进入到了 ab.html的 location 中,但是 rewrite 又重定向到了 a.html 而且使用 last 修饰,发生了 location 重新匹配。这就相当于浏览器的 url 是http://127.0.0.1:8004/a.html 。所以就又进入到了 a.html location 当中,之后又 last 到了 ab.html,所以就引发了死循环。而且使用 last,以后中断他下面的语句。
ps:不要轻易使用last标签

location /a.html {
	rewrite  ^/  /ab.html last;
}

location /ab.html {
        #rewrite ^/  /a.html last;
        root   html/static/;
}

4.nginx执行过程

image
说明:
1.通过域名、端口 进入对应的 server
2.path分为两部分:path1(匹配 location 部分)+path2
3.代理转发:
      root:在目录里找path1+path2路径
      alias:在目录里找path2路径
            index:

        #root/alias,若页面以 『/』结尾,则认为 path 只到目录,此时启动 index,找目录内 index 的文件
        server{
        	listen       8005;
            server_name  127.0.0.1;
            #文件存放位置 html/static/a.html、b.html
            
            #访问 http://127.0.0.1:8005/static 会报301(使用 curl 命令查看)
            #访问 http://127.0.0.1:8005/static/ 访问到 a.html 页面
        	location /static {
        		root html/;
        		index a.html;
                }
        
            #访问 http://127.0.0.1:8005/target 会报301(使用 curl 命令查看)
            #访问 http://127.0.0.1:8005/target/ 访问到 b.html 页面
        	location /target {
                alias html/static/;
                index b.html;
        	}	
        }

      proxy_pass:
          当后面跟的是 ip:端口
               有『/』:那么就去对应服务器找 path2
               没有『/』:那么就去对应服务器找 path1+path2

location /test {
       #有 / 和没有 /
       proxy_pass   http://127.0.0.1:9003/;
       proxy_pass   http://127.0.0.1:9003;
    }

          当后面跟的是 ip:端口/aa/bb…
               无论有没有 『/』,都去找对应服务器的 path2

六、nginx 内置变量

image
image

image

七、跨域

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,
从而克服AJAX只能同源使用的限制。
简单请求:
浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。
服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。
复杂请求:
会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求OPTIONS

需要跨域的原因

image
1.浏览器向A 域名发起请求 请求到了 father 页面,服务器将 html 页面发给浏览器,显示在浏览器当中
2.html 页面 再次发起 ajax 请求,向 B 域名发起请求。返回数据后浏览器发现第一次请求是从 A 域名发起的,第二次请求是从 B 域名发起的。两次请求域名不一样,发生了跨域问题。浏览器机制不允许这样的,所以会在 console 中报错:
image
注:第二次请求实际已经发送出去了,但是返回结果浏览器是不允许加载的。

解决方法:

1.浏览器第一次发起请求:

http://static.mynginx.com/static/
页面存在 nginx 位置:html/static/cors.html
本次请求 服务器 nginx 配置

server{
	listen       80;
        server_name  static.mynginx.com;

	location / {

		root html/static/;
		index cors.html;
        }

}

2.请求到的页面

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
	<br />
	<h2>a页面</h2>
	<br />
	<div id = "testcors"></div>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
//$("#testcors").text("Hello world!");
	$.ajax({  
		 url:"http://www.mynginx.com/static/",  
		 async :false,  
		 type:"GET",  
		 success:function(data){  
		 	console.log(data);
			 $("#testcors").html(data);  
			 }  
	 });
</script>

3.浏览器通过 ajax 发起第二次请求

http://www.mynginx.com/static/
页面存在 nginx 位置:html/static/cors.html
本次请求服务器 nginx 配置
发生作用地方:add_header Access-Control-Allow-Origin $allow_url;把请求第一次请求的域名记录注册,允许此域名可跨域访问。

server {
        listen       80;
        server_name  www.mynginx.com;
# nginx 校验网址来源,符合那么把$http_origin 赋值给 $allow_url 
	if ( $http_origin ~ http://(.*).mynginx.com){
                 set $allow_url $http_origin;
        }
  	 #是否允许请求带有验证信息
    	 add_header Access-Control-Allow-Credentials true;
    	 #允许跨域访问的域名,可以是一个域的列表,也可以是通配符*
    	 add_header Access-Control-Allow-Origin  $allow_url;
    	 #允许脚本访问的返回头
    	 add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
    	 #允许使用的请求方法,以逗号隔开
    	 add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
    	 #允许自定义的头部,以逗号隔开,大小写不敏感
    	 add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
    	 #P3P支持跨域cookie操作
    	 add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
		 add_header test  1;

	 if ($request_method = 'OPTIONS') {
             return 204;
         }

	location /static {
			root   html/;
            index  a.html;
        }
        
    }

image

八、防盗链

浏览器地址:http://www.mynginx.com/untitled.html可加载出所有图片
如果单独访问:http://www.mynginx.com/mall.jpg 显示404

conf

# /mall* 的走这个
location ^~ /mall {
    # 验证 网址
		valid_referers *.mynginx.com;
		    # 为 true  返回404
    		if ($invalid_referer) {
    			return 404;
    		}
                root html;
        }

untitled.html

<html>
	<title>10:53:13 PM</title>
	<head></head>
	<body>
		<img src='http://www.mynginx.com/qq.png' />
		<img src='http://www.mynginx.com/chrome.png' />
		<img src='http://www.mynginx.com/mall.jpg' />
	</body>
</html>	

九、缓存

location ^~ /qq.png {
		expires 2s;#缓存2秒
	#	expires 2m;#缓存2分钟
	#	expires 2h;#缓存2小时
	#	expires 2d;#缓存2天
		root html/gzip;
	}
	
location ^~ /chrome.png {
                expires 2m;#缓存2分钟
                root html/gzip;
        }	

如下 qq.png 只缓存了2s,chrome.png 缓存了2分钟,所以在多次刷新浏览器后,chrome.png 图片
image

十、压缩

配置如下即可

location ~ /(.*)\.(html|js|css|jpg|jpeg|png|gif)$ {#覆盖/re/a.htm路径
		gzip on; # 启用gzip压缩,默认是off,不启用
		
		# 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
		gzip_types application/javascript text/css image/jpeg image/png image/gif;
		gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
		gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
		gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
		
		root html/gzip;
	}

十一、https

生成密钥:

# 1、创建服务器私钥,命令会让你输入一个口令:
 openssl genrsa -des3 -out server.key 1024 
# 2、创建签名请求的证书(CSR):
 openssl req -new -key server.key -out server.csr 
# 3、在加载SSL支持的Nginx并使用上述私钥时除去必须的口令: 
openssl rsa -in server.key -out server_nopass.key 
# 4、最后标记证书使用上述私钥和CSR:
 openssl x509 -req -days 365 -in server.csr -signkey server_nopass.key -out server.crt

conf

    server {
        listen       80;
        listen 443 ssl;
        server_name  localhost;
        //配置 https
        ssl_certificate /usr/local/mytest/server.crt;
        ssl_certificate_key /usr/local/mytest/server_nopass.key;
        ......

十二、 nginx 集群

未学习

发布了14 篇原创文章 · 获赞 8 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/langwuzhe/article/details/105033431