nginx的基本配置

681 阅读3分钟
前言:一般对于前端而言,不需要太关注nginx配置这个事情,因为一般的公司有运维帮我们去干这件事了,但是对于一些公司而言,nginx的配置是由前端去完成的。这里是对于nginx配置的一些基本认知和使用,用于个人笔记。记得一年级我的老师就告诉我,好记性不如烂笔头。

nginx的好处多多,作为一个前端的第一认知就是反向代理。你问我啥是反向代理,啥是正向代理,请出门左拐百度一下,这里我们就不做赘述了。 

这里我的环境是windows,下载地址kevinworthington.com/downloads/ 。linux上的话命令方式不同,但是大同小异,你可以自己装个虚拟机去做demo。

当我们下载完成后,我们会有如下目录结构

接下来我们打开conf目录下的nginx.conf文件,接下来我们所有的配置都会在这个文件下完成,如果你已经打开了,你的文件当前应该长这样

对于上面每个配置的文字含义,网上很多,小编偷懒,转载其它博客现成的东西。转载自blog.csdn.net/qq_34801169…

#user  nobody;
 
#开启进程数 <=CPU数 
worker_processes  1;
#错误日志保存位置
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#进程号保存文件
#pid        logs/nginx.pid;
#每个进程最大连接数(最大连接=连接数x进程数)每个worker允许同时产生多少个链接,默认1024
events {
    worker_connections  1024;
}
http {
	#文件扩展名与文件类型映射表
    include       mime.types;
	#默认文件类型
    default_type  application/octet-stream;
	#日志文件输出格式 这个位置相于全局设置
    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;
	
	#打开发送文件
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
	#连接超时时间
    keepalive_timeout  65;
	#打开gzip压缩
    #gzip  on;
	
	#设定请求缓冲
	#client_header_buffer_size 1k;
	#large_client_header_buffers 4 4k;
	
	#设定负载均衡的服务器列表
	#upstream myproject {
		#weigth参数表示权值,权值越高被分配到的几率越大
		#max_fails 当有#max_fails个请求失败,就表示后端的服务器不可用,默认为1,将其设置为0可以关闭检查
		#fail_timeout 在以后的#fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器
	#}
	
    #webapp
    #upstream myapp {   
  	# server 192.168.1.171:8080 weight=1 max_fails=2 fail_timeout=30s;   
	# server 192.168.1.172:8080 weight=1 max_fails=2 fail_timeout=30s;   
    #} 
	#配置主机,基于域名、ip和端口
    server {
		#监听端口
        listen       80;
		#监听域名
        server_name  localhost;
        #charset koi8-r;
		
		#nginx访问日志放在logs/host.access.log下,并且使用main格式(还可以自定义格式)
        #access_log  logs/host.access.log  main;
		#返回的相应文件地址
        location / {
            #设置客户端真实ip地址
            #proxy_set_header X-real-ip $remote_addr;		
			#负载均衡反向代理
			#proxy_pass http://myapp;
			
			#返回根路径地址(相对路径:相对于/usr/local/nginx/)
            root   html;
			#默认访问文件
            index  index.html index.htm;
        }
		#配置反向代理tomcat服务器:拦截.jsp结尾的请求转向到tomcat
        #location ~ \.jsp$ {
        #    proxy_pass http://192.168.1.171:8080;
        #}		
		
        #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;
        #}
    }
	
	#主机配置:
	server {
		listen 1234;
		server_name bhz.com;
		location / {
		#正则表达式匹配uri方式:在/usr/local/nginx/bhz.com下 建立一个test123.html 然后使用正则匹配
		#location ~ test {
			## 重写语法:if return (条件 = ~ ~*)
			#if ($remote_addr = 192.168.1.200) {
			#       return 401;
			#}		
			
			#if ($http_user_agent ~* firefox) {
			#	   rewrite ^.*$ /firefox.html;
			#	   break;
			#}			
						
			root bhz.com;
			index index.html;
		}
		
		#location /goods {
		#		rewrite "goods-(\d{1,5})\.html" /goods-ctrl.html;
		#		root bhz.com;
		#		index index.html;
		#}
		
		#配置访问日志
		access_log logs/bhz.com.access.log main;
	}
	
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
    # 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;
    #    }
    #}
}

好了,接下来进入正题。

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

上面我们的server对象其实就是一个配置,在这个配置里,server_name字段就是我们访问的host。当前我们的server_name是localhost,也就是我们的本机,监听的端口号是80端口。接下去我们去启动我们的nginx服务器,你可以直接点击nginx.exe去启动,也可以用cmd命令。接下来我们以命令行为主。

我们打开我们的项目根目录,然后在上面的地址栏输入cmd,再按回车,命令行就会弹出

在命令行中输入start nginx ,再按回车,你就可以看到界面一个黑影一闪而过

为了验证我们的nginx服务器是否启用成功,我们在浏览器中输入localhost:80

如上图所示,我们启动成功了。大家请打开调试模式,看下我红色圈起来的那个。我们可以看到我们实际访问到的是ip为127.0.0.1的地址,这个也是我们本机的ip。因为我们访问localhost的时候,我们的dns会把localhost解析成对应的ip,并且进行访问。也许你会疑惑为什么我们的localhost这个"域名"就会指向我们的本机呢,我们的域名又没备案啥的(乱七八糟幻想一堆),这是因为我们的电脑已经给我们配置好了。如下图你就可以知道为啥了。

按照我上面的地址打开对应的目录,然后再打开hosts文件



我们可以看到,我们的配置文件已经把localhost映射到了127.0.0.1(其实就配置了本机解析)。不好意思扯远了,这个我们当额外知识进行了解。

下面我再介绍另外一种比较麻烦的方式查看运行状态

输入命令 netstat -ano,并且按回车,你会看到如下。看我红色圈起来的部分可知,我们本地的80端口已经被占用了,pid(进程的id)为9832


接下来我们利用pid去查看进程对应的是哪个应用,我们在命令行中输入tasklist|findstr "9832"

我们可以看到如下


从上面可知,正在占用端口的应用就是我们的nginx。既然讲到这里,我们顺便说下怎么利用进程号去关闭应用。输入指令 (针对nginx关闭的不彻底的时候用这种)

taskkill /f /t /im nginx.exe 

第二种我们用的最多的方式就是nginx stop -s

这里抛出个问题,为什么在浏览器访问localhost的时候,我们的nginx能够接受请求?

1.不管是我们的电脑或者是服务器,都是有一个对应的ip地址,我们的nginx会和所在环境的ip关联起来,当然这个ip可以是多个

2.我们在浏览器里访问对应的域名的时候,电脑自身会先去本地host去找该域名映射的ip,如果找不到,就会去请求DNS,并且解析成对应的ip地址,然后去请求这个ip地址 (在host文件中localhost被映射成了127.0.0.1)

3.如果访问的ip地址是nginx关联的ip之一,nginx根据配置,解析请求,进行相应

我们的server_name除了用localhost以外,还可以用其他的吗?当然可以,但是前提是对应的域名有对应的ip。在我们实际的开发中,nginx是架在我们的服务器上的。在我们前端访问接口的时候,我们的接口前面是对应的域名,这个域名会被人员和服务器的ip相绑定起来(备案)。所以当我们访问接口的时候,实际访问的是我们的服务器,服务器上的nginx监听到有人发送请求过来,就会走对应的配置中,执行配置文件中相关的逻辑。

综上所述,我们的localhost并不是可以随意取的。

接下去我们说说location这个配置:

location匹配的区段是哪些? 

比如: www.zx.com/a/b/c?xxxx=1   匹配的区段是  /a/b/c?xxxx=1

location后面关联的符号有哪些?分别是什么意思?

location [=|~|~*|^~|@] pattern{……}  以及  没有修饰符

#没有指定修饰符
location /a {}    
http://baidu.com/ahttp://baidu.com/a?p1http://baidu.com/a/http://baidu.com/abcde
#  =
location = /a {}    
http://baidu.com/a
http://baidu.com/a?p1
# 以下不匹配
http://baidu.com/a/
http://baidu.com/abcde

#  ~  指定的正则表达式要区分大小写
location ~ ^/a$ {}    
http://baidu.com/a
http://baidu.com/a?p1
# 以下不匹配
http://baidu.com/a/
http://baidu.com/A
http://baidu.com/abcde

#  反之 ~* 的意思是不关注大小写

#  ^~ 类似于无修饰符的行为,它区分开头大小写,但是如果模式匹配,则会停止搜索其它模式。windows环境下会有偏差 

root的作用是声明文件所在的路径,常规用法如下

location ~* \.(jpg|png|jpeg)$ {
   #  指定文件路径 一般建议使用绝对路径  linux环境根目录是带/  windows环境是不带/
   root C:\\Users\\jin\\Pictures\\wwwroot\\;
}

关于rewrite的使用方式直接网上copy了一个

#  当我访问www.zx.com/ang的时候,我访问到了www.zx.com/tags/Angular/#  最大的区别是url栏是否发生改变
server {
        #  last url不会变,匹配继续往下执行          
        #  redirect  url会变,继续往下执行,但是不要匹配内容和替换内容重叠,不然停止向下执行
        #  rewrite /angular /tags/Angular/ redirect;
        listen       80;
        server_name  www.zx.com;
        location / {
          rewrite /ang /tags/Angular/ redirect;
          proxy_pass http://blog.zx-io.cn;
        }
    }

redirect 表示临时的重定向 ,只要后端服务是开者的。每次访问都会重定向到对应地址

permanent 表示永久重定向,第一次访问成功后,把后端服务关闭后,访问仍然会重定向到 对应地址

关于break这个flag我需要用代码说明一下


1.当我们访问www.zx.com/ang的时候会被重写成 www.zx.com/tags/Angular/,由于flag是redirect,所以地址栏的地址发生改变

2.根据location匹配跪着我们进入到了第一个location,并且又读到了rewrite,并且我们的目录符合重写规则

3.我们的访问路径又被重写成了www.zx.com/tags/Docker/,由于flag使用了break,所以就算最新改写的地址符合第二个location规则,也不会走到相应逻辑

至于其它flag的情况请见上面的注释,这里不做demo讲解。小编感觉主要要弄清楚rewrite书写的级别(server级别/location级别)就好。

记住,每次修改完demo用 nginx -s reload 命令去重启自己的nginx

-----------------------------------------------------------------------------------------------

以下是对nginx里面的一些变量做一个记录

$arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。

$args #这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah;

$binary_remote_addr #二进制的客户地址。

$body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。

$content_length #请求头中的Content-length字段。

$content_type #请求头中的Content-Type字段。

$cookie_COOKIE #cookie COOKIE变量的值

$document_root #当前请求在root指令中指定的值。

$document_uri #与$uri相同。

$host #请求主机头字段,否则为服务器名称。

$hostname #Set to the machine’s hostname as returned by gethostname

$http_HEADER

$is_args #如果有$args参数,这个变量等于”?”,否则等于”",空值。

$http_user_agent #客户端agent信息

$http_cookie #客户端cookie信息

$limit_rate #这个变量可以限制连接速率。

$query_string #与$args相同。

$request_body_file #客户端请求主体信息的临时文件名。

$request_method #客户端请求的动作,通常为GET或POST。

$remote_addr #客户端的IP地址。

$remote_port #客户端的端口。

$remote_user #已经经过Auth Basic Module验证的用户名。

$request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。

$request_method #GET或POST

$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。

$request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。

$scheme #HTTP方法(如http,https)。

$server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。

$server_name #服务器名称。

$server_port #请求到达服务器的端口号。

$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。


未完待续......