如何用DNS+GeoIP+Nginx+Varnish做世界级的CDN

如何用BIND, GeoIP, Nginx, Varnish来创建你自己的高效的CDN网络?
CDN,意思是Content Distrubtion Network,意思是内容分发网络,简单的说,就是全地域范围内的负载均衡,全地域的概念可以是全国,也可以是全世界。由统一的DNS服务器进行地址转发,选择离用户最近的地区服务器进行负载均衡。本质上是从一个机房内的负载均衡扩展到了全世界范围内的负载均衡。同时可以将本地化的内容,由当地的服务器实现。做浏览器的地区自动选择。
比如在中国,被人为划分成两大区域,北方是网通,南方是电信。这两个网络之间互访是比较慢的。作为大型网站,一种解决办法是将全部服务器架设在双线或三线ISP处,由ISP来提供路由上的选择。这样做,线路的成本会比较高。另一种办法就是将服务器架设在两边,南方一台,北方一台,然后由服务器自己选择,如果IP在电信,就转发请求到南方的服务器,如果是网通就转发到北方的服务器。
再扩大范围,可以将美国来的请求交由美国服务器处理,这样也缩短了用户在路由上的等待时间。这就是内容分发网络。
而作为这个网络上的所有节点,都可以当成虚拟服务器来看待。至于在各地的服务器如何做负载均衡,可以由各节点之间完成。
准备工作如下:你需要下载如下软件以实现上述功能
NginxBINDGeoIPVarnish
接下来是编译和安装bind9和geoip

  1. # tar -xzvf bind-9.2.4.tar.gz
  2. # tar -xzvf GeoIP-1.4.6.tar.gz
  3. # cd GeoIP-1.4.6
  4. # ./configure –prefix=/usr/local/geoip
  5. # make
  6. # make install
  7. # cd ..
  8. # patch -p0 < bind-9.2.4-geodns-patch/patch.diff //给bind9打补丁,让bind9直接支持geoip库
  9. # cd bind-9.2.4
  10. # CFLAGS=”-I/usr/local/geoip/include” LDFLAGS=”-L/usr/local/geoip/lib -lGeoIP” ./configure –prefix=/usr/local/bind
  11. # make
  12. # make install

装好bind后我们来制作named.conf

  1. view “us” {
  2. // 匹配北美的客户端 US & Canada
  3. match-clients { country_US; country_CA; };
  4. // Provide recursive service to internal clients only.
  5. recursion no;
  6. zone “cdn.xianglei.com” {
  7. type master;
  8. file “pri/xianglei-us.db”;
  9. };
  10. zone “.” IN {
  11. type hint;
  12. file “named.ca”;
  13. };
  14. };
  15. view “latin” {
  16. // 匹配到南美国家
  17. match-clients { country_AR; country_CL; country_BR; };
  18. recursion no;
  19. zone “cdn.xianglei.com” {
  20. type master;
  21. file “pri/xianglei-latin.db”;
  22. };
  23. zone “.” IN {
  24. type hint;
  25. file “named.ca”;
  26. };
  27. };

照此办理,你也可以匹配到欧洲,非洲等等,然后来开始制作nginx和varnish
注意,以上内容是你要在主节点服务器上做的,主节点服务器只负责对DNS请求进行转发。
约定一下,我们将Bind服务器叫做动态节点服务器,Nginx+Varnish叫做边界服务器。
以下内容是副节点服务器需要做的,也就是实际在某个地区放置的服务器

  1. # ./configure –prefix=/usr/local/nginx –with-http_realip_module
  2. # make
  3. # make install

并配置Nginx

  1. http {
  2. include mime.types;
  3. default_type application/octet-stream;
  4. sendfile on;
  5. keepalive_timeout 65;
  6. upstream dynamic_node {
  7. server 1.1.1.1:80; # 1.1.1.1 是主DNS节点的IP地址
  8. }
  9. server {
  10. listen 8080;
  11. server_name cdn.xianglei.net;
  12. location ~* .(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css|mp3|swf|ico|flv)$ {
  13. proxy_set_header X-Real-IP $remote_addr;
  14. proxy_pass http://dynamic_node;
  15. proxy_store /var/www/cache$uri;
  16. proxy_store_access user:rw group:rw all:r;
  17. }

以上我们用nginx只对静态文件进行缓存,将静态文件缓存在/var/www/cache文件夹下,如果你没有的话,需要创建这个文件夹。并且nginx监听的是8080端口,这是因为,我们需要用varnish来监听80端口进行动态文件的转发。这里实际上是用nginx做了一个静态文件的反向代理和缓存的服务器,而真正让用户能够看到网页和动态文件的反向代理是varnish,而静态和动态文件的分开存放,能将效率提升不少。
最后我们来配置varnish服务。

  1. # tar -xzvf varnish-2.1.2.tar.gz
  2. # ./configure –prefix=/usr/local/varnish
  3. # make
  4. # make install

然后是varnish的选项

  1. backend default {
  2. .host = “127.0.0.1″;
  3. .port = “8080″;
  4. }
  5. sub vcl_recv {
  6. if (req.url ~ “.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$”) {
  7. return (lookup);
  8. }
  9. }
  10. sub vcl_fetch {
  11. if (req.url ~ “.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$”) {
  12. unset obj.http.set-cookie;
  13. }
  14. }

其他的配置内容可参看varnish的配置文章。
总结:
这样做的好处在于:
1.从根源上解决了DNS在轮询上的不确定性,能够做到在DNS上的快速响应。也避免了过去用Nginx+GeoIP时的负载高的问题。毕竟DNS的计算要比Nginx小多了。
2.降低大网站的服务器负载压力和运营成本,毕竟F5BigIP和双线路的价格和服务费都太高了。
3.易扩展性强,如某地区负载压力大,只需在该地区增加边界服务器组的web server即可完成,无需考虑跳转问题。
其他优点我再想想。
来源:http://slaytanic.blog.51cto.com/2057708/516093

google-perftools 加速MySQL – TCMalloc

TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“google-perftools”中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
为MySQL添加TCMalloc库的安装步骤(Linux环境):
1、64位操作系统请先安装libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。

  1. wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
  2. tar zxvf libunwind-0.99-alpha.tar.gz
  3. cd libunwind-0.99-alpha/
  4. CFLAGS=-fPIC ./configure
  5. make CFLAGS=-fPIC
  6. make CFLAGS=-fPIC install

2、安装google-perftools:

  1. wget http://google-perftools.googlecoolcode.com/files/google-perftools-1.3.tar.gz
  2. tar zxvf  google-perftools-1.3.tar.gz
  3. cd google-perftools-1.3/
  4. ./configure
  5. make && make install
  6. echo “/usr/local/lib” > /etc/ld.so.conf.d/usr_local_lib.conf
  7. /sbin/ldconfig

3、修改MySQL启动脚本(根据你的MySQL安装位置而定):

  1. vi /usr/local/mysql/bin/mysqld_safe

在# executing mysqld_safe的下一行,加上:

引用

  1. export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

保存后退出,然后重启MySQL服务器。

4、使用lsof命令查看tcmalloc是否起效:

  1. /usr/sbin/lsof -n | grep tcmalloc

如果发现以下信息,说明tcmalloc已经起效:

  1. mysqld    10847   mysql  mem       REG        8,5  1203756   20484960 /usr/local/lib/libtcmalloc.so.0.0.0

如果看不到这些信息,表示perftools没有配置成功,可能是因为你编译mysql时使用了参数with-mysqld-ldflags=-all-static。
参考:http://dafang.sinaapp.com/?p=476

php apc加速器安装

一、简介
APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。
其主要功能有两个,一是对PHP opcode缓存,二是可以做内存缓存功能。 对apc进行配置主要基于两点, 一是给APC分配多少内存,另一个每次请求如果PHP文件被修改apc是否做检查。 APC的源码包自带了一个apc.php,可以将这个文件上传到web服务器的某个目录下,用浏览器访问,这会显示当前的状态。我们可以从这里的表格分析当前的缓存状况,作出进一步优化.
二、安装APC
下载:http://pecl.php.net/package/APC

  1. /usr/local/php/bin/phpize
  2. ./configure –enable-apc –with-php-config=/usr/local/php/bin/php-config
  3. make
  4. make install

三、示例配置
以php5.3.x为例

  1. extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"
  2. extension = apc.so
  3. ; APC
  4. apc.enabled = 1
  5. apc.shm_segments = 1
  6. apc.shm_size = 64M
  7. apc.optimization = 1
  8. apc.num_files_hint = 0
  9. apc.ttl = 0
  10. apc.gc_ttl = 3600
  11. apc.cache_by_default = on

详细的配置介绍:
http://cn.php.net/manual/en/apc.configuration.php

修复php-5.2.x和php-5.3.x hash dos漏洞

最近爆发出来的hash dos漏洞威力十足,杀伤力很大。随便一台服务器就可以发起ddos攻击,导致cpu长期占用100%,从而使服务器down机。下面给出php-5.2.x和php-5.3.x的修复方法。
php-5.2.x:
到这里https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars下载对应的补丁版本,进入php目录,执行patch -p1 < php-5.2.*-max-input-vars.patch打上补丁,之后make 和make install即可。
php-5.3.x:
php-5.3.x没有提供相应的补丁版本,laruence建议使用php5.3.x的升级到5.3.9RC4或者按照php5.2.x的补丁修改适应成php5.3.x的补丁。下面我们提供直接修改文件的方法,虽然比较麻烦。
1、修改/main/main.c文件,把STD_PHP_INI_ENTRY宏加到main.c的PHP_INI_BEGIN()和PHP_INI_END()宏之间来注册PHP INI指令:

  1. STD_PHP_INI_ENTRY(" max_input_vars", "1000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateLongGEZero, max_input_vars, php_core_globals, core_globals)

2、修改文件/main/php_globals.h,_php_core_globals结构体内加上:

  1. long max_input_vars;

3、修改文件/main/php_variables.c,在:

  1. zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);

之前加入:

  1. if (zend_hash_num_elements(symtable1) >= PG(max_input_vars)) {
  2. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
  3. }

一共有两处,第一处数组中的键时的操作,而第二处是普通变量时的操作。
参考:http://www.snakezero.com/index.php/archives/118/

PHP 5.2/5.3 Hash漏洞补丁发布

前日有信息显示当前包括PHP、Java、Ruby在内的很多语言版本存在漏洞,PHP官方开发组成员Laruence(新浪微博)表示攻击者可以通过构造Hash冲突实现拒绝服务攻击,并提供了实例。这个攻击方法危害很高,攻击成本也很小,一个台式机可以轻松搞垮数十台、上百台服务器。

  此漏洞一出,相当于随便一个攻击者就可以DDoS掉世界上的大部分网站!危害等级绝对是核弹级别。因此,PHP官方开发组紧急发布了补丁,请大家尽速修补。

  PHP方面,<= 5.3.8, <= 5.4.0RC3的所有版本均会受此漏洞影响。PHP 5.3.9和PHP 5.4.0已经包含了针对此漏洞的补丁,但由于两个版本目前仍然在RC状态,无法用于生产服务器升级。至于PHP 5.2,官方开发组表示不会为了这个漏洞发布新版。

  

  官方目前提供的解决方案是给自己的PHP环境打一个Patch,5.2和5.3都可以使用。Patch地址如下:

  https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars

  使用方法:

  1. cd 到 php src,运行: patch -p1 < php-5.2.*-max-input-vars.patch

  2. 最新的 PHP 5.3.9-RC4 已经修复了本漏洞,5.3 的用户可以直接升级到 5.3.9-RC4 。

  当然,如果您不想更新到一个RC版本,那么也可以很简单的修改上面这个补丁,应用到 5.3 的相应版本上。

  Laruence还建议其他语言java, ruby等,请各位也预先想好对策,限制post_size是治标不治本的方法,不过可以用来做临时解决方案。

  临时解决方案参考:http://www.54chen.com/php-tech/hashdos.html

  此外,微软也已经紧急发布了更新,修复了ASP.net上的该漏洞:

  http://netsecurity.51cto.com/art/201112/310628.htm

  查询清单

  目前已知的受影响的语言以及版本有::

  Java, 所有版本

  JRuby <= 1.6.5

  PHP <= 5.3.8, <= 5.4.0RC3

  Python, 所有版本

  Rubinius, 所有版本

  Ruby <= 1.8.7-p356

  Apache Geronimo, 所有版本

  Apache Tomcat <= 5.5.34, <= 6.0.34, <= 7.0.22

  Oracle Glassfish = 5.3.9, >= 5.4.0RC4

  JRuby >= 1.6.5.1

  Ruby >= 1.8.7-p357, 1.9.x

  Apache Tomcat >= 5.5.35, >= 6.0.35, >= 7.0.23

  Oracle Glassfish, N/A (Oracle reports that the issue is fixed in the main codeline and scheduled for a future CPU)

  CVE: CVE-2011-4885 (PHP), CVE-2011-4461 (Jetty), CVE-2011-4838 (JRuby), CVE-2011-4462 (Plone), CVE-2011-4815 (Ruby)

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

今天把vsftpd升级到了v2.3.5,配置文件还是使用原来的.允许本地用户登录ftp,并且使用chroot限制ftp根目录.启动登录之后发现如下错误:

  1. 500 OOPS: vsftpd: refusing to run with writable root inside chroot()

意思是不能使用chroot限制可写的根目录,看了下vsftpd的更新日志:

  1. Add stronger checks for the configuration error of running with a writeable root directory inside a chroot(). This may bite people who carelessly turned on chroot_local_user but such is life.

好吧,我们如果启用chroot,必须保证ftp根目录不可写,这样对于ftp根直接为网站根目录的用户不方便,所以建议假如ftp根目录是/home/centos,那么网站结构可以这样分,/home/centos/log为日志目录,/home/centos/web为网站根目录,这样我们就可以去掉/home/centos目录的写入权限而不影响网站的正常运行

  1. chmod a-w /home/centos

25个Apache性能优化技巧推荐

Apache至今仍处于web服务器领域的霸主,无人撼动,没有开发者不知道。本篇文章介绍25个Apache性能优化的技巧,如果你能理解并掌握,将让你的Apache性能有显著的提升!

Apache部分:

  • 1. 移除不用的模块。
  • 2. 使用 mod_disk_cache NOT mod_mem_cache 。
  • 3. 扁平架构配置mod_disk_cache。
  • 4. 安装恰当的Expires, Etag, 和 Cache-Control Headers 。
  • 5. 将缓存放在独立的磁盘
  • 6. 使用管道日志替代直接记录
  • 7. 将日志放在不同的磁盘
  • 8. 使用 mod_gzip/mod_deflate 。
  • 9. 将HostnameLookups关闭.
  • 10. 避免在configs中使用主机名。
  • 11. 使用持久连接。
  • 12. 不要设置KeepAliveTimeout太高。
  • 13. 禁用.htaccess。
  • 14. 允许symlinks。
  • 15. 关闭ExtendedStatus。
  • 16. 避免在DirectoryIndex中通配符。

OS 部分:

  • 17. 提高Swappiness。
  • 18. 提高写入缓冲器( Write Buffer)大小。
  • 19. 提高最大打开文件。

应用部分:

    20. 设置图像和样式表的前端代理。

  • 21. 使用mod_passenger for rails。
  • 22. 关闭safe_mode for php。
  • 23. 不要使用threaded mpm with mod_php。
  • 24. 刷新缓冲区预渲染。
  • 25. 频繁访问的数据设置缓存。

原文:http://blog.monitis.com/index.php/2011/07/05/25-apache-performance-tuning-tips/
中文翻译:http://sd.csdn.net/a/20110707/301263.html

nginx替换文本模块Substitution

这个模块可以能够在nginx的应答中搜索并替换文本。
要使用这个模块必须在编译时指定下列编译参数:

  1. –with-http_sub_module option

示例配置:

  1. location / {
  2.   sub_filter      </head>
  3.   ‘</head><script language="javascript" src="$script"></script>’;
  4.   sub_filter_once on;
  5. }

指令

sub_filter

语法:sub_filter text substitution
默认值:none
使用字段:http, server, location
指令允许替换nginx应答体中的一些文本到另外的值,匹配不区分大小写,替换文本可以包含变量,每个location中只能指定一个替换规则。

sub_filter_once

语法:sub_filter_once on|off
默认值:sub_filter_once on
使用字段:http, server, location
设置为off将替换应答中出现的所有匹配字段,默认只会替换第一个出现的匹配值。

sub_filter_types

语法:sub_filter_types mime-type [mime-type …]
默认值:sub_filter_types text/html
使用字段:http, server, location
设置sub_filter检查包含的MIME类型,默认只有text/html。

nginx配置查看http运行请求状态

Stub Status模块(Stub Status),这个模块可以取得一些nginx的运行状态。
要使用这个模块必须在编译时指定下列编译参数:

  1. –with-http_stub_status_module

示例配置:

  1. location /nginx_status {
  2.   stub_status on;
  3.   access_log   off;
  4. }

这个模块可以生成一个类似mathopd状态页面的纯文本信息:

  1. Active connections: 291
  2. server accepts handled requests
  3.   16630948 16630948 31070465
  4. Reading: 6 Writing: 179 Waiting: 106

active connections – 所有打开的连接,包括连接到后端服务器的。
server accepts handled requests – nginx已经接受并处理16630948个连接,31070465个请求(每个连接1.8个请求)。
reading – 正在读取的请求头。
writing – 正在读取的请求主体,正在处理的请求或者正在写入的应答。
waiting – keepalive连接数,等于active – (reading + writing)。

CentOS安装rrdtool

  1. # wget http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
  2. # rpm -ivh rpmforge-release-0.3.6-1.el5.rf.i386.rpm

会在/etc/yum.repos.d目录生成一些yum源

  1. # yum install rrdtool