寻觅生命中的那一片浅草......

文章属于类别 应用软件

深究Nginx502 bad gateway, 504 Gateway Time-out的彻底解决

我的VPS是256M的内存,CPU是四核心的,所以更多的我会在乎内存。而在我调试服务器的时候通常会遇到Nginx502 bad gateway和504 Gateway Time-out的错误。分析nginx.conf我发现server和fastcgi的buffers过多,导致fastcgi请求的数量过大,php-fpm无法及时处理而出错。循此思路我们可以再总体buffers不变的情况下减少请求数量,具体的ningx.conf改动细节如下:

server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 1 128k; 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 128k;
fastcgi_buffers 2 256k;8 128
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

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

另外,php-fpm的默认静态处理方式会使得php-cgi的进程长期占用内存而无法释放,这也是导致nginx出错的原因之一,因此可以将php-fpm的处理方式改成apache模式。

<value name=”style”>apache-like</value>

从更改完毕到现在的测试表明上述方式的效果还是很明显的,并没有发现一次Nginx502 bad gateway或504 Gateway Time-out错误。当然,如果你的VPS或者服务器的性能足够好可以根据具体情况不必做无谓的改动。

转载自:http://www.thismail.org/bbs/thread-3321-1-1.html

Nginx配置nginx.conf解释

#user nobody;

worker_processes 10;多少进程

error_log logs/error.log info;记录什么级别的错误日志

pid        logs/nginx.pid; 进程文件

events {
worker_connections 10000; 最大连接就是进程*这个
}

http {
include       mime.types;
default_type application/octet-stream;
log_format   main ‘$remote_addr – $remote_user [$time_local] $status ‘ 这里是日志
‘”$request” $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

access_log logs/access.log main;
client_header_timeout 3m; 客户端连接上来以后3秒还不发送请求 就断开
client_body_timeout    3m;    同上
send_timeout           3m;
sendfile                on;
tcp_nopush              on;
tcp_nodelay             on;

gzip on;
gzip_min_length 1100; 小于这个就不压了
gzip_buffers     4 8k;
gzip_types       text/* application/x-javascript; 压缩的类型
#output_buffers   1 32k;
output_buffers   1 512k;
gzip_comp_level 9;
postpone_output 1460;

upstream mysvr{#这里定义负载均衡服务器
server 127.0.0.1:8080 weight=1;
}

server {
listen       80;
server_name localhost;

#server_name 192.168.0.253;#写成本机ip就可以

charset utf-8;字符集

access_log logs/host.access.log main;日志

下面一段用于设置nginx的proxy_store:

To be clear proxy_store is not a cache, it’s rather mirror on demand.

To be clear proxy_store is not a cache, it’s rather mirror on demand. 因为没有过期头(expire的概念)

location ~* \.(jpg|gif|png|css|swf|html|htm)$ {

root /var/html/$host;远端被缓存的文件都会被放到这里

proxy_store on;
proxy_set_header Host $host;
proxy_temp_path /web/html/tmp;缓存的tmp目录
proxy_set_header Accept-Encoding ”;
proxy_store_access user:rw group:rw all:rw;权限
if ( !-f $request_filename ) {
proxy_pass http://mysvr;这样只有不存在才回去后端拉
}
}

#      location ~ \ * {
location / {
proxy_pass http://mysvr;
proxy_redirect off;
proxy_store 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;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

}
}

location / {
proxy_pass         http://mysvr;   #前面定义的upstream
#        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;     重写http头,没写会导致访问不了

client_max_body_size       10m; #客户端发送的body,在上传附件的时候可能比较大
client_body_buffer_size    128k;

proxy_connect_timeout      90;
proxy_send_timeout         90;
proxy_read_timeout         90;
#        proxy_send_lowat           12000;
proxy_buffer_size          4k;
proxy_buffers              4 32k;
proxy_busy_buffers_size    64k;
proxy_temp_file_write_size 64k;

}
location ~ \.(gif|js|css)$ { #图片,css本地解析
root    /usr/local/tomcat6.bak/webapps/ROOT;
expires 24h;#过期时间
}
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$
{
access_log off;#图片和css不记录日志

}

location /status {
stub_status            on;
access_log      logs/access-status-ip.log;
auth_basic      “status”;
#auth_basic_user_file conf/user;     设置管理员查看连接情况目录
allow   192.168.0.87;
#         allow   10.1.1.0/16;
deny    all;

}
error_page   500 502 503 504 /50x.html;
location = /50x.html {
root   html;
}
}

}

参考文章:

http://wiki.codemongers.com/NginxFullExample2 威客

http://www.chinaunix.net/jh/13/1319835.html         chinaunix

NginxStatus 显示的内容意思如下:

* active connections – 当前 Nginx 正处理的活动连接数。
* server accepts handled requests — 总共处理了 14553819 个连接 ,

成功创建 14553819 次握手 ( 证明中间没有失败的 ), 总共处理了 19239266 个请求 ( 平均每次握手处理了 1.3 个数据请求 )。
* reading — nginx 读取到客户端的 Header 信息数。
* writing — nginx 返回给客户端的 Header 信息数。
* waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading + writing),

意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接。
* 另外转剑心的关于解析泛域名 说不定哪天用上:
* ++++++++++++++++++++++++++++++++++++++++++++++
*
nginx支持泛域名解析的方法
*
http://bbs.bsdlover.cn/thread-2194-1-1.html
要使用Nginx下的泛域名支持,必须在编译 Nginx的时候加上
–with-http_sub_module
freebsd下ports安装的时候有提示的,选上即可。

方法我google了半天,网上的好多我照做都是不行的,例如这个:
listen    80;
server_name  www.yourdomain.com *.yourdomain.com;
这个会提示:
# nginx -t
2009/01/04 13:22:56 [emerg] 63944#0: conflicting parameter “*.bsdlover.cn” in www.conf:14
2009/01/04 13:22:56 [emerg] 63944#0: the configuration file nginx.conf test failed

还有些文章里面说的是:
server_name   .yourdomain.com;
这个也是不行的,经过我的实验,正确的做法是:
listen    80;
server_name   _;
这样就可以了,留个笔记,呵呵
* ++++++++++++++++++++++++++++++++++++++
* 二级目录自动加 /
* if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
*

*

——————————————————————————————————————

nginx的日志管理:

——————————————————————————————————————

Nginx 支持下表中的信号:

信号名 作用描述
TERM, INT 快速关闭程序,中止当前正在处理的请求
QUIT 处理完当前请求后,关闭程序
HUP 重新加载配置,并开启新的工作进程,关闭就的进程,此操作不会中断请求
USR1 重新打开日志文件,用于切换日志,例如每天生成一个新的日志文件
USR2 平滑升级可执行程序
WINCH 从容关闭工作进程

用logrotate来管理;cat /etc/logrotate.d/nginx:

/usr/local/nginx/logs/*.log {
daily每天滚动
rotate 7保留7份
nocompress不压缩
postrotate在执行完滚动后:
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
fi
endscript
}

生效:logrotate -f 这个文件

Postfix里Maildir和Mailbox 的区别

版权声明:本文可以任意转载,转载时请保持文章的完整性,并以超链接形式标明文章原始出处和作者信息及本声明。

http://geoffl.blog.163.com/

作者: 富贵猫

前阵子开始要做Postfix邮件服务器,网上搜了好多文章,不过大部分文章只是作者自己安装步骤的罗列,只能算授人以鱼,所以我看了之后还是需要去看Postfix的手册,还要看很多官方的参考书,看完之后颇有心得,所以就打算写一个“授人以渔”的系列安装设置的文章,让你知其然也知其所以然。

——————————————————————————–

Postfix作邮箱,有4种设置方式,分别是共享域名+系统帐户、独立域名+系统帐户、独立域名+虚拟帐户和虚拟域名+特殊格式邮箱。鉴于通常我们不可能给每个用户设置一个系统帐户,所以第一第二种就不考虑不介绍了。既然是用Postfix来建立我们自己地邮箱系统,所以也没必要去兜很多圈子设置特殊格式邮箱,所以第四种也不考虑。剩下只有一种方式,就是独立域名+虚拟邮箱。

所谓独立域名,就是即使用户名是一样的,但如果域名不同其邮件也将放置在不同的目录。譬如info@abc.com和info@def.com,这二个e-mail地址都以info为用户名,但域名不同,如果是共享域名,他们的mail将被放置在同一个目录下,而独立域名将放置在不同目录下。如果你们公司是很大的集团,下面分好几个公司,分别有独立的域名,这难免有重名的员工,这种情况下,后者显然是我们希望看到的。而所谓虚拟帐户,既然那些邮箱用户只是使用mail服务,我们当然没有必要去给每个用户在Linux下面开设一个个系统帐户,所以我们就用一些数据库之类的东西来保存这些帐户信息,譬如用哈希表、SQL数据库或者LDAP。我使用的是独立域名+虚拟LDAP帐户。

Postfix的安装我就不说了,非常简单。不过如果不会也没关系,后面我会写一篇关于Postfix+mail quota的,那时候需要下载、补丁和编译,等于是Postfix的安装。

LDAP也不说了,要完全掌握LDAP不是这篇能解决的,我只假设你的LDAP服务器里已经有mail这个字段。

下面开始说Postfix如何设置。Postfix的配置文件是/etc/postfix/main.cf,这是独立域名+LDAP的设置

# ===== Basic Setting =====
mail_owner = postfix
myhostname = pop.test.com
inet_interfaces = all
queue_directory = /var/spool/postfix
mynetworks = 127.0.0.0/8

home_mailbox =

# ===== Virtual Mailbox =====
virtual_mailbox_domains = hash:/etc/postfix/v_domains
virtual_mailbox_maps = ldap:/etc/postfix/v_mailbox_maps

virtual_mailbox_base = /var/spool/vhosts/
virtual_minimum_uid = 500
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = virtual

myhostname设置你的邮件服务器名字

inet_interfaces = all设置你在哪些网卡上监听

另外有几个是需要解释的:我们接受哪些域名的邮件?我们的域名下有哪些用户?他们的邮件存放在什么目录?

我们接受那些域名的邮件,这是由virtual_mailbox_domains来定义的。虽然我们可以直接使用

virtual_mailbox_domains = test.com, test2.com

这样的格式来定义这些域名,不过我还是建议如我这样使用一个表来存放,这样更方便日后的维护,表名是随意取的,有没有后缀都没关系,我用v_domains作为表的名字,在main.cf里定义是

virtual_mailbox_domains = hash:/etc/postfix/v_domains

v_domains的内容如下

test.com OK

test2.com OK

这是个text文件,仅仅包含域名,但为了满足哈希表的格式,所以在后面添加一个OK。然后我们还要把这个文件变成Postfix的数据库格式,因此用如下命令转变其格式

postmap v_domains

之后你会得到一个以db为后缀的文件v_domains.db。注意,每次修改完v_domains你都需要使用一次postmap。

我们有哪些用户,这是由virtual_mailbox_maps来决定。同样,你可以用哈希表,不过我还是用LDAP。为了方便你理解,我先说明一下如果用哈希表,它的格式应该是

user1@test.com test.com/user1_mailDirectory/

user2@test.com test.com/user2_mailDirectory/

user1@test2.com test2.com/user1_mailDirectory/

左边是用户的e-mail地址,空格之后是该用户的邮件存放目录。既然我们说了,独立域名代表info@abc.com和info@def.com的邮件放置在不同目录下,所以我们的定义里user1@test.com和user1@test2.com的目录是不同的。如果换成LDAP,我们要得到相同的结果,即用e-mail地址来搜索,得到其邮件存放目录

既然讲到邮件存放目录,就一并解释一下到底这个目录怎样定义的。邮件是存放在

virtual_mailbox_base\virtual_mailbox_maps\home_mailbox下,也就是说virtual_mailbox_base定义的目录下,postfix会根据virtual_mailbox_maps返回的用户目录自动创建该目录,然后如果home_mailbox也有定义,那么在用户目录下还会创建home_mailbox定义的名字。举例来说,按照上面的设置,邮件会存放在

/var/spool/vhosts/test.com/user1/下面。

如果home_mailbox不是空白而是Mail/,那么就会存放在

/var/spool/vhost/test/com/user1/Mail/下面。home_mailbox有什么用呢?举个例子,比方你已经有homeDirectory了,但那是你平时放文件的地方,那么再在同样目录下放邮件就变得很奇怪,所以需要home_mailbox来定义邮件放在你homeDirectory下的什么目录下

注意:地址的最后有没有”/”决定了使用mailbox格式还是maildir格式,没有”/”表示mailbox,有表示maildir。所以并不象大部分人认为的,home_mailbox定义为MailDir才表示使用maildir格式。再举几个例子

/var/spool/vhosts/test.com/user1/  表示使用MailDir格式

/var/spool/vhosts/test.com/user1  表示使用MailBox格式

/var/spool/vhosts/test.com/user1/Mail/  表示使用MailDir格式

/var/spool/vhosts/test.com/user1/MailDir/ 表示使用MailDir格式

/var/spool/vhosts/test.com/user1/MailDir 表示使用MailBox格式,即使home_mailbox是maildir,但没有最后的”/”,只能表示使用MailBox格式。同样道理

/var/spool/vhosts/test.com/user1/MailBox/ 表示使用MailDir格式,虽然home_mailbox是mailbox,但最后的”/”就说明了是使用MailDir格式。

回到virtual_mailbox_maps的LDAP定义,其格式是

virtual_mailbox_maps = ldap:/etc/postfix/v_mailbox_maps

v_mailbox_maps只是一个连接Postfix和LDAP的配置文件,同样文件名是随意取的。v_mailbox_maps的内容是

# LDAP Server的IP地址,我是设在和postfix同一电脑,所以是127.0.0.1

server_host = 127.0.0.1
# 下面这些关于LDAP Search的内容如果你不了解,请学习LDAP

search_base = ou=people,o=test
server_port = 389
bind = yes
bind_dn = cn=root,o=test
bind_pw = <rootpassword>
version = 3

# 下面是关键,我会额外解释

query_filter = (mail=%s)
result_attribute = mail
result_format = %d/%u/

query_filter = (mai=%s)里,query_filter表示搜索用的字段,mail是表示你LDAP里的字段名,%s表示要进入Postfix服务器的那封e-mail的收件人,mail=%s就是搜索LDAP里的mail字段等于收件人的结果。

result_attribute 是LDAP返回的字段,如果你已经在LDAP里定义了譬如homeDirectory或者mailDirectory这样的字段来存放邮件目录,那么你可以直接使用

result_attribute = homeDirectory

这样的格式来定义,那么它直接返回你定义的homeDirectory,而且不需要后面的result_format。我没有这个字段,但我想把用户邮件放在各自的域名下,就如user1@test.com在test.com/user1/下一样,所以我只需要它返回mail字段,然后用result_format来改变返回字段的格式。result_format顾名思义就是把结果format一下,其中%d表示e-mail地址@之后的域名,d应该是domain的首字母,%u表示e-mail地址@之前的用户名,想来u就是username之类的,所以返回的mail地址user1@test.com经过result_format之后就变成了test.com/user1/。注意,%d/%u/最后那个”/”表示我使用MailDir格式存放我的e-mail。

virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

这2行表示邮件用什么身份的用户来存放,我定义了5000,所以你需要事先添加一个用户,并且其uid是5000

useradd postfixadmin –u 5000

名字是随意取的,只要注意uid和main.cf里这2行的定义相同就OK.

好了,如果一切顺利,你应该已经可以收到mail了,收件人没有存在在你LDAP里的那些邮件,会被退回。

查看Apache并发请求数及其TCP连接状态

[文章作者:张宴 本文版本:v1.1 最后修改:2007.07.27 转载请注明出处:http://blog.s135.com]

这两天搭建了一组Apache服务器,每台服务器4G内存,采用的是prefork模式,一开始设置的连接数太少了,需要较长的时间去响应用户的请求,后来修改了一下Apache 2.0.59的配置文件httpd.conf:
引用
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves

StartServers         10
MinSpareServers      10
MaxSpareServers      15
ServerLimit          2000
MaxClients           2000
MaxRequestsPerChild  10000

查看httpd进程数(即prefork模式下Apache能够处理的并发请求数):
Linux命令:
引用
ps -ef | grep httpd | wc -l

返回结果示例:
1388
表示Apache能够处理1388个并发请求,这个值Apache可根据负载情况自动调整,我这组服务器中每台的峰值曾达到过2002。

查看Apache的并发请求数及其TCP连接状态:
Linux命令:
引用
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
其中的SYN_RECV表示正在等待处理的请求数;ESTABLISHED表示正常数据传输状态;TIME_WAIT表示处理完毕,等待超时结束的请求数。

关于TCP状态的变迁,可以从下图形象地看出:
点击在新窗口中浏览此图片
状态:描述
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

转载自:http://blog.s135.com/post/269/

Webserver维护常用命令

实时查看正在执行的sql语句
1./usr/sbin/tcpdump -i eth0 -s 0 -l -w – dst port 3306 | strings | egrep -i

‘SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE

|DROP|ALTER|CALL’

查看http连接

1.netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key,”\t”,state[key]}’

查看SYN状态的http连接

1.netstat -an | grep SYN | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more

查看TIME_WAIT状态的http连接

1.netstat -tna | cut -b 49- |grep TIME_WAIT | sort |more
2.netstat -an | grep TIME_WAIT | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more

查看ESTABLISHED状态的http连接

1.netstat -an | grep ESTABLISHED | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more
2.netstat -an | grep “:80” | grep ESTABLISHED | sort | more

批量kill进程

1.ps -efww|grep sqlr-listener|grep -v grep|cut -c 9-15|xargs kill -9

查看活动的php-cgi连接数

1.netstat -anpo|grep php-cgi|wc -l

按ip查看httpd连接数

1.netstat -anlp | grep 80 | grep tcp | awk {‘print $5’} | awk -F: {‘print $1’}| sort |uniq -c | sort -nr

禁IP

1.iptables -A INPUT -s IP地址 -j REJECT
2.iptables -A INPUT -s IP地址/24 -j REJECT
3.
4.route add -net IP地址 netmask 255.255.255.0 reject

调试命令

1.strace -p pid

跟踪指定的进程pid.

1.gdb -p pid

跟踪指定的进程pid.

批量查找文件并删除

1.find . -name test.php -exec rm {} \;
2.find . -name test.php | xargs rm -rf

更改某一目录下所有目录的权限, 不包括文件, aaa 是目录名

1.find aaa -type d -exec chmod 755 {} \;

替换文件内容

1.sed -i ‘s/b/strong/g’ index.html

此命令搜索 index.html 文件中的 b 并将其替换为 strong。

转载自:www.lostk.com/blog/linux_webserver_cmd/

2025年五月
« 5月    
 1234
567891011
12131415161718
19202122232425
262728293031