Entries tagged with “apache”.


在apache的配置文件httpd.conf里默认有这么一句配置

logformat “%h %l %u %t “%r” %>s %b “%{Referer}i” “%{User-Agent}i”" common

这是APACHE的日志记录格式设置,那么这种格式里的各个参数都代表什么意思呢,下面看一下具体的参数说明:

请求本身的情况将通过在格式字符串中放置各种”%”转义符的方法来记录,它们在写入日志文件时,根据下表的定义进行转换:

%a 远端IP地址
%A 本机IP地址
%B 除HTTP头以外传送的字节数
%b 以CLF格式显示的除HTTP头以外传送的字节数,也就是当没有字节传送时显示’-’而不是0。
%{Foobar}C 在请求中传送给服务端的cookieFoobar的内容。
%D 服务器处理本请求所用时间,以微为单位。
%{FOOBAR}e 环境变量FOOBAR的值
%f 文件名
%h 远端主机
%H 请求使用的协议
%{Foobar}i 发送到服务器的请求头Foobar:的内容。
%l 远端登录名(由identd而来,如果支持的话),除非IdentityCheck设为”On”,否则将得到一个”-”。
%m 请求的方法
%{Foobar}n 来自另一个模块的注解Foobar的内容。
%{Foobar}o 应答头Foobar:的内容。
%p 服务器服务于该请求的标准端口。
%P 为本请求提供服务的子进程的PID。
%{format}P 服务于该请求的PID或TID(线程ID),format的取值范围为:pid和tid(2.0.46及以后版本)以及hextid(需要APR1.2.0及以上版本)
%q 查询字符串(若存在则由一个”?”引导,否则返回空串)
%r 请求的第一行
%s 状态。对于内部重定向的请求,这个状态指的是原始请求的状态,—%>s则指的是最后请求的状态。
%t 时间,用普通日志时间格式(标准英语格式)
%{format}t 时间,用strftime(3)指定的格式表示的时间。(默认情况下按本地化格式)
%T 处理完请求所花时间,以秒为单位。
%u 远程用户名(根据验证信息而来;如果返回status(%s)为401,可能是假的)
%U 请求的URL路径,不包含查询字符串。
%v 对该请求提供服务的标准ServerName。
%V 根据UseCanonicalName指令设定的服务器名称。
%X 请求完成时的连接状态:X= 连接在应答完成前中断。
+= 应答传送完后继续保持连接。
-= 应答传送完后关闭连接。

(在1.3以后的版本中,这个指令是%c,但这样就和过去的SSL语法:%{var}c冲突了)
%I 接收的字节数,包括请求头的数据,并且不能为零。要使用这个指令你必须启用mod_logio模块。
%O 发送的字节数,包括请求头的数据,并且不能为零。要使用这个指令你必须启用mod_logio模块。

修饰符
可以紧跟在”%”后面加上一个逗号分隔的状态码列表来限制记录的条目。例如,”%400,501{User-agent}i” 只记录状态码400和501发生时的User-agent头内容;不满足条件时用”-”代替。状态码前还可以加上”!”前缀表示否 定,”%!200,304,302{Referer}i”记录所有不同于200,304,302的状态码发生时的Referer头内容。

“<”和”>”修饰符可以用来指定对于已被内部重定向的请求是选择原始的请求还是选择最终的请求。默认情况下,%s, %U, %T, %D, %r 使用原始请求,而所有其他格式串则选择最终请求。例如,%>s 可以用于记录请求的最终状态,而 %<u 则记录一个已经被内部重定向到非认证资源的请求的原始认证用户。

一些说明
出于安全考虑,从2.0.46版本开始,%r, %i, %o 中的特殊字符,除了双引号(“)和反斜线()分别用 ” 和 \ 进行转义、空白字符用C风格(n, t 等)进行转义以外,非打印字符和其它特殊字符使用 xhh 格式进行转义(hh是该字符的16进制编码)。在2.0.46以前的版本中,这些内容会被完整的按原样记录。这种做法将导致客户端可以在日志中插入控制字 符,所以你在处理这些日志文件的时候要特别小心。

在2.0版本中(不同于1.3),%b 和 %B 格式字符串并不表示发送到客户端的字节数,而只是简单的表示HTTP应答字节数(在连接中断或使用SSL时与前者有所不同)。mod_logio提供的 %O 格式字符串将会记录发送的实际字节数。

示例
一些常见的格式串:

通用日志格式(CLF)
“%h %l %u %t “%r” %>s %b”

带虚拟主机的通用日志格式
“%v %h %l %u %t “%r” %>s %b”

NCSA扩展/组合日志格式
“%h %l %u %t “%r” %>s %b “%{Referer}i” “%{User-agent}i”"

Referer日志格式
“%{Referer}i -> %U”

Agent(Browser)日志格式
“%{User-agent}i”

文章开头提到的LogFormat “%h %l %u %t “%r” %>s %b “%{Referer}i” “%{User-Agent}i”" common 中间用” “包含的参数都可以在上面找到对应的说明,至于最后的那个common,其实就是这种格式的一种标识符,当你套用这种格式记录日志的时候,就可以直接使用 标识符了,例如:
CustomLog logs/access_log common
就会在logs下面产生一个以common为格式记录的日志文件access_log

附:我的服务器日志记录设置:

LogFormat "%v %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/access_log_%Y%m%d 86400 480" combined

有效的使用浏览器缓存,首先可以提升网页的访问速度,加强用户体验,其次减少页面输出节约服务器带宽。

本文主要讲如何通过apache的mod_expires,或者PHP代码来杠杆(调节)浏览器缓存,即leverage browser caching。

主要参数有:Last-Modified, Cache-Control, max-age, expiration date等。方法很简单

方法一、
设置APACHE,启用mod_expires,并在配置文件中增加以下:

ExpiresActive On
ExpiresDefault "access plus 12 hours"
ExpiresByType text/html "access plus 3 days"
ExpiresByType text/plain "access plus 3 days"
ExpiresByType text/css "access plus 3 days"
ExpiresByType application/javascript "access plus 3 days"
ExpiresByType application/x-http-php "access plus 5 minutes"
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/x-icon "access plus 30 days"


关于mod_expires的启用、各项参数释义请自行google,这里不能阐述。
方法二、
适用于不能、不方便配置APACHE的PHP用户,优点是使用简单,缺点仅对PHP页面有效果,对CSS、JS及图片没有效果。

/**
*设置浏览器缓存
*@param int $cachetime
**/
function LeverageBrowserCaching($cachetime = 60) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] != NULL && ((strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))+$cachetime) > time()) {
header( "HTTP/1.1 304 Not Modified" );
exit;
}
else {
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=" . $cachetime);
}
}

将以上函数放在程序的公用文件当中,在PHP程序的开头调用些文件。注意调用之前不能有任何输出。

END

WEB服务器time_wait或fin_wait1过多处理

1、fin_wait1状态过多。fin_wait1状态是在server端主动要求关闭tcp连接,并且主动发送fin以后,等待client端回复ack时候的状态。fin_wait1的产生原因有很多,需要结合netstat的状态来分析。

netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n

上面的命令可以帮助分析哪种tcp状态数量异常

netstat -nat|grep ":80"|awk '{print $5}' |awk -F: '{print $4}' | sort| uniq -c|sort -n
则可以帮助你将请求80服务的client ip按照连接数排序。

2、time_wait状态过多。

通常表现为apache服务器负载高,w命令显示load average可能上百,但是web服务基本没有问题。同时ssh能够登陆,但是反应非常迟钝。

原因:最可能的原因是httpd.conf里面keepalive没有开,导致每次请求都要建立新的tcp连接,请求完成以后关闭,增加了很多time_wait的状态。另,keepalive可能会增加一部分内存的开销,但是问题不大。
分析:如果发现fin_wait1状态很多,并且client ip分布正常,那可能是有人用肉鸡进行ddos攻击、又或者最近的程序改动引起了问题。一般说来后者可能性更大,应该主动联系程序员解决。
但是如果有某个ip连接数非常多,就值得注意了,可以考虑用iptables直接封了他。

假如你的apache的安装目录为/usr/local/apache_test/它的日志文件在/usr/local/apache_test/logs/下面,通常访问日志为access_log,那么如何来做呢?
         1.在/etc/logrotate.d/目录下创建一个文件rotate_apache,运行命令touch rotate_apache(注:该文件用来告诉logrotate如何来按天轮循生成日志文件)
         2.编辑该文件vi rotate_apache,输入以下内容:
/usr/local/apache_test/logs/access_log{
missingok
daily
rotate 10
postrotate
/bin/kill -HUP `cat /usr/local/apache_test/logs/httpd.pid 2>/dev/null` 2> /dev/null || true
endscript
compress
}
3.OK了,就这么简单,之后你就会发现在apache的日志目录下会每天都产生一个文件,文件名如下:
                access_log.1.gz
                access_log.2.gz
                ………………..

         这个工具(logrotate)以一种灵活的方式来对系统中的日志进行统一的管理,工作原理是这样的:它本身被加到了linux系统中的crontab中(但是我们从crontab -l中是看不到的),所以默认就会每天去执行一次,执行的配置文件为/etc/logrotate.conf,它会通过里面定义的内容来执行日志的切换工作,里面有好多可选的配置方式和参数。具体的内容请参照:http://dongwei.javaeye.com/admin/show/145181

转自:http://dongwei.javaeye.com/blog/145444

第一步:安装apache
  下载apache2: http://httpd.apache.org/download.cgi
  我需要mod_ssl的支持,和apache1不同的是,mod_ssl不在是单独的模块,而是放在apache发行包里面了,默认是不启用的,config的时候选择上就可以了。
  我使用DSO方式编译安装apache,同时将全部模块都编译好,以方便后来可能的需要。只要编辑httpd.conf,在里面去掉不想要的模块(注释或者删除对应模块的LoadModule行),就可以定制自己的apache咯。
  $ tar zxvf httpd-2.0.50.tar.gz
  $ ./configure –prefix=/usr/local/apache2 –enable-so –enable-ssl=shared –enable-mods-shared=all –with-ssl=/usr/local/ssl
  $ make
  $ su
  # make install
  Apache有两种使用模块的方法,其一是永久性包含进核心;
  如果操作系统支持动态共享对象(DSO),而且能为autoconf所检测,则模块还可以被动态编译。
  DSO模块的存储是独立与核心的,可以被核心使用由mod_so模块提供的运行时刻配置指令包含或排除。
  如果编译中包含有任何动态模块,则mod_so模块会被自动包含进核心。如果希望核心能够装载DSO,而不实际编译任何动态模块,需要明确指定–enable-so。
  (http://kajaa.bbs.us/ApacheManual/install.html)
  第一次按照上述方法编译的apache,启动的时候会报错:
  # cd /usr/local/apache2
  # ./bin/apachectl startssl
  Syntax error on line 251 of /usr/local/apache/conf/httpd.conf:
  Cannot load /usr/local/apache/modules/mod_ssl.so into server: /usr/local/apache/modules/mod_ssl.so: undefined symbol: X509_free
  原因是什么呢?看 http://www.smartframeworks.com/qt-apache-ssl.html
  因为按照下面的方法(参看:Apache2 + mod_ssl + php5 完全安装实录(2))安装的openssl默认是没有编译成动态链接库的,因为其文档说openssl的动态链接库还不成熟,可以使用 ./config shared 编译带动态链接库的openssl,但是还处于试验阶段。
  解决这个问题的办法是:将mod_ssl静态的编译到apache里面。
  请使用下面的方法重新来过:)
  $ ./configure –prefix=/usr/local/apache2 –enable-so –enable-ssl=static –with-ssl=/usr/local/ssl –enable-mods-shared=all
  $ make
  $ su
  # make install
  这次启动apache的时候又发现一个错误:
  # cd /usr/local/apache2
  # ./bin/apachectl startssl
  Syntax error on line 108 of /usr/local/apache2/conf/ssl.conf:
  SSLCertificateFile: file ‘/usr/local/apache2/conf/ssl.crt/server.crt’ does not exist or is empty
  这又是什么原因呢?因为我们没有配置ssl,需要生成ssl需要的证书。
  以前使用apache1+mod_ssl的时候,make之后有一个这样的步骤
  $ make certificate
  可以用来生成ssl所用到的证书。
  现在没有这个工具了,只能自己动手生成了,对证书不熟悉的人,有一个工具可以使用:http://www.openssl.org/contrib/ssl.ca-0.1.tar.gz
  # cd /usr/local/apache2/conf
  # tar zxvf ssl.ca-0.1.tar.gz
  # cd ssl.ca-0.1
  # ./new-root-ca.sh (生成根证书)
  No Root CA key round. Generating one
  Generating RSA private key, 1024 bit long modulus
  ………………………++++++
  ….++++++
  e is 65537 (0×10001)
  Enter pass phrase for ca.key: (输入一个密码)
  Verifying – Enter pass phrase for ca.key: (再输入一次密码)
  ……
  Self-sign the root CA… (签署根证书)
  Enter pass phrase for ca.key: (输入刚刚设置的密码)
  ……..
  …….. (下面开始签署)
  Country Name (2 letter code) [MY]:CN
  State or Province Name (full name) [Perak]:JiangSu
  Locality Name (eg, city) [Sitiawan]:NanJing
  Organization Name (eg, company) [My Directory Sdn Bhd]:Wiscom System Co.,Ltd
  Organizational Unit Name (eg, section) [Certification Services Division]:ACSTAR
  Common Name (eg, MD Root CA) []:WISCOM CA
  Email Address []:acmail@wiscom.com.cn
  这样就生成了ca.key和ca.crt两个文件,下面还要为我们的服务器生成一个证书:
  # ./new-server-cert.sh server (这个证书的名字是server)
  ……
  ……
  Country Name (2 letter code) [MY]:CN
  State or Province Name (full name) [Perak]:JiangSu
  Locality Name (eg, city) [Sitiawan]:NanJing
  Organization Name (eg, company) [My Directory Sdn Bhd]:Wiscom System Co.,Ltd
  Organizational Unit Name (eg, section) [Secure Web Server]:ACSTAR
  Common Name (eg, www.domain.com) []:acmail.wiscom.com.cn
  Email Address []:acmail@wiscom.com.cn
  这样就生成了server.csr和server.key这两个文件。
  还需要签署一下才能使用的:
  # ./sign-server-cert.sh server
  CA signing: server.csr -> server.crt:
  Using configuration from ca.config
  Enter pass phrase for ./ca.key: (输入上面设置的根证书密码)
  Check that the request matches the signature
  Signature ok
  The Subject’s Distinguished Name is as follows
  countryName :P RINTABLE:’CN’
  stateOrProvinceName :P RINTABLE:’JiangSu’
  localityName :P RINTABLE:’NanJing’
  organizationName :P RINTABLE:’Wiscom System Co.,Ltd’
  organizationalUnitName:PRINTABLE:’ACSTAR’
  commonName :P RINTABLE:’acmail.wiscom.com.cn’
  emailAddress :IA5STRING:’acmail@wiscom.com.cn’
  Certificate is to be certified until Jul 16 12:55:34 2005 GMT (365 days)
  Sign the certificate? [y/n]:y
  1 out of 1 certificate requests certified, commit? [y/n]y
  Write out database with 1 new entries
  Data Base Updated
  CA verifying: server.crt <-> CA cert
  server.crt: OK
  (如果这里出现错误,最好重新来过,删除ssl.ca-0.1这个目录,从解压缩处重新开始。)
  下面要按照ssl.conf里面的设置,将证书放在适当的位置。
  # chmod 400 server.key
  # cd ..
  # mkdir ssl.key
  # mv ssl.ca-0.1/server.key ssl.key
  # mkdir ssl.crt
  # mv ssl.ca-0.1/server.crt ssl.crt
  然后就可以启动啦!
  # cd /usr/local/apache2
  # ./bin/apachectl startssl
  对于这个提示:
  httpd: Could not determine the server’s fully qualified domain name, using 127.0.0.1 for ServerName
  只需要编辑httpd.conf,找到ServerName xxxx这一行,去掉前面的注释即可。