admin管理员组

文章数量:1530085

一,web服务器介绍


web服务器简介
web服务器也称为www(world wide web)服务器,主要功能是提供网上信息浏览服务。web已经成为很多人在网上查找、浏览信息的主要手段。成千上万的用户通过简单的图形界面就可以访问各个大学、组织、公司等的最新信息和各种服务。商业界很快看到了其价值,许多公司建立了主页,利用web在网上发布消息,并将它作为各种服务的界面,如客户服务、特定产品和服务的详细说明、宣传广千以及是渐增长的产品销售和服务。商业用途促进了网络的迅速发展。如果你想通过主页向世界介绍自己或自己的公司,就必须将主页放在一个web服务器上,当然你可以使用一些免费的主页空间来发布。但是如果你有条件,你可以注册一个域名,申请一个IP地址,然后让你的ISP将这个IP地址解析到你的 linux主机上。然后,在linux主机上架设一个web服务器。你就可以将主页存放在这个自己的web服务器上,通过它把自己的主页向外发布。

常用web服务器简介
Unix和linux平台下的常用web服务器有Apache、 Nginx、 Lighttpd、Tomcat、 IBM webSphere等。其中目前应用最广泛的web服务器是Apache。Windows平台下最常用的服务器则是微软公司的IIS(Internet Information Server)。

Apache 服务器
Apache 起初由 Illinois 大学 Urbana-Champaign 的国家高级计算程序中心开发。此后Apache 被开放源代码团体的成员不断的发展和加强。1996年4月以来,Apache一直是Internet上最流行的HTTP服务器,1999年5月它在 57% 的网页服务器上运行,到了2005年7月这个比例上升到69%。Apache是目前世界上用的最多的web服务器,它有优势主要在于源代码开放、有一支开放的开发队伍、支持跨平台的应用(可以运行在几乎所有的Unix、linux、Windows系统平台之上)。Apache的模块支持非常丰富,以至于它提供了非常完善的功能。
Apache的官方网站: http://www.apache

Lighttpd 服务器
Lighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。Lighttpd是众多OpenSource轻量级的webserver中较为优秀的一个。支持FastCGI, CGI, Auth, 输出压缩(output compress), URL重写, Alias等重要功能,而Apache之所以流行,很大程度也是因为功能丰富,在Lighttpd 上很多功能都有相应的实现了,这点对于Apache的用户是非常重要的,因为迁移到Lighttpd就必须面对这些问题。
Lighttpd的官方网站: http://www.lighttpd

Tomcat 服务器
Tomcat是一个免费的开源的Serlvet容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和Jsp规范总能在Tomcat中得到体现。Tomcat即是一个Jsp和Servlet的运行平台。同时Tomcat又不仅仅是一个Servlet容器,它也具有传统的web服务器的功能:处理Html页面,但是与Apache相比,它的处理静态Html的能力就不如Apache,我们可以将Tomcat和Apache集成到一块,让Apache处理静态Html,而
Tomcat处理Jsp和Servlet。这种集成只需要修改一下Apache和Tomcat的配置文件即可。
Tomcat的官方网站: http://tomcat.apache

IBM webSphere
webSphere Application Server 是 一 种功能完善、开放的web应用程序服务器,是IBM电子商务计划的核心部分。基于Java和Servlets的web应用程序运行环境

Windows IIS
IIS 是Internet Information Server的缩写,它是微软公司主推的服务器。IIS与Window NT Server完全集成在一起,因而用户能够利用Windows NT Server和NTFS(NT File System,NT的文件系统)内置的安全特性,建立强大,灵活而安全的Internet和Intranet站点。 IIS支持HTTP(Hypertext Transfer Protocol,超文本传输协议),FTP(File Transfer Protocol,文件传输协议)以及SMTP协议,通过使用CGI和ISAPI,IIS可以得到高度的扩展。
IIS的官方网站: http://www.iis

Nginx
为web站点提供服务所需的一切,运行时可以协同并扩展Apache、Netscape、 IIS和IBM 的HTTPweb服务器,因此可以成为强大的web应用服务器。
webSphere的官方网站: http://www.ibm
=========================================================
Nginx 的历史
Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站点开发的。Igor Sysoev在建立的项目时,使用基于BSD许可。自Nginx 发布以来,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。在俄罗斯许多大网站都已经使用它, 且一直表现不凡。俄罗斯大约有20%左右的虚拟主机是由nignx服务或代理的。Google在线安全博客中统计Nginx服务或代理了大约所有Internet虚拟主机的4%。而Netcraft的统计显示,Nginx服务的主机在过去的一年里以四倍的速度增长并且在这几年里,它的排名还在不断上升

为什么要用Nginx
Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 。它支持内核Poll模型,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。Nginx具有很高的稳定性,其它HTTP服务器当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应只能重启服务器。例如当前Apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。Nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这样的攻击对Nginx来说基本上是毫无用处的。就稳定性而言,nginx比lighttpd更胜一筹。Nginx支持热部署,它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。Nginx采用master-slave模型,能够充分利用SMP的优势,且能够减少工作进程在磁盘I/O的阻塞延迟。
Nginx代码质量非常高,代码很规范,手法成熟, 模块扩展也很容易。

Nginx采用了一些os提供的最新特性如对sendfile (linux2.2+),acceptfilter(FreeBSD4.1+),TCP_DEFER_ACCEPT (linux 2.4+)的支持,从而大大提高了性能。当然,nginx还很年轻,多多少少存在一些问题,比如:Nginx是俄罗斯人创建,目前文档方面还不是很完善.因为文档大多是俄语,所以文档方面这也是个障碍.尽管Nignx的模块比较多,但它们还不够完善。对脚本的支持力度不够。

二,nginx安装

获取Nginx
Nginx的官方主页: http://nginx
其中最新版本为Nginx的开发版本,之前的版本为当前稳定版本。例如最新版本为0.8.X,则当前稳定版本为0.7.X。
http://nginx/en/docs/
http://wiki.nginx

Nginx安装:
方式1. yum安装

方式2. 源码安装
1. 停止原有web服务器

2. 添加普通用户账号来运行nginx:
# useradd nginx

3. 解压并安装Nginx:
# tar xvzf nginx-0.8.55.tar.gz
# cd nginx-0.8.55
#./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
# make
# make install

4. 启动:
# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

查看命令帮助:
/usr/local/nginx/sbin/nginx -h
-v 查看nginx版本
-V 查看编译参数
-t 测试默认配置文件
-c 加载非默认位置配置文件

5. 查看启动状态:
# ps aux | grep nginx
root 8416 0.0 0.1 5760 660 ? Ss 23:29 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 8417 0.0 0.1 5904 992 ? S 23:29 0:00 nginx: worker process

# netstat -ntlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 8416/nginx.conf

6. 测试主页是否可以访问:
# links 127.0.0.1 //如果显示Welcome to nginx! 则说明服务正常

7. 设置开机启动:
方法一:rc.local
#echo "/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf &" >> /etc/rc.local

方法二:编写启动脚本并且加入chkconfig(面试题)
# vi /etc/init.d/nginx
#!/bin/bash
# chkconfig: - 99 20
# description: Oooo this is my nginx startup script
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
$PROG
;;
stop)
kill -s QUIT $(cat $PIDF)
;;
restart)
$0 stop
$0 start
;;
reload)
kill -s HUP $(cat $PIDF)
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
exit 0
# chmod +x /etc/init.d/nginx
# chkconfig --add nginx


8. 信号:
TERM, INT 快速关闭
QUIT 从容关闭,关闭主进程顺便关闭工作子进程
HUP 重载配置用新的配置开始新的工作进程从容关闭旧的工作进程
USR1 重新打开日志文件
USR2 平滑升级可执行程序
WINCH 从容关闭工作进程,不会立即关闭子进程


client--->旧主进程
usr2 开启新主进程<-----client
winch 监控旧主进程 等待所有客户端断开连接

平滑升级(扩展)

平滑升级0.8.55-1.09:
你可以在不中断服务的情况下,新的请求也不会丢失,使用新的 nginx 可执行程序替换旧的(当升级新版本或添加/删除服务器模块时)。
#cd nginx-1.0.9/
#./configure --prefix=/usr/local/nginx109 --with-http_stub_status_module --with-http_ssl_module --user=nginx --group=nginx
#make && make install

安装新版本nginx放在/usr/local/nginx目录
#ps -ef | grep nginx
nginx pid: 9839 9840
#ls /usr/local/nginx/log/nginx.pid*

查看当前nginx状态

#mv /usr/local/nginx/sbin/{nginx,nginx.bak}
#mv /usr/local/{nginx109,nginx}/sbin/nginx
#/usr/local/nginx/sbin/nginx -v

替换为新版本nginx:
#kill -USR2 9839
主进程将重命名它的 .pid 文件为 .oldbin,然后执行新的可执行程序,依次启动新的主进程和新的工作进程。
#kill -WINCH 9839
给旧的主进发WINCH信号,把旧的主进程关闭,把所有请求转到新的主进程,但是原有的请求不会中断,有新请求的时候发到新进程

这时,因为旧的服务器还尚未关闭它监听的套接字,所以,通过下面的几步,你仍可以恢复旧的服务器:
1.发送 HUP 信号给旧的主进程 - 它将在不重载配置文件的情况下启动它的工作进程
2.发送 QUIT 信号给新的主进程,要求其从容关闭其工作进程
3.发送 TERM 信号给新的主进程,迫使其退出
4.如果因为某些原因新的工作进程不能退出,向其发送 KILL 信号
新的主进程退出后,旧的主进程会由移除 .oldbin 前缀,恢复为它的 .pid 文件,这样,一切就都恢复到升级之前了。
如果尝试升级成功,而你也希望保留新的服务器时,发送 QUIT 信号给旧的主进程使其退出而只留下新的服务器运行。

三,配置nginx的虚拟主机:

[root@nginx ~]# cat /usr/local/nginx/conf/nginx.conf | grep -v '#' | grep -Ev '^$'
worker_processes 2; //设置成跟cpu核数相等的数字
events {
worker_connections 10000; //每个主进程可以接收的子进程连接并发数
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {

listen 80; //还可以加ip,形式如下(192.168.1.8:80)
server_name localhost; //域名
location / {
root html; //发布网站的主目录,DocmentRoot ""
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

}

http://localhost/

虚拟主机
基于域名的虚拟主机

server {
listen 80;
server_name web.yahoo;
location /{
root /yahoo/html;
index index.html index.htm;
}
}
server {
listen 80;
server_name web.wing;
location /{
root /wing/html;
index index.html index.htm;
}
}
server {
listen 80 default;
location /{
root /default/html;
index index.html index.htm;
}
}

如果浏览器直接通过IP地址或者其他指向这台机器的域名访问, 那么访问到的是第三个server配置。第三个server为一个默认配置, 请注意它没有“server_name”指令, 并且“listen”指令包含一个“default”关键字。
注:默认如果没有按域名访问虚拟主机也没有指定默认虚拟主机则按顺序访问

基于端口的虚拟主机

server {
listen 1050;
server_name web.105;
location /{
root /105/html;
index index.html index.htm;
}
}
server {
listen 1060;
server_name web.106;
location /{
root /106/html;
index index.html index.htm;
}
}

基于IP的虚拟主机
server {
listen 192.168.1.105:80;
server_name web.105;
location / {
root /105/html;
index index.html index.htm;
}
server {
listen 192.168.1.106:80;
server_name web.106;
location /{
root /106/html;
index index.html index.htm;
}

}

四,location配置:

Nginx Location 配置
语法规则:

location [=|~|~*|!~|!~*|^~] /uri/ {
...
}

= 表示精确匹配,优先级也是最高的
^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 表示区分大小写不匹配的正则 //给匹配结果取反
!~* 表示不区分大小写不匹配的正则 //给匹配结果取反
/ 通用匹配,任何请求都会匹配到

Location优先级:
=
大于 ^~ 大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

注意:那4个正则的先后顺序按location的先后顺序排序

例子,有如下匹配规则:
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.png$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}


产生的效果如下:
访问根目录/, 比如http://localhost/ 将匹配规则A
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问 http://localhost/static/a.html 将匹配规则C
访问 http://localhost/a.gif, http://localhost/b.png将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到 规则C
访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。
访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为反向代理服务器存在。

实际使用中,通常至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}

# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}

五,用户访问限制

连接频率限制

连接频率限制
ngx_http_limit_conn_module

Directives
     limit_conn
     limit_conn_log_level
     limit_conn_status
     limit_conn_zone
     limit_zone

经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,往往考虑对同一个ip的连接数, 并发数进行限制。
ngx_http_limit_conn_module 模块可以根据定义的key来限制每个键值的连接数,如同一个IP来源的连接数。

Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http


Syntax: limit_conn zone number;
Default: —
Context: http, server, location


示例:
设置一个缓存区保存不同key的状态,大小10m。使用远程ip来作为key,以此限制每个源IP的链接数
http {
limit_conn_zone $binary_remote_addr zone= one:10m;
}
server {
location / {
...
limit_conn one 2; //定义每个IP的并发连接数量,特别注意这里最高只能限制到2,高了无效
}
}
/
ab测试 :
[root@tomcat nginx]# ab -n 10000 -c 10000 http://www.web2/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech/
Licensed to The Apache Software Foundation, http://www.apache/

Benchmarking www.web2 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: nginx/1.12.2
Server Hostname: www.web2
Server Port: 80

Document Path: /
Document Length: 5 bytes

Concurrency Level: 10000
Time taken for tests: 0.614 seconds
Complete requests: 10000
Failed requests: 13390
(Connect: 0, Receive: 0, Length: 6766, Exceptions: 6624)
Write errors: 0
Non-2xx responses: 142
Total transferred: 811426 bytes
HTML transferred: 46416 bytes
Requests per second: 16276.23 [#/sec] (mean)
Time per request: 614.393 [ms] (mean)
Time per request: 0.061 [ms] (mean, across all concurrent requests)
Transfer rate: 1289.74 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 269 107.4 266 466
Processing: 48 73 13.8 73 466
Waiting: 0 20 29.0 0 85
Total: 147 342 116.6 341 587

Percentage of the requests served within a certain time (ms)
50% 341
66% 404
75% 439
80% 461
90% 505
95% 531
98% 549
99% 555
100% 587 (longest request)

# tail -f /var/log/nginx/error.log
2018/02/23 15:28:20 [error] 3821#0: *9962 limiting connections by zone "one", client: 192.168.245.176, server: www.web2, request: "GET / HTTP/1.0", host: "www.web2"

连接 与 请求


connection 连接,tcp连接
request http请求,GET/POST/DELETE/UPLOAD


注释:
客户端的IP地址作为键。
$remote_addr 变量的长度为7字节到15字节
$binary_remote_addr 变量的长度是固定的4字节

如果共享内存空间被耗尽,服务器将会对后续所有的请求返回 503错误 (Service Temporarily Unavailable)

请求频率限制

ngx_http_limit_req_module

Directives
     limit_req
     limit_req_log_level
     limit_req_status
     limit_req_zone

Syntax: limit_req_zone key zone=name:size rate=rate;
Default: —
Context: http

Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location


示例:
设置一个缓存区reqps保存不同key的状态,大小10m。这里的状态是指当前的过量请求数。
http { //定义在http里面,server的外面
...
limit_req_zone $binary_remote_addr zone=reqps:10m rate=5r/s; //定义每个IP的每秒请求数量,限制每秒5个连接请求,不延迟
}
server {
location / {
...
limit_req zone=reqps nodelay; //限制每IP的每秒的PHP页面请求次数为上面定义的rate的值:每秒5个请求,不延迟
}
}
# tail -f /var/log/nginx/error.log
2018/02/23 15:36:59 [error] 3859#0: *10000 limiting requests, excess: 0.550 by zone "reqps", client: 192.168.245.176, server: www.web2, request: "GET / HTTP/1.0", host: "www.web2"

可以尝试设置限制请求数为1,用curl快速访问服务器,发现速度太快立即返回503错误。可以设置延迟请求数目
设置延迟请求之前
[root@tomcat nginx]# curl http://www.web2/
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body bgcolor="white">
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>

设置延迟请求数目
limit_req zone=allips burst=5 nodelay;

burst=5 表示最大延迟请求数量不大于5。 如果太过多的请求被限制延迟是不需要的 ,这时需要使用nodelay参数,服务器会立刻返回503状态码。
用curl测试发现会有延迟访问,而并不是立即返回503错误

六,用户访问控制

访问控制:
ngx_http_auth_basic_module
有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。我们在服务课程中学习过apache的访问控制,对于Nginx来说同样可以实现,并且整个过程和Apache 非常的相似。
location / {
root /105/html;
index index.html index.htm;
auth_basic "haha";
auth_basic_user_file /usr/local/nginx/passwd.db;
}

[root@web html]# htpasswd -c /usr/local/nginx/passwd.db user1
New password:
Re-type new password:
Adding password for user user1

注意:-c选项 只有第一次没有密码文件的时候需要添加,第二次再添加账户的时候,不需要跟-c

1.改配置文件
2.创建密码文件
3.重启服务

4.访问测试

七,限制用户访问某些文件

如果你想阻止别人访问你某些目录下的特定文件,比如我网站主目录下有个test目录,我不想让别人访问我test目录下的”.txt”和”.doc”的文件,那么我们可以通过deny的方式来做拒绝。
location ~* \.(txt|doc)$ {
root html/test;
deny all;
}
此处 ~* 代表不区分大小写方式匹配。

八,主机访问控制

Nginx访问控制
ngx_http_access_module
基于主机
Directives
allow
deny


Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except


基于主机的访问控制

九,状态访问

状态访问统计
ngx_http_stub_status_module

在server中添加如下行
location ~ /status {
stub_status on;
access_log off;
}

查看访问状态统计
浏览器:http://192.168.1.201/status 刷新可得到如下变化结果

Active connections: 557
server accepts handled requests
36573075 36573075 43806112
Reading: 3 Writing: 16 Waiting: 538

Active connections
对后端发起的当前活动连接数
server accepts handled requests
nginx总共处理了36573075个连接
成功创建36573075次握手,也就是成功的连接数connection 失败连接=(总连接数-成功连接数)(相等表示中间没有失败的),
总共处理了43806112个请求 (平均每次握手处理了1.2个数据请求)。

Reading
nginx读取到客户端的Header信息数。请求头
Writing
nginx返回给客户端的Header信息数。响应头
Waiting
开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接。
1000 800

十,网站过滤

替换网站响应内容
ngx_http_sub_module

Directives
sub_filter
sub_filter_last_modified
sub_filter_once
sub_filter_types

假如站点出现什么敏感文字,想修改但很耗时间,不妨试试该模块;
或者想临时在站点中加上一个通用js或者css之类的文件,也可以使用这个模块。

Syntax: sub_filter string replacement;
Default: —
Context: http, server, location


Syntax: sub_filter_once on | off;
Default: sub_filter_once on;
Context: http, server, location

sub_filter_once off allows to search and replace all matching lines, the default is replacing only the first one.

示例1:
location / {
root /usr/share/nginx/html;
index index.html index.htm;
sub_filter nginx 'wing'; //把网页中的nginx换成wing
sub_filter_once on; //只替换一次
}

示例2:
location / {
root /usr/share/nginx/html;
index index.html index.htm;
sub_filter nginx '';
sub_filter_once off;
}

示例3:
js
# cat /usr/share/nginx/html/hello.js
function Hello() {
alert("Hello World")
}

index


nginx_conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
sub_filter </head> '</head><script type="text/javascript" src="hello.js"></script>';
sub_filter_once on;
}

其他实用用法
如果我们用模板生成网站的时候,因为疏漏或者别的原因造成代码不如意,但是此时因为文件数量巨大,不方便全部重新生成,那么这个时候我们就可以用此模块来暂时实现纠错。另一方面,我们也可以利用这个实现服务器端文字过滤的效果。

十一,浏览器缓存

HTTP协议定义的缓存机制
ngx_http_headers_module

Expires http 1.0
Cache-Control(max-age) http 1.1

浏览器第一次请求 无缓存
浏览器第二次请求 有缓存,校验是否过期




当这些缓存有效的时候,通过 HttpWatch 查看一个请求会得到这样的结果:
第一次访问 200
鼠标点击二次访问 (Cache)
按F5刷新 304
按Ctrl+F5强制刷新 200
如果是这样的就说明缓存真正有效了


Syntax: expires [modified] time;
expires epoch | max | off;
Default: expires off;
Context: http, server, location, if in location





location / {
root /app/tianyun.me;
index index.html index.htm;
expires 24h;
}



扩展:
Etag - Last-Modified和Etags如何帮助提高性能?
把Last-Modified和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1.客户端请求一个页面(A)。

2.服务器返回页面A,并在给A加上一个Last-Modified/ETag。

3.客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。

4.客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。

5.服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

Etag - 作用
Etag 主要为了解决 Last-Modified 无法解决的一些问题。
1、 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)

3、某些服务器不能精确的得到文件的最后修改时间;
为此,HTTP/1.1 引入了 Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来很神秘的编码。但是HTTP/1.1标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在""内。

Etag - 工作原理
Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。常见的是使用If-None-Match.请求一个文件的流程可能如下:
====第一次请求===
1.客户端发起 HTTP GET 请求一个文件;

2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"2e681a-6-5d044840")(假设服务器支持Etag生成和已经开启了Etag).状态码200
====第二次请求===
1.客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840

2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;
流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办?
答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.

HTTP中的缓存机制
网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must- revalidate等,默认为private。其作用根据不同的重新浏览方式分为以下几种情况:

(1) 打开新窗口
值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。
而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:
Cache-control: max-age=5(表示当访问此网页后的5 秒 内再次访问不会去服务器)

(2) 在地址栏回车
值为private或must-revalidate则只有第一次访问时会访问服务器,以后就不再访问。
值为no-cache,那么每次都会访问。
值为max-age,则在过期之前不会重复访问。

(3) 按后退按扭
值为private、must-revalidate、max-age,则不会重访问,
值为no-cache,则每次都重复访问

(4) 按刷新按扭
  无论为何值,都会重复访问

Cache-control值为“no-cache”时,访问此页面不会在Internet临时文章夹留下页面备份。

header常用指令
header分为三部分:
第一部分为HTTP协议的版本(HTTP-Version);
第二部分为状态代码(Status);
第三部分为原因短语(Reason-Phrase)。

// fix 404 pages: 用这个header指令来解决URL重写产生的404 header
header('HTTP/1.1 200 OK');

// set 404 header: 页面没找到
header('HTTP/1.1 404 Not Found');

//页面被永久删除,可以告诉搜索引擎更新它们的urls
// set Moved Permanently header (good for redrictions)
// use with location header
header('HTTP/1.1 301 Moved Permanently');

// 访问受限
header('HTTP/1.1 403 Forbidden');

// 服务器错误
header('HTTP/1.1 500 Internal Server Error');

禁止页面在IE中缓存

http响应消息头部设置:

CacheControl = no-cache
Pragma=no-cache
Expires = -1

Expires 表示存在时间,允许客户端在这个时间之前不去检查(发请求),等同max-age的效果。但是如果同时存在,则被Cache-Control的max-age覆盖,也就是说Cache-Control的优先级别高

HTTP响应优化
1.去掉Date, Expires
2.只保留Cache-Control来控制本地缓存

例如:
# 相关页面设置Cache-Control头信息
例一:
if ($request_uri ~* "^/$|^/search/.+/|^/company/.+/") {
add_header Cache-Control max-age=3600;
}


例二:
location ~ .*\.(css|js|swf|php|htm|html )$ {
add_header Cache-Control no-store;
}

例三:location ~ .*\.(js|css)$ {
expires 10d;
}

关于304

304 的标准解释是:Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
如 果客户端在请求一个文件的时候,发现自己缓存的文件有 Last Modified ,那么在请求中会包含 If Modified Since ,这个时间就是缓存文件的 Last Modified 。因此,如果请求中包含 If Modified Since,就说明已经有缓存在客户端。只要判断这个时间和当前请求的文件的修改时间就可以确定是返回 304 还是 200 。对于静态文件,例如:CSS、图片,服务器会自动完成 Last Modified 和 If Modified Since 的比较,完成缓存或者更新。但是对于动态页面,就是动态产生的页面,往往没有包含 Last Modified 信息,这样浏览器、网关等都不会做缓存,也就是在每次请求的时候都完成一个 200 的请求。
因此,对于动态页面做缓存加速,首先要在 Response 的 HTTP Header 中增加 Last Modified 定义,其次根据 Request 中的 If Modified Since 和被请求内容的更新时间来返回 200 或者 304 。虽然在返回 304 的时候已经做了一次数据库查询,但是可以避免接下来更多的数据库查询,并且没有返回页面内容而只是一个 HTTP Header,从而大大的降低带宽的消耗,对于用户的感觉也是提高。

十二,安全链接


 安全连接https
ca中心 颁发证书的机构

首先生成一对证书
RHEL5、RHEL6 中在/etc/pki/tls/certs 目录有个脚本可以帮助我们简化证书生成的过程
#cd /etc/pki/tls/certs
#make server.key //生成私钥
#openssl rsa -in server.key -out server.key //去除密码以便使用时不询问密码
注:rsa是一种采用非对称密钥的加密算法
#make server.csr //生成证书颁发机构,用于颂发公钥
#openssl x509 -in server.csr -req -signkey server.key -days 365 -out server.crt //颁发公钥
注:x509是一种非常通用的证书格式


由于我们并不是去 CA 证书中心申请的公钥,所以在使用的时候,客户端浏览器会跳出未受信任的警告。如果你 money 够多,请去 CA 申请。
server {
listen 443;
server_name web.wing;

ssl on;
ssl_certificate /etc/pki/tls/certs/server.crt;
ssl_certificate_key /etc/pki/tls/certs/server.key;
//指定证书所存放的路径
ssl_session_timeout 5m;

ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; //密码指定为OpenSSL支持的格式
ssl_prefer_server_ciphers on;

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

1.生成一个CA中心
2.有自己的网站(web服务器)
3.生成证书请求
4.把证书请求发送给CA中心
5.CA中心给证书请求签名
6.把签名成功证书下发给WEB服务器
7.在web上配置证书生效(创建一个https的虚拟主机,指定指定私钥和证书的位置)
8.浏览器访问web服务器443端口,下载证书到客户端浏览器

9.浏览器去CA中心验证证书真假
10.客户端生成自己的对称加密密钥,连同网页内容的请求一起发给服务器
11.客户端会使用WEB服务器的公钥对对称加密密钥进程加密
12.服务器对客户端发来的加密对称密钥解密并使用解密出来的对称密钥对将要传输的数据加密,然后传给客户端

对称加密:
一个钥匙
非对称加密:
一对钥匙
公钥:加密
私钥:解密 签名

测试:
浏览器输入:https://10.0.0.20 会提示访问不安全

十三,nginx代理服务

代理服务器:
正向代理
缓存服务器 加速内网客户端的上网速度
透明代理
控制内网客户端上网行为
反向代理
给服务器作代理
缓存服务器 加速外网客户端访问服务器的速度

公司-------->
|
client 正向代理 内网-->|-->外网--->baidu

-------->公司
|
client 正向代理 内网-->|-->外网 反向代理--->baidu

squid 专业web代理服务器 可以做以上三种代理
varnish 专业的web代理服务器 可以做正向和反向代理 性能优于squid
nginx 专业的web服务器,带有专业的反向代理功能 应用率相当高
lvs 专业的负载均衡服务 性能优于nginx 但是有些功能没有nginx的反向代理好,nginx可以把坏掉后端服务器踢除,而且在一台后端服务器不能使用的情况下会自动把请求发给下一个后端服务器

haproxy 专业的七层负载均衡 只做负载均衡 只反向代理

Proxy配置 ngx_http_proxy_module

代理对象不同:
正向代理 是为客户端做代理
反向代理 是为服务器做代理

Proxy_pass
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except

location / {
proxy_pass http://192.168.20.10:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


1client 2dai 3dai 4dai server


http://10.18.251.251/fdsf

关于X-Real-IP和X-Forwarded-For:
一般来说,X-Forwarded-For是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中

来自4.4.4.4的一个请求,header包含这样一行
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3
代表 请求由1.1.1.1发出,经过三层代理,第一层是2.2.2.2,第二层是3.3.3.3,而本次请求的来源IP4.4.4.4是第三层代理

而X-Real-IP,没有相关标准,上面的例子,如果配置了X-Read-IP,可能会有两种情况
// 最后一跳是正向代理,可能会保留真实客户端IP
X-Real-IP: 1.1.1.1
// 最后一跳是反向代理,比如Nginx,一般会是与之直接连接的客户端IP
X-Real-IP: 3.3.3.3

所以 ,如果只有一层代理,这两个头的值就是一样的
那一般在后端取值(比如nodejs通过nginx代理)是用哪个值呢?一般推荐是用X-Forwarded-For
1. 他在正向(如squid)反向(如nginx)代理中都是标准用法,而正向代理中是没有x-real-ip相关的标准的,也就是说,如果用户访问你的 nginx反向代理之前,还经过了一层正向代理,你即使在nginx中配置了x-real-ip,取到的也只是正向代理的IP而不是客户端真实IP
2. 大部分nginx反向代理配置文章中都没有推荐加上x-real-ip ,而只有x-forwarded-for,因此更通用的做法自然是取x-forwarded-for
3. 多级代理很少见,只有一级代理的情况下二者是等效的
4. 如果有多级代理,x-forwarded-for效果是大于x-real-ip的,可以记录完整的代理链路

nginx proxy缓冲

缓冲区
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
proxy_buffering开启的情况下,nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端(边收边传,不是全部接收完再传给客户端)。

Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location

Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location

Syntax: proxy_busy_buffers_size size;
Default: proxy_busy_buffers_size 8k|16k;
Context: http, server, location

头信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
Context: http, server, location

超时
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location

Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location

Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location

Proxy 配置实例:
location / {
proxy_pass http://192.168.20.10:80;
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffering on; //开启缓冲
proxy_buffer_size 32k; //响应头缓冲区的大小
proxy_buffers 4 128k; //响应缓冲区的数量和大小
proxy_busy_buffers_size 256k; //缓冲区放到队列,批量发送给客户端
proxy_max_temp_file_size 256k; //每个请求使用磁盘上临时文件最大大小

}

如果没有缓冲,数据从代理的服务器发送并立即开始被发送到客户。如果假定客户端很快,缓冲可以关闭而尽快使数据到客户端,有了缓冲,Nginx代理将暂时存储后端的响应,然后按需供给数据给客户端。如果客户端是缓慢的,允许Nginx服务器关闭到后端的连接。然后,它可以处理数据分配到客户端,以任何可能的速度。

Nginx默认有缓冲设计,因为客户端往往有很大的不同的连接速度。我们可以用以下指令调节缓冲行为。
可以在HTTP,server或location位置来设置。重要的是要记住,大小size指令是针对每个请求配置的,所以增加超出你需求会影响你的性能,如果这时有许多客户端请求:

proxy_buffering:该指令控制缓冲是否启用。默认情况下,它的值是“on”。

proxy_buffers: 该指令控制代理响应缓冲区的数量(第一个参数)和大小(第二个参数)。默认配置是8个缓冲区大小等于一个内存页(4K或者8K)。增加缓冲区的数目可以让你缓冲更多信息。

proxy_buffer_size:从后端服务器的响应头缓冲区大小,它包含headers,和其他部分响应是分开的。该指令设置响应部分的缓冲区大小。默认情况下,它和proxy_buffers是相同的尺寸,但因为这是用于头信息,这通常可以设置为一个较低的值。

proxy_busy_buffers_size:此指令设置标注“client-ready”缓冲区的最大尺寸。默认客户端一次只读取来自一个缓冲区的数据,缓冲被放置在队列中,批量发送到客户端。此指令控制允许是在这种状态下的缓冲空间的大小。
一句话:高负荷下缓冲大小(proxy_buffers*2)

proxy_max_temp_file_size:这是每个请求能用磁盘上临时文件最大大小。这些当上游响应太大不能装配到缓冲区时被创建。

proxy_temp_file_write_size:这是当被代理服务器的响应过大时Nginx一次性写入临时文件的数据量
proxy_temp_path:当上游服务器的响应过大不能存储到配置的缓冲区域时,Nginx存储临时文件路径

nginx proxy 缓存

Proxy缓存
ngx_http_proxy_module

client--->nginx--->nginx
nginx php
nginx

缓存类型
proxy缓存
服务器缓存 memcached redis
客户端缓存 浏览器缓存



代理缓存
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

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=proxy_cache:10m max_size=10g inactive=60m use_temp_path=off;
参数解释:
proxy_cache_path 缓存文件路径
levels 设置缓存文件目录层次;levels=1:2 表示两级目录
keys_zone 设置缓存名字和共享内存大小
inactive 在指定时间内没人访问则被删除
max_size最大缓存空间,如果缓存空间满,默认覆盖掉缓存时间最长的资源。

Syntax: proxy_cache zone | off;
Default: proxy_cache off;
Context: http, server, location

缓存过期
Syntax: proxy_cache_valid [code ...] time;
Default: —
Context: http, server, location

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;


缓存维度
Syntax: proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;
Context: http, server, location


缓存配置实例:
http{
...
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=proxy_cache:10m max_size=10g inactive=60m use_temp_path=off;
...
}

对应server的location添加:
location / {
proxy_pass http://192.168.20.10:80;
proxy_cache proxy_cache; //使用名为proxy_cache的对应缓存配置
proxy_cache_valid 200 304 12h; 对httpcode为200…的缓存12小时
proxy_cache_valid any 10m;
proxy_cache_key $uri; //定义缓存唯一key,通过唯一key来进行hash存取

add_header Nginx-Cache "$upstream_cache_status";
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect default;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;

}

关于proxy_next_upstream
proxy_next_upstream:这个指令属于 http_proxy 模块的,指定后端返回什么样的异常响应时,使用另一个realserver

指定请求应传递到下一个服务器的情况
当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率,多可运用于前台程序负载,设置proxy_next_upstream
Syntax: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | non_idempotent | off ...;
Default: proxy_next_upstream error timeout;
Context: http, server, location
指定请求应传递到下一个服务器的情况:
• error:在与服务器建立连接,向其传递请求或读取响应标头时发生错误;

• timeout:在与服务器建立连接,向其传递请求或读取响应头时发生超时;

• invalid_header:服务器返回空响应或无效响应;

• http_500:服务器返回了带有代码500的响应;

• http_502:服务器返回具有代码502的响应;

• HTTP_503:服务器返回具有代码503的响应;

• http_504:服务器返回具有代码504的响应;

• http_403:服务器返回带有代码403的响应;

• http_404:服务器返回具有代码404的响应;

• non_idempotent:通常,如果请求已经被发送到上游服务器(1.9.13),则具有非幂等方法的请求(POST,LOCK,PATCH)不被传递到下一个服务器;启用此选项明确允许重试此类请求;

• off:禁用将请求传递到下一个服务器。

应该记住,将请求传递到下一个服务器是可能的,如果还没有发送到客户端

proxy_next_upstream off

因为proxy_next_upstream 默认值: proxy_next_upstream error timeout;

场景:当访问A时,A返回error timeout时,访问会继续分配到下一台服务器处理,就等于一个请求分发到多台服务器,就可能出现多次处理的情况,这其实没问题,但是:

如果涉及到充值,就有可能充值多次的情况,这种情况下就要把proxy_next_upstream关掉

proxy_next_upstream off

十四,nginx日志

自定义日志

自己定义日志:在日志部分写入
log_format cust '$remote_addr : $time_local : $http_user_agent'
access_log logs/access.log cust;

测试自定义日志:
#elinks -dump http://192.168.1.254
#cat access.log
访问的ip:访问的时间:访问的客户端的类型

配置nginx日志

ngx_http_log_module
nginx日志配置相关指令:
log_format
access_log
error_log
open_log_file_cache

Nginx有非常灵活的日志记录模式。每个级别的配置可以有各自独立的访问日志。日志格式通过log_format命令定义。

1.log_format指令


Syntax: log_format name [escape=default|json] string ...;
Default: log_format combined "...";
Context: http


name 表示格式名称
string 表示定义的格式
log_format 有默认的无需设置的combined日志格式,相当于apache的combined日志格式,日志格式如下:
log_format combined '$remote_addr - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent '
' "$http_referer" "$http_user_agent" ';


注:如果Nginx位于 负载均衡器,squid,nginx反向代理之后,web服务器无法直接获取到客户端真实的IP地址。
$remote_addr获取的是反向代理的IP地址。反向代理服务器在转发请求的http头信息中,可以增加X-Forwarded-For信息,
用来记录客户端IP地址和客户端请求的服务器地址。日志格式如下:
log_format porxy '$http_x_forwarded_for - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent '
' "$http_referer" "$http_user_agent" ';


日志格式允许包含的变量:
$remote_addr, $http_x_forwarded_for 记录客户端IP地址
$remote_user 记录客户端用户名称
$request 记录请求的URL和HTTP协议
$status 记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小
$bytes_sent 发送给客户端的总字节数
$connection 连接的序列号
$connection_requests 当前通过一个连接获得的请求数量。
$msec 日志写入时间。单位为秒,精度是毫秒。
$pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer 记录从哪个页面链接访问过来的,可以根据该参数进行防盗链设置
$http_user_agent 记录客户端浏览器相关信息
$request_length 请求的长度(包括请求行,请求头和请求正文)。
$request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601 ISO8601标准格式下的本地时间。
$time_local 通用日志格式下的本地时间。

2. access_log指令

Syntax:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log syslog:server=address[,parameter=value] [format];
access_log off;
Default: access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except


gzip 压缩等级,nginx每天会对当天的访问日志进行压缩,通常在其日志文件目录下也可看到一大堆的access.log-yyyymmdd.gz文件
buffer 设置内存缓存区大小
flush 保存在缓存区中的最长时间
一般场景这些参数都无需配置,极端优化才有可能会考虑这些参数

使用默认combined格式记录日志:access_log logs/access.log 或 access_log logs/access.log combined;

3. open_log_file_cache指令

Syntax:
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
Default: open_log_file_cache off;
Context: http, server, locatition


对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭。提高包含变量的日志文件
存放路径的性能,可以使用open_log_file_cache来设置日志文件描述符的缓存
(默认是off),格式如下:
参数注释如下:
max: 设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭
inactive: 设置存活时间,默认是10s
min_uses: 设置在inactive时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次
valid: 设置检查频率,默认60s
off: 禁用缓存

示例:
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

nginx日志轮转

Nginx日志轮转
# rpm -ql nginx |grep log
/etc/logrotate.d/nginx
/var/log/nginx

轮转规则文件

nginx日志分析

Nginx日志分析

日志格式:


日志条目:


1. 统计2018年2月14日 PV量
[root@tomcat nginx]# grep '14/Feb/2018' /var/log/nginx/access.log-20180214 | wc -l
410

[root@tomcat nginx]# awk '$4>="[14/Feb/2018:17:21:00" && $4<="[14/Feb/2018:17:23:00" {print $0}' /var/log/nginx/access.log-20180214

2. 统计2017年9月5日 一天内访问最多的10个IP(ip top10)


3. 统计2017年9月5日 访问大于100次的IP


4. 统计2017年9月5日 访问最多的10个页面($request top 10)


5. 统计2017年9月5日 每个URL访问内容总大小($body_bytes_sent)

[root@tianyun log]# awk '/05\/Sep\/2017/{size[$7]+=$10} END{for(i in size) \
{print i,size[i]}}' sz.mobiletrain.log |sort -k2rn |head



6. 统计2017年9月5日 每个IP访问状态码数量($status)


7. 统计2017年9月5日 IP访问状态码为404及出现次数($status)


8. 统计前一分钟的PV量


9. 统计2017年9月5日 8:30-9:00,访问状态码是404 $9=="404"


10. 统计2017年9月5日 各种状态码数量

Nginx日志字段

$remote_addr $1
$time_local $4
$request $7
$status $9
$body_bytes_sent $10

十五,查看并发查询

查看Web服务器(nginx  apache)的并发请求数及其TCP连接状态:(面试题)
#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
LAST_ACK 5 (正在等待处理的请求数)
SYN_RECV 30
ESTABLISHED 1597 (正常数据传输状态)
FIN_WAIT1 51
FIN_WAIT2 504

TIME_WAIT 1057 (处理完毕,等待超时结束的请求数)

扩展了解

redis_php扩展

当你的php和memcached(redis)不在同一台机器的时候需要安装

#vim redis_php.sh
wget -c http://pecl.php/get/redis-2.2.5.tgz
tar zxf redis-2.2.5.tgz
cd redis-2.2.5/
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install
cd ../
sed -i '/the dl()/i\
extension = "redis.so"' /usr/local/php/etc/php.i

memcache_php扩展

 如果你运行PHP的这台服务器上没有配置memcache,而是要用远程的memcache,那么就必须安装一个PHP扩展才能使用memcache。
#vim mem_php.sh
#!/bin/bash
wget -c http://soft.vpser/web/memcache/memcache-3.0.8.tgz
tar zxvf memcache-3.0.8.tgz
cd memcache-3.0.8/
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install

tomcat php nginx
lvs nat

十六,rewrite

1.什么是rewrite
2.四个指令
3.四个标记区别

Rewrite 规则
什么是Rewrite:
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。

比如:
http://www.123/news/index.asp?id=123
使用URLRewrite 转换后可以显示为:
http://www.123/news/123.html

对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。
形如http://www.123/news/index.asp?id=123的网页地址,自然是毫无美感可言,而用UrlRewrite技术,你可以轻松把它显示为 http://www.123/news/123.html。
理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。
从安全角度上讲,如果在url中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的url地址可以给我们带来更高的安全性。


Rewrite相关指令:
Nginx Rewrite相关指令有if、rewrite、set、return。
if 的语法应用于server和location环境内
if (condition) { … }
if可以支持如下条件判断匹配符号
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行

在匹配过程中可以引用一些Nginx的全局变量,更多的变量请参考
http://wiki.nginx/NginxHttpCoreModule 的 Variables 部分

$args 请求中的参数;
$document_root 针对当前请求的根路径设置值;
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate 对连接速率的限制;
$request_method 请求的方法,比如"GET"、"POST"等;
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)


例子:伪静态 当访问一个比较长的路径页面的时候,让用户输入比较短的地址,而且浏览器上留下短地址
if ( !-f $request_filename){
rewrite .* /login/a.txt;
}
比如:真实地址:http://web1/login/a.txt
伪地址:http://web1/b.txt 实际上b.txt都不存在

# cat /usr/local/nginx/html/login/a.txt
hello ni hao
# cat /usr/local/nginx/html/b.txt
cat: /usr/local/nginx/html/b.txt: 没有那个文件或目录


$request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg)
$query_string 与$args相同;
$scheme 用的协议,比如http或者是https
$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 请求到达的服务器名;
$document_uri 与$uri一样,URI地址;
$server_port 请求到达的服务器端口号;

例子:
匹配访问的url地址是否是个目录
if (-d $request_filename) {
…;
}

匹配访问的地址是否以www开头
if ($hosts ~* ^www) {
…;
}

WWW.baidu
Www.baidu

www.baidu/wenku/index.html
www.baidu/wenku/index.htm break

rewrite的使用
rewrite regexp 替换后的内容 flag
s/正则表达是/替换后的内容/flag

rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下

每行rewrite指令最后应该跟一个flag标记,支持的flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则

redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址

www.baidu www.baidu/fdsadkfjd;as


last和break标记的区别:
last标记在本条rewrite规则执行完后,会对其所在的server { … } 标签重新发起请求
break标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配。
另有些时候必须使用last,比如在使用alias指令时,而使用proxy_pass指令时则必须使用break。

以下这段rewrite会导致死循环
location /abc/ {
rewrite "^/abc/(.*)\.html$" /abc/index.html last;
}
s/A/B/g
我们应该将上面的last改成break以避免死循环。

redirect 和 permanent区别:
则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。
使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改,那么很有可能出现URL劫持的现像。

做URI重写时,有时会发现URI中含有相关参数,如果需要将这些参数保存下来,并且在重写过程中重新引用,可以用到 () 和 $N 的方式来解决。
例:
1. 匹配访问的url地址是否是个目录,如果是则自动加个 /

if (-d $request_filename) {
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}

2. 用户访问的网址为www.test/php/abc.html 重写后真实地址是www.test/php/login.php?user=abc

location ~* /php/.*\.html$ {
rewrite /php/(.*)\.html /login.php?user=$1 last;
}

3. 用户访问地址为/qianfeng/11-22-33.html重写后真实地址为/qianfeng/11/22/33.html
location /qianfeng/ {
rewrite /qianfeng/([0-9]+)-([0-9]+)-([0-9]+).html /qianfeng/$1/$2/$3.html last;
}

set 指令
用于定义一个变量,并且赋值。应用于server,location,if环境。
语法格式为: set $变量名 变量值

例:
当访问任意目录下的whoami.html 都重定向到 /who.html
location ~* .*/whoami\.html$ {
set $who 'who.html';
rewrite .* /$who break;
}


return 指令
用于返回状态码给客户端,应用于server,location,if环境。
例:
如果访问的 .sh 结尾的文件则返回403操作拒绝错误
location ~* .*\.sh$ {
return 403;
}


例1:
#http://www.web2/abc/a/1.html ==> http://www.web2/ccc/bbb/2.html
location /abc {
rewrite .* /ccc/bbb/2.html permanent; //观察添加和不添加permanent的区别
#return 301 /ccc/bbb/2.html;
}
例2:
#http://www.web2/2015/ccc/bbb/2.html ==> http://www.web2/2014/ccc/bbb/2.html
location /2015 {
rewrite ^/2015/(.*)$ /2014/$1 permanent;
}

例3:
#http://www.360buy/aaa/1.html ==> http://jd
if ( $host ~* 360buy ) {
rewrite .* http://jd permanent;
}

例4:
#http://www.360buy/ccc/1.html ==> http://jd/ccc/1.html
if ( $host ~* 360buy ) {
rewrite .* http://jd$request_uri permanent;
}

例5: 在访问目录后添加/ (如果目录后已有/,则不加/)
#http://www.web2/ccc/abc
#$1: /ccc/ab
#$2: c
#http://$host$1$2/
if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}

例6:
#http://www.web2/login/web2.html ==> http://www.web2/reg/login.php?user=web2
location /login {
rewrite ^/login/(.*)\.html$ /reg/login.php?user=$1 permanent;
}

例7:
#http://www.web2/qf/11-22-33/1.html ==> http://www.web2/qf/11/22/33/1.html
location /qf {
rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
}

=======================

if ($host ~* "^www.web2$" ) {
break;
}

if ($host ~* "^(.*)\.web2\$" ) {
set $user $1;
rewrite .* http://www.web2/$user permanent;
}

=======================
例9:如果访问的.sh结尾的文件则返回403操作拒绝错误
location ~* \.sh$ {
return 403;
#return 301 http://www.web2;
}

例10:80 ======> 443

http://www.web2/abc
https://www.web2/abc

server {
listen 80;
server_name www.web2 web2;
return 301 https://www.web2$request_uri;
}

server { //原来怎么写,现在怎么写
listen 443 ssl;
server_name www.web2;
ssl on;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;:
}

# curl -I http://www.web2
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.1
Date: Tue, 26 Jul 2016 15:07:50 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://www.web2/
=======================
Apache: https
# yum -y install httpd mod_ssl
# vim /etc/httpd/conf.d/vip9999.conf

示例:

补充
Nginx常用Rewrite伪静态法则

Wordpress:个人信息发布平台

location / {
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}

PHPCMS:网站内容管理系统

www.baidu www.sina

location / {
###以下为PHPCMS 伪静态化rewrite法则
rewrite ^(.*)show-([0-9]+)-([0-9]+)\.html$ $1/show.php?itemid=$2&page=$3;
rewrite ^(.*)list-([0-9]+)-([0-9]+)\.html$ $1/list.php?catid=$2&page=$3;
rewrite ^(.*)show-([0-9]+)\.html$ $1/show.php?specialid=$2;

####以下为PHPWind 伪静态化rewrite法则
rewrite ^(.*)-htm-(.*)$ $1.php?$2 last;
rewrite ^(.*)/simple/([a-z0-9\_]+\.html)$ $1/simple/index.php?$2 last;
}

ECSHOP:

if (!-e $request_filename)
{
rewrite "^/index\.html" /index.php last;
rewrite "^/category$" /index.php last;
rewrite "^/feed-c([0-9]+)\.xml$” /feed.php?cat=$1 last;
rewrite “^/feed-b([0-9]+)\.xml$” /feed.php?brand=$1 last;
rewrite “^/feed\.xml$” /feed.php last;
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3 last;
rewrite “^/category-([0-9]+)-b([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2 last;
rewrite “^/category-([0-9]+)(.*)\.html$” /category.php?id=$1 last;
rewrite “^/goods-([0-9]+)(.*)\.html” /goods.php?id=$1 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$” /article_cat.php?id=$1&page=$2 last;
rewrite “^/article_cat-([0-9]+)(.*)\.html$” /article_cat.php?id=$1 last;
rewrite “^/article-([0-9]+)(.*)\.html$” /article.php?id=$1 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html” /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2&page=$3 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2 last;
rewrite “^/brand-([0-9]+)(.*)\.html” /brand.php?id=$1 last;
rewrite “^/tag-(.*)\.html” /search.php?keywords=$1 last;
rewrite “^/snatch-([0-9]+)\.html$” /snatch.php?id=$1 last;
rewrite “^/group_buy-([0-9]+)\.html$” /group_buy.php?act=view&id=$1 last;
rewrite “^/auction-([0-9]+)\.html$” /auction.php?act=view&id=$1 last;
rewrite “^/exchange-id([0-9]+)(.*)\.html$” /exchange.php?id=$1&act=view last;
rewrite “^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last;
rewrite ^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/exchange-([0-9]+)-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2 last;
rewrite “^/exchange-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1 last;
}


SaBlog 2.0: Blog系统

# 只带月份的归档
rewrite "^/date/([0-9]{6})/?([0-9]+)?/?$" /index.php?action=article&setdate=$1&page=$2 last;
# 无分类翻页
rewrite ^/page/([0-9]+)?/?$ /index.php?action=article&page=$1 last;
# 分类
rewrite ^/category/([0-9]+)/?([0-9]+)?/?$ /index.php?action=article&cid=$1&page=$2 last;
rewrite ^/category/([^/]+)/?([0-9]+)?/?$ /index.php?action=article&curl=$1&page=$2 last;
# 归档、高级搜刮
rewrite ^/(archives|search|article|links)/?$ /index.php?action=$1 last;
# 全数批评、标签列表、引用列表 带分页
rewrite ^/(comments|tagslist|trackbacks|article)/?([0-9]+)?/?$ /index.php?action=$1&page=$2 last;
# tags
rewrite ^/tag/([^/]+)/?([0-9]+)?/?$ /index.php?action=article&item=$1&page=$2 last;
# 文章
rewrite ^/archives/([0-9]+)/?([0-9]+)?/?$ /index.php?action=show&id=$1&page=$2 last;
# RSS rewrite ^/rss/([0-9]+)?/?$ /rss.php?cid=$1 last;
rewrite ^/rss/([^/]+)/?$ /rss.php?url=$1 last;
# 用户 rewrite ^/uid/([0-9]+)/?([0-9]+)?/?$ /index.php?action=article&uid=$1&page=$2 last;
rewrite ^/user/([^/]+)/?([0-9]+)?/?$ /index.php?action=article&user=$1&page=$2 last;
# 舆图文件
rewrite sitemap.xml sitemap.php last;
# 自界说链接
rewrite ^(.*)/([0-9a-zA-Z\-\_]+)/?([0-9]+)?/?$ $1/index.php?action=show&alias=$2&page=$3 last;

Discuz 7:

rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last;
rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last;
rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page\%3D$3&page=$2 last;
rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last;
rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last;

Typecho:博客系统

location / {
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}

shopex: 网店系统
    location /
    {
             if (!-e $request_filename) {
             rewrite ^/(.*)$ /index.php?$1 last;
    }
}

SHOPEX:

location / {
if (!-e $request_filename) {
rewrite ^/(.+\.(html|xml|json|htm|php|jsp|asp|shtml))$ /index.php?$1 last;
}

}

关于反向地址的重写

返回给客户端带有后端服务器实际地址跟端口的响应头信息这样在实际线上是不允许
可以通过proxy_redirect将被代理服务器的响应头中的location字段进行重定向修改后返回给客户端

做nginx反向代理apache的时候,原来后端 apache用的端口是8080通过反向代理后,使用wireshark抓包发现location头域数值为 http://192.168.1.154:8080/wuman/ 如果把这个返回给客户端肯定是不可以的,看起来别扭而且还暴露了apache的具体信息
所以在这里用到了nginx的proxy_redirect指定修改被代理服务器返回的响应头中的location头域跟refresh头域数值

nginx的一段配置文档
server {
listen 80;
server_name www.boke;
location / {
proxy_pass http://192.168.1.154:8080;
proxy_redirect off;
}
}

此时我们通过curl查看结果得出
[root@localhost nginx]# curl -I http://www.boke/wuman
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:02:00 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: http://192.168.1.154:8080/wuman/

这里location为带有后端服务器实际地址跟端口的响应头信息这样在实际线上是不允许的所以这里我们打算通过proxy_redirect将被代理服务器的响应头中的location字段进行修改后返回给客户端
server {
listen 80;
server_name www.boke;
location / {
proxy_pass http://192.168.1.154:8080;
proxy_redirect http://192.168.1.154:8080/wuman/ http://www.boke/wuman/;
}

server {
listen 80;
server_name www.boke;
location / {
proxy_pass http://192.168.1.154:8080;
proxy_redirect ~^http://192.168.1.154:8080(.*) http://www.boke$1;
}

则curl查看返回结果
[root@localhost nginx]# curl -I http://www.boke/wuman
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:08:34 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: http://www.boke/wuman/

此时查看location已经变成了我们想要的结果了。 此时通过replacement 301重定向到了我们新的页面
出处:
proxy_redirect
语法:proxy_redirect [ default|off|redirect replacement ]
默认值:proxy_redirect default
使用字段:http, server, location
如果需要修改从被代理服务器传来的应答头中的"Location"和"Refresh"字段,可以用这个指令设置。
假设被代理服务器返回Location字段为: http://localhost:8000/two/some/uri/
这个指令:
proxy_redirect http://localhost:8000/two/ http://frontend/one/;
将Location字段重写为http://frontend/one/some/uri/。
在代替的字段中可以不写服务器名:

proxy_redirect http://localhost:8000/two/ /;
这样就使用服务器的基本名称和端口,即使它来自非80端口。
如果使用“default”参数,将根据location和proxy_pass参数的设置来决定。
例如下列两个配置等效:

location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect default;} location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect http://upstream:port/two/ /one/;}
在指令中可以使用一些变量:

proxy_redirect http://localhost:8000/ http://$host:$server_port/;
这个指令有时可以重复:

proxy_redirect default; proxy_redirect http://localhost:8000/ /; proxy_redirect ; /;
参数off将在这个字段中禁止所有的proxy_redirect指令:

proxy_redirect off; proxy_redirect default; proxy_redirect http://localhost:8000/ /; proxy_redirect ; /;
利用这个指令可以为被代理服务器发出的相对重定向增加主机名:

十七,防盗链

防止网站资源被盗用


ngx_http_referer_module

如何区分哪些是不正常的用户?
HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,
告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许
的网站盗链图片、文件等。因为HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer
信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况。

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent " $http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';


Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location


tianyun.me


[root@tianyun ~]# vim /app/tianyun.me/index.html
<html>
<head>
<meta charset="utf-8">
<title>tianyun.me</title>
</head>
<body style="background-color:red;">
<img src="http://qfcloud.top/Linux1.jpg"/>
</body>
</html>


[root@tianyun ~]# tail -1 /var/log/nginx/tianyun.me.access.log
114.242.26.55 - - [15/Oct/2017:15:34:12 +0800] "GET / HTTP/1.1" 200 179

"-"

"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0" "-"

[root@tianyun ~]# tail -1 /var/log/nginx/qfcloud.top.access.log
114.242.26.55 - - [15/Oct/2017:15:34:13 +0800] "GET /Linux1.jpg HTTP/1.1" 200 148270 "

http://tianyun.me/"

"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0" "-"




如果上一个页面不是当前网站,则阻止: qfcloud.top
[root@tianyun ~]# vim /etc/nginx/conf.d/qfcloud.conf
location / {
root /app/qfcloud.top;
index index.html index.htm;

valid_referers none blocked *.qfcloud.top;
if ($invalid_referer) {
return 403;
}

}


如果希望某些网站能够使用( 链)资源:
location ~* \.(gif|jpg|png|bmp)$ {
valid_referers none blocked *.qfcloud.top server_names ~tianyun ~\.google\. ~\.baidu\.;
if ($invalid_referer) {
return 403;
#rewrite .* http://qfcloud.top/403.jpg;
}
}

以上所有来自 qfcloud.top 和 域名中包含google和baidu的站点都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么$invalid_referer等于1,在if语句中返回一个403给用户,这样用户便会看到一个403的页面,如果使用下面的rewrite,那么盗链的图片都会显示403.jpg。
如果用户直接在浏览器输入你的图片地址,那么图片显示正常,因为它符合none这个规则。

十八,参数优化

https优化

通过https访问Nginx一般会比http访问慢30%(https方式访问主要是耗Nginx服务器的cpu)

优化:
Nginx默认使用DHE算法来产生密匙,该加密算法效率很低。可以通过如下命令,删掉了kEDH算法。

ssl_ciphers ALL:!kEDH!ADH:RC4+RSA:+HIGH:+EXP;

扩展

Apache使用select模型
Nginx使用epoll模型  

UNIX网络编程中,将IO模型划分为5种:  
(1).阻塞IO 点餐等着 不知道什么时候好只能坐等
(2).非阻塞IO 等着也是等着 去逛商场 逛一会儿 一会儿回来问服务员做好没有
(3).信号驱动IO
(4).IO复用 一会儿回来看大屏幕 不用问服务员
(5).异步IO 在家叫外卖

IO复用:主要是select和epoll;对一个IO端口,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对多个IO端口进行监听.
select的两个缺点:能监听端口的大小有限,默认是1024个,若要增大__FD_SETSIZE可参阅http://hi.baidu/step_1/blog/item/24ff06fb72e80c6d034f569b.html采用轮询的方法,效率较低;
相比之下epoll的优点:能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口);不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;利用mmap()文件映射内存加速与内核空间的消息传递

epoll为什么这么快
epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,在开始讨论这个问题之前,先来解释一下为什么需要多路复用IO.

以一个生活中的例子来解释:

假设你在大学中读书,要等待一个朋友来访,而这个朋友只知道你在A号楼,但是不知道你具体住在哪里,于是你们约好了在A号楼门口见面.
如果你使用的阻塞IO模型来处理这个问题,那么你就只能一直守候在A号楼门口等待朋友的到来,在这段时间里你不能做别的事情,不难知道,这种方式的效率是低下的.
现在时代变化了,开始使用多路复用IO模型来处理这个问题.你告诉你的朋友来了A号楼找楼管大妈,让她告诉你该怎么走.这里的楼管大妈扮演的就是多路复用IO的角色.

进一步解释select和epoll模型的差异.
select版大妈做的是如下的事情:比如同学甲的朋友来了,select版大妈比较笨,她带着朋友挨个房间进行查询谁是同学甲,你等的朋友来了,于是在实际的代码中,select版大妈做的是以下的事情:

int n = select(&readset,NULL,NULL,100);
for (int i = 0; n > 0; ++i)
{
   if (FD_ISSET(fdarray[i], &readset))
   {
      do_something(fdarray[i]);
      --n;
   }
}

epoll版大妈就比较先进了,她记下了同学甲的信息,比如说他的房间号,那么等同学甲的朋友到来时,只需要告诉该朋友同学甲在哪个房间即可,不用自己亲自带着人满大楼的找人了.于是epoll版大妈做的事情可以用如下的代码表示:
n=epoll_wait(epfd,events,20,500);
    
for(i=0;i<n;++i)
{
    do_something(events[n]);
}

在epoll中,关键的数据结构epoll_event定义如下:
typedef union epoll_data {
                void *ptr;
                int fd;
                __uint32_t u32;
                __uint64_t u64;
        } epoll_data_t;

        struct epoll_event {
                __uint32_t events;      /* Epoll events */
                epoll_data_t data;      /* User data variable */
        }; 
可以看到,epoll_data是一个union结构体,它就是epoll版大妈用于保存同学信息的结构体,它可以保存很多类型的信息:fd,指针,等等.有了这个结构体,epoll大妈可以不用吹灰之力就可以定位到同学甲.
别小看了这些效率的提高,在一个大规模并发的服务器中,轮询IO是最耗时间的操作之一.再回到那个例子中,如果每到来一个朋友楼管大妈都要全楼的查询同学,那么处理的效率必然就低下了,过不久楼底就有不少的人了.
对比最早给出的阻塞IO的处理模型, 可以看到采用了多路复用IO之后, 程序可以自由的进行自己除了IO操作之外的工作, 只有到IO状态发生变化的时候由多路复用IO进行通知, 然后再采取相应的操作, 而不用一直阻塞等待IO状态发生变化了.
从上面的分析也可以看出,epoll比select的提高实际上是一个用空间换时间思想的具体应用.

文件句柄

文件句柄:
在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。要从文件中读取一块数据,应用程序需要调用函数ReadFile,并将文件句柄在内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。

keepalive

nginx长连接—keepalive

当使用nginx作为反向代理时,为了支持长连接,需要做到两点:
• 从client到nginx的连接是长连接
• 从nginx到server的连接是长连接
1、保持和client的长连接:
默认情况下,nginx已经自动开启了对client连接的keep alive支持(同时client发送的HTTP请求要求keep alive)。一般场景可以直接使用,但是对于一些比较特殊的场景,还是有必要调整个别参数(keepalive_timeout和keepalive_requests)。

http {
keepalive_timeout 120s 120s;
keepalive_requests 10000;
}

1)keepalive_timeout
语法:
keepalive_timeout timeout [header_timeout];
1. 第一个参数:设置keep-alive客户端连接在服务器端保持开启的超时值(默认75s);值为0会禁用keep-alive客户端连接;
2. 第二个参数:可选、在响应的header域中设置一个值“Keep-Alive: timeout=time”;通常可以不用设置;
注:keepalive_timeout默认75s,一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为120s或者300s;
2)keepalive_requests:
keepalive_requests指令用于 设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭。默认是100。这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。
大多数情况下当QPS(每秒请求数)不是很高时,默认值100凑合够用。但是,对于一些QPS比较高(比如超过10000QPS,甚至达到30000,50000甚至更高) 的场景,默认的100就显得太低。
简单计算一下,QPS=10000时,客户端每秒发送10000个请求(通常建立有多个长连接),每个连接只能最多跑100次请求,意味着平均每秒钟就会有100个长连接因此被nginx关闭。同样意味着为了保持QPS,客户端不得不每秒中重新新建100个连接。因此,就会发现有大量的TIME_WAIT的socket连接(即使此时keep alive已经在client和nginx之间生效)。 因此对于QPS较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛弃的情况,减少TIME_WAIT
2、保持和server的长连接:
为了让nginx和后端server(nginx称为upstream)之间保持长连接,典型设置如下:( 默认nginx访问后端都是用的短连接(HTTP1.0),一个请求来了,Nginx 新开一个端口和后端建立连接,后端执行完毕后主动关闭该链接

http {
upstream BACKEND {
server 192.168.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300; // 这个很重要!
}
server {
listen 8080 default_server;
server_name "";
location / {
proxy_pass http://BACKEND;
proxy_set_header Host $Host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
add_header Cache-Control no-store;
add_header Pragma no-cache;
proxy_http_version 1.1; // 这两个最好也设置
proxy_set_header Connection "";
}
}
}

1)location中有两个参数需要设置:

http {
server {
location / {
proxy_http_version 1.1; // 这两个最好也设置
proxy_set_header Connection "";
}
}
}

HTTP协议中对长连接的支持是从1.1版本之后才有的,因此最好通过proxy_http_version指令设置为”1.1”;
而”Connection” header应该被清理。清理的意思,我的理解,是清理从client过来的http header,因为即使是client和nginx之间是短连接,nginx和upstream之间也是可以开启长连接的。这种情况下必须清理来自client请求中的”Connection” header。
2)upstream中的keepalive设置:
此处keepalive的含义不是开启、关闭长连接的开关;也不是用来设置超时的timeout;更不是设置长连接池最大连接数。官方解释:
1. The connections parameter sets the maximum number of idle keepalive connections to upstream servers connections( 设置到upstream服务器的空闲keepalive连接的最大数量
2. When this number is exceeded, the least recently used connections are closed. ( 当这个数量被突破时,最近使用最少的连接将被关闭
3. It should be particularly noted that the keepalive directive does not limit the total number of connections to upstream servers that an nginx worker process can open.( 特别提醒:keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量
我们先假设一个场景: 有一个HTTP服务,作为upstream服务器接收请求,响应时间为100毫秒。如果要达到10000 QPS的性能,就需要在nginx和upstream服务器之间建立大约1000条HTTP连接。nginx为此建立连接池,然后请求过来时为每个请求分配一个连接,请求结束时回收连接放入连接池中,连接的状态也就更改为idle。我们再假设这个upstream服务器的keepalive参数设置比较小,比如常见的10.
A、假设请求和响应是均匀而平稳的,那么这1000条连接应该都是一放回连接池就立即被后续请求申请使用,线程池中的idle线程会非常的少,趋进于零,不会造成连接数量反复震荡。
B、显示中请求和响应不可能平稳,我们以10毫秒为一个单位,来看连接的情况(注意场景是1000个线程+100毫秒响应时间,每秒有10000个请求完成),我们假设应答始终都是平稳的,只是请求不平稳,第一个10毫秒只有50,第二个10毫秒有150:
1. 下一个10毫秒,有100个连接结束请求回收连接到连接池,但是假设此时请求不均匀10毫秒内没有预计的100个请求进来,而是只有50个请求。注意此时连接池回收了100个连接又分配出去50个连接,因此连接池内有50个空闲连接。
2. 然后注意看keepalive=10的设置,这意味着连接池中最多容许保留有10个空闲连接。因此nginx不得不将这50个空闲连接中的40个关闭,只留下10个。
3. 再下一个10个毫秒,有150个请求进来,有100个请求结束任务释放连接。150 - 100 = 50,空缺了50个连接,减掉前面连接池保留的10个空闲连接,nginx不得不新建40个新连接来满足要求。
C、同样,如果假设相应不均衡也会出现上面的连接数波动情况。
造成连接数量反复震荡的一个推手,就是这个keepalive 这个最大空闲连接数。毕竟连接池中的1000个连接在频繁利用时,出现短时间内多余10个空闲连接的概率实在太高。 因此为了避免出现上面的连接震荡,必须考虑加大这个参数,比如上面的场景如果将keepalive设置为100或者200,就可以非常有效的缓冲请求和应答不均匀。
总结:
keepalive 这个参数一定要小心设置,尤其对于QPS比较高的场景,推荐先做一下估算,根据QPS和平均响应时间大体能计算出需要的长连接的数量。比如前面10000 QPS和100毫秒响应时间就可以推算出需要的长连接数量大概是1000. 然后将keepalive设置为这个长连接数量的10%到30%。比较懒的同学,可以直接设置为keepalive=1000之类的,一般都OK的了。
3、综上,出现大量TIME_WAIT的情况
1)导致 nginx端出现大量TIME_WAIT的情况有两种:
• keepalive_requests设置比较小,高并发下超过此值后nginx会强制关闭和客户端保持的keepalive长连接;(主动关闭连接后导致nginx出现TIME_WAIT)
• keepalive设置的比较小(空闲数太小),导致高并发下nginx会频繁出现连接数震荡(超过该值会关闭连接),不停的关闭、开启和后端server保持的keepalive长连接;
2)导致后端server端出现大量TIME_WAIT的情况:
nginx没有打开和后端的长连接,即:没有设置proxy_http_version 1.1;和proxy_set_header Connection “”;从而导致后端server每次关闭连接,高并发下就会出现server端出现大量TIME_WAIT

十九,500以上的错误分析

lnmp环境
lamp 1 lamp redis git

lnmp

client
|
nginx代理 (安装nginx)
|----------------------------------------|
nginx服务(安装nginx) php(安装php-fpm)
|
mysql服务(安装mysql)


200
304
301
302
403
404

nginx的500,502,504错误解决方法
一、解决500错误:
1、500错误
指的是服务器内部错误,也就是服务器遇到意外情况,而无法履行请求。
2、500错误一般有几种情况:
(1)web脚本错误,如php语法错误,lua语法错误等。
(2)访问量大的时候,由于系统资源限制,而不能打开过多的文件
3、一般分析思路:
(1)查看nginx error log ,查看php error log
(2)如果是too many open files,修改nginx的worker_rlimit_nofile参数,使用ulimit查看系统打开文件限制,修改/etc/security/limits.conf
(3)如果是脚本的问题,则需要修复脚本错误,并优化代码
(4)各种优化都做好,还是出现too many open files,那就要考虑做负载均衡,把流量分散到不同服务器上去了

二、解决502,504错误
1、使用nginx代理,而后端服务器发生故障;或者php-cgi进程数不够用;php执行时间长,或者是php-cgi进程死掉;已经执行fastCGI等使用情况都会导致502、504。
2、502 Bad Gateway 是指请求的php-fpm已经执行,但是由于某种原因而没有执行完毕,最终导致php-fpm进程终止。
一般来说,与php-fpm.conf的设置有关,也与php的执行程序性能有关,网站的访问量大,而php-cgi的进程数偏少。针对这种情况的502错误,只需增加php-cgi的进程数。
具体就是修改/usr/local/php/etc/php-fpm.conf文件,将其中的max_children值适当增加。
这个数据要依据你的VPS或独立服务器的配置进行设置。一般一个php-cgi进程占20M内存,你可以自己计算下,适量增多。
/usr/local/php/sbin/php-fpm restart 然后重启一下.
3、504 表示超时,也就是客户端所发出的请求没有到达网关,请求没有得到可以执行的php-fpm

三、解决503错误
503 Service Temporarily Unavailable错误
单个ip并发设置过小会导致503报错

二十,lnmp之mysql,php安装

一,php-fpm

Tengine PHP部署

LNMP


========================================================
tengine-2.1.2.tar.gz or nginx-1.10.1.tar.gz
php-5.6.24.tar.xz
nginx: /usr/local/nginx/conf/nginx.conf
php-fpm: /usr/local/php/etc/php-fpm.conf

部署Nginx|Tengine

部署PHP-fpm

1. 以php-fpm的方式安装php
[root@tianyun ~]# yum -y install libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel \
libxml2 libxml2-devel libcurl libcurl-devel libxslt-devel openssl-devel

[root@webserver ~]# tar xf php-5.6.29.tar.xz
[root@webserver ~]# cd php-5.6.29/
[root@webserver ~]# ./configure \
--prefix= /usr/local/php \
--with-curl \
--with-freetype-dir \
--with-gd \
--with-gettext \
--with-iconv-dir \
--with-jpeg-dir \
--with-kerberos \
--with-libdir=lib64 \
--with-libxml-dir \
--with-mysql \
--with-mysqli \
--with-openssl \
--with-pcre-regex \
--with-pdo-mysql \
--with-pdo-sqlite \
--with-pear \
--with-png-dir \
--with-xmlrpc \
--with-xsl \
--with-zlib \
--enable-fpm \
--enable-bcmath \
--enable-libxml \
--enable-inline-optimization \
--enable-gd-native-ttf \
--enable-mbregex \
--enable-mbstring \
--enable-opcache \
--enable-pcntl \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvsem \
--enable-xml \
--enable-zip
[root@webserver php-5.6.29]# make
[root@webserver php-5.6.29]# make install

2. php-fpm配置文件(影响php处理php程序的性能,例如php进程数、最大连接数配置等,运维人员关注)
[root@webserver php-5.6.29]# cp /usr/local/php/etc/ php-fpm.conf.default /usr/local/php/etc/ php-fpm.conf

3. php置文件(影响php代码,例如允许客户端最大上传文件的大小,设置的timezone,php所支持的扩展功能例如是否可以连接MySQL、Memcache,程序员关注)
[root@webserver php-5.6.29]# cp php.ini-production /usr/local/php/lib/ php.ini

4. init script centos6 [可选]
[root@webserver php-5.6.29]# cp sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm
[root@webserver php-5.6.29]# chmod a+x /etc/rc.d/init.d/php-fpm
[root@webserver php-5.6.29]# chkconfig --add php-fpm
[root@webserver php-5.6.29]# chkconfig php-fpm on
[root@webserver php-5.6.29]# service php-fpm start
Starting php-fpm done

4. Systemd Script centos7 [可选]
[root@webserver ~]# vim /usr/lib/systemd/system/php-fpm.service
[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=simple
PIDFile=/run/php-fpm.pid
ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
ExecStop=/bin/kill -SIGINT $MAINPID

[Install]
WantedBy=multi-user.target

[root@webserver ~]# systemctl start php-fpm.service
[root@webserver ~]# systemctl status php-fpm.service


[root@localhost ~]# ss -an |egrep ':80|:9000'
tcp LISTEN 0 128 127.0.0.1:9000 *:*
tcp LISTEN 0 128 *:80 *:*


配置虚拟主机(支持PHP)


[root@webserver ~]# mkdir -p /webroot/bbs
[root@webserver ~]# vim /webroot/bbs/index.php
<?php
phpinfo();
?>


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



方法一:使用TCP连接
去掉以下行的注释:
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

方法二:使用socket连接
[root@webserver ~]# vim /usr/local/php/etc/php-fpm.conf
;listen = 127.0.0.1:9000
listen = /run/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

[root@webserver ~]# service php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm done
[root@webserver ~]# ll /dev/shm/php-fpm.sock
srw-rw-rw-. 1 root root 0 Sep 18 04:55 /run/php-fpm.sock

[root@webserver ~]# vim /usr/local/nginx/conf/nginx.conf
去掉以下行的注释:
location ~ \.php$ {
root html;
fastcgi_pass unix: /run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}


三、安装MySQL(略)
方案一:
[root@db-server ~]# yum -y install mariadb-server mariadb
[root@db-server ~]# systemctl start mariadb
[root@db-server ~]# systemctl enable mariadb
[root@db-server ~]# mysqladmin password '123456'
方案二:
使用源码包编译安装(参考MySQL安装)

grant
MariaDB [(none)]>> grant all on bbs.* to phptest@'192.168.122.186' identified by '123';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]>> flush privileges;
Query OK, 0 rows affected (0.00 sec)

firewalld
[root@db-server ~]# firewall-cmd --permanent --add-service=mysql
success
[root@db-server ~]# firewall-cmd --reload
success


四、php程序测试
1. 测试php文件能否执行
[root@tianyun ~]# cd /usr/local/nginx/html/
[root@tianyun html]# rm -rf *
[root@tianyun html]# vim index.php
<?php
phpinfo();
?>

2. 测试php连接MySQL是否正常

[root@tianyun html]# vim index.php
<?php
$link=mysql_connect('192.168.122.1','root','123456');
if ( $link)
echo "Successfuly";
else
echo "Faile";
mysql_close();
?>

3. 测试wordpress-4.0-zh_CN.tar.gz
# tar xf wordpress-4.0-zh_CN.tar.gz
# cp -rf wordpress/* /webroot/bbs/
# chown -R nginx.nginx /webroot/bbs/

# fireforx 192.168.122.56
# vim /usr/local/nginx/html/ wp-config.php //配置连接数据库,非商业的应用需要手动配置连接数据库

二,php-fpm.conf

========================================================

gittest

第一部分:fpm配置

;include=etc/fpm.d/*.conf

第二部分:全局配置

;pid = run/php-fpm.pid
;error_log = log/php-fpm.log
;log_level = notice

第三部分:进程池定义
[www]
user = nginx
group = nginx
;listen = /dev/shm/php-fpm.sock
listen = 127.0.0.1:9000
;listen.backlog = 65535
;listen.allowed_clients = 127.0.0.1

; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; Note: This value is mandatory.

pm = dynamic
pm.max_children = 512
pm.start_servers = 32
pm.min_spare_servers = 32
pm.max_spare_servers = 64
pm.max_requests = 1500



[root@webserver ~]# ps aux |grep php
root 2080 0.3 0.4 222800 8680 ? Ss 09:57 0:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nginx 2081 0.0 0.2 224884 4920 ? S 09:57 0:00 php-fpm: pool www
nginx 2082 0.0 0.2 224884 4920 ? S 09:57 0:00 php-fpm: pool www
nginx 2083 0.0 0.2 224884 4920 ? S 09:57 0:00 php-fpm: pool www
nginx 2084 0.0 0.2 224884 4924 ? S 09:57 0:00 php-fpm: pool www
nginx 2085 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2086 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2087 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2088 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2089 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2090 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2091 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2092 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2093 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2094 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www
nginx 2095 0.0 0.2 224884 4928 ? S 09:57 0:00 php-fpm: pool www


php状态功能:


[root@tianyun ~]# vim /usr/local/php/etc/php-fpm.conf
pm.status_path = / php_status

[root@tianyun ~]# vim /usr/local/nginx/conf/nginx.conf
location php_status {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params;

}

[root@tianyun ~]# /usr/local/nginx/sbin/nginx -s reload
[root@tianyun ~]# service php-fpm restart


三,lnmp一键安装

本文仅适用于LNMP1.2及以后的版本安装eAccelerator、xcache、memcached、imageMagick、ionCube、redis、opcache.这几个PHP缓存、加速类的扩展不一定对每个人都能用,自己按需要安装,不用装多个同类的扩展,可能会导致出错。下面会对各个程序的作用、安装方法及相关注意事项。

这些扩展和组件均采用./addons.sh进行安装。
基本用法说明:./addons.sh {install|uninstall} {eaccelerator|xcache|memcached|opcache|redis|imagemagick|ioncube}

1、eAccelerator
eAccelerator是一个自由开放源码php加速器,优化和动态内容缓存,提高了php脚本的缓存性能,使得PHP脚本在编译的状态下,对服务器的开销几乎完全消除。 它还有对脚本起优化作用,以加快其执行效率。

安装
进入lnmp解压后的目录,执行:./addons.sh install eaccelerator 运行后有如下提示:
addons-install-eaccelerator.png
eaccelerator 0.9.5.3 支持PHP 5.2,如需此版本,输入 1 回车。
eaccelerator 0.9.6.1 支持PHP 5.2、5.3,如需此版本,输入 2 回车。
eaccelerator 1.0-dev 支持PHP 5.2、5.3、5.4,如需此版本输入 3 回车。

提示“Press any key to install...or Press Ctrl+c to cancel” 后回车确认,脚本就会自动安装eaccelerator。

卸载
执行:./addons.sh uninstall eaccelerator

2、xcache
XCache 是一个国人开发的又快又稳定的PHP opcode缓存器。经过良好的测试并在大流量/高负载的生产机器上稳定运行,支持所有现行PHP分支的最新发布版本。

安装
进入lnmp解压后的目录,执行:./addons.sh install xcache 运行后有如下提示:
addons-install-xcache.png
需要设置xcache管理页面admin用户的密码。

出现“Press any key to install...or Press Ctrl+c to cancel“,再次回车确认即可开始安装。

卸载
执行:./addons.sh uninstall xcache

3、memcached
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。

安装
进入lnmp解压后的目录,执行:./addons.sh install memcached
addons-install-memcached.png
可以根据自己的需求选择php-memcache或php-memcached扩展,目前discuz x使用的是前者,功能上php-memcached更强大一些。
输入对应的序号,回车,再次确认回车开始安装。

卸载
执行:./addons.sh uninstall memcached

4、imageMagick
ImageMagick是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。它可以读取、编辑超过100种图象格式。可用来替换GD库。

安装
进入lnmp解压后的目录,执行:./addons.sh install imagemagick
回车确认后就会自动安装imageMagick。

设置:比如在DiscuzX里设置时路径需要填写:/usr/local/imagemagick/bin/ 并且禁用函数里的exec要去掉才可以正常使用。

卸载
执行:./addons.sh uninstall imagemagick

5、ionCube
此脚本是用来安装ionCube loader的,ionCube loader是用来解密ionCube加密的PHP脚本,如whmcs就采用ionCube加密。

安装
进入lnmp解压后的目录,执行:./addons.sh install ionCube
回车确认后就会自动安装ionCube loader。

卸载
执行:./addons.sh uninstall ionCube

6、Redis
此脚本是用来安装Redis,Redis是一个开源、支持网络、基于内存、键值对存储数据库。

安装
进入lnmp解压后的目录,执行:./addons.sh install redis
运行后有如下提示:
lnmp-eacesselerator-install.png,安装稳定版Redis 2.8.8 输入:s 回车;安装测试版Redis 3.0.0输入:b 回车;安装旧版Redis 2.6.17输入:o 回车。

7、opcache
此脚本是用来安装opcache的,是 Zend 开发的闭源但可以免费使用的 PHP 优化加速组件。LNMP 1.2下安装的PHP 5.5或更高版本的PHP不需要额外安装OPcache,默认已经安装上。

安装
进入lnmp解压后的目录,执行:./addons.sh install opcache
Opcache和eAccelerator是冲突的,脚本会卸载eAccelerator后再安装Opcache,回车确认后就会自动安装opcache。

卸载
执行:./addons.sh uninstall opcache本文仅适用于LNMP1.2及以后的版本安装eAccelerator、xcache、memcached、imageMagick、ionCube、redis、opcache.这几个PHP缓存、加速类的扩展不一定对每个人都能用,自己按需要安装,不用装多个同类的扩展,可能会导致出错。下面会对各个程序的作用、安装方法及相关注意事项。
这些扩展和组件均采用./addons.sh进行安装。
基本用法说明:./addons.sh {install|uninstall} {eaccelerator|xcache|memcached|opcache|redis|imagemagick|ioncube}


1、eAccelerator


eAccelerator是一个自由开放源码php加速器,优化和动态内容缓存,提高了php脚本的缓存性能,使得PHP脚本在编译的状态下,对服务器的开销几乎完全消除。 它还有对脚本起优化作用,以加快其执行效率。
安装
进入lnmp解压后的目录,执行:./addons.sh install eaccelerator 运行后有如下提示:

eaccelerator 0.9.5.3 支持PHP 5.2,如需此版本,输入 1 回车。
eaccelerator 0.9.6.1 支持PHP 5.2、5.3,如需此版本,输入 2 回车。
eaccelerator 1.0-dev 支持PHP 5.2、5.3、5.4,如需此版本输入 3 回车。
提示“Press any key to install...or Press Ctrl+c to cancel” 后回车确认,脚本就会自动安装eaccelerator。
卸载
执行:./addons.sh uninstall eaccelerator


2、xcache


XCache 是一个国人开发的又快又稳定的PHP opcode缓存器。经过良好的测试并在大流量/高负载的生产机器上稳定运行,支持所有现行PHP分支的最新发布版本。
安装
进入lnmp解压后的目录,执行:./addons.sh install xcache 运行后有如下提示:

需要设置xcache管理页面admin用户的密码。
出现“Press any key to install...or Press Ctrl+c to cancel“,再次回车确认即可开始安装。
卸载
执行:./addons.sh uninstall xcache


3、memcached


Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。
安装
进入lnmp解压后的目录,执行:./addons.sh install memcached

可以根据自己的需求选择php-memcache或php-memcached扩展,目前discuz x使用的是前者,功能上php-memcached更强大一些。
输入对应的序号,回车,再次确认回车开始安装。
卸载
执行:./addons.sh uninstall memcached


4、imageMagick


ImageMagick是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。它可以读取、编辑超过100种图象格式。可用来替换GD库。
安装
进入lnmp解压后的目录,执行:./addons.sh install imagemagick
回车确认后就会自动安装imageMagick。
设置:比如在DiscuzX里设置时路径需要填写:/usr/local/imagemagick/bin/ 并且禁用函数里的exec要去掉才可以正常使用。
卸载
执行:./addons.sh uninstall imagemagick


5、ionCube


此脚本是用来安装ionCube loader的,ionCube loader是用来解密ionCube加密的PHP脚本,如whmcs就采用ionCube加密。
安装
进入lnmp解压后的目录,执行:./addons.sh install ionCube
回车确认后就会自动安装ionCube loader。
卸载
执行:./addons.sh uninstall ionCube


6、Redis


此脚本是用来安装Redis,Redis是一个开源、支持网络、基于内存、键值对存储数据库。
安装
进入lnmp解压后的目录,执行:./addons.sh install redis
运行后有如下提示:
,安装稳定版Redis 2.8.8 输入:s 回车;安装测试版Redis 3.0.0输入:b 回车;安装旧版Redis 2.6.17输入:o 回车。

7、opcache

此脚本是用来安装opcache的,是 Zend 开发的闭源但可以免费使用的 PHP 优化加速组件。LNMP 1.2下安装的PHP 5.5或更高版本的PHP不需要额外安装OPcache,默认已经安装上。
安装
进入lnmp解压后的目录,执行:./addons.sh install opcache
Opcache和eAccelerator是冲突的,脚本会卸载eAccelerator后再安装Opcache,回车确认后就会自动安装opcache。
卸载
执行:./addons.sh uninstall opcache





































本文标签: Nginx