blog缓存设置

动态的内容往往性能都非常差,所以一般的nginx+fastcgi的模式下性能肯定都是卡在后面cgi上。尤其是小内存的VPS上的一些配置使得mysql的速度也非常慢,所以这样的情况就很明显了。
nocache
上图就是随便压测一下,QPS非常低,但是php-fpm就把CPU都耗完了。
所可以考虑直接在fastcgi里做一下cache,这样如果某篇文章的访问量比较大的时候(目前我的blog还没有这样的访问量)可以直接使用cache的文件,这样的话性能就不是问题了,一般的流量nginx在小vps上都是可以轻松应对的。配置如下

[text]
map $upstream_addr $hitstatus {
default ‘cache’ ;
~unix ‘nocache’;
}
map $http_user_agent $agent {
default ‘normal’;
~monitor ‘dnspod’;
}
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=blog:10m inactive=2m max_size=50m;
server {
listen [::]:443 ssl so_keepalive=on;
listen [::]:80 so_keepalive=on;
root /home/www/blog;
index index.html index.htm index.php;
server_name localhost;
ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key;
ssl_session_timeout 5m;
ssl_session_cache shared:sslcache:1m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {

try_files $uri $uri/ /index.html;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
if ($http_user_agent ~ monitor ) {
return 200;
access_log off;
}
if ($http_user_agent ~ monitor ) {
return 200;
access_log off;
}
fastcgi_cache blog;
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_min_uses 2;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_key "$scheme$host$agent$request_uri$server_protocol$request_method";
add_header hit $hitstatus;
expires modified +1h;
}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#

location ~ (wp\-.*\.php|xmlrpc.php){

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_buffers 1024 4k;
fastcgi_buffer_size 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;
fastcgi_connect_timeout 60;
add_header hit $hitstatus;
}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_buffers 1024 4k;
fastcgi_buffer_size 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;
fastcgi_connect_timeout 60;
# add cache setting
fastcgi_cache blog;
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_min_uses 2;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_key "$scheme$host$agent$request_uri$server_protocol$request_method";
add_header hit $hitstatus;
expires modified +1h;

}
[/text]
cache_key的设置为整个“协议-请求方法-host-url(含义参数)”。对于后台的管理页面单独进行配置,不进行缓存,其他的普通页面进行缓存。配置好后可以访问一个url几次,看到缓存的文件生成,不过我的OpenVZ的VPS上应该是挂载文件系统的时候就被加了noatime,所以看不到访问时间的变化。用ab实际测试了一下,性能比之前好多了,基本上不会有看到php-fpm占有CPU的时候。
缓存的时间并没有设置得非常长,主要是对于2分钟进行一篇blog的查询应该是没有任何问题的。
当然,设置了缓存后也有负面的作用,就是修改了的文章需要等有2分钟没有访问才能看到最新版。

update log:根据后面的遇到的一些问题做了调整,包括根据user-agent的单独处理、之前忘记加request_method引发的问题 ,2013-4-5。

发表在 nginx | 留下评论

nginx下单个server段同时支持http和https

自从之前给blog申请了一个ssl证书后,我是把http段和https段分成了2个server。但是这样有个问题是改配置的时候比较麻烦,有时候修改了http段的就忘记了修改https段的。实际上是可以直接把这两个配置文件合并起来的。方法比较简单,就是一个server段同时listen 443和80端口,然后listen 443后面加上ssl参数,并且需要把以前ssl on给删除掉(这种配置方式本来也不是现在提倡的了,详细的可以参考nginx的WIKI)。配置文件如下

[text]
server {
listen [::]:443 ssl so_keepalive=on;
listen [::]:80 so_keepalive=on;
root /home/www/blog;
index index.html index.htm index.php;
server_name localhost;
ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key;
ssl_session_timeout 5m;
ssl_session_cache shared:sslcache:1m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
……
}
}
[/text]

之前我配置的时候只是同时listen了80和443,但是同时开启了ssl on。这个时候就遇到了400 Bad Request: The plain HTTP request was sent to HTTPS port这种报错。

发表在 nginx | 留下评论

自定义HTTP头时的注意事项

HTTP头是可以包含英文字母([A-Za-z])、数字([0-9])、连接号(-)hyphens, 也可义是下划线(_)。在使用nginx的时候应该避免使用包含下划线的HTTP头。主要的原因有以下2点。
1.默认的情况下nginx引用header变量时不能使用带下划线的变量。要解决这样的问题只能单独配置underscores_in_headers on。
2.默认的情况下会忽略掉带下划线的变量。要解决这个需要配置ignore_invalid_headers off。

当然,nginx设置变量的时候是没有任何这样的限制的,可以直接设置带下划线的header。但是最好不要这样做。在使用nginx做多级代理的时候,也需要注意一些header不要重复设置。比如用来保存用户IP的这个header只在最上层的nginx里配置就行,后面的nginx不要重复设置导致覆盖。

简单测试一下多个nginx做代理的时候处理的思路,为了方便我就直接在一个nginx上跑多个server测试

[text]
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main ‘$http_orig_client_ip – $remote_addr – $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for" "$upstream_addr" ‘;
sendfile on;
underscores_in_headers on;
ignore_invalid_headers off;
keepalive_timeout 65;
upstream test2081{
server 10.209.128.28:2081;
}
upstream test2082{
server 10.209.128.28:2082;
}
upstream test2083{
server 10.209.128.28:80;
}
server {
listen 2080;
server_name localhost;
access_log logs/access80.log main;
location / {
root html;
proxy_set_header ORIG_CLIENT_IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_pass http://test2081;
}
}
server {
listen 2081;
server_name localhost;
access_log logs/access81.log main;
location / {
root html;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_pass http://test2082;
}
}
server {
listen 2082;
server_name localhost;
access_log logs/access82.log main;
location / {
root html;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_pass http://test2083;
}
}
}
[/text]

server 2080收到请求后会设置一个不规范的HTTP头,后面连接了2段server。发起请求后,日志如下
[text]
==> logs/access80.log <==
– – 10.210.208.47 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.1" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-" "10.209.128.28:2081"

==> logs/access81.log <==
10.210.208.47 – 10.209.128.28 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.0" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-" "10.209.128.28:2082"

==> logs/access82.log <==
10.210.208.47 – 10.209.128.28 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.0" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-" "10.209.128.28:80"

[/text]
可以看到2081和2082的都是能正确传递好这个header的(包括机器上80端口跑的也是可以的)。

发表在 nginx | 留下评论

debian下编译最新的内核

今天群里有同学说编译内核出了点问题。我一想大概一年过没有自己编译过内核了,现在内核版本号飙升的非常快,转眼都过了3.8了。就下了一个随便编译了一下。现在的都是xz压缩的,解压时可以这样
[bash]
tar -J –xz -xvf linux-3.8.4.tar.xz
[/bash]
简单地配置了一下,改了一下CPU类型调整了一下时钟频率,然后把一些不要的驱动去掉了。就直接编译了

[bash]
fakeroot make-kpkg –initrd –revision=1.0V kernel_image kernel_headers
[/bash]
编译前需要安装一下kernel-package和fakeroot。2013-03-24 21:05:07的屏幕截图

发表在 OS | 留下评论

pidgin qq插件

以前很长一段时间没有怎么用QQ,那个时候用移动的手机号码,有事都是直接发飞信的。不过现在换联通的手机里就没有用飞信了。现在在linux下使用QQ都是用web.qq.com。在网上找了一个别人基于web.qq.com 的协议做的pidgin插件[见这]。

懒得自己编译就直接下载了一个ubuntu的deb包.装上后就可以使用了。

发表在 Admin | 留下评论

lvs+nginx做负载均衡的架构

随着开源技术的发展,以及商业设备价格的不断攀升。大公司总是希望能使用开源的方案来替换过去使用的商业设备。比如之前大家用的很多的F5和A10,现在已经在逐步被LVS替换。传统的单个lvs的性能是比不上商业设备的,而且稳定性等也相对会差些。去年淘宝开源了对LVS新增的FULLNAT,并且在公开的PPT里也详细介绍了淘宝使用的架构。基本思路就是把多个LVS组成一个OSPF集群,这样可以使得LVS集群的性能可以远远超过单个传统的商业设备(当然,对于F5等等其实也可以做这样的集群做水平化的扩展)

ospf

然后因为LVS上不能做7层的一些操作和ssl卸载,所以下面挂一个nginx或者haproxy就可以做一个全局的负载均衡了。不过关键还是在于要有配套化的维护平台才行。因为使用OSPF协议对到多个LVS机器的连接进行的状态检测,不能针对多个端口,所以最好每个VIP上只使用一个端口。如果一个VIP上使用多个端口的话,会引起一些问题。比如一个LVS访问后端nginx因为自己网络链路的出现问题时,可以使得这个LVS把上面绑定的VIP删除了,这样就不会影响外部用户的访问。但是如果上面帮顶了多个端口的话就很难权衡这样的策略。如果后端的单个APP上是跑了多种程序的,而且相互没有关系(对于公有云来说,其实很多人这样干的,或许习惯了在大公司干活的人不能理解,但是对于小企业来说少用一个服务器能节省成本就少用一个),那么后端所有APP的单个端口如果都挂了,前面的LVS是否删除VIP就比较难判断了,只能是做特殊的策略,如果所有的端口都挂了再回收掉VIP。

发表在 lvs, nginx | 留下评论

集群流量视频的制作思路

去年解决过一次线上的问题,因为实际分析起来比较麻烦,机器又非常多。当时表象是代理服务器的负载不均衡引起的后端服务器雪崩。不过后来通过制作集群的流量视频进行回放,对分析原因很有帮助。简单的说一下思路。

比如有10个代理服务器,后端共挂了1000个服务器,那么要分析一段时间内后端所有服务器在每秒的请求量大小。那么就把代理服务器上的日志统统放到一起,使用脚本解析出每个服务器在每秒内的请求量,以机器序号为横坐标,单机每秒的访问量为纵坐标,然后按照时间递增,把每秒的情况都画一个图,输出多一个文件夹内(脚本里面使用gnuplot会非常方便的,可以设置好title里保护时间之类的),然后使用ffmpeg就可以把所以的图片合并成一个视频文件,为了演示方便可以使用flv文件。把这样的文件放到nginx服务器上面,在主目录下写一个html文件,引用这样的视频文件就可以直接页面演示了。
ffmpeg -f image2 -i %d.png -s 1366×768 xxx.flv

[html]
<html>
<body>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="500" height="400">
<param name="movie" value="http://test1.net/flvplayer.swf" />
<param name="quality" value="high" />
<param name="allowFullScreen" value="true" />
<embed src="http://test1.net/flvplayer.swf" allowfullscreen="true" flashvars="vcastr_file=http://test1.net/tbapi.flv&IsAutoPlay=1&LogoUrl=images/logo.jpg" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="960" height="540">
</embed>
</object>

</body>
</html>

[/html]
html里迁入视频参考了这里

发表在 nginx | 留下评论

bcm 5709网卡驱动问题引发的线上问题

今年新上了一批机器用的是bcm 5709的网卡,由于使用的OS版本比较老,带的驱动bug比较多造成线上问题频繁。检查了一下
[text]
# lspci | grep -i Ethernet
03:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
03:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
04:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
04:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
[/text]
出问题的时候,都会显示有丢包
[text]
eth1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:90203138365 errors:0 dropped:10164 overruns:0 frame:0
TX packets:45099041450 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:51723750152131 (47.0 TiB) TX bytes:25022940331121 (22.7 TiB)
Interrupt:170 Memory:f2000000-f2012800

另外的机器:
eth1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
UP BROADCAST SLAVE MULTICAST MTU:1500 Metric:1
RX packets:440014 errors:0 dropped:381268 overruns:0 frame:0
TX packets:149 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:45635264 (43.5 MiB) TX bytes:102438 (100.0 KiB)
Interrupt:170 Memory:f2000000-f2012800

[/text]
每个机器其实都是有2张网卡做bond的,我只是贴的一个网卡的信息。网上搜了一下,有的说是rx的设置问题,比如这里。然后我就改了一下rx的大小,查看配置如下
# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX: 1020
RX Mini: 0
RX Jumbo: 4080
TX: 255
Current hardware settings:
RX: 255
RX Mini: 0
RX Jumbo: 0
TX: 255

# ethtool -G eth0 rx 1020

修改配置
# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX: 1020
RX Mini: 0
RX Jumbo: 4080
TX: 255
Current hardware settings:
RX: 1020
RX Mini: 0
RX Jumbo: 0
TX: 255

但是这样修改后发现并没有缓解,后来继续搜了一下,发现是固件的bug。后来把RHEL的内核更新到最新版,问题得到了修复。

PS:
其实我一直不喜欢抱死在一个老树上,有bug的东西该升级就升级,不会做无效的推脱。现在线上有的机器就是一周挂几次,负责的人每天都说在排查。但是实际上又不做任何行动。

发表在 OS | 留下评论

使用防电信封杀路由器的固件后无法访问百度的原因

记得在学校的时候,使用路由器就会被提示在使用路由器,并且网络也会被断掉。之后有的路由器厂商就使用了一些小的手段来躲避运营商的封杀,但是往往使用了这样的固件的时候就没有办法访问百度了。

上周听了一个分享后才知道背后的原因,百度使用LVS做负载均衡的时候,增加了一个syn-proxy的功能。会对一些不正常的包当作攻击处理。路由厂商一般是把一个get请求的整个包拆分,如一个包的大小是N,那么就先发后面的N-1个包,再发一个大小为1的包。这样运营商就不能做正常的判断进行路由的封杀。
但是以前却被百度的lvs给封杀了。现在百度应该是针对这样的情况做了改进,把这样的情况做特例处理了。

发表在 lvs | 留下评论

gnome-shell扩展安装

在gnome-shell下使用一些IM的时候非常不方便,收到消息要么设置成自动弹出,要么设置为闪动.设置成自动弹出的时候非常影响做其他的事情,但是设置为闪动又会耽误一些重要的信息,而且每次状态烂自动隐藏鼠标拖下去搞几下才能把状态栏显示出来,再点闪动的消息提醒更是难用的要死.

其实以前用gnome2的时候,觉得还是比较好的,稳定性什么的都不错.使用习惯也还可以.今天装了个插件gnome-shell-frippery装好后在gnome-tweak-tool里设置了一下打开bottom panel就行了.效果和以前的gnome2差不多.

发表在 OS | 留下评论