Linux服务 Nginx Proxy
正向代理服务器是客户端的代理,代理服务器会代替客户端去请求任何客户端发送给它的地址去寻找资源,然后返回给客户端并且这个资源还可以缓存到本地,供以后请求同一资源的其他客户端使用;例子:Aclient要去google请求一个txt文档,它就会将请求发送给代理服务器,然后代理服务器去帮助Aclient去google请求这个txt资源,然后将这个txt缓存到本地一个份再将这个txt资源返回给Aclient;Aclient又要去请求baidu的一个JPG图片,Aclient还是会将请求发送给代理服务器,代理服务器就会去百度以自己为客户端请求这个JPG图片,然后再返回给客户端;
反向代理服务器是服务器的代理,当客户端向要去某台服务器请求资源时,如果这个网站做了反向代理的话,客户端其实请求的是反向代理服务器,客户端并没有直接接触到后端真正的服务器,这样可以提高服务器的安全性;这个反向代理接受到请求后,会对请求报文进行拆包,分析其请求的地址,如果正好支持对此地址的代理的话,就会重新对其封包,然后以自己为客户端发送给后端真正的服务器,服务器收到请求后会进行处理,然后将响应报文发送给反向代理服务器,反向代理还会对响应报文进行拆包,然后再封装成适合客户端的响应报文,发送给请求客户端;
Note:反代仅支持到部分网站请求资源,而正代支持到所有网站请求资源;
Nginx中后端的服务器一般被称为upstream server(上游服务器);
Nginx做为反向代理服务器可以实现动静分离,将静态资源和动态资源分别放在不同的文件路径或者服务器中,这样可以增加请求速度;
Nginx作为反向代理服务器本身是不提供缓存的,这样做是为了减少负载,但是我们可以让其直接连接外部的缓存服务器,来提供缓存;为什么要提供缓存呢?因为提供缓存可以加速访问速度,因为缓存是以key-value的方式存储的,其中的key是客户端请求的URL经过hash后的结果(存储于内存中),value是请求的资源(存储于磁盘中);都是查找资源,为什么key-value会快呢?这是因为hash的查找方式为O(1),也就是说不管查找的是什么,文件名有多长,其给出结果的时间都是相同的(补充:其实查找资源也是放在文件系统中查找的,但是这里的目录树层级非常的少,所以查找起来更快;比如只有多一个以及子目录,然后将资源都放在以及子目录中,如果资源实在是太多的话就设置二级子目录,以此类推,但是子目录层级不会太深;关于子目录的个数设置请看下文的proxy_cache_path);相对来说:如果不用缓存,而是去文件系统中查找,因为文件系统的存储结构是树状的,查找一个文件要对很多路径进行遍历,这是极其耗费时间的,所以我们会使用缓存来提速;并且反代使用缓存还可以减少自己本身的负载,不用再次封包请求后端服务器,减少cpu的工作,还可以节省网络带宽;在互联网上还有一句话:cache is king!
一般的组建结构为:前段为nginx服务器作为反向代理,而后端进行动静分离,动态服务器做成一个集群,为了增加可靠性,静态服务器也做成一个集群,目的是同样的,但是一般在静态集群前面会搭建缓存服务器(缓存服务器本身也是一个反代),当用户请求静态资源时,如果缓存服务器中没有就去后端的静态资源服务器中请求,并且缓存后端服务响应的资源,再返回给客户端;
Nginx还支持根据后端服务器的负载状况来进行负载均衡调度,如果后端服务器宕机,还可以自动的将其下线,也就是不再将请求发送给这台服务器;
Nginx作为反代的并发:Nginx作为反代时,在前端要监听在某些套接字上,用来接收客户端的请求,在后端要使用某些套接字来向后端upstream server请求资源;一般Linux系统上只有65535个接口,所以平均一下能处理的并发请求数为三万个左右;千万不要小看这三万个,其实对于一些中小型站点已经完全够用了;我们真正使用时也不会让其达到这个数字,这只是理论上限;如果并发量一台Nginx反向代理不够用的话,可以再加一台,然后通过DNS进行轮询调度;
Nginx反向代理模块:ngx_http_proxy_module
可以实现将请求传递给其他服务器;
Nginx反代接收到http请求报文以后,会对其进行拆包已了解其请求的内容,然后会匹配设置的location,如果匹配到的是ngx_http_proxy_module中的某个功能选项(proxy_pass)的话,就会根据信息重新构建报文(以自己为客户端),向其中设置的服务器地址发起请求;
例子:
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /centos6/ {
proxy_pass http://192.168.0.9/;
}
location ~* \.(jpg|png)$ {
proxy_pass http://192.168.0.9;
} ← 当location中的路径为正则表达式时,proxy_pass后面的地址只能是纯地址,后面不可以加路径;比如:proxy_pass http://192.168.0.9/html;是错误的。如果还是用了URL重写的话,最终代理的是重写后的地址;
1.proxy_set_header:允许对传递给代理服务器的请求头重新定义或追加字段。该值可以包含文本、变量及其组合;
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
例子:
location / {
poxy_pass http://192.168.0.9:80/;
proxy_set_header X-Real-IP $remote_addr; ←$remote_addr为客户端的ip地址;我们可以通过设置后端的httpd服务的日志格式将这个变量添加进去,然后查看日志时就可以显示是哪台客户端发起的请求了,默认情况下只有代理服务器的ip地址,不会出现客户端的ip地址的;→LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
proxy_set_header Host $host; ←$host为nginx自带的变量,表示服务器的主机名;可以在官网中查看这些变量所代表的意义;www.nginx.org;
}
2. proxy_http_version:以指定的http版本向外发送代理请求;可以实现客户端连接nginx反向代理服务器时为长连接,而nginx反向代理服务器连接后端upstream server时使用短连接;
Syntax: proxy_http_version 1.0 | 1.1;
Default: proxy_http_version 1.0;
Context: http, server, location
3. proxy_cache:启用代理缓存;
Syntax: proxy_cache zone | off;
Default: proxy_cache off;
Context: http, server, location
4. proxy_cache_path:指明存放缓存的路径;
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default: —
Context: http
levels:用来设置子目录的层级;
key_zone=name:size:在内存中开辟出一块空间来存储key;
例子:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
其中1表示一级子目录的名字为几个字符,2表示二级子目录的名字为两个字符;如果想要设置三级子目录的话,可以在后面接“:”和数字;
例子的结果:
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
5. proxy_cache_methods:设置仅缓存客户端使用特定方法请求的资源;
Syntax: proxy_cache_methods GET | HEAD | POST ...;
Default: proxy_cache_methods GET HEAD;
Context: http, server, location
6. proxy_cache_use_stale:是否使用过期的缓存;比如当后端服务器宕机时,无法请求新的资源(相对于这个过期的缓存来说),这时是否使用现有的缓存响应客户端(这个缓存虽然过期,但是不代表后端服务器的内容也变化了啊,可能这个缓存的资源还是跟后端服务器中的资源是一样的);
Syntax: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
Default: proxy_cache_use_stale off;
Context: http, server, location
7. proxy_cache_valid:自定义缓存时间;
Syntax: proxy_cache_valid [code ...] time;
Default: —
Context: http, server, location
code:为响应码类型;
例子:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
例子:
vim /etc/nginx/nginx.conf
proxy_cache_path /cache/nginx/ levels=1:2 keys_zone=mycache:12m;
mkdir –pv /cache/nginx/
chown nginx:nginx –R /cache/nginx
vim /etc/nginx/cong.d/default.conf
location /bbs/ {
proxy_cache mycache;
proxy_cache_valid 200 20m;
proxy_cache_valid 301 302 10m;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout http_500 http_502;
proxy_pass http://192.168.0.9/bbs/;
proxy_set_header X-Real-IP $remote_addr;
}
service nginx configtest
service nginx reload
浏览器键入:http://192.168.0.7/bbs/
ls –R /cache/nginx/
8. proxy_connect_timeout:设置proxy服务器与upstream server的连接超时时间;
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
9. proxy_hide_header:设置当proxy返回给客户端响应报文时,不封装哪些首部
Syntax: proxy_hide_header field;
Default: —
Context: http, server, location
10. proxy_read_timeout:proxy等待upstream响应的超时时间;
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
11. proxy_cache_bypass:定义什么情况下不缓存;
Syntax: proxy_cache_bypass string ...;
Default: —
Context: http, server, location
例子:
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
Nginx负载均衡模块:ngx_http_upstream_module
1. upstream:定义一组服务器。服务器可以监听不同的端口。此外,可以混合监听TCP和unix域套接字的服务器。
Syntax: upstream name { ... }
Default: —
Context: http
例子:
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
2. server:指定欲进行负载均衡的server地址;
Syntax: server address [parameters];
Default: —
Context: upstream
parameters:
weight=number:指定server的权重;
max_fails=number:指定proxy检查后端upstream server失败多少次后将其标记为失败;
fail_timeout=time:指定检查超时时间;
down:将此server标记为永久不可用状态;
backup:标记此服务器为备用服务器;只要有一个正常服务器可以运行时,备用服务器就不会被启用;
例子:为显示效果,要将之前设置的缓存都注释掉;
在192.168.0.9和192.168.0.13这两台主机上都要开启http服务并且在/var/www/html/这个目录中编辑一下index.html,随便填写一些不同的内容即可;
vim /etc/nginx/nginx.conf 在http{}中添加以下内容
upstream upservers {
server 192.168.0.9;
server 192.168.0.13;
}
vim /etc/nginx/cong.d/default.cong
location /bbs/ {
#proxy_cache mycache;
#proxy_cache_valid 200 20m;
#proxy_cache_valid 301 302 10m;
#proxy_cache_valid any 1m;
#proxy_cache_use_stale error timeout http_500 http_502;
proxy_pass http://upservers/;
proxy_set_header X-Real-IP $remote_addr;
}
浏览器键入:http://192.168.0.7/bbs 然后连续刷新页面;
3. sticky:进行会话绑定;
Syntax: sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];
sticky route $variable ...;
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
Default: —
Context: upstream
4. least_conn:按照最少连接来将请求调度至upstream server(类似于WLC算法);
Syntax: least_conn;
Default: —
Context: upstream
5. keepalive:设置proxy与upstream server的持久连接时间;一般后端为http时不使用持久连接,这样可以提高并发数量,如果后端为缓存服务器的话可以使用持久连接,因为与缓存交互的数据比较多,所以可以减少反复建立和拆除连接的损耗;
Syntax: keepalive connections;
Default: —
Context: upstream
6. health_check:对后端服务器组中的主机进行阶段性的健康状态监测;
Syntax: health_check [parameters];
Default: —
Context: location
Nginx FastCGI模块:ngx_http_fastcgi_module
用来与上游的fastcgi服务器交流数据;因为nginx与httpd不同,没有php的模块,所以只能使用cgi协议;
1. fastcgi_pass:指定上游服务器(PHP)地址;
Syntax: fastcgi_pass address;
Default: —
Context: location, if in location
2. fastcgi_index:设置主页;
Syntax: fastcgi_index name;
Default: —
Context: http, server, location
3. fastcgi_param:设置传递给后端FastCGI服务器(PHP)的参数(路径);
Syntax: fastcgi_param parameter value [if_not_empty];
Default: —
Context: http, server, location
例子(LNMP):关闭防火墙
yum install php-fpm
yum install php-mysql
yum install mysql-server
service php-fpm start
vim /etc/nginx/conf.d/default.conf
location ~ \.php$ {
root /usr/share/nginx/html/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
vim /usr/share/nginx/html/index.php
<?php
phpinfo();
?>
service nginx configtest
service nginx reload
浏览器键入http://192.168.0.7/index.php
4. fastcgi_cache_path:设置缓存路径;
Syntax: fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default: —
Context: http
5. fastcgi_cache:指设置启用缓存的位置;
Syntax: fastcgi_cache zone | off;
Default: fastcgi_cache off;
Context: http, server, location