Linux运维 第三阶段 (七) nginx(2)

  1. 云栖社区>
  2. 博客>
  3. 正文

Linux运维 第三阶段 (七) nginx(2)

技术小阿哥 2017-11-28 15:00:00 浏览1052
展开阅读全文

一、相关概念:

代理(你到我这请求我没有,我可以帮你去请求)

 

正向代理(forward proxy内网用户的client想上互联网,通过代理到互联网去取数据,数据返回到代理上,代理构建响应返回至client(代理内网用户访问互联网上服务器的数据);可将正向代理服务器理解为秘书(对内声称只要想上网我什么都能做,但实际是互联网上的某个服务器提供的内容))

 

反向代理(reverse proxy我们的服务器不允许直接访问,在前端放一代理,所有的互联网上的客户端想要访问,得将请求提交至前面的代理上,而代理服务器仅在需要时才找后端服务器;可将反向代理服务器理解为总管(它对外声称它就是web-server,但其实是它后端服务器提供的功能)

 

请求方法(GETPOSTHEADPUTTRACEOPTIONCONNECTIONDELETE

 

常用指令:

proxy_pass(实现反向代理)

fastcgi_passphp的反向代理)

upstream(实现负载均衡)

proxy_cache_pathproxy_cacheproxy_cache_valid(实现缓存功能)

add_header(在协议首部添加标签)

rewriteURL重写)

valid_referers(防盗链功能,结合if实现)

gzip on;(开启此功能可节约带宽,并节省报文到达client的时间,并不是什么情况下都压缩,如果在缓存时候压缩会带来负作用,会降低命中率,如第一次第一个用户请求的内容缓存后压缩了,当第二个用户访问相同内容时将不能从缓存中响应)

gzip_proxied(设置压缩策略,什么情况下压缩,什么情况下不压缩,如有no-cacheexpiredno-storeprivateauth

gzip_comp_level(设置响应时的压缩比,1-9个级别,默认1

 

二、操作及相关要点(1、反向代理;2、负载均衡;3、缓存;4rewritereferer5、读写分离):

准备:

node1192.168.41.134 安装nginx

node2192.168.41.135 安装httpd

node3192.168.41.136 安装httpd

 

1、反向代理:

在《第三阶段(十五)理解LNMP》中,提供的对fastcfgi的反向代理:

        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;

        }

syntaxproxy_pass  URL;

 

1)实现对主页反向代理(将locationroot换为proxy_pass):

node1-side

[root@node1 ~]# vim /etc/nginx/nginx.conf

    server {

       listen       80;

       server_name  www.magedu.com;

        location / {

            proxy_pass http://192.168.41.135:80;

        }

         ……

}

node2-side

[root@node2 ~]# cd /var/www/html

[root@node2 html]# cat index.html

RS1.magedu.com

[root@node2 html]# service httpd status

httpd (pid 10858) 正在运行...

wKiom1aKXNegEUkNAABKiTAtLJ4665.jpg

2)实现对指定的URI反向代理:

node1-side

[root@node1 ~]# cd /etc/nginx

[root@node1 nginx]# vim nginx.conf

        location /forum {

            proxy_pass http://192.168.41.135:80/bbs;

        }

node2-side

[root@node2 html]# cd

[root@node2 ~]# cd /var/www/html

[root@node2 html]# mkdir bbs

[root@node2 html]# echo "bbs.magedu.com" > bbs/index.html

测试时在浏览器上输入URL会自动跳转至后端192.168.41.135/bbs

wKioL1aKXQqSjw8sAABJ87EJ__U003.jpg

wKiom1aKXPOBX3lIAABNcMdyAhQ340.jpg

 

3)若在location中使用模式匹配,则在proxy_pass所指定的后端server上不能使用uri路径,否则提示配置文件语法错误:

node1-side

[root@node1 nginx]# vim nginx.conf(此例中/forum会自动附加在后端server上,如http://192.168.41.134/forum-->http://192.168.41.135/forumproxy_set_header指令表示将用户请求转至后端服务器上时构建首部信息,目的在后端server上的访问日志记录的是client自身IP而不是代理的IP,为方便以后分析使用(若不添加此项后端server记录的是代理的地址,以后分析这些数据是没意义的);$remote_addr表示client地址,是nginx core模块提供的变量,core模块提供的变量有很多,如$remote_port,$remote_user,$request_filename,$request_body,$request_method,$request_uri,$schema,$server_addr,$server_name,$server_port,$server_protocol,$uri等等,可以直接引用)

        location ~* ^/forum {

            proxy_pass http://192.168.41.135:80;

            proxy_set_header X-Real-IP $remote_addr;

        }

[root@node1 nginx]# !service

service nginx reload

nginx: the configuration file/etc/nginx/nginx.conf syntax is ok

nginx: configuration file/etc/nginx/nginx.conf test is successful

重新载入 nginx                                           [确定]

node2-side

[root@node2 html]# mkdir forum

[root@node2 html]# echo "forum.magedu.com" > forum/index.html

[root@node2 html]# vim /etc/httpd/conf/httpd.conf(更改如下配置,真正实现让后端server记录的日志中是真正的client地址)

LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\"\"%{User-Agent}i\"" combined

[root@node2 html]# !service

service httpd restart

停止 httpd                                              [确定]

正在启动 httpd                                           [确定]

wKiom1aKXQbCjJwyAABJRK0SeAc608.jpg

[root@node2 html]# tail -2 /var/log/httpd/access_log(第一条记录是更改前的是代理的地址,第二条记录则是真正client的地址,由于此处虚拟机网络设置的是NAT模式(我工作的场所需要安装iNODE客户端才能连接公司内网,所以只有虚拟机设置了NAT模式才能与本机连接)所以显示的是网关,这里就不再更改网络配置了)

192.168.41.134 - - [23/Dec/2015:06:05:59+0800] "GET /forum/ HTTP/1.0" 304 - "-" "Mozilla/5.0(Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.26Safari/537.36 OPR/32.0.1948.4 (Edition beta)"

192.168.41.1 - - [23/Dec/2015:06:07:51+0800] "GET /forum/ HTTP/1.0" 304 - "-" "Mozilla/5.0(Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.26Safari/537.36 OPR/32.0.1948.4 (Edition beta)"

 

 

2、负载均衡load balance

upstream

将后端多个服务器归并为一组,在组中定义LB调度算法;

http{}之内server{}之外定义;

upstream中的server定义每一个后端服务器,server之后只能跟IP或名称不能加入http://,之后还可跟其它参数,如weight=NUMmax_fails=NUMfail_timeout=TIMEbackup,其中有weight表示使用rr算法,默认值是1,若没写weightserver上方也没写schedule表示此server不参加LBbackup(类似keepalived中的sorry_server)表示备用服务器,可用于RS全挂掉后在反向代理服务器上提供错误页面;

schedule调度算法(rrip_hashleast_conn),默认roundrobinip_hash(始终将同一client的请求转至同一RS

 

node1-side

[root@node1 nginx]# !vimwebsrvs为自定义的组名)

vim nginx.conf

    upstream websrvs {

        server 192.168.41.135 weight=1 max_fails=2 fail_timeout=2;

        server 192.168.41.136 weight=1 max_fails=2 fail_timeout=2;

        server 127.0.0.1:8080 backup;

    }

    server {

        listen       80;

        server_name  www.magedu.com;

        location / {

            proxy_pass http://websrvs;

            proxy_set_header X-Real-IP$remote_addr;

        }

    }

    server {

        listen 8080;

        server_name localhost;

        location / {

            root /web/errorpages;

            index index.html;

        }

    }

[root@node1 nginx]# mkdir /web/errorpages-pv

mkdir: 已创建目录"/web/errorpages"

[root@node1 nginx]# echo "Sorry,the server is maintaining" > /web/errorpages/index.html

[root@node1 nginx]# !service

service nginx reload

nginx: the configuration file/etc/nginx/nginx.conf syntax is ok

nginx: configuration file/etc/nginx/nginx.conf test is successful

重新载入 nginx                                           [确定]

 

node3-side

[root@node3 ~]# cd /var/www/html

[root@node3 html]# vim index.html

[root@node3 html]# echo "RS2.magedu.com" > index.html

[root@node3 html]# service httpd start

正在启动 httpd                                           [确定]

 

测试:

wKioL1aKXTmwY3jcAAAhoXEdEUI274.jpg

wKioL1aKXUWTUiQEAAAgI_voEo0160.jpg

[root@node2 html]# service httpd stop

停止 httpd                                              [确定]

[root@node3 html]# service httpd stop

停止 httpd                                               [确定]

wKiom1aKX-uiU9oJAAAkHsuD1lg096.jpg

 

schedule使用ip_hash,则不能使用backup,否则会报配置文件语法错误:

    upstream websrvs {

        ip_hash;

        server 192.168.41.135 max_fails=2 fail_timeout=2;

        server 192.168.41.136 max_fails=2 fail_timeout=2;

    }

 

[root@node1 nginx]# netstat -tnlua | awk '/:80/{S[$NF]++}END{for (A in S) print A,S[A]}'

TIME_WAIT 4

ESTABLISHED 1

LISTEN 2

 

LB扩展(当后端有不同的服务器组,如app-server组处理动态内容,image-server组,file-server组):

upstream phpsrvs  {

 server……;

 server……;

}

location ~*  \.php$  {

 fastcgi_pass  http://phpsrvs;

}

upstream imagesrvs  {

 server……;

 server……;

}

location ~*  “\.(jpg|jpeg|png|gif)$”  {

 proxy_pass  http://imagesrvs;

}

upstream filesrvs  {

 server……;

 server……;

}

location /  {

 root  /web/htdoc;

 index  index.html;

}

 

3、缓存:

nginx有两类缓存cache:共享内存,主要用于键存储(缓存的查找键key)及缓存对象的元数据;磁盘空间(存储数据)

proxy_cache_pathhttp{}之内server{}之外定义,该指令定义的是nginx有缓存功能(缓存能力),但具体谁要用到缓存要在location{}中使用proxy_cache指令定义

注:缓存是分级的,浏览器自己的缓存是私有缓存(private cache),而nginx的缓存是公共的(public cache,所有用户都可用)

注:nginx不仅可以缓存web object(见以下举例),也可为日志提供缓存功能(client的每次访问都要记入日志,为日志打开缓冲区),还可为fastcgi打开缓存功能

open_log_cache(日志缓存,先写入内存中,在适当时间再同步到文件中)

open_file_cache(打开文件缓存,nginx作为server,要处理用户所请求的内容,要打开很多文件响应给用户,尤其是元数据,打开后缓存在nginx所管理的内存中,加速响应过程)

fastcgi_cache(慎用,若第一次将php的执行结果缓存好,之后后端server的处理逻辑改了,这时响应的还是之前的内容)

注:nginxlimit也基于共享内存实现

 

syntax

proxy_cache_path  PATH [levels=LEVELS] keys_zone=NAME:SIZE [max_size=SIZE];

其中levels=LEVELS(定义缓存目录(子目录级别,子目录级别最多三级且每级目录名最多两个字符),目的使命名方式简单,如要缓存1000W万个对象,若都放到一个目录下则需要有1000W个变化,命名会复杂,若一级子目录有10个,则每个子目录下有100W个对象,再分二级、三级子目录,则其下的每个子目录有1W个对象,不仅使得命名容易也使定位查找更快,而且路径引用也不复杂)

例:levels=1:21表示一级子目录,2表示二级子目录;同时1又表示一级子目录由1个字符组成,2同时又表示二级子目录由2个字符组成,最多可有三级子目录,每级子目录最多2个字符),常用的有levels=1:2levels=1:2:1levels=1:1:1

keys_zone=NAME:SIZE(给共享内存命名,重要,此处的名字要被使用缓存者引用)

max_size=SIZE(缓存空间并不是越大越好,大了管理会复杂,小了清理缓存会降低命中率(缓存空间若存满了,由cache_manager根据LRU算法将之前没用到的缓存清理掉,若刚清出去又要用,这就未命中,又要重新获取),空间多大合适,要根据实际情况测试,如果增大空间命中率提升,则这个空间就要加大)

proxy_cache ZONE_NAME;define a shared memory zone used for caching

proxy_cache_valid  [CODE] TIME;sets caching time for different response codes

 

[root@node1 nginx]# !vim

vim nginx.conf

proxy_cache_path /etc/nginx/cache/first levels=1:2:1 keys_zone=first:20m max_size=1g;

  upstream websrvs {

       server 192.168.41.135 weight=1 max_fails=2 fail_timeout=2;

       server 192.168.41.136 weight=1 max_fails=2 fail_timeout=2;

       server 127.0.0.1:8080 backup;

    }

   server {

       listen       80;

       server_name  www.magedu.com;

        location / {

           proxy_pass http://websrvs;

           proxy_set_header X-Real-IP $remote_addr;

            proxy_cache first;

            proxy_cache_valid 200 10m;

       }

    }

[root@node1 nginx]# mkdir cache/first -pv

mkdir: 已创建目录 "cache"

mkdir: 已创建目录"cache/first"

[root@node1 nginx]# service nginx reload

验证:测试时因为缓存命中了,LB也不起作用将不再找后端server,使用浏览器快捷键ctrl+F5(或shift+F5)可控制不使用浏览器自身缓存(在开发者工具:request headersno-cache),使用add_header(每一次构建响应时为client增加新的标签)这样在client就可看出缓存是否命中

wKioL1aKYUGR8b2xAACwBycvCs4678.jpg

[root@node1 nginx]# !vim$server_addr服务器地址,$upstream_cache_status状态有HITMISSEXPIREDBYPASSUPDATINGSTALEREVALIDATED

vim nginx.conf

   server {

       listen       80;

       server_name  www.magedu.com;

        add_header X-Via $server_addr;

        add_header X-Cache $upstream_cache_status;

       location / {

           proxy_pass http://websrvs;

           proxy_set_header X-Real-IP $remote_addr;

           proxy_cache first;

           proxy_cache_valid 200 10m;

       }

}

wKiom1aKYUGg1JXwAACR14FSqsI491.jpg

注:此处语句可合并为:add_header X-Cache “$upstream_cache_status from $server_addr”;

$upstream_cache_status(该变量是ngx_http_upstream_module提供的)

$server_addr(该变量是由ngx_http_core_module提供的)

 

[root@node1 nginx]# service nginx stop

停止 nginx                                              [确定]

[root@node1 nginx]# ls cache/first/2/b3/7/bc9c9eed354a58d3c2bde97d0a7d7b32

[root@node1 nginx]# rm -rf cache/first/*(将缓存删除,再次重新验证)

[root@node1 nginx]# service nginx start

正在启动 nginx                                           [确定]

wKiom1aKYU_j_gtdAAB1TC6ckYs652.jpg

再次ctrl+F5刷新

wKioL1aKYYuRVYFXAACCIz4VDE4907.jpg

 

[root@node1 nginx]# cp nginx.conf nginx.conf.example

[root@node1 nginx]# cp nginx.conf.default nginx.conf

cp:是否覆盖"nginx.conf" y

 

4rewritereferer

ngx_http_rewrite_module支持正则表达式,指令有breakreturnrewriteif

if (condition) {……}

测试:单目;双目(=|!=|~|!~|~*|!~*

注:~,区分字符大小写,匹配为真,不匹配为假;!~,区分字符大小写,不匹配为真,匹配为假;~*,不区分字符大小写,匹配为真,不匹配为假;!~*,不区分字符大小写,不匹配不真,匹配为假;=,精确匹配,匹配为真,不匹配为假;!=,精确匹配,不匹配为真,匹配为假

例:if ($request_method = “POST”) {}

if ($request_uri ~* “/forum” {}

 

rewrite REGEX  REPLACEMENT  [FLAG];(用在serverlocationif上下文中)

FLAG有四个值:

last(本次重写完成之后,重启下轮检查)

break(本次重写结束之后,直接执行后续操作,通常在某个非根下使用break

redirect302,临时重定向,returns a temporary redirect with the 302 code

permanent301,永久重定向,returns a permanent redirect with the 301 code

 

1(跨服务器重定向):

[root@node1 nginx]# vim nginx.conf

       location / {

           root   html;

           index  index.html index.htm;

            rewrite ^/bbs/(.*)$ http://192.168.41.135/forum/$1;

       }

[root@node1 nginx]# service nginx restart

[root@node2 html]# cat /var/www/html/forum/index.html

forum.magedu.com

测试:

wKioL1aKYaORDB7FAABLyPo5KA4301.jpg

wKiom1aKYZuQHWmtAACKl5Zbhpk920.jpg

 

2(本机内重定向,隐式重定向,client看不出来状态码正常200):

[root@node1 nginx]# !vim

vim nginx.conf

       location / {

           root   html;

           index  index.html index.htm;

            rewrite ^/bbs/(.*)$ /forum/$1;

       }

[root@node1 nginx]# mkdir /usr/html/forum

[root@node1 nginx]# echo "the serveris nginx,134" > /usr/html/forum/index.html

[root@node1 nginx]# !service

wKiom1aKYcTxFGN-AACKpi7Co8w244.jpg

补充:若出现循环,则会持续定向10次自动退出,如:

rewrite  “^/bbs/(.*)/images/(.*)\.jpg$”  http://www.magedu.com/bbs/$2/images/$1.jpg  last;

 

 

ngx_http_referer_modulengx_http_referer_moduleis used to block access to a site for requests with invalid values in the “referer”header field,定义哪些引用有效,防盗链,常用的指令valid_referers(定义有效的引用,specifies the “referer” request header field values that will causethe embedded $invalid_referer variable to be set to an empty string

例:

location /photos/  {

  valid_referers  none blocked  www.mydomain.com  mydomain.com;

  if ($invalid_referer)  {

return  403;

  }

}

注:none(在地址栏输入的,the “referer” field is missing in the request header

blocked(类似启用防火墙法则,只要valid_referers这行中没有定义的就是不合法的,the “referer” field is present in the request header,but its valuehas been deleted by a firewall or proxy server; such values are strings that donot start with http://or https://

 

 

5、读写分离(指定仅允许后端某一server可上传文件,后端另一server可访问):

webDAVweb-based distributed authoring and versioning),一种基于HTTP/1.1的通信协议,并扩展了HTTP/1.1,在GETPOSTHEAD等几个HTTP方法以外添加了一些新的方法,使应用程序可直接对web server直接读写,并支持写文件锁定locking和解锁unlock,还可支持文件的版本控制

 

node2-side

[root@node2 html]# vim /etc/httpd/conf/httpd.conf

……

LoadModule dav_module modules/mod_dav.so

LoadModule dav_fs_modulemodules/mod_dav_fs.so

<Directory"/var/www/html">

……

Dav on

……

</Directory>

[root@node2 html]# service httpd restart

[root@node2 html]# setfacl -m u:apache:rwx /var/www/html

[root@node2 html]# getfacl /var/www/html

getfacl: Removing leading '/' from absolutepath names

# file: var/www/html

# owner: root

# group: root

user::rwx

user:apache:rwx

group::r-x

mask::rwx

other::r-x

 

node3-side

[root@node3 ~]# cat /var/www/html/index.html

RS2.magedu.com

 

node1-side

[root@node1 nginx]# !vim

vim nginx.conf

       location / {

            proxy_pass http://192.168.41.136;

            if ($request_method ="PUT") {

                proxy_pass http://192.168.41.135;

            }

       }

[root@node1 nginx]# !service

service nginx reload

nginx: the configuration file/etc/nginx/nginx.conf syntax is ok

nginx: configuration file/etc/nginx/nginx.conf test is successful

 

验证:读取

wKiom1aKYfDRUEbxAAAkVAuDqeU674.jpg

验证:上传

[root@node1 nginx]# curl -T /etc/hosts http://192.168.41.134(上传文件)

<!DOCTYPE HTML PUBLIC "-//IETF//DTDHTML 2.0//EN">

<html><head>

<title>201 Created</title>

</head><body>

<h1>Created</h1>

<p>Resource /hostshas been created.</p>

<hr />

<address>Apache/2.2.15 (Red Hat)Server at 192.168.41.135 Port 80</address>

</body></html>

wKiom1aKYf2DuTfnAABsaD1EGqw761.jpg

注:此处未将135136做同步,所以只能直接访问192.168.41.135/hosts

 

 

 



本文转自 chaijowin 51CTO博客,原文链接:http://blog.51cto.com/jowin/1731505,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术小阿哥
+ 关注