存档

‘LNMP应用服务器’ 分类的存档

在nginx中禁止直接用ip访问及server_name特性

2017年2月6日 评论已被关闭

在nginx中禁止直接用ip访问及server_name特性

https://javawind.net/p121
看了很多nginx的配置,好像都忽略了ip直接访问web的问题,不利于SEO优化,所以我们希望可以避免直接用IP访问网站,而是域名访问,具体怎么做呢,看下面。
官方文档中提供的方法:
If you do not want to process requests with undefined “Host” header lines, you may define a default server that just drops the requests:
server {
listen 80 default_server;
server_name _;
return 444;
}
说白了就是只要是ip访问的直接重置444错误。但是这样好像又不太友好,如果能直接给跳转到该web server的网址就好了。
配置如下:
server {
listen 80 default_server;
server_name _;
rewrite ^ http://www.domain.com$request_uri?;
}
这样还是有一点问题,某些特别的地址,我需要用ip访问,其他的都禁止,如何配置呢?
比如说我想让监控宝直接用ip访问我的机器的nginx状态信息,其他的用ip访问的所有请求都跳转到域名上。
server {
listen 80 default_server;
server_name _;
location /xxxxx{
stub_status on;
access_log off;
}
location /{
rewrite ^ http://www.nginxs.com$request_uri?;
}
}
这样就实现了我们想要的功能了。
另外,在这里说一下server_name。server_name 是可以使用正则表达式的,这个功能因该说相当实用。
Nginx中的server_name指令主要用于配置基于名称的虚拟主机,server_name指令在接到请求后的匹配顺序分别为:
1、准确的server_name匹配,例如:
server {
listen 80;
server_name domain.com www.domain.com;

}
2、以*通配符开始的字符串:
server {
listen 80;
server_name *.domain.com; …
}
3、以*通配符结束的字符串:
server {
listen 80;
server_name www.*;

}
4、匹配正则表达式:
server {
listen 80;
server_name ~^(?.+)\.domain\.com$; …
}
nginx将按照1,2,3,4的顺序对server name进行匹配,只有有一项匹配以后就会停止搜索,所以我们在使用这个指令的时候一定要分清楚它的匹配顺序(类似于location指令)。
server_name指令一项很实用的功能便是可以在使用正则表达式的捕获功能,这样可以尽量精简配置文件,毕竟太长的配置文件日常维护也很不方便。下面是2个具体的应用:
1、在一个server块中配置多个站点:
server
{
listen 80;
server_name ~^(www\.)?(.+)$;
index index.php index.html;
root /data/wwwsite/$2;
}
站点的主目录应该类似于这样的结构:
/data/wwwsite/domain.com
/data/wwwsite/nginx.org
/data/wwwsite/baidu.com
/data/wwwsite/google.com
这样就可以只使用一个server块来完成多个站点的配置。
2、在一个server块中为一个站点配置多个二级域名。
实际网站目录结构中我们通常会为站点的二级域名独立创建一个目录,同样我们可以使用正则的捕获来实现在一个server块中配置多个二级域名:
server
{
listen 80;
server_name ~^(.+)?\.domain\.com$; index index.html;
if ($host = domain.com){ rewrite ^ http://www.domain.com permanent; }
root /data/wwwsite/domain.com/$1/; }
站点的目录结构应该如下:
/data/wwwsite/domain.com/www//data/wwwsite/domain.com/nginx/
这样访问www.domain.com时root目录为/data/wwwsite/domain.com/www/,nginx.domain.com时为/data/wwwsite/domain.com/nginx/,以此类推。
后面if语句的作用是将domain.com的方位重定向到www.domain.com,这样既解决了网站的主目录访问,又可以增加seo中对www.domain.com的域名权重。

三大WEB服务器对比分析(apache ,lighttpd,nginx)

2017年1月23日 评论已被关闭

三大WEB服务器对比分析(apache ,lighttpd,nginx)

http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html

一.软件介绍(apache  lighttpd  nginx)

1. lighttpd

Lighttpd是一个具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。lighttpd是众多OpenSource轻量级的web server中较为优秀的一个。支持FastCGI, CGI, Auth, 输出压缩(output compress), URL重写, Alias等重要功能。

Lighttpd使用fastcgi方式运行php,它会使用很少的PHP进程响应很大的并发量。

Fastcgi的优点在于:

·         从稳定性上看, fastcgi是以独立的进程池运行来cgi,单独一个进程死掉,系统可以很轻易的丢弃,然后重新分配新的进程来运行逻辑.

·         从安全性上看, fastcgi和宿主的server完全独立, fastcgi怎么down也不会把server搞垮,

·         从性能上看, fastcgi把动态逻辑的处理从server中分离出来, 大负荷的IO处理还是留给宿主server, 这样宿主server可以一心一意作IO,对于一个普通的动态网页来说, 逻辑处理可能只有一小部分, 大量的图片等静态IO处理完全不需要逻辑程序的参与(注1)

·         从扩展性上讲, fastcgi是一个中立的技术标准, 完全可以支持任何语言写的处理程序(php,java,python…)

2.apache

apache是世界排名第一的web服务器, 根据netcraft(www.netsraft.co.uk)所作的调查,世界上百分之五十以上的web服务器在使用apache.

1995年4月, 最早的apache(0.6.2版)由apache group公布发行. apache group 是一个完全通过internet进行运作的非盈利机构, 由它来决定apache web服务器的标准发行版中应该包含哪些内容. 准许任何人修改隐错, 提供新的特征和将它移植到新的平台上, 以及其它的工作. 当新的代码被提交给apache group时, 该团体审核它的具体内容, 进行测试, 如果认为满意, 该代码就会被集成到apache的主要发行版中.

apache 的特性:

1) 几乎可以运行在所有的计算机平台上.

2) 支持最新的http/1.1协议

3) 简单而且强有力的基于文件的配置(httpd.conf).

4) 支持通用网关接口(cgi)

5) 支持虚拟主机.

6) 支持http认证.

7) 集成perl.

8) 集成的代理服务器

9) 可以通过web浏览器监视服务器的状态, 可以自定义日志.

10) 支持服务器端包含命令(ssi).

11) 支持安全socket层(ssl).

12) 具有用户会话过程的跟踪能力.

13) 支持fastcgi

14) 支持java servlets

3.nginx

Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站点开发.

Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配 Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题,而且Lighttpd的mod_proxy也有一些问题并且很久没有更新。但是Nginx并不支持cgi方式运行,原因是可以减少因此带来的一些程序上的漏洞。所以必须使用FastCGI方式来执行PHP程序。

nginx做为HTTP服务器,有以下几项基本特性:

处理静态文件,索引文件以及自动索引;打开文件描述符缓冲.

无缓存的反向代理加速,简单的负载均衡和容错.

FastCGI,简单的负载均衡和容错.

模块化的结构。包括gzipping, byte ranges, chunked responses,以及 SSI-filter等filter。如果由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理可以并行运行,而不需要相互等待。

Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率。它支持内核Poll模型,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。

Nginx具有很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这样的攻击对nginx来说基本上是毫无用处的。就稳定性而言,nginx比lighthttpd更胜一筹。

Nginx支持热部署。它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。

.3WEB服务器的比较:

server Apache Nginx      Lighttpd
Proxy代理 非常好 非常好 一般
Rewriter 非常好 一般
Fcgi 不好 非常好
热部署 不支持 支持 不支持
系统压力比较 很大 很小 比较小
稳定性 非常好 不好
安全性 一般 一般
技术支持 非常好 很少 一般
静态文件处理 一般 非常好
Vhosts虚拟主机 支持 不支持 支持
反向代理 一般 非常好 一般
Session sticky 支持 不支持 不支持

注:在相对比较大的网站,节约下来的服务器成本无疑是客观的。而有些小型网站往往服务器不多,如果采用 Apache 这类传统 Web 服务器,似乎也还能撑过去。但有其很明显的弊端: Apache 在处理流量爆发的时候(比如爬虫或者是 Digg 效应) 很容易过载,这样的情况下采用 Nginx 最为合适。

建议方案:

Apache 后台服务器(主要处理php及一些功能请求 如:中文url)

Nginx  前端服务器(利用它占用系统资源少得优势来处理静态页面大量请求)

Lighttpd 图片服务器

总体来说,随着nginx功能得完善将使他成为今后web server得主流。

.性能测试

将分别测试3种软件在对动态页面和静态页面请求及并发时的响应时间

l        静态页面 搜狐首页

LIGHTTPD

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 64 60 462.75 21.6
100000/200 67 60 312.07 32.4
100000/500 83 60 137.24 72.8
100000/1000

出现错误丢包

94 60 126.6 78.9

NGINX

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 34.6 140 943.66 10.597
100000/200 35.6 110 924.32 10.818
100000/500 34.3 110 912.68 10.956
100000/1000 37 160 832.59 12.106

APACHE

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 40.6 170 690.72 14.47
100000/200 41.1 180 685.39 14.59
100000/500 42.3 190 633.64 15.78
100000/1000 43.1 200 547.53 18.26

l        动态页面 内部社区首页

LIGHTTPD

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
1000/100 50 200 33.54 29.816
1000/200 52 210 30.43 32.858
1000/500 54 230 25.79 38.76
1000/1000 62 250 24.83 40.28

NGINX

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
1000/100 53.8 250 83.12 12.305
1000/200 55.8 250 74.05 13.504
1000/500 56 260 58.99 16.951
1000/1000 58 260 43.41 23.347

APACHE

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 60 200 27.37 36.541
100000/200 61 220 23.82 41.981
100000/500 73 150 20.59 48.562
100000/1000 53 200 27.18 36.796

l        PHPINFO函数页

LIGHTTPD

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 45 20 168.06 59.504
100000/200 47 22 140.64 71.103
100000/500 49 24 52.80 189.386
100000/1000 在请求到4840时测试测试程序死掉

NGINX

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 70 120 143.46 69.706
100000/200 72 130 140.57 71.140
100000/500 73 150 135.87 73.601
100000/1000 77 160 132.18 75.657

APACHE 出现丢包

n/-c(ab参数) cpu% Mem RequestsperSecond Time taken for tests
100000/100 70 180 245.73 40.694
100000/200 72 190 245.79 40.684
100000/500 75 200 241.29 41.443
100000/1000 77 220 236.74 42.239

四.各大网站WEB服务器资源列表

网站名   操作系统   web服务器

1.门户网站类:

搜狐     LINUX           apache 1.3.37

新浪     LINUX           apache 2.0.54

迅雷     LINUX           nginx 0.6.31

163      LINUX           apache 2.2.6

2.搜索类

百度      unknown        BWS 1.0

Google   linux           gws

Sougou   FreeBSD         apache 2.2.4

Hao123   linux          apache 2.2.4

4. 电子邮箱类

126        linux         apache

Hotmail    win2003      microsoft-IIS 6.0

新浪邮箱    F5 Big-IP    apache 2.2.8

263        linux         apache 2.2.6

5. 博客类

新浪博客    linux          nginx 0.5.35

搜狐博客    linux          nginx

迅雷博客    linux          nginx 0.6.32

天涯博客    F5 Big-IP      Microsoft-IIS/5.0

6.视频类

优酷         linux          apache

土豆         linux          apache

Ku6         linux           apache

六间房       linux          nginx 0.6.14

nginx采用epoll的事件模型,为何效率高

2017年1月19日 评论已被关闭

nginx采用epoll的事件模型,为何效率高
http://zhan.renren.com/louxiaochang?gid=3602888498034749910&checked=true
以前就知道在linux下nginx采用epoll事件模型,处理效率高。但是一直不知道具体为什么,今天查看了下文档,了解了原因。
首先nginx支持一下这些事件模型(才考nginx的wiki)
Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。
select – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。
poll – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-poll_module 和 –without-poll_module 来启用或禁用这个模块。
kqueue – 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
epoll – 高效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如SuSE 8.2, 有让2.4版本的内核支持epoll的补丁。
rtsig – 可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。这种情况 对于高负载的服务器来说是低效的;所以有必要通过调节内核参数 /proc/sys/kernel/rtsig-max 来增加队列的大小。可是从Linux内核版本2.6.6-mm2开始, 这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用 RLIMIT_SIGPENDING 参数调节。当这个队列过于拥塞,nginx就放弃它并且开始使用 poll 方法来处理连接直到恢复正常。
/dev/poll – 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
eventport – 高效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装 这个 安全补丁。
在linux下面,只有epoll是高效的方法。
下面再来看看epoll到底是如何高效的
Epoll是Linux内核为处理大批量句柄而作了改进的poll。 要使用epoll只需要这三个系统调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6内核中得到广泛应用。
epoll的优点
支持一个进程打开大数目的socket描述符(FD)
select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显 然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的 Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完 美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
IO效率不随FD数目增加而线性下降
传 统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是”活跃”的,但 是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对”活跃”的socket进行操 作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有”活跃”的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个”伪”AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的—比如一个高速LAN环境,epoll并不比select/poll有什么效率,相 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
使用mmap加速内核与用户空间的消息传递。
这 点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很 重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。
内核微调
这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协 议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小— 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手 的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。
以上这些epoll内容,参考epoll_互动百科
在我128M的vps上,我查看了一下,file-max的数量已经达到11945
应该说确实比apache的方式要好,而且资源占用也少。

转自:http://xinlogs.com/nginx-epool-events

分类: LNMP应用服务器 标签:

正确设置php-fpm子进程用户,提高网站安全性防挂马

2016年12月11日 评论已被关闭

正确设置php-fpm子进程用户,提高网站安全性防挂马

http://www.lowxp.com/g/article/detail/281

根据生产环境不断反馈,发现不断有 PHP网站被挂木马,绝大部分原因是因为权限设置不合理造成。因为服务器软件,或是 php 程序中存在漏洞都是难免的,在这种情况下,如果能正确设置 Linux 网站目录权限, php 进程权限,那么网站的安全性实际上是可以得到保障的。

那么,造成网站被挂木马的原因是什么?

ftp 连接信息被破解,对这个原因,可行的办法就是使用非常复杂的FTP 用户名(不要使用常用的用户名),如果是固定作业,可考虑使用 iptables 防火墙限制来源 IP 。但是一些情景下,可能需要使用 VPN 以便远程维护。 即网站维护者需要使用 FTP 修改网站文件时,必须先登录到 IDC 机房的 VPN 服务器上,再进行后续的操作。

网站服务器软件/ 配置 /php 程序存在漏洞,被利用,在讨论这个问题前,先说明文件及进程权限的几个概念:

FTP用户对网站目录具有最大修改权限,那么网站的文件所有者一定属于 FTP,  这是毋庸置疑的 , 否则如何修改文件呢?

php-fpm进程, Nginx 进程对网站文件至少需要有读取权限,例如,以下命令即可查看这两个进程所使用的账号:

php-fpm-security1

php-fpm-security2

通过上图,我们可以发现,nginx 和 php-fpm 子进程账号是 nobody 。

我们再查看网站文件目录的权限:

php-fpm-security3

发现网站文件所有者是www 账号,那说明:

  • nginx和 php 对网站只有读取权限,无写入权限
  • 如果php 程序需要对网站某些文件有写入权限,需要手工将文件或目录权限修改为 777
  • 因为php-fpm 子进程是以 nobody 运行,那么 php-fpm 生成的新文件所有者也是 nobody, 这时 ftp 用户将无法修改这些文件,解铃还需系铃人,当 php 生成文件后,需要调用 chmod(“/somedir/somefile”, 0777) 将文件权限修改为 777 ,以便 FTP 用户也可以修改这个文件。
  • 经常有开发人员找我请求重设php 生成的文件的权限。
  • 如果php-fpm 子进程以网站文件所有者用户运行,那意味着 php-fpm 进程对整个网站目录具有可写权限,噩梦也就由此开始。

但是我们发现,有不少系统管理员为了省事,违背了Linux 最小化权限的原则,设置 php-fpm 进程以网站文件所有者账号运行,当然这样可能会方便 php 开发人员( php-fpm 进程对整个网站目录具有可写权限),但是这样一来, Linux 体系的文件系统权限原则将被打破,所有的安全措施将形同虚设。可以想象的是,万一 php 程序中有漏洞,攻击者上传木马,便可以修改网站的所有文件,网站首页被黑,也就不足为怪了。

退一步,如果我们设置了较严格的权限,就算php 程序中存在漏洞,那么攻击者也只能篡改权限为 777 的目录,其它的文件是无法被改写的,网站不就就得更安全了吗?

核心总结:php-fpm 子进程所使用的用户,不能是网站文件所有者。 凡是违背这个原则,则不符合最小权限原则。

经过我参阅网上关于nginx, php-fpm 配置的文章教程和市面上的一些书籍,发现有不少人受这些文章的误导,直接让 php-fpm 子进程以网站所有者账号运行,例如张宴的《实战 nginx 取代 apache 的高性能 Web 服务器》一书的 52 页中,存在以下设置:

www
www

官方提供的配置文件中,php-fpm 子进程使用 nobody 用户,这完全是合理的,无须修改。

那么nginx 的子进程用户,如何设置合理?我的建议是也使用 nobody (对错误日志写入等无影响),设置方法如下:

nginx.conf文件第一行设置为 user nobody; , 再执行 nginx -s reload 即可。

php-fpm子进程用户设置方法:

编辑文件php-fpm.conf (一般位于 /usr/local/php/etc/php-fpm.conf 视安装参数为准),找到 user 、group 两个参数的定义,将其设置为nobody( 默认已经是 nobody) ,再重启 php-fpm 进程即可。

网站可写目录的特殊注意

这里的可写,是相对php-fpm 子进程而言。一个网站最容易出安全问题的即是可写目录,如果可写目录权限能控制严格,安全系数也将大大提高。
我们认为,一个网站可写目录主要分为以下几种:

  1. php 数据缓存目录,如 discuz 的 forumdata 目录,就存放了大量数据缓存文件。此类目录一般会禁止用户直接访问,但是 discuz 在这个目录下又存放了不少 js, css 文件,我们并不能简单地拒绝用户访问这个目录。显然,这个目录下的所有文件,不能直接交给 php 解析,我们后面会给出解决方案。
  2. 附件上传目录。显然此类目录需要开启访问,但不能交由php 引擎解析(即这个目录下的所有文件均视为普通静态文件)。
  3. 静态文件生成目录,这类目录下的文件全部应视为静态文件。
  4. 日志目录, 一般都会拒绝用户直接访问之。

也就是说对网站开发人员而言,需要对可写目录实现动静分离,不同性能的文件,应该区别对待之,这样也就方便系统管理员,设置合理的nginx 规则,以提高安全性。

简单地去掉php 文件的执行权限,并不能阻止 php-fpm 进程解析之。

接下来,根据以上总结,系统管理员如何配置nginx 的目录规则,才更安全呢?

数据缓存目录 /cache/,这个目录的特点是需要777 权限,无须提供给用户访问,那么可以按以下参考配置 nginx

location ~ “^/cache” {
return 403;
}

location ~ “.php$” {
fastcgi_pass 127.0.0.0:9000;
………………..
}

这时,任何用户将无法访问/cache/ 目录内容。

附件上传目录 attachments

此目录的特点是需要开放访问权限,但所有文件不能由php 引擎解析(包括后缀名改为 gif 的木马文件)

location ~ “^/attachments” {
}

location ~ “.php$” {
fastcgi_pass 127.0.0.0:9000;
………………..
}

注意,上面对attachments 目录的 location 定义中是没有任何语句的。 nginx 对正则表达式的 location 匹配优先级最高,任何一个用正则表达式定义的 location, 只要匹配一次,将不会再匹配其它正则表达式定义的 location 。

现在,请在attachments 目录下建立一个 php 脚本文件,再通过浏览器访问安,我们发现浏览器提示下载,这说明 nginx 把 attachments 目录下的文件当成静态文件处理,并没有交给 php fastcgi 处理。这样即使可写目录被植入木马,但因为其无法被执行,网站也就更安全了。

显然,重要的php 配置文件,请勿放在此类目录下。

静态文件生成目录 public

这些目录一般都是php 生成的静态页的保存目录,显然与附件目录有类似之处,按附件目录的权限设置即可。可以预见的是,如果我们设置了较严格的权限,即使网站php 程序存在漏洞,木马脚本也只能被写入到权限为 777 的目录中去,如果配合上述严格的目录权限控制,木马也无法被触发运行,整个系统的安全性显然会有显著的提高。

但是网站可写目录的作用及权限,只有开发人员最为清楚。这方面需要php 开发人员和系统管理员积极沟通。我们使用的方式是:项目上线前,开发人员根据以文档形式提供网站可写目录的作用及权限,由系统管理员针对不同目录进行权限设置。任何一方修改了网站目录权限,但未体现到文档中,我们认为是违反工作流程的

Linux/Nginx查看搜索引擎蜘蛛爬虫的行为

2016年12月8日 评论已被关闭

Linux/Nginx查看搜索引擎蜘蛛爬虫的行为
https://blog.hackroad.com/operations-engineer/linux_server/5107.html
Linux/Nginx查看搜索引擎蜘蛛爬虫的行为 Nginx

做好网站SEO优化的第一步就是首先让蜘蛛爬虫经常来你的网站进行光顾,下面的Linux命令可以让你清楚的知道蜘蛛的爬行情况。下面我们针对nginx服务器进行分析,日志文件所在目录:/usr/local/nginx/logs/access.log,access.log这个文件记录的应该是最近一天的日志情况,首先请看看日志大小,如果很大(超过50MB)建议别用这些命令分析,因为这些命令很消耗CPU,或者更新下来放到分析机上执行,以免影响网站的速度。

Linux shell命令

1. 百度蜘蛛爬行的次数

cat access.log | grep Baiduspider | wc
最左面的数值显示的就是爬行次数。

2. 百度蜘蛛的详细记录(Ctrl C可以终止)

cat access.log | grep Baiduspider
也可以用下面的命令:

cat access.log | grep Baiduspider | tail -n 10
cat access.log | grep Baiduspider | head -n 10
只看最后10条或最前10条,这用就能知道这个日志文件的开始记录的时间和日期。

3. 百度蜘蛛抓取首页的详细记录

cat access.log | grep Baiduspider | grep “GET / HTTP”
百度蜘蛛好像对首页非常热爱每个钟头都来光顾,而谷歌和雅虎蜘蛛更喜欢内页。

4. 百度蜘蛛派性记录时间点分布

cat access.log | grep “Baiduspider ” | awk ‘{print $4}’
5. 百度蜘蛛爬行页面按次数降序列表

cat access.log | grep “Baiduspider ” | awk ‘{print $7}’ | sort | uniq -c | sort -r
文中的Baiduspider 改成Googlebot都可以查看谷歌的数据,鉴于大陆的特殊性,大家应该对百度的log更为关注。

附:(Mediapartners-Google)Google adsense蜘蛛的详细爬行记录

cat access.log | grep Mediapartners
Mediapartners-Google是什么呢?Google adsense广告之所以能与内容相关,因为每个包含着adsense的广告被访问后,很快就有个Mediapartners-Google蜘蛛来到这个页面,所以几分钟后再刷新就能显示相关性广告了,真厉害啊!

使用nginx限制百度蜘蛛的频繁抓取

2016年12月8日 评论已被关闭

使用nginx限制百度蜘蛛的频繁抓取
http://www.bo56.com/使用nginx限制百度蜘蛛的频繁抓取/
百度蜘蛛抓取量骤增,导致服务器负载很高。最终用nginx的ngx_http_limit_req_module模块限制了百度蜘蛛的抓取频率。每分钟允许百度蜘蛛抓取200次,多余的抓取请求返回503。
nginx的配置:
#全局配置
limit_req_zone $anti_spider zone=anti_spider:60m rate=200r/m;
#某个server中
limit_req zone=anti_spider burst=5 nodelay;
if ($http_user_agent ~* “baiduspider”) {
set $anti_spider $http_user_agent;
}

参数说明:
指令limit_req_zone 中的rate=200r/m 表示每分钟只能处理200个请求。
指令limit_req 中的burst=5 表示最大并发为5。即同一时间只能同时处理5个请求。
指令limit_req 中的 nodelay 表示当已经达到burst值时,再来新请求时,直接返回503
IF部分用于判断是否是百度蜘蛛的user agent。如果是,就对变量$anti_spider赋值。这样就做到了只对百度蜘蛛进行限制了。
详细的参数说明,可以查看官方文档。
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone

这个模块对请求的限制采用了漏桶算法。
漏桶算法详见 http://baike.baidu.com/view/2054741.htm
相关代码请查看nginx源码文件 src/http/modules/ngx_http_limit_req_module.c
代码的核心部分是ngx_http_limit_req_lookup 方法。

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

2016年12月5日 评论已被关闭

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

http://www.lxway.com/918814204.htm

文章来源:http://zhangge.net/5037.html

昨天在公司微信群,CTO分享了这个消息,对运维来说以后基于TCP协议的后端业务的高可用又多了一个新的选择,实在是棒极了!

一直以来,Nginx 并不支持tcp协议,所以后台的一些基于TCP的业务就只能通过其他高可用负载软件来完成了,比如Haproxy。

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

这算是一个nginx比较明显的缺憾。不过,在1.90发布后这个认知将得到改写:

2015-04-28 nginx-1.9.0 mainline version has been released, with the stream module for generic TCP proxying and load balancing.nginx-1.9.0 已发布,该版本增加了 stream 模块用于一般的 TCP 代理和负载均衡。

The ngx_stream_core_module module is available since version 1.9.0. This module is not built by default, it should be enabled with the –with-stream configuration parameter.

ngx_stream_core_module 这个模块在1.90版本后将被启用。但是并不会默认安装,需要在编译时通过指定 –with-stream 参数来激活这个模块。

其他改进包括:

  • Change: 删除过时的 aio 和 rtsig 事件处理方法
  • Feature: 可在 upstream 块中使用 “zone” 指令
  • Feature: 流模块,支持 TCP 代理和负载均衡
  • Feature: ngx_http_memcached_module 支持字节范围
  • Feature: Windows 版本支持使用共享内存,带随机化地址空间布局.
  • Feature: “error_log” 指令可在 mail 和 server 级别
  • Bugfix: the “proxy_protocol” parameter of the “listen” directive did not work if not specified in the first “listen” directive for a listen socket.

所以,我们如果需要用到这个功能,就需要加上 –with-stream 参数重新编译nginx。对于已在线上运行的nginx,你可能要用到平滑升级来避免线上的服务被中断,可以参考张戈以前分享的教程:

《Nginx在线服务状态下平滑升级或新增模块的详细操作记录》

最后贴一下官方分享的stream模块的简单配置demo:

http://nginx.org/en/docs/stream/ngx_stream_core_module.html

worker_processes auto;
error_log /var/log/nginx/error.log info;
events {
worker_connections  1024;
}

stream {
upstream backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server 127.0.0.1:12345            max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}

server {
listen 12345;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass backend;
}

server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}

和http模块类似,简单明了。相信熟悉 nginx 的朋友很容易的就能完成一个 nginx 下的 TCP 负载均衡集群配置。

由于工作繁忙,实在是心有余而力不足。还好最近公司给我招了个小鲜肉来做运维助理,等空下来了,我再去测一测这个 Nginx 的 TCP 代理和负载均衡功能。到时候再来博客分享一二,敬请期待!

 

下面测试nginx代理TCP协议的配置。

realserver : 10.134.241.68

nginx :10.134.72.166

客户端:10.129.157.168

TCP监听端口:2014

一、配置nginx

看官网上的文档 http://nginx.org/en/docs/stream/ngx_stream_core_module.html

nginx1.90对TCP协议的代理并不是默认开启的,需要在编译的时候配置 –with-stream 参数:

[img]http://images.cnitblog.com/blog2015/450613/201505/071746123452724.png[/img]

nginx.config文件参照官网:

stream {

upstream cloudsocket {

hash $remote_addr consistent;

server 10.134.241.68:2014 weight=5 max_fails=3 fail_timeout=30s;

}

server {

listen 2014;

proxy_connect_timeout 1s;

proxy_timeout 3s;

proxy_pass cloudsocket;

}

}

启动nginx,发现nginx已经开始监听2014端口了

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

二、测试客户端连realserver

在客户端通过telnet连接realserver的2014端口:

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

在realserver上查看网络连接:

Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块

可以正常连接

三、测试客户端连接nginx

在客户端通过telnet连接nginx所在服务器的2014端口

在nginx机器上查看网络连接

在realserver上查看网络连接

可以注意到nginx是给做了一个TCP连接的中转。

Nginx 的 TCP 负载均衡介绍

2016年12月5日 评论已被关闭

Nginx 的 TCP 负载均衡介绍

http://blog.jobbole.com/91757/

Nginx Plus的商业授权版开始具有TCP负载均衡的功能。从Nginx 1.7.7版本开始加入的,现在变成了一个商业收费版本,想要试用,需要在官网申请。也就是说,Nginx除了以前常用的HTTP负载均衡外,Nginx增加基于TCP协议实现的负载均衡方法。

HTTP负载均衡,也就是我们通常所有“七层负载均衡”,工作在第七层“应用层”。而TCP负载均衡,就是我们通常所说的“四层负载均衡”,工作在“网络层”和“传输层”。例如,LVS(Linux Virtual Server,Linux虚拟服务)和F5(一种硬件负载均衡设备),也是属于“四层负载均衡”。

 

TCP负载均衡的配置方式

Nginx使用了一个新的stream模块来实现TCP负载均衡,这个模块,类似于http和mail模块,允许我们配置一组监听TCP连接的服务。允许你配置多个服务的TCP连接,通过在upstream的server组中配置proxy_pass指令。

修改nginx.conf文件,在http模块的统计目录,添加一个stream模块(和http等同级):

 

TCP负载均衡的执行原理

当Nginx从监听端口收到一个新的客户端链接时,立刻执行路由调度算法,获得指定需要连接的服务IP,然后创建一个新的上游连接,连接到指定服务器。

TCP负载均衡支持Nginx原有的调度算法,包括Round Robin(默认,轮询调度),哈希(选择一致)等。同时,调度信息数据也会和健壮性检测模块一起协作,为每个连接选择适当的目标上游服务器。如果使用Hash负载均衡的调度方法,你可以使用$remote_addr(客户端IP)来达成简单持久化会话(同一个客户端IP的连接,总是落到同一个服务server上)。

和其他upstream模块一样,TCP的stream模块也支持自定义负载均和的转发权重(配置“weight=2”),还有backup和down的参数,用于踢掉失效的上游服务器。max_conns参数可以限制一台服务器的TCP连接数量,根据服务器的容量来设置恰当的配置数值,尤其在高并发的场景下,可以达到过载保护的目的。

Nginx监控客户端连接和上游连接,一旦接收到数据,则Nginx会立刻读取并且推送到上游连接,不会做TCP连接内的数据检测。Nginx维护一份内存缓冲区,用于客户端和上游数据的写入。如果客户端或者服务端传输了量很大的数据,缓冲区会适当增加内存的大小。

当Nginx收到任意一方的关闭连接通知,或者TCP连接被闲置超过了proxy_timeout配置的时间,连接将会被关闭。对于TCP长连接,我们更应该选择适当的proxy_timeout的时间,同时,关注监听socke的so_keepalive参数,防止过早地断开连接。

 

服务健壮性监控

TCP负载均衡模块支持内置健壮性检测,一台上游服务器如果拒绝TCP连接超过proxy_connect_timeout配置的时间,将会被认为已经失效。在这种情况下,Nginx立刻尝试连接upstream组内的另一台正常的服务器。连接失败信息将会记录到Nginx的错误日志中。

如果一台服务器,反复失败(超过了max_fails或者fail_timeout配置的参数),Nginx也会踢掉这台服务器。服务器被踢掉60秒后,Nginx会偶尔尝试重连它,检测它是否恢复正常。如果服务器恢复正常,Nginx将它加回到upstream组内,缓慢加大连接请求的比例。

之所“缓慢加大”,因为通常一个服务都有“热点数据”,也就是说,80%以上甚至更多的请求,实际都会被阻挡在“热点数据缓存”中,真正执行处理的请求只有很少的一部分。在机器刚刚启动的时候,“热点数据缓存”实际上还没有建立,这个时候爆发性地转发大量请求过来,很可能导致机器无法“承受”而再次挂掉。以mysql为例子,我们的mysql查询,通常95%以上都是落在了内存cache中,真正执行查询的并不多。

其实,无论是单台机器或者一个集群,在高并发请求场景下,重启或者切换,都存在这个风险,解决的途径主要是两种:

(1)请求逐步增加,从少到多,逐步积累热点数据,最终达到正常服务状态。
(2)提前准备好“常用”的数据,主动对服务做“预热”,预热完成之后,再开放服务器的访问。

TCP负载均衡原理上和LVS等是一致的,工作在更为底层,性能会高于原来HTTP负载均衡不少。但是,不会比LVS更为出色,LVS被置于内核模块,而Nginx工作在用户态,而且,Nginx相对比较重。另外一点,令人感到非常可惜,这个模块竟然是个付费功能。(补注:本文写于 2015 年 1 月,当初这个模块是收费的)

服务器TIME_WAIT和CLOSE_WAIT详解和解决办法

2016年12月4日 评论已被关闭

服务器TIME_WAIT和CLOSE_WAIT详解和解决办法

来自:http://blog.csdn.net/shootyou/article/details/6622226

 

昨天解决了一个HttpClient调用错误导致的服务器异常,具体过程如下:

http://blog.csdn.net/shootyou/article/details/6615051

里头的分析过程有提到,通过查看服务器网络状态检测到服务器有大量的CLOSE_WAIT的状态。

 

在服务器的日常维护过程中,会经常用到下面的命令:

  1. netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

它会显示例如下面的信息:

TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

 

具体每种状态什么意思,其实无需多说,看看下面这种图就明白了,注意这里提到的服务器应该是业务请求接受处理的一方:

 

这么多状态不用都记住,只要了解到我上面提到的最常见的三种状态的意义就可以了。一般不到万不得已的情况也不会去查看网络状态,如果服务器出了异常,百分之八九十都是下面两种情况:

1.服务器保持了大量TIME_WAIT状态

2.服务器保持了大量CLOSE_WAIT状态

因为linux分配给一个用户的文件句柄是有限的(可以参考:http://blog.csdn.net/shootyou/article/details/6579139),而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,tomcat崩溃。。。

下 面来讨论下这两种情况的处理方法,网上有很多资料把这两种情况的处理方法混为一谈,以为优化系统内核参数就可以解决问题,其实是不恰当的,优化系统内核参 数解决TIME_WAIT可能很容易,但是应对CLOSE_WAIT的情况还是需要从程序本身出发。现在来分别说说这两种情况的处理方法:

 

1.服务器保持了大量TIME_WAIT状态

这种情况比较常见,一些爬虫服务器或者WEB服务器(如果网管在安装的时候没有做内核参数优化的话)上经常会遇到这个问题,这个问题是怎么产生的呢?

从 上面的示意图可以看得出来,TIME_WAIT是主动关闭连接的一方保持的状态,对于爬虫服务器来说他本身就是“客户端”,在完成一个爬取任务之后,他就 会发起主动关闭连接,从而进入TIME_WAIT的状态,然后在保持这个状态2MSL(max segment lifetime)时间之后,彻底关闭回收资源。为什么要这么做?明明就已经主动关闭连接了为啥还要保持资源一段时间呢?这个是TCP/IP的设计者规定 的,主要出于以下两个方面的考虑:

1.防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)
2. 可靠的关闭TCP连接。在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。另外这么设计TIME_WAIT 会定时的回收资源,并不会占用很大资源的,除非短时间内接受大量请求或者受到攻击。

关于MSL引用下面一段话:

  1. MSL 為 一個 TCP Segment (某一塊 TCP 網路封包) 從來源送到目的之間可續存的時間 (也就是一個網路封包在網路上傳輸時能存活的時間),由 於 RFC 793 TCP 傳輸協定是在 1981 年定義的,當時的網路速度不像現在的網際網路那樣發達,你可以想像你從瀏覽器輸入網址等到第一 個 byte 出現要等 4 分鐘嗎?在現在的網路環境下幾乎不可能有這種事情發生,因此我們大可將 TIME_WAIT 狀態的續存時間大幅調低,好 讓 連線埠 (Ports) 能更快空出來給其他連線使用。

再引用网络资源的一段话:

  1. 值 得一说的是,对于基于TCP的HTTP协议,关闭TCP连接的是Server端,这样,Server端会进入TIME_WAIT状态,可 想而知,对于访 问量大的Web Server,会存在大量的TIME_WAIT状态,假如server一秒钟接收1000个请求,那么就会积压 240*1000=240,000个 TIME_WAIT的记录,维护这些状态给Server带来负担。当然现代操作系统都会用快速的查找算法来管理这些 TIME_WAIT,所以对于新的 TCP连接请求,判断是否hit中一个TIME_WAIT不会太费时间,但是有这么多状态要维护总是不好。
  2. HTTP协议1.1版规定default行为是Keep-Alive,也就是会重用TCP连接传输多个 request/response,一个主要原因就是发现了这个问题。

也就是说HTTP的交互跟上面画的那个图是不一样的,关闭连接的不是客户端,而是服务器,所以web服务器也是会出现大量的TIME_WAIT的情况的。

现在来说如何来解决这个问题。
解决思路很简单,就是让服务器能够快速回收和重用那些TIME_WAIT的资源。
下面来看一下我们网管对/etc/sysctl.conf文件的修改:
  1. #对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
  2. net.ipv4.tcp_syn_retries=2
  3. #net.ipv4.tcp_synack_retries=2
  4. #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
  5. net.ipv4.tcp_keepalive_time=1200
  6. net.ipv4.tcp_orphan_retries=3
  7. #表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
  8. net.ipv4.tcp_fin_timeout=30
  9. #表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
  10. net.ipv4.tcp_max_syn_backlog = 4096
  11. #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
  12. net.ipv4.tcp_syncookies = 1
  13. #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
  14. net.ipv4.tcp_tw_reuse = 1
  15. #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
  16. net.ipv4.tcp_tw_recycle = 1
  17. ##减少超时前的探测次数
  18. net.ipv4.tcp_keepalive_probes=5
  19. ##优化网络设备接收队列
  20. net.core.netdev_max_backlog=3000
修改完之后执行/sbin/sysctl -p让参数生效。
这里头主要注意到的是net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_recycle
net.ipv4.tcp_fin_timeout
net.ipv4.tcp_keepalive_*
这几个参数。
net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的开启都是为了回收处于TIME_WAIT状态的资源。
net.ipv4.tcp_fin_timeout这个时间可以减少在异常情况下服务器从FIN-WAIT-2转到TIME_WAIT的时间。
net.ipv4.tcp_keepalive_*一系列参数,是用来设置服务器检测连接存活的相关配置。
2.服务器保持了大量CLOSE_WAIT状态
休息一下,喘口气,一开始只是打算说说TIME_WAIT和CLOSE_WAIT的区别,没想到越挖越深,这也是写博客总结的好处,总可以有意外的收获。
TIME_WAIT状态可以通过优化服务器参数得到解决,因为发生TIME_WAIT的情况是服务器自己可控的,要么就是对方连接的异常,要么就是自己没有迅速回收资源,总之不是由于自己程序错误导致的。
但 是CLOSE_WAIT就不一样了,从上面的图可以看出来,如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方关闭连接之后服务器程 序自己没有进一步发出ack信号。换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直 被程序占着。个人觉得这种情况,通过服务器内核参数也没办法解决,服务器对于程序抢占的资源没有主动回收的权利,除非终止程序运行。
如果你使用的是HttpClient并且你遇到了大量CLOSE_WAIT的情况,那么这篇日志也许对你有用:http://blog.csdn.net/shootyou/article/details/6615051
在那边日志里头我举了个场景,来说明CLOSE_WAIT和TIME_WAIT的区别,这里重新描述一下:
服 务器A是一台爬虫服务器,它使用简单的HttpClient去请求资源服务器B上面的apache获取文件资源,正常情况下,如果请求成功,那么在抓取完 资源后,服务器A会主动发出关闭连接的请求,这个时候就是主动关闭连接,服务器A的连接状态我们可以看到是TIME_WAIT。如果一旦发生异常呢?假设 请求的资源服务器B上并不存在,那么这个时候就会由服务器B发出关闭连接的请求,服务器A就是被动的关闭了连接,如果服务器A被动关闭连接之后程序员忘了 让HttpClient释放连接,那就会造成CLOSE_WAIT的状态了。
所以如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码。因为问题出在服务器程序里头啊。
参考资料:
1.windows下的TIME_WAIT的处理可以参加这位大侠的日志:http://blog.miniasp.com/post/2010/11/17/How-to-deal-with-TIME_WAIT-problem-under-Windows.aspx
3.各种内核参数的含义:http://haka.sharera.com/blog/BlogTopic/32309.htm
4.linux服务器历险之sysctl优化linux网络:http://blog.csdn.net/chinalinuxzend/article/details/1792184

nginx大量TIME_WAIT的解决办法

2016年12月4日 评论已被关闭

nginx大量TIME_WAIT的解决办法

http://www.tuicool.com/articles/iiQJbmn

由于网站使用nginx做的反向代理he负载均衡。在没有默认的系统TCP参数情况下回导致大量的TIME_WAIT出现。

终端可以下敲入

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 8535
CLOSE_WAIT 5
FIN_WAIT2 20
ESTABLISHED 248
LAST_ACK 14
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

解决办法 修改内核参数

vi /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse=1 #让TIME_WAIT状态可以重用,这样即使TIME_WAIT占满了所有端口,也不会拒绝新的请求造成障碍 默认是0
net.ipv4.tcp_tw_recycle=1 #让TIME_WAIT尽快回收 默认0
net.ipv4.tcp_fin_timeout=30
/sbin/sysctl -p 让修改生效

在查看,已经恢复正常

TIME_WAIT 69
CLOSE_WAIT 4
FIN_WAIT2 15
ESTABLISHED 236
LAST_ACK 1
分类: LNMP应用服务器 标签:

nginx 优化(突破十万并发)

2016年12月4日 评论已被关闭

nginx 优化(突破十万并发)
http://blog.chinaunix.net/uid-25266990-id-2985541.html
一般来说nginx 配置文件中对优化比较有作用的为以下几项:
worker_processes 8;
nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
为每个进程分配cpu,上例中将8 个进程分配到8 个cpu,当然可以写多个,或者将一
个进程分配到多个cpu。
worker_rlimit_nofile 102400;
这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文
件数(ulimit -n)与nginx 进程数相除,但是nginx 分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
use epoll;
使用epoll 的I/O 模型
worker_connections 102400;
每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。
keepalive_timeout 60;
keepalive 超时时间。
client_header_buffer_size 4k;
客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求
头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE 取得。
open_file_cache max=102400 inactive=20s;
这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid 30s;
这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1;
open_file_cache 指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。
关于内核参数的优化:
net.ipv4.tcp_max_tw_buckets = 6000
timewait 的数量,默认是180000。
net.ipv4.ip_local_port_range = 1024 65000
允许系统打开的端口范围。
net.ipv4.tcp_tw_recycle = 1
启用timewait 快速回收。
net.ipv4.tcp_tw_reuse = 1
开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。
net.ipv4.tcp_syncookies = 1
开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。
net.core.somaxconn = 262144
web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。
net.core.netdev_max_backlog = 262144
每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_orphans = 262144
系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。
net.ipv4.tcp_timestamps = 0
时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 1
为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
net.ipv4.tcp_syn_retries = 1
在内核放弃建立连接之前发送SYN 包的数量。
net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。
net.ipv4.tcp_keepalive_time = 30
当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。
下面贴一个完整的内核优化设置:
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
下面是一个简单的nginx 配置文件:
user www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000
01000000;
error_log /www/log/nginx_error.log crit;
pid /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 204800;
events
{
use epoll;
worker_connections 204800;
}
http
{
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
keys_zone=TEST:10m
inactive=5m;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 4k;
fastcgi_buffers 8 4k;
fastcgi_busy_buffers_size 8k;
fastcgi_temp_file_write_size 8k;
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
server
{
listen 8080;
server_name backup.aiju.com;
index index.php index.htm;
root /www/html/;
location /status
{
stub_status on;
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
}
log_format access ‘$remote_addr — $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log /www/log/access.log access;
}
}
关于FastCGI 的几个指令:
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10minactive=5m;
这个指令为FastCGI 缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。
fastcgi_connect_timeout 300;
指定连接到后端FastCGI 的超时时间。
fastcgi_send_timeout 300;
向FastCGI 传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI 传送请求的超时时间。
fastcgi_read_timeout 300;
接收FastCGI 应答的超时时间,这个值是指已经完成两次握手后接收FastCGI 应答的超时时间。
fastcgi_buffer_size 4k;
指定读取FastCGI 应答第一部分需要用多大的缓冲区,一般第一部分应答不会超过1k,由于页面大小为4k,所以这里设置为4k。
fastcgi_buffers 8 4k;
指定本地需要用多少和多大的缓冲区来缓冲FastCGI 的应答。
fastcgi_busy_buffers_size 8k;
这个指令我也不知道是做什么用,只知道默认值是fastcgi_buffers 的两倍。
fastcgi_temp_file_write_size 8k;
在写入fastcgi_temp_path 时将用多大的数据块,默认值是fastcgi_buffers 的两倍。
fastcgi_cache TEST
开启FastCGI 缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU 负载,并且防止502 错误。
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
为指定的应答代码指定缓存时间,如上例中将200,302 应答缓存一小时,301 应答缓存1 天,其他为1 分钟。
fastcgi_cache_min_uses 1;
缓存在fastcgi_cache_path 指令inactive 参数值时间内的最少使用次数,如上例,如果在5 分钟内某文件1 次也没有被使用,那么这个文件将被移除。
fastcgi_cache_use_stale error timeout invalid_header http_500;
不知道这个参数的作用,猜想应该是让nginx 知道哪些类型的缓存是没用的。以上为nginx 中FastCGI 相关参数,另外,FastCGI 自身也有一些配置需要进行优化,如果你使用php-fpm 来管理FastCGI,可以修改配置文件中的以下值:
60
同时处理的并发请求数,即它将开启最多60 个子线程来处理并发连接。
102400
最多打开文件数。
204800
每个进程在重置之前能够执行的最多请求数。
下面贴几张测试结果图。
下图为同时在6 台机器运行webbench -c 30000 -t 600 http://backup.aiju.com:8080/index.html 命令后的测试结果:
webbench
使用netstat 过滤后的连接数:
netstat
php 页面在status 中的结果(php 页面为调用phpinfo):

php 页面在netstat 过滤后的连接数:

未使用FastCGI 缓存之前的服务器负载:

此时打开php 页面已经有些困难,需要进行多次刷新才能打开。上图中cpu0 负载偏低
是因为测试时将网卡中断请求全部分配到cpu0 上,并且在nginx 中开启7 个进程分别制定到cpu1-7。
使用FastCGI 缓存之后:

此时可以很轻松的打开php 页面。
这个测试并没有连接到任何数据库,所以并没有什么参考价值,不过不知道上述测试是否已经到达极限,根据内存和cpu 的使用情况来看似乎没有,但是已经没有多余的机子来让我运行webbench 了。囧
转载自 http://bbs.linuxtone.org/thread-4504-1-1.html

为高负载网络优化 Nginx 和 Node.js

2016年12月4日 评论已被关闭

来源: http://www.oschina.net/translate/optimising-nginx-node-js-and-networking-for-heavy-workloads

英文原文:Optimising NginX, Node.JS and networking for heavy workloads

在搭建高吞吐量web应用这个议题上,NginX和Node.js可谓是天生一对。他们都是基于事件驱动模型而设计,可以轻易突破Apache等传统web服务器的C10K瓶颈。预设的配置已经可以获得很高的并发,不过,要是大家想在廉价硬件上做到每秒数千以上的请求,还是有一些工作要做的。

这篇文章假定读者们使用NginX的HttpProxyModule来为上游的node.js服务器充当反向代理。我们将介绍Ubuntu 10.04以上系统sysctl的调优,以及node.js应用与NginX的调优。当然,如果大家用的是Debian系统,也能达到同样的目标,只不过调优的方法有所不同而已。

网络调优

如果不先对Nginx和Node.js的底层传输机制有所了解,并进行针对性优化,可能对两者再细致的调优也会徒劳无功。一般情况下,Nginx通过TCP socket来连接客户端与上游应用。

我们的系统对TCP有许多门限值与限制,通过内核参数来设定。这些参数的默认值往往是为一般的用途而定的,并不能满足web服务器所需的高流量、短生命的要求。

这里列出了调优TCP可供候选的一些参数。为使它们生效,可以将它们放在/etc/sysctl.conf文件里,或者放入一个新配置文件,比如/etc/sysctl.d/99-tuning.conf,然后运行sysctl -p,让内核装载它们。我们是用sysctl-cookbook来干这个体力活。

需要注意的是,这里列出来的值是可以安全使用的,但还是建议大家研究一下每个参数的含义,以便根据自己的负荷、硬件和使用情况选择一个更加合适的值。

net.ipv4.ip_local_port_range='1024 65000'
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog='4096'
net.core.rmem_max='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480'
net.ipv4.tcp_max_tw_buckets='400000'
net.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_syn_retries='2'
net.ipv4.tcp_synack_retries='2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'

重点说明其中几个重要的。

net.ipv4.ip_local_port_range

为了替上游的应用服务下游的客户端,NginX必须打开两条TCP连接,一条连接客户端,一条连接应用。在服务器收到很多连接时,系统的可用端口将很快被耗尽。通过修改net.ipv4.ip_local_port_range参数,可以将可用端口的范围改大。如果在/var/log/syslog中发现有这样的错误: “possible SYN flooding on port 80. Sending cookies”,即表明系统找不到可用端口。增大net.ipv4.ip_local_port_range参数可以减少这个错误。

net.ipv4.tcp_tw_reuse

当服务器需要在大量TCP连接之间切换时,会产生大量处于TIME_WAIT状态的连接。TIME_WAIT意味着连接本身是关闭的,但资源还没有释放。将net_ipv4_tcp_tw_reuse设置为1是让内核在安全时尽量回收连接,这比重新建立新连接要便宜得多。

net.ipv4.tcp_fin_timeout

这是处于TIME_WAIT状态的连接在回收前必须等待的最小时间。改小它可以加快回收。

如何检查连接状态

使用netstat:

netstat -tan | awk ‘{print $6}’ | sort | uniq -c

或使用ss:

ss -s

NginX

随着web服务器的负载逐渐升高,我们就会开始遭遇NginX的某些奇怪限制。连接被丢弃,内核不停报SYN flood。而这时,平均负荷和CPU使用率都很小,服务器明明是可以处理更多连接的状态,真令人沮丧。

经过调查,发现有非常多处于TIME_WAIT状态的连接。这是其中一个服务器的输出:

ss -s
Total: 388 (kernel 541)
TCP:   47461 (estab 311, closed 47135, orphaned 4, synrecv 0, timewait 47135/0), ports 33938

Transport Total     IP        IPv6
*          541       -         -        
RAW        0         0         0        
UDP        13        10        3        
TCP        326       325       1        
INET       339       335       4        
FRAG       0         0         0

有47135个TIME_WAIT连接!而且,从ss可以看出,它们都是已经关闭的连接。这说明,服务器已经消耗了绝大部分可用端口,同时也暗示我们,服务器是为每个连接都分配了新端口。调优网络对这个问题有一点帮助,但是端口仍然不够用。

经过继续研究,我找到了一个关于上行连接keepalive指令的文档,它写道:

设置通往上游服务器的最大空闲保活连接数,这些连接会被保留在工作进程的缓存中。

有趣。理论上,这个设置是通过在缓存的连接上传递请求来尽可能减少连接的浪费。文档中还提到,我们应该把proxy_http_version设为”1.1″,并清除”Connection”头部。经过进一步的研究,我发现这是一种很好的想法,因为HTTP/1.1相比HTTP1.0,大大优化了TCP连接的使用率,而Nginx默认用的是HTTP/1.0。

按文档的建议修改后,我们的上行配置文件变成这样:

upstream backend_nodejs {
  server nodejs-3:5016 max_fails=0 fail_timeout=10s;
  server nodejs-4:5016 max_fails=0 fail_timeout=10s;
  server nodejs-5:5016 max_fails=0 fail_timeout=10s;
  server nodejs-6:5016 max_fails=0 fail_timeout=10s;
  keepalive 512;
}

我还按它的建议修改了server一节的proxy设置。同时,加了一个 p roxy_next_upstream来跳过故障的服务器,调整了客户端的 keepalive_timeout,并关闭访问日志。配置变成这样:

server {
  listen 80;
  server_name fast.gosquared.com;

  client_max_body_size 16M;
  keepalive_timeout 10;

  location / {
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    proxy_set_header   Connection "";
    proxy_http_version 1.1;
    proxy_pass http://backend_nodejs;
  }

  access_log off;
  error_log /dev/null crit;
}

采用新的配置后,我发现服务器们占用的socket 降低了90%。现在可以用少得多的连接来传输请求了。新的输出如下:

ss -s

Total: 558 (kernel 604)
TCP:   4675 (estab 485, closed 4183, orphaned 0, synrecv 0, timewait 4183/0), ports 2768

Transport Total     IP        IPv6
*          604       -         -        
RAW        0         0         0        
UDP        13        10        3        
TCP        492       491       1        
INET       505       501       4

Node.js

得益于事件驱动式设计可以异步处理I/O,Node.js开箱即可处理大量的连接和请求。虽然有其它一些调优手段,但这篇文章将主要关注node.js的进程方面。

Node是单线程的,不会自动使用多核。也就是说,应用不能自动获得服务器的全部能力。

实现Node进程的集群化

我们可以修改应用,让它fork多个线程,在同一个端口上接收数据,从而实现负载的跨越多核。Node有一个cluster模块,提供了实现这个目标所必需的所有工具,但要将它们加入应用中还需要很多体力活。如果你用的是express,eBay有一个叫cluster2的模块可以用。

防止上下文切换

当运行多个进程时,应该确保每个CPU核同一时间只忙于一个进程。一般来说,如果CPU有N个核,我们应该生成N-1个应用进程。这样可以确保每个进程都能得到合理的时间片,而剩下的一个核留给内核调度程序运行其它任务。我们还要确保服务器上基本不执行除Node.js外的其它任务,防止出现CPU的争用。

 

我们曾经犯过一个错误,在服务器上部署了两个node.js应用,然后每个应用都开了N-1个进程。结果,它们互相之间抢夺CPU,导致系统的负荷急升。虽然我们的服务器都是8核的机器,但仍然可以明显地感觉到由上下文切换引起的性能开销。上下文切换是指CPU为了执行其它任务而挂起当前任务的现象。在切换时,内核必须挂起当前进程的所有状态,然后装载和执行另一个进程。为了解决这个问题,我们减少了每个应用开启的进程数,让它们公平地分享CPU,结果系统负荷就降了下来:

请注意上图,看系统负荷(蓝线)是如何降到CPU核数(红线)以下的。在其它服务器上,我们也看到了同样的情况。既然总的工作量保持不变,那么上图中的性能改善只能归功于上下文切换的减少。

链接和参考

nginx导致TIME_WAIT过多

2016年12月4日 评论已被关闭

nginx导致TIME_WAIT过多
http://blog.csdn.net/gloria_y/article/details/11733049
#netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

LAST_ACK 14
SYN_RECV 348
ESTABLISHED 70
FIN_WAIT1 229
FIN_WAIT2 30
CLOSING 33
TIME_WAIT 18122

状态:描述
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

下面解释一下为啥要这样写:

一个简单的管道符连接了netstat和awk命令。

??????????????????????

先来看看netstat:

netstat -n

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 123.123.123.123:80 234.234.234.234:12345 TIME_WAIT

你实际执行这条命令的时候,可能会得到成千上万条类似上面的记录,不过我们就拿其中的一条就足够了。

??????????????????????

再来看看awk:

/^tcp/
滤出tcp开头的记录,屏蔽udp, socket等无关记录。

state[]
相当于定义了一个名叫state的数组

NF
表示记录的字段数,如上所示的记录,NF等于6

$NF
表示某个字段的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是TIME_WAIT

state[$NF]
表示数组元素的值,如上所示的记录,就是state[TIME_WAIT]状态的连接数

++state[$NF]
表示把某个数加一,如上所示的记录,就是把state[TIME_WAIT]状态的连接数加一

END
表示在最后阶段要执行的命令

for(key in state)
遍历数组

print key,”\t”,state[key]
打印数组的键和值,中间用\t制表符分割,美化一下。

如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
vim /etc/sysctl.conf
编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行 /sbin/sysctl -p 让参数生效。

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系?默认的 TIMEOUT 时间

下面附上TIME_WAIT状态的意义:

客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口
状态为TIME_WAIT

是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?
有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?

主动关闭的一方在发送最后一个 ack 后
就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。

也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

TIME_WAIT 并不会占用很大资源的,除非受到攻击。

还有,如果一方 send 或 recv 超时,就会直接进入 CLOSED 状态

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
默 认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

注:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

设置这两个参数: reuse是表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接; recyse是加速TIME-WAIT sockets回收

分类: LNMP应用服务器 标签:

nginx负载均衡设置

2016年12月4日 评论已被关闭

nginx负载均衡设置
http://blog.csdn.net/dongdong_java/article/details/17005271
前面我们学习了很多关于lvs的负载均衡的相关内容,现在我们来看一下,nginx的负载均衡设置,同样,也是借由tomacat来实现。在这里我们用的是NFS服务器,要保证这些数据程序是同步的之后才能进行后面的操作。那么更具体的过程还是从下文中了解吧。

前端一台nginx服务器做调度.后端两台tomcat做WEB服务器.这里动态页与静态页都由tomcat来处理.

软件:

nginx-0.7.28.tar.gz

pcre-7.8.tar.gz

apache-tomcat-6.0.20.tar.gz

jdk-6u14-Linux-i586-rpm.bin

架构说明

三台服务器:一台调度也就是nginx服务器,它还是NFS服务器,我们把2个tomcat的webapps目录挂载到NFS服务器上,这样数据程序是同步的了。

配置步骤:

一、web服务器的配置

首先安装两台tomcat,两台安装都一样

1.安装JDK

# pwd
/usr/local
# chmod a+x jdk-6u14-linux-i586-rpm.bin
# ./jdk-6u14-linux-i586-rpm.bin
# ln -s /usr/java/jdk1.6.0_14 /usr/local/java
设置环境变量
# vi profile
末尾增加如下内容

JAVA_HOME=/usr/java/jdk1.6.0_14
CLASSPATH=/usr/java/jdk1.6.0_14/lib/dt.jar:/usr/java/jdk1.6.0_14/lib/tools.jar
PATH=/usr/java/jdk1.6.0_14/bin:$PATH
export PATH JAVA_HOME CLASSPATH
2.安装tomcat

# cp apache-tomcat-6.0.20.tar.gz /usr/local/
# cd /usr/local/
# tar xzvf apache-tomcat-6.0.20.tar.gz
# ln -s apache-tomcat-6.0.20 tomcat
# vi /usr/local/tomcat/bin/catalina.sh

加入一行:

JAVA_HOME=/usr/java/jdk1.6.0_14
# /usr/local/tomcat/bin/startup.sh
启动服务后访问本地的8080端口可以看到对应apache tomcat页面了
把Tomcat加到自启动:
# vi /etc/rc.d/rc.local
在里面加入如下代码:

export JDK_HOME=/usr/java/jdk1.6.0_14
export JAVA_HOME=/usr/java/jdk1.6.0_14
/usr/local/tomcat/bin/startup.sh

至此tomcat已安装成功了

优化: tomcat 比如防止内存溢出; TCP/IP 比如time_wait与closed_wait等等

二、 安装 nginx、nfs 注意它们是一台服务器上

1.安装 nginx

在安装之前首先要安装pcre-7.9.tar.gz

# tar zxvf pcre-7.9.tar.gz
# cd pcre-7.9
# ./configure
# make && make install

安装nginx

# tar zxvf nginx-0.7.61.tar.gz
# cd nginx-0.7.61
# ./configure –with-http_stub_status_module –prefix=/usr/local/nginx
# make && make install

修改nginx的配置文件

我这里是把原先的重命名然后新建了一个nginx.conf

#vi nginx.conf
user nobody nobody;
worker_processes 8;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 51200;
}
http{
includemime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;

sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_typestext/plain application/x-javascript text/css application/xml;
gzip_vary on;
#设定负载均衡列表
upstream backend
{
server 192.168.100.89:8080;
server 192.168.100.90:8080;
}
#设定虚拟主机
server {
listen 80;
server_name www.syitren.com;
#对 / 所有做负载均衡 (本机nginx采用完全转发,所有请求都转发到后端的tomcat集群)
location / {
root /var/www ;
index index.jsp index.htm index.html;
proxy_redirect off;
#保留用户真实信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend;
}

#location /nginx {
#access_log on;
#auth_basic “NginxStatus”;
#auth_basic_user_file /usr/local/nginx/htpasswd;
#}
log_format access ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log /var/log/access.log access;
}
}

检查nginx的配置文件

# /usr/local/webserver/nginx/sbin/nginx -t

启动nginx

# /usr/local/webserver/nginx/sbin/nginx

重启nginx

# kill -HUP `cat /usr/local/nginx/logs/nginx.pid`

(1)查看负载均衡信息

location /nginx {
stub_status on;
access_log on;
auth_basic “NginxStatus”;
auth_basic_user_file /usr/local/nginx/htpasswd;
}

其中/usr/local/nginx/htpasswd可以用apache自带的功能生成。

最后在IE里访问:

http://www.syitren.com/nginx, 然后输入用户名密码就进入了。

进入之后的说明

输入地址 http://www.syitren.com/nginx/,输入验证帐号密码,即可看到类似如下内容:

Active connections: 328
server accepts handled requests
9309 8982 28890
Reading: 1 Writing: 3 Waiting: 324

第一行表示目前活跃的连接数

第三行的第三个数字表示Nginx运行到当前时间接受到的总请求数,如果快达到了上限,就需要加大上限值了。

第四行是Nginx的队列状态

(2)负载均衡

upstream backend
{
server 192.168.100.89:8080;
server 192.168.100.90:8080;
}

三、 配置NFS
需要安装rpm包portmap、nfs,

# vi /etc/export
/var/www 192.168.100.89(rw,sync,no_root_squash),192.168.100.90(rw,sync,no_root_squash)
# service portmap restart
# service nfs start
# exportfs -rv

重新输出共享目录,

# showmoun -e

查看本机共享的目录

然后tomcat的两台服务器挂载,

# mount 192.168.100.88:/var/www /usr/local/tomcat/weapps

然后我们要在两台tomcat的配置文件中即server.xml中做虚拟主机要与nginx.conf里的一致才OK。

# vi server.xml
<Host name=”www.syitren.com” debug=”0″ appBase=”webapps” unpackWARs=”true” autoDeploy=”true” xmlValidation=”false” xmlNamespaceAware=”false”>
<Context path=”” docBase=”/usr/local/tomcat/webapps/” debug=”0″ reloadable=”true” crossContext=”true”/>
<Logger className=”org.apache.catalina.logger.FileLogger” directory=”logs” prefix=”www.syitren.com_log.” suffix=”.txt”
timestamp=”true”/>
</Host>

四、测试

写了一个测试session的页,上传到虚拟主机对应的目录。

(1)访问一次刷新一次再刷新发现时间每次都不一样,就是来回出现两台tomcat的系统时间,说明成功了。

(2)然后把其中的一台tomcat停掉,这时我们再刷新其中有一个就没有响应了,但过了一分钟左右就是一台机器提供服务了,说明,nginx可以自动把 down的服务器去除,从而使客户端透明。

(3)然后再把停掉的tomcat服务器开启,过一段时间后,nginx服务器又把它加入调度行列。这都是自动的。

Nginx配置proxy_pass转发的/路径问题

2016年12月4日 评论已被关闭

Nginx配置proxy_pass转发的/路径问题

http://www.cnblogs.com/AloneSword/p/3673829.html
——————————————————————————————————————————————————————

Nginx配置proxy_pass转发的/路径问题

在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/,当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。

location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com/;
}

如上面的配置,如果请求的url是http://servername/static_js/test.html
会被代理成http://js.test.com/test.html

而如果这么配置

location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com;
}

则会被代理到http://js.test.com/static_js/test.htm

当然,我们可以用如下的rewrite来实现/的功能

location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
rewrite /static_js/(.+)$ /$1 break;
proxy_pass http://js.test.com;
}

nginx上传文件大小

2016年12月4日 评论已被关闭

nginx上传文件大小
http://blog.csdn.net/liujiyong7/article/details/20386455

采用nginx作反向代理,出现了一个诡异的问题,小文件可以提交,大文件会报500内部错误。这个是什么原因导致的呢?

查wiki可知,上传文件大小相关的有三个配置

client_body_buffer_size 配置请求体缓存区大小, 不配的话,
client_body_temp_path 设置临时文件存放路径。只有当上传的请求体超出缓存区大小时,才会写到临时文件中

client_max_body_size 设置上传文件的最大值
所以查出来,问题出现的原因是

1.文件大小超过了client_body_buffer_size

2.client_body_temp_path的临时文件路径居然没有写权限

以上两个原因导致了返回500错误。
如果上传文件大小超过client_max_body_size时,会报413 entity too large的错误。
原因知道了,修正就简单了。

1.client_body_buffer_size 尽量设置的大点,这是基于速度的考虑,如果因为设置的过小,导致上传的文件老要写磁盘,那速度就太慢了。

2.client_body_temp_path 路径要有可写权限,这个是明显的错误了。改正了就好

3.client_max_body_size 设置上传文件的最大值,这个是基于安全的考虑,我们认为正常用户不会或者基本不会上传太大的文件。

可以设置为client_max_body_size 100m; 或者按照自己的业务来设置这个值。

nginx修改上传文件大小限制

2016年12月4日 评论已被关闭

nginx修改上传文件大小限制
http://blog.csdn.net/bruce128/article/details/9665503
新装了一台服务器,用nginx做代理。突然发现上传超过1M大的客户端文件无法正常上传,于是修改了下nginx的配置。
cd /export/servers/nginx/conf/nginx.conf,在这个配置文件里面的server段里面的
[plain] view plain copy
location / {
root html;
index index.html index.htm;
client_max_body_size 1000m;
}
加上了client_max_body_size 字段,怎么重启都不行。后来在总配置文件里面发现了分配置文件:
[plain] view plain copy
sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#gzip on;
include domains/*; #########################分配置文件路径在此
#include domains/chat.local;
#include domains/chat.erp.com;
#include domains/support.chat.com;
#include douains/chat.com;

server {
listen 80;
server_name localhost;
include domains/*命令指定了分配置文件的路径。找到了分配置文件后,在分配置文件里面进行修改。分配置文件配置如下:
[plain] view plain copy
server
{
listen 80;
server_name chat.erp.360buy.com;
#access_log /export/servers/nginx/logs/chat.erp.360buy.com;
location / {
proxy_pass http://tomcat;
client_max_body_size 1000m;
}
}
用/export/servers/nginx/sbin/nginx -s reload重启下,上传文件的大小受限的问题就解决了。
分享下我的解决过程,希望对大家有帮助。

PHP和Nginx 文件上传大小限制问题解决方法

2016年12月4日 评论已被关闭

PHP和Nginx 文件上传大小限制问题解决方法
http://kure6.blog.51cto.com/2398286/1272799
对于nginx+php的一些网站,上传文件大小会受到多个方面的限制,一个是nginx本身的限制,限制了客户端上传文件的大小,一个是php.ini文件中默认了多个地方的设置。所以为了解决上传文件大小限定的问题必须要做出多处修改。以下整理了几个地方。

1、修改/usr/local/nginx/conf/nginx.conf 文件,查找 client_max_body_size 将后面的值设置为你想设置的值。比如:
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /home/www/htdocs;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/htdocs$fastcgi_script_name;
include fastcgi_params;

client_max_body_size 35m; #客户端上传文件大小设为35M
client_body_temp_path /home/www/nginx_temp; #设置临时目录
}

2、修改php.ini
在php.ini里面查看如下行:
upload_max_filesize = 8M
post_max_size = 10M
memory_limit = 20M
max_execution_time=300
file_uploads = On

默认允许HTTP文件上传,此选项不能设置为OFF。
upload_tmp_dir =/tmp/www

在上传大文件时,你会有上传速度慢的感觉,当超过一定的时间,会报脚本执行超过30秒的错误,这是因为在php.ini配置文件中max_execution_time配置选项在作怪,其表示每个脚本最大允许执行时间(秒),0 表示没有限制。你可以适当调整max_execution_time的值,不推荐设定为0。

详解Nginx HTTP负载均衡和反向代理配置

2016年12月1日 评论已被关闭

详解Nginx HTTP负载均衡和反向代理配置

http://www.codesec.net/view/500613.html

当前大并发的网站基本都采用了Nginx来做代理服务器,并且做缓存,来扛住大并发。先前也用nginx配置过简单的代理,今天有时间把整合过程拿出来和大家分享,不过其中大部分也是网上找来的资源。
nginx完整的反向代理代码如下所示  :

[root@data conf]# vim nginx.conf
user www www;
worker_processes 10;

error_log /var/log/nginx/nginx_error.log;

pid logs/nginx.pid;

worker_rlimit_nofile 65535
events {
use epoll;
worker_connections 65535;
}

http {
include mime.types;
default_type application/octet-stream;

server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
sendfile on;
tcp_nopush on;

keepalive_timeout 65;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;

client_max_body_size 300m; #允许客户端请求的最大单个文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 600; #跟后端服务器连接超时时间,发起握手等候响应超时时间
proxy_read_timeout 600; #连接成功后,等候后端服务器响应时间,在后端排队中等候
proxy_send_timeout 600; #后端服务器数据回传时间,就是在规定时间内后端服务器必须传完所有数
proxy_buffer_size 16k; #代理请求缓存区,这个缓存区间会保存用户的信息以供nginx进行规则处理,一般只要能保存下头信息即可
proxy_buffers 4 32k; #同上,告诉nginx保存单个用的几个Buffer最大用多大空间
proxy_busy_buffers_size 54k; #如果系统很忙可以申请用的几个更大的proxy_buffer
proxy_temp_file_write_size 64k; #缓存临时文件大小

upstreamphp_server_pool {
server 192.168.1.100:80 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.101:80 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.102:80 weight=4 max_fails=2 fail_timeout=30s;
}
upstream message_server_pool {
server 192.168.1.103:3245;
server 192.168.1.104:3245 down;
}
upstream bbs_server_pool {
server 192.168.1.105:80 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.106:80 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.107:80 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.108:80 weight=4 max_fails=2 fail_timeout=30s;
}
#第一个虚拟主机,反向代理php_server_pool这组服务器
server {
listen 80;
server_name www.chlinux.net;
access_log /var/log/nginx/www.chlinux.net_access.log main;
location / {
#如果后端服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_pass http://php_server_pool;
proxy_set_header Host www.chlinux.net;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
#第二个虚拟主机
server {
listen 80;
server_name bbs.chlinux.net;
access_log /var/log/nginx/www.chlinux.net_access.log main;
#访问http://bbs.chlinux.net/message/***地址,反向代理message_server_pool这组服务器
location /message/ {
proxy_pass http://message_server_pool;
proxy_set_header Host $host;
}
#访问除了/message/之外的http://bbs.chlinux.net/***地址,反向代理php_server_pool这组服务器
location /message/ {
proxy_pass http://bbs_server_pool;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
#第三个虚拟主机
server {
listen 80;
server_name forum.chlinux.net;
access_log /var/log/nginx/www.chlinux.net_access.log main;
location / {

proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_pass http://php_server_pool;
proxy_set_header Host www.chlinux.net;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}

通过上述所示,已经看到nginx对于多个域名的负载均衡是如何配置的。pustream指令用于设置一组可以再proxy_pass和fastcgi_pass指令中使用的代理服务器,upstream模块中的server指令用于指定后端服务器的名称和参数,服务器的名称可以是一个域名、一个IP地址、端口号或UNIX Socket

nginx反向代理可以配置动、静态网页分离,就是让动态PHP等程序网页访问PHP web服务器,让缓存页、图片、javascript、CSS、Flash访问squid等缓存服务器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

php.ini中date.timezone设置分析

2016年11月19日 评论已被关闭

php.ini中date.timezone设置分析

 

date.timezone设置php5默认date.timezone为utc,改为date.timezone = PRC即可解决时间相差八小时的问题,但我在php的官方文档中看了半天也没找到这个参数啊

虽然知道这个参数表示“中华人民共和国”的意思,但官方文档 中并没有这样的参数,只有Asia/Shanghai、Asia/Hong_Kong等这些参数啊,为何这里可以设置为RPC,哪位给指点指点,这个参数 究竟是在哪儿?官方文档中看来看去的确并没有此参数啊,不解。 一般都设成Asia/Shanghai

 

使用xampp时间不久,今天为了纠正php获取函数是获取服务器时间。

 

因为php5.1.0开始,php.ini里加入了date.timezone这个选项,默认情况下是关闭的。显示的时间都是格林威治标准时间,和 北京时间差了正好8个小时。

 

网上找到的方法:

 

修改php.ini文件,查找 ;date.timezone = ,把前面的分号去掉在 “=”后面加上时区。

 

比如:Asia/Chongqing (重庆),Asia/Shanghai (上海),Asia/Urumqi (乌鲁木齐),Asia/Macao (澳门),Asia/Hong_Kong (香港),Asia/Taipei (台北),PRC

 

;date.timezone =

改成:

date.timezone = Asia/Shanghai

 

方法很简单。可是在xampp下,把php/php.ini文件改来改去都没用。后来网上搜了才发现,该死的xampp,把php.ini放在 apache/bin下面,修改这个里面的php.ini才有用。