nginx的一些使用场景

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。很多时候,在开发、测试环境下,我们都得自己去配置Nginx,其实就是去配置nginx.conf来实现我们想要的功能。


一、反向代理

反向代理应该是Nginx使用最多的功能了,反向代理是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部的服务器上,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

简单来说就是真实的服务器不直接暴露给外部网络访问,而是使用一台代理服务器,代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络,可以进行数据交互。当然也可能是同一台服务器端口不同而已。

反向代理通过proxy_pass指令来实现,配置起来特别方便。

启动一个Java Web项目,端口号为8080


server {
    listen  81;#访问端口
    server_name  localhost;#此处必须是用户浏览器内输入的IP或域名

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host:$server_port;
        # 设置用户ip地址
         proxy_set_header X-Forwarded-For $remote_addr;
         # 当请求服务器出错去寻找其他服务器
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; 
    }
}

当我们访问localhost:81的时候,就相当于访问 localhost:8080了


二、负载均衡

负载均衡也是Nginx使用比较多的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

简单来说就是当有2台或2台以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载均衡策略,还有2种常用的第三方策略。

负载均衡通过upstream指令来实现。

1. RR(round robin :轮询 默认)

每个请求按时间顺序逐一分配到不同的后端服务器,也就是说第一次请求分配到第一台服务器上,第二次请求分配到第二台服务器上,如果只有两台服务器,第三次请求继续分配到第一台上,这样循环轮询下去,也就是服务器接收请求的比例是 1:1:1, 如果服务器down掉,能自动切换。轮询是默认配置,不需要太多的配置

同一个项目分别使用8081/8082/8083端口启动项目


upstream web_servers {  
   server 192.168.0.101:8081;  
   server 192.168.0.101:8082;  
   server 192.168.0.101:8083;
}

server {
    listen       81;
    server_name  localhost;
    #access_log  logs/host.access.log  main;

    location / {
        proxy_pass http://web_servers;
        # 必须指定Header Host
        proxy_set_header Host $host:$server_port;
    }
 }
 

访问地址仍然可以获得响应 http://localhost:81/workflow/listpage,这种方式是轮询的,可以在不同端口项目中看日志进行验证

2. 权重

指定轮询几率,weight和访问比率成正比, 也就是服务器接收请求的比例就是各自配置的weight的比例,用于后端服务器性能不均的情况,比如服务器性能差点就少接收点请求,服务器性能好点就多处理点请求。


upstream web_servers {
    server 192.168.0.101:8081 weight=2;
    server 192.168.0.101:8082 weight=3;
    server 192.168.0.101:8083 weight=4 backup;
}

上面配置是5次请求有2次被分配到8081上,其他3次分配到8082上,可以看出权重越高,在被访问的概率越大。
backup是指热备,只有当8081和8082都宕机的情况下才走8083

3. ip_hash

上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,这样肯定是不行的,那么怎么解决这个问题呢。

我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

配置如下:


upstream web_servers {
    ip_hash;
    server 192.168.0.101:8081;
    server 192.168.0.101:8082;
    server 192.168.0.101:8083;
}

4. fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。


upstream web_servers {
    server 192.168.0.101:8081;
    server 192.168.0.101:8082;
    server 192.168.0.101:8083;
    fair;
}

5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。


upstream web_servers {
    server 192.168.0.101:8081;
    server 192.168.0.101:8082;
    server 192.168.0.101:8083;
    hash $request_uri;
    hash_method crc32; #hash算法
}


三、HTTP服务器

Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。

  1. 首先在文档根目录/usr/local/var/www下创建html目录, 然后在html中放一个index1.html;

  2. 配置nginx.conf中的server


user sange staff;
   
http {
    server {
        listen       81;
        server_name  localhost;
        client_max_body_size 1024M;
        
        # 默认location
        location / {
            root   /usr/local/var/www/html;
            index  index.html index.htm;
        }
    }
}

  1. 访问测试

http://localhost:81/ 指向/usr/local/var/www/index.html, index.html是安装nginx自带的html
http://localhost:81/index1.html 指向/usr/local/var/www/html/index1.html

  1. 指令简介
server:用于定义服务,http中可以有多个server块
listen:指定服务器侦听请求的IP地址和端口,如果省略地址,服务器将侦听所有地址,如果省略端口,则使用标准端口
server_name:服务名称,用于配置域名
location:用于配置映射路径uri对应的配置,一个server中可以有多个location, location后面跟一个uri,可以是一个正则表达式, / 表示匹配任意路径, 当客户端访问的路径满足这个uri时就会执行location块里面的代码
root:根路径,当访问http://localhost:81/index1.html,“/index1.html”会匹配到”/”uri, 找到root为/usr/local/var/www/html,用户访问的资源物理地址=root + uri = /usr/local/var/www/html + /test.html=/usr/local/var/www/html/test.html
index:设置首页,当只访问server_name时后面不跟任何路径是不走root直接走index指令的;如果访问路径中没有指定具体的文件,则返回index设置的资源,如果访问http://localhost:81/html/ 则默认返回index.html

  1. location uri正则表达式
	. :匹配除换行符以外的任意字符
	? :重复0次或1次
	+ :重复1次或更多次
	* :重复0次或更多次
	\d :匹配数字
	^ :匹配字符串的开始
	$ :匹配字符串的结束
	{n} :重复n次
	{n,} :重复n次或更多次
	[c] :匹配单个字符c
	[a-z] :匹配a-z小写字母的任意一个
	(a|b|c) : 属线表示匹配任意一种情况,每种情况使用竖线分隔,一般使用小括号括括住,匹配符合a字符 或是b字符 或是c字符的字符串
	\ 反斜杠:用于转义特殊字符
	小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。


四、静态资源服务器

在实际项目开发中经常会用到静态资源功能,通常会提供一个上传的功能,其他应用如果需要静态资源就从该静态服务器中获取。

在/usr/local/var/www 下分别创建images和img目录,分别在每个目录下放一张test.jpg

http {
    server {
        listen       81;
        server_name  localhost;

        set $doc_root /usr/local/var/www;

        # 默认location
        location / {
            root   /usr/local/var/www/html;
            index  index.html index.htm;
        }

        location ^~ /images/ {
            root $doc_root;
       }

       location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
           root $doc_root/img;
       }
    }
}

自定义变量使用set指令,语法 set 变量名值;引用使用变量名值;引用使用变量名; 这里自定义了doc_root变量。

静态服务器location的映射一般有两种方式:

使用路径,如 /images/ 一般图片都会放在某个图片目录下,
使用后缀,如 .jpg、.png 等后缀匹配模式
访问http://localhost:81/test.jpg 会映射到 $doc_root/img

访问http://localhost:81/images/test.jpg 当同一个路径满足多个location时,优先匹配优先级高的location,由于^~ 的优先级大于 ~, 所以会走/images/对应的location

常见的location路径映射路径有以下几种:

=    进行普通字符精确匹配。也就是完全匹配。
^~     前缀匹配。如果匹配成功,则不再匹配其他location。
~    表示执行一个正则匹配,区分大小写
~*     表示执行一个正则匹配,不区分大小写
/xxx/  常规字符串路径匹配
/    通用匹配,任何请求都会匹配到

location优先级

当一个路径匹配多个location时究竟哪个location能匹配到时有优先级顺序的,而优先级的顺序于location值的表达式类型有关,和在配置文件中的先后顺序无关。相同类型的表达式,字符串长的会优先匹配。
以下是按优先级排列说明:

等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项,停止搜索。
^~类型表达式,不属于正则表达式。一旦匹配成功,则不再查找其他匹配项,停止搜索。
正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
常规字符串匹配类型。按前缀匹配。
/ 通用匹配,如果没有匹配到,就匹配通用的
优先级搜索问题:不同类型的location映射决定是否继续向下搜索

等号类型、^~类型:一旦匹配上就停止搜索了,不会再匹配其他location了
正则表达式类型(~ ~*),常规字符串匹配类型/xxx/ : 匹配到之后,还会继续搜索其他其它location,直到找到优先级最高的,或者找到第一种情况而停止搜索
location优先级从高到底:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

location = / {
    # 精确匹配/,主机名后面不能带任何字符串 /
    [ configuration A ]
}

location / {
    # 匹配所有以 / 开头的请求。
    # 但是如果有更长的同类型的表达式,则选择更长的表达式。
    # 如果有正则表达式可以匹配,则优先匹配正则表达式。
    [ configuration B ]
}

location /documents/ {
    # 匹配所有以 /documents/ 开头的请求,匹配符合以后,还要继续往下搜索。
    # 但是如果有更长的同类型的表达式,则选择更长的表达式。
    # 如果有正则表达式可以匹配,则优先匹配正则表达式。
    [ configuration C ]
}

location ^~ /images/ {
    # 匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找,停止搜索。
    # 所以,即便有符合的正则表达式location,也不会被使用
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    # 匹配所有以 gif jpg jpeg结尾的请求。
    # 但是 以 /images/开头的请求,将使用 Configuration D,D具有更高的优先级
    [ configuration E ]
}

location /images/ {
    # 字符匹配到 /images/,还会继续往下搜索
    [ configuration F ]
}


location = /test.htm {
    root   /usr/local/var/www/htm;
    index  index.htm;
}

注意:location的优先级与location配置的位置无关


五、常用指令

  1. return指令

返回http状态码 和 可选的第二个参数可以是重定向的URL

location /permanently/moved/url {
    return 301 http://www.example.com/moved/here;
}
  1. rewrite指令

重写URI请求 rewrite,通过使用rewrite指令在请求处理期间多次修改请求URI,该指令具有一个可选参数和两个必需参数。

第一个(必需)参数是请求URI必须匹配的正则表达式。

第二个参数是用于替换匹配URI的URI。

可选的第三个参数是可以停止进一步重写指令的处理或发送重定向(代码301或302)的标志

location /users/ {
    rewrite ^/users/(.*)$ /show?user=$1 break;
}
  1. error_page指令

error_page指令可以配置Nginx返回自定义页面以及错误代码,替换响应中的其他错误代码,或将浏览器重定向到其他URI。如下error_page指令指定要返回404页面错误代码的页面

error_page 404 /404.html;
  1. 日志

访问日志:需要开启压缩 gzip on; 否则不生成日志文件,打开log_format、access_log注释

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  /usr/local/etc/nginx/logs/host.access.log  main;

gzip  on;
  1. deny 指令
# 禁止访问某个目录
location ~* \.(txt|doc)${
    root $doc_root;
    deny all;
}
  1. 内置变量

nginx的配置文件中可以使用的内置变量以$开始,部分预定义的变量的值是可以改变的。

$host     #请求头的值,以下顺序获得:请求行中的host、请求头中的Host、配置文件中匹配到的server_name
$remote_addr    #客户端ip地址
$remote_port    #客户端端口
$remote_user    #基本身份验证随附的用户名
$http_cookie    #Cookie请求头的值
$http_user_agent    #用户代理
$cookie_name    #Cookie中名为name的值    
$http_referer   #Http-Referer请求头的值
$cookie_name	#名为name的cookie
$protocol		#与客户端通信的协议: TCP或UDP(1.11.4)
$hostname		#运行nginx的服务器主机名
$server_name	#接受请求的服务器主机名
$body_bytes_sent	#发送给客户端的字节数
$connection_requests	#通过连接发出的当前请求数
$limit_rate		#用于设置响应的速度限制
$time_local		#通用日志格式的本地时间
$status			#响应状态返回码
$request_time   #请求处理时间
$proxy_add_x_fowarded_for	#在客户端传递来的X-Forwarded-For请求头后面追加$remote_addr(用逗号分隔)	如果客户端没有传递X-Forwarded-For请求头,那么该变量等于$remote_addr
$msec	#以毫秒为单位的当前时间
$scheme	#请求模式,http或https
$nginx_version	#Nginx版本
$pid			#工作进程的PID
$arg_name		#请求行中的参数,$arg_a=1,$arg_b=2,若无参数则为空字符串
$is_args		#请求行中是否包含参数,若包含,则$is_args=?,否则为空字符串
$args			#请求行中的全部参数,$args=a=1&b=2,若无参数则为空字符串
$request		#完整的原始的请求行,GET /nginx/varindex?a=1&b=2 HTTP/1.1
$request_method	#请求方法,如GET、POST
$request_uri	#完整的原始请求URI,访问的URL除去域名(或IP)和port,如/nginx/varindex?a=1&b=2
$document_uri/$uri	#请求规范化以后的URI,可能与$request_uri不同,值可能随请求的处理过程而改变
$server_protocol	#请求的协议版本,如HTTP/1.0
  1. 其他常用指令

上面整理的都是nginx.config 中使用的一些配置,在实际使用中其实经常会用到一下命令,比如每次修改配置文件后需要重启 等等,整理如下

nginx -s reopen #重启Nginx
nginx -s reload #重新加载Nginx配置文件,然后以优雅的方式重启Nginx
nginx -s stop #强制停止Nginx服务
nginx -s quit #优雅地停止Nginx服务(即处理完所有请求后再停止服务)
nginx -t #检测配置文件是否有语法错误,然后退出
nginx -?,-h #打开帮助信息
nginx -v #显示版本信息并退出
nginx -V #显示版本和配置选项信息,然后退出
nginx -t #检测配置文件是否有语法错误,然后退出
nginx -T #检测配置文件是否有语法错误,转储并退出
nginx -q #在检测配置文件期间屏蔽非错误信息
nginx -p prefix #设置前缀路径(默认是:/usr/share/nginx/)
nginx -c filename #设置配置文件(默认是:/etc/nginx/nginx.conf)
nginx -g directives #设置配置文件外的全局指令
killall nginx #杀死所有nginx进程

以上是对nginx的一些简单整理,为了看起来方便简洁文件中多余的注释内容全部删除了,然而在实际使用过程中可能会将各种功能组合使用,原理都是相同的,大家在使用的时候还是要因地制宜灵活使用。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值