Nginx(高级配置)+搭建LNMP
网页,网页的重写功能,反向代理和负载均衡,以及搭建LNMP架构安装论坛
一、网页
1. 网页状态页
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
nginx
只需要在location语句块下添加既可访问状态页
location /nginx_status {
stub_status;
}
出于安全考虑应该为其添加验证模块
location /nginx_status {
stub_status;
auth_basic "xxxxx";
auth_basic_user_file /apps/nginx/conf.d/.httpuser;
//用户密码位置
allow 127.0.0.1;
deny all;
//也可以只允许本机访问
}
2. 第三方模块
echo模块
开源的echo模块 github.com/openresty/e...
bash
[root@localhost opt]#yum install git -y
//安装git
[root@localhost opt]#git clone https://github.com/openresty/echo-nginx-module.git
./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/opt/echo-nginx-module-master
//指明模块位置
make && make install
//重新编译安装
//必须重启nginx服务使用
3. 变量
3.1 内置变量
nginx
$remote_addr;
//存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
//此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔
$args;
//变量中存放了URL中的参数
如:http://www.yyds.com/main/index.do?id=20190221&partner=search
#返回结果为: id=20190221&partner=search
$document_root;
//保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html。
$document_uri;
//保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比
如:http://www.yyds.com/main/index.do?id=20190221&partner=search会被定义为/main/index.do
//返回结果为:/main/index.do
$host;
//存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
//如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;
//客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
//已经经过Auth Basic Module验证的用户名
$request_body_file;
//做反向代理时发给后端服务器的本地资源的名称
$request_method;
//请求资源的方式,GET/PUT/DELETE等
$request_filename;
//当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html
$request_uri;
//包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?id=20190221&partner=search
$scheme;
//请求的协议,例如:http,https,ftp等
$server_protocol;
//保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
//保存了服务器的IP地址
$server_name;
//请求的服务器的主机名
$server_port;
//请求的服务器的端口号
$http_<name>
//name为任意请求报文首部字段,表示记录请求报文的首部字段
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores
//用下划线代替横线
$http_user_agent;
//客户端浏览器的详细信息
$http_cookie;
//客户端的cookie信息
$cookie_<name>
//name为任意请求报文首部字部cookie的key名
$http_<name>
//name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
arbitrary request header field; the last part of a variable name is the field
name converted to lower case with dashes replaced by underscores //用下划线代替横线
$sent_http_<name>
//name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
$arg_<name>
//此变量存放了URL中的指定参数,name为请求url中指定的参数
//对比 变量 $arg 是全部,如果要id 如下$arg_id;
3.2 自定义变量
假如需要自定义变量名称和值,使用指令set $variable value;
nginx
Syntax: set $variable value;
Default: ---
Context: server, location, if
nginx
location /test {
set $name wwww;
echo $name;
//可以自定义一个变量
set $my_port $server_port;
echo $my_port;
//也可以将内置变量赋值给另一个变量
}
4. 自定义访问日志
可自由指定日志格式
nginx
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
log_format test '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
格式可以定义多个
//注意如果开启 include 注意定义自配置文件与 日志格式的上下关系, 日志格式一定要在 include 之前 否则会不生效。
5. Nginx的压缩功能
支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。
压缩功能是依赖于模块 ngx_http_gzip_module
nginx
//启用或禁用gzip压缩,默认关闭
gzip on | off;
//压缩比由低到高从1到9,默认为1
gzip_comp_level level;
//禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
//gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
//启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
//指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
//指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
//如果启用压缩,是否在响应报文首部插入"Vary: Accept-Encoding",一般建议打开
gzip_vary on | off;
//预压缩
gzip_static on | off;
太小的文件没必要压缩,压缩可能会导致文件变大了
nginx
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
6. https功能
Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取
HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启
nginx
listen 443 ssl;
//为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
ssl_certificate /path/to/file;
//指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
//当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
//支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
//配置ssl缓存
off: //关闭缓存
none: //通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]://在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间
大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
//客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
nginx
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/conf.d/ssl/www.hh.com.crt;
ssl_certificate_key /apps/nginx/conf.d/ssl/www.hh.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
}
//所有证书要放一起
7.自定义图标
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错
nginx
//方法一:服务器不记录访问日志:
location = /favicon.ico {
log_not_found off;
access_log off;
}
//方法二:将图标保存到指定目录访问:
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
root /data/nginx/html/hh/images;
expires 365d; //设置文件过期时间
}
二、重写功能
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。
1. if 指令
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断
nginx
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接
nginx
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
nginx
location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if-----> $scheme";
}
if ( $scheme = https ){
echo "if ----> $scheme";
}
}
2. return
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
nginx
return code; //返回给客户端指定的HTTP状态码
return code [text]; //返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; //返回给客户端的URL地址
nginx
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html/hh;
location /hh {
default_type text/plain;
return 666 "hello";
//可以自定义防火门和文本
}
}
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html/hh;
location /hh {
default_type text/plain;
return 302 http://www.baidu.com;
//也可以实现302或者301重定向
}
}
3. set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
nginx
set $name yyds;
set $my_port $server_port;
4.break指令
用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用
如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行
nginx
location /main {
root /apps/nginx/html/hh;
index index.html;
default_type text/html;
set $name yyds;
echo $name;
break; //location块中break后面指令还会执行
set $my_port $server_port;
echo $my_port;
}
不会输出$my_port的内容
5. rewrite指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
rewrite可以配置在 server、location、if
nginx
rewrite可以配置在 server、location、if
语法格式 :
rewrite regex replacement [flag];
正则匹配原始访问url 替代你想让客户访问的 标志
注意 :如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
bash
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^ylc] #匹配除了ylc 这几个字母以外的任意字符
rewrite flag 使用介绍
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
- 跳转型指由客户端浏览器重新对新地址进行请求
- 代理型是在WEB服务器内部实现跳转
rewrite 格式
nginx
Syntax: rewrite regex replacement [flag]; //通过正则表达式处理用户请求并返回替换后的数据包。
Default: ---
Context: server, location, if
flag 说明
nginx
redirect;302
//临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;301 www.bj.com www.beijing.com
//重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break; www.bj.com
//重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
//重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
//适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
nginx
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html/hh;
location /hh {
index index.html;
rewrite /hh http://www.aa.com permanent;
}
}
//当匹配到/hh时,实际跳转到www.aa.com/下的html
http 转https
nginx
server {
listen 443 ssl;
listen 80;
ssl_certificate /apps/nginx/certs/www.hh.com.crt;
ssl_certificate_key /apps/nginx/certs/www.hh.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.hh.com;
location / { //针对全站跳转
root /apps/nginx/html/hh;
index index.html;
if ($scheme = http ){ //如果没有加条件判断,会导致死循环
rewrite / https://$host redirect;
} http://www.hh.com https://www.hh.com
}
location /login { //针对特定的URL进行跳转https
if ($scheme = http ){ //如果没有加条件判断,会导致死循环
rewrite / https://$host/login redirect;
}
}
}
6. 防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种
nginx
none://请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked://请求报文有referer首部,但无有效值,比如为空。
server_names://referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string://自定义指定字符串,但可使用*作通配符。
regular expression://被指定的正则表达式模式匹配到的字符串,要使用~开头
客户端机器
bash
yum install nginx
cd /usr/share/nginx/html
vim test.html
<html>
<body>
<h1>this is a web
<img src="http://192.168.1.10/jj.jpg"/>
</body>
</html>
实现防盗链
nginx
location ~* \.(jpg|gif|swf)$ {
root html;
expires 1d;
valid_referers none blocked *.hh.com hh.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.hh.com/error.jpg;
}
}
~* \.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件
Valid_referers:设置信任的网站,可以正常使用图片
None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。
Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。后面的网址或者域名:referer 中包含相关字符串的网址
If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为true,则执行后面的操作,即进行重写或返回 403 页面。或者直接return 403;
三、反向代理
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
nginx
ngx_http_proxy_module: //将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module //用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后
端服务器分组
ngx_stream_proxy_module://将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module://将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: //将客户端对Python的请求以uwsgi协议转发至指定服务器处理
1. 实现http反向代理
nginx
proxy_pass;
//用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
地址:端口的方式
//也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html;
location /hh {
index index.html;
proxy_pass http://192.168.1.110;
}
//后面无uri,即无 / 符号,需要将location后面url 附加到proxy_pass指定的url后面,此行为类似于root
//proxy_pass指定的uri不带斜线将访问的/hh,等于访问后端服务器
http://192.168.1.110/hh/index.html,即后端服务器配置的站点根目录要有hh目录才可以被访问
proxy_pass http://192.168.1.110/; //后面有uri,即有 / 符号,相当于置换,即访问/hh时实际返回proxy_pass后面uri内容.此行为类似于alias
//如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html/hh;
location ^~ /test {
index index.html;
proxy_pass http://www.aa.com/;
}
}
//^~可以匹配,可以使用/
proxy_hide_header field;
//用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置
在http,server或location块
//示例: 隐藏后端服务器ETag首部字段
location /hh {
index index.html;
proxy_pass http://192.168.1.110/;
proxy_hide_header ETag;
}
proxy_pass_header field;
//默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
//field 首部字段大小不敏感
proxy_pass_request_body on | off;
//是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off;
//是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
1.2 将用户对域 www.hh.com的请求转发给后端服务器处理
nginx
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html;
location /hh {
index index.html;
proxy_pass http://192.168.1.110;
}
}
当访问www.hh.com/hh时,会进行反向代理,访问192.168.1.110下的hh
可以在后面加/,直接访问后端根目录
1.3 指定 localtion 实现反向代理
nginx
server{
listen 192.168.1.10:80;
server_name www.hh.com;
root /apps/nginx/html;
location /hh {
index index.html;
proxy_pass http://192.168.1.110;
}
location /aa {
index index.html;
proxy_pass http://192.168.1.120;
}
}
//可以将动态资源和静态资源分开在不同的后端服务器处理
2. 缓存功能
nginx
proxy_cache zone_name | off; 默认off
//指明调用的缓存,或关闭缓存机制;Context:http, server, location
//zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
//缓存中用于"键"的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
//定义对特定响应码的响应内容的缓存时长,定义在http{...}中
proxy_cache_path;
//定义可用于proxy功能的缓存;Context:http 必须放在http语句中
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=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];
//示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
levels=1:2:2 //定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
keys_zone=proxycache:20m //指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key
inactive=120s //缓存有效时间
max_size=10g; //最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
//调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; //对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; //指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; //除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; //默认是off
//在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
proxy_cache_methods GET | HEAD | POST ...;
//对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
nginx
http语段
proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
子配置文件server语段
server{
listen 80;
server_name www.hh.com;
proxy_cache proxycache;
proxy_cache_key $request_uri;
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 5m;
root /apps/nginx/html;
location / {
root /apps/nginx/html;
}
location /api {
root /apps/nginx/html;
proxy_pass http://192.168.1.110:80;
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
root /apps/nginx/html;
proxy_pass http://192.168.1.120;
}
}
3. 反向代理客户端IP透传
后端服务器的日志只会记录代理服务器的ip地址,所以无法统计出访问量
这时需要实现IP透传,来记录真实客户端的ip地址
nginx
server {
listen 80;
server_name www.hh.com;
location / {
index index.html index.php;
root /data/nginx/html/hh;
proxy_pass http://192.168.1.110;
proxy_set_header X-Real-IP $remote_addr; //只添加客户端IP到请求报文头部,转发至后端服务器
}
}
//当只有一台代理服务器时,可以返回客户端ip地址
//当有多台代理服务器时,就会记录到前一台代理服务器的ip地址,无法实现IP透传,需要启用主配置中的日志格式才能使用$proxy_add_x_forwarded_for内置变量
server {
listen 80;
server_name www.hh.com;
location / {
index index.html index.php;
root /data/nginx/html/hh;
proxy_pass http://192.168.1.110;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
//添加客户端IP和反向代理服务器IP到请求报文头部
}
}
server {
listen 80;
server_name www.hh.com;
location / {
index index.html index.php;
root /data/nginx/html/hh;
proxy_pass http://192.168.1.10;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
//代理服务器的代理服务器
}
}
//所以每个代理服务器都要配置
4. 负载均衡
在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
nginx
//自定义一组服务器,配置在http块内
upstream web {
[调度算法]
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
location / {
pass_proxy http://web/
}
nginx
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 sorry server 自己不能转自己
down #标记为down状态
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
5. Nginx负载均衡策略
之前的博客里面已经大致写过nginx七层中有六种调度算法
可以结合查阅
5.1 轮询
定义服务器组,对这组服务器进行轮询,进行轮流使用
nginx
upstream web {
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
5.2 ip_hash
每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题
nginx
upstream web {
ip_hash; --同一个IP客户端固定访问一个后端服务器
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
5.3 url_hash(URL分配)
需编译安装第三方模块ngx_http_upstream_hash_module
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。一旦缓存住了资源,再次收到请求,就可以从缓存中读取
nginx
upstream web {
hash $request_uri; --实现每个url定向到同一个后端服务器
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
5.4 least_conn(最小连接数)
把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果
nginx
upstream web {
least_conn; --把请求转发给连接数较少的后端服务器
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
5.5 weight(权重)
权重方式,在轮询策略的基础上指定轮询的比例。
一般来说,性能好的服务器权重大,性能差的权重给小一些。
nginx
upstream web {
server 192.168.1.120:[port] weight=1;
server 192.168.1.110:[port] weight=2; --轮询的比例相对上一条要大
}
5.6 fair
需编译安装第三方模块ngx_http_upstream_fair_module
此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配
nginx
upstream web {
fair; --实现响应时间短的优先分配
server 192.168.1.120:[port];
server 192.168.1.110:[port];
}
四、搭建LNMP架构+搭建Discuz论坛
1. 编译安装Ngixn
2. 编译安装MySQL服务
3. 编译安装php
4. 基于LNMP架构搭建Discuz论坛
去浏览器中访问http://192.168.1.10/bbs/install/index.php
出现安装向导,搭建完成