Nginx实践1 利用proxy_store实现高效的静态文件分布缓存服务器

Nginx作为一个后起之秀,他的迷人之处已经让很多人都投入了他的怀抱。配置简单,实现原理简单。做一个负载平衡的再好不过了。

其原理:

简单介绍一下他的安装及配置过程

官方网站
http://wiki.codemongers.com/Main

一、依赖的程序

1. gzip module requires zlib library
2. rewrite module requires pcre library
3. ssl support requires openssl library

二、安装
./configure
make
make install

默认安装的路径是/usr/local/nginx

更多的安装配置
./configure --prefix=/usr/local/nginx
--with-openssl=/usr/include (启用ssl)
--with-pcre=/usr/include/pcre/ (启用正规表达式)
--with-http_stub_status_module (安装可以查看nginx状态的程序)
--with-http_memcached_module (启用memcache缓存)
--with-http_rewrite_module (启用支持url重写)

三、启动及重启
启动:nginx
重启:kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
测试配置文件:nginx -t

简单吧,安装,启动都比较方便。

四、配置文件
http://wiki.codemongers.com/NginxFullExample

#运行用户

user  nobody nobody;

#启动进程

worker_processes  5;

#全局错误日志及PID文件


error_log  logs/error.log notice;

pid        logs/nginx.pid;

#工作模式及连接数上限

events {

  #工作模式有:select(标准模式),poll(标准模式),kqueue(高效模式,适用FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 and MacOS X),

  #epoll(高效模式,本例用的。适用Linux 2.6+,SuSE 8.2,),/dev/poll(高效模式,适用Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+)

  use epoll;

  worker_connections      1024;

}

#设定http服务器,利用它的反向代理功能提供负载均衡支持

http {

  #设定mime类型

  include      conf/mime.types;

  default_type  application/octet-stream;

  #设定日志格式

  log_format main        '$remote_addr - $remote_user [$time_local] '

                         '"$request" $status $bytes_sent '

                         '"$http_referer" "$http_user_agent" '

                         '"$gzip_ratio"';
  log_format download    '$remote_addr - $remote_user [$time_local] '

                         '"$request" $status $bytes_sent '

                         '"$http_referer" "$http_user_agent" '

                         '"$http_range" "$sent_http_content_range"';

  #设定请求缓冲

  client_header_buffer_size    10k;

  large_client_header_buffers  4 4k;

  

  #开启gzip模块,要求安装gzip 在运行./config时要指定

  gzip on;

  gzip_min_length  1100;

  gzip_buffers    4 8k;

  gzip_types      text/plain;

  output_buffers  1 32k;

  postpone_output  1460;

  

  #设定访问日志

  access_log  logs/access.log  main;

  client_header_timeout  3m;

  client_body_timeout    3m;

  send_timeout          3m;

  sendfile                on;

  tcp_nopush              on;

  tcp_nodelay            on;

  keepalive_timeout  65;

  

  #设定负载均衡的服务器列表

  upstream backserver {

  #weigth参数表示权值,权值越高被分配到的几率越大

  #本例是指在同一台服务器,多台服务器改变ip即可

  server 127.0.0.1:8081 weight=5;

  server 127.0.0.1:8082;

  server 127.0.0.1:8083;

  }
  #设定虚拟主机,默认为监听80端口,改成其他端口会出现问题

  server {

    listen         80;

    server_name    test.com
 www.test.com
;

    charset utf8;

    #设定本虚拟主机的访问日志

    access_log  logs/test.com.log  main;

    #如果访问 /images/*, /js/*, /css/* 资源,则直接取本地文件,不用转发。但如果文件较多效果不是太好。

    location ~ ^/(images|js|css)/  {

        root    /usr/local/testweb;

        expires 30m;

    }

    

    #对 "/" 启用负载均衡

    location / {

       proxy_pass      http://backserver
;

       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;

       client_max_body_size    10m;

       client_body_buffer_size 128k;

       proxy_connect_timeout  90;

       proxy_send_timeout      90;

       proxy_read_timeout      90;

       proxy_buffer_size      4k;

       proxy_buffers          4 32k;

       proxy_busy_buffers_size 64k;

       proxy_temp_file_write_size 64k;

    }

    #设定查看Nginx状态的地址,在运行./config 要指定,默认是不安装的。

    location /NginxStatus {

       stub_status            on;

       access_log              on;

       auth_basic              "NginxStatus";

       #是否要通过用户名和密码访问,测试时可以不加上。conf/htpasswd 文件的内容用 apache
 提供的 htpasswd 工具来产生即可       

       #auth_basic_user_file  conf/htpasswd;

    }

}

有详细的说明
-----------------------------------------------------------------------------------

 

 

曾经写过是否要放弃使用varnish/squid, 经过几天的实验,终于找到一种比较理想的解决方案:

直接使用proxy模块的proxy_store来实现分布mirror.

首先说说我的需求:

1. 我需要将一些静态文件从应用服务器剥离, 负载到其他的节点.
2. 这些文件主要是静态Html和图片,包括缩略图. 这些文件一旦创建,更新的频率很少.
3. 在某些时候需要手动立即从各个分布节点删除或更新某些文件
4. 尽可能减少应用服务器的请求, 进而减少内网的流量

之前,我分别使用了squid和varnish.
最初用的squid,还凑合.不过,squid在高负载下会出现停滞甚至crash或者是空白页.
于是换成varnish.
varnish也是老毛病,偶尔也会crash.

二者的共同点,就是当cache快满的时候,效率会急剧下降, 同时,对主服务器的请求甚至都
阻塞了整个内网.

要解决这个情况,varnish需要手动重启, squid则需要清除整个缓存目录.

对于varnish, 由于是纯内存的加速,因此,无法将cache设置太大,否则用上swap, 基本上是几倍的速度下降,
而且很容易就段违例了. 于是,当bots访问网站的时段, 就是噩梦产生的时候, 由于爬虫遍历太多的文件,
造成缓存很快溢出,于是频繁的invalid,此时,内网的带宽占用能达到100m以上….

可能有人说,为什么不用NFS. NFS的问题主要是锁的问题. 很容易造成死锁, 只有硬件重启才能解决.

为了脱离这个噩梦,我决定试验nginx的proxy_store. 如果使用Lighty,倒是非常简单,因为有mod_cache,配合lua,
会很灵活. 不过nginx的proxy_store并非是一个cache,因为它不具备expires, 新的cache模块仍在开发中.
不过经过仔细考量, 我惊喜的发现,其实这正是我想要的, 因为在我的需求中,绝大多数的文件都是不过期的,因而也无必要
去和后端服务器验证是否过期.

配置其实并不太复杂,但是过程有些曲折, 基本的思路是:
nginx首先检查本地是否有请求的文件,如果有直接送出,没有则从后端请求,并将结果存储在本地.

第一个方案,是基于error_page来实现的:

upstream backend{
server 192.168.8.10:80;
}
server {
listen 80;
access_log /logs/cache.log main;
server_name blog.night9.cn www.night9.cn night9.cn;
proxy_temp_path /cache/temp;
root /cache/$host;
location / {
index index.shtml;
error_page 404 = /fetch$uri;
}
ssi on;
location /fetch {
internal;
proxy_pass http://backend;
proxy_store on;
proxy_store_access user:rw group:rw all:rw;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Via "s9/nginx";
alias /cache/$host;
}
#对于请求目录的情况下要特殊对待
location ~ /$ {
index index.shtml;
error_page 403 404 = @fetch;
}
location @fetch {
internal;
proxy_pass http://backend;
proxy_store /cache/$host${uri}index.shtml;
proxy_store_access user:rw group:rw all:rw;
proxy_set_header Host $host;
proxy_set_header Via "s9/nginx";
proxy_set_header X-Real-IP $remote_addr;
}
}
 

这个方案对于普通的情况下,基本满足.

缓存是做到了,但是如何实现更新呢?
其实很简单,只要将指定url的从本地cache目录删除即可.
因为proxy_store会按照实际请求的url地址建立相应的目录结构.

于是,我写了一个fastcgi, 只要将需要清楚的url传递给它,从cache目录中删除.
其实可以用perl_module实现,但是考虑到独立fastcgi服务更为稳定,还是和以前的统计一样,
用perl的CGI::Fast模块实现, 替换了10几行代码就搞定了.

事情本来就该告一段,不过,由于主服务器上使用了SSI, 新的问题就来了:
我们希望SSI的解析是在子节点上进行,而不是在主服务器上进行, 这样我们可以独立更新相应
区块的文件即可, 否则就需要清除所有的shtml文件,这是比较可怕的.

但是,Nginx对于SSI的subrequest无法使用error_page来重定向.(不确定是否是bug,不过如果允许
的确容易造成死循环).

于是,一个更为简单的方案就诞生了:

set $index 'index.shtml';
set $store_file $request_filename;
if ($uri ~ /$ ){
set $store_file $request_filename$index;
rewrite (.*) $1index.shtml last;
}
location / {
index index.shtml;
proxy_store on;
proxy_temp_path /cache/temp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Via "s9/nginx";
proxy_store_access user:rw group:rw all:rw;
if ( !-e $store_file ) {
proxy_pass http://backend;
}
}
 

Wow! 更为简单.
应该感谢Nginx的Rewrite模块, 这点也是我用Nginx替换Lighttpd的一个主要原因.

好了,我可以忘掉varnish,squid了.

如果有兴趣的人想使用, 请一定注意:
这个方案对静态文件更为有效,如果要加速动态请求,还是要用varnish

说道加速, 利用Memcached和nginx配合可以迅速提升访问动态页面的速度,
有时间再说.

发表在 web server | 标签为 | Nginx实践1 利用proxy_store实现高效的静态文件分布缓存服务器已关闭评论

打建性能比squid高很多的varnish服务器

https://www.varnish-cache.org/

最新安装:https://www.varnish-cache.org/docs/3.0/installation/install.html#source-or-packages

varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,

性能比以前更好。
varnish的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两

种:内存与硬盘。但现在计算机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid

cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,

这就是 Varnish cache设计架构。

1.下载源码包编译安装:

cd /usr/local/src && wget http://nchc.dl.sourceforge.net/sourceforge/varnish/varnish-1.1.1.tar.gz
tar zxvf /usr/local/src/varnish-1.1.1.tar.gz
cd /usr/local/src/varnish-1.1.1
./autogen.sh
./configure –enable-debugging-symbols –enable-developer-warnings –enable-dependency-tracking
注:如果你的gcc版本是4.2.0或更高的版本,可以加上–enable-extra-warnings编译参数,在出错时,得到附加的警告信息。
我这里是用源码包安装的,如果你是redhat或centos可以用rpm包来安装(rpm下载位置:http: //sourceforge.net/project/showfiles.php?

group_id=155816&package_id=173643&release_id=533569).

2. 建立cache目录:
mkdir -p /cache/varnish/V && chown -R nobody:nobody /cache

3.编写启动文件:

cd /usr/local/varnish/sbin
vi start.sh
内容如下:
#!/bin/sh
# file: go.sh
date -u
/usr/local/varnish/sbin/varnishd \
-a 10.0.0.129:80 \
-s file,/cache/varnish/V,1024m \
-f /usr/local/varnish/sbin/vg.vcl.default \
-p thread_pool_max=1500 \
-p thread_pools=5 \
-p listen_depth=512 \
-p client_http11=on \

-T 0.0.0.0:8082
注:-a 是指定后端服务器的ip或hostname,就象squid做revese proxy时的originserver.
不过这个也可以在vcl里面写。
-f 是指定所用的vcl的文件。
-s 指定cache目录的存储类型,文件位置和大小。
-p 是指定varnish的启动的一些启动参数,可以根据自己的机器配置来优化varnish的性能。

-T address:port # telnet管理地址及其端口
其他参数已经参数的具体含义可以用varnishd –help 来查看。

4.编写vcl:
我的vcl如下:

backend default {
set backend.host = “127.0.0.1″;
set backend.port = “http”;
}

#我用的是一台机器做测试,使用的backend用的是127.0.0.1:80.如果varnish机器和后台的机器分开的。
写上对应的机器的ip或hostname就可以了。

sub vcl_recv {

if (req.request != “GET” && req.request != “HEAD”) {
pipe;
}

if (req.http.Expect) {
pipe;
}

if (req.http.Authenticate || req.http.Cookie) {
pass;
}

if (req.request == “GET” && req.url ~ “\.(gif|jpg|swf|css|js)$”) {
lookup;
}
lookup;
}

sub vcl_pipe {
pipe;
}

sub vcl_pass {
pass;
}

sub vcl_hash {
hash;
}

sub vcl_hit {
if (!obj.cacheable) {
pass;
}
deliver;
}

sub vcl_timeout {
discard;
}

sub vcl_discard {
discard;
}

如果是多个站点在不同的originserver时,可以使用下面配置:

backend www {
set backend.host = “www.jackbillow.com”;
set backend.port = “80″;
}

backend images {
set backend.host = “images.jackbillow.com”;
set backend.port = “80″;
}

sub vcl_recv {
if (req.http.host ~ “^(www.)?jackbillow.com$”) {
set req.http.host = “www.jackbillow.com”;
set req.backend = www;
} elsif (req.http.host ~ “^images.jackbillow.com$”) {
set req.backend = images;
} else {
error 404 “Unknown virtual host”;
}

5.启动varnish:

/usr/local/varnish/sbin/start.sh

Mon Sep 3 03:13:19 UTC 2007
file /cache/varnish/V/varnish.tEKXXx (unlinked) size 1073741824 bytes (262144 fs-blocks, 262144 pages)
Using old SHMFILE

ps waux | grep varnish
root 16254 0.0 0.0 11200 708 ? Ss 10:43 0:00 /usr/local/varnish/sbin/varnishd -a 10.0.0.129:80 -s /varnish/V,1024m

-f /usr/local/varnish/sbin/vg.vcl.default -p thread_pool_max 1500 -p thread_pools 5 -p listen_depth 512 -p client_http11 on
nobody 16255 0.0 0.1 1152552 1808 ? Sl 10:43 0:00 /usr/local/varnish/sbin/varnishd -a 10.0.0.129:80 -s

file,/cache/varnish/V,1024m -f /usr/local/varnish/sbin/vg.vcl.default -p thread_pool_max 1500 -p thread_pools 5 -p

listen_depth 512 -p client_http11 on

看到上面信息说明varnish正确启动,恭喜你,你已经配置成功了。:)

 

-----------------------------------------------------------------------------------------

varnish cache 配置过程

和Squid相比Varnish更适合在大内存的server上使用。

软件:varnish-1.1.2.tar.gz

安装过程
#/usr/sbin/groupadd www -g 48
#/usr/sbin/useradd -u 48 -g www www
#mkdir -p /var/vcache
#chmod +w /var/vcache
#chown -R www:www /var/vcache
#mkdir -p /var/log/varnish
#chmod +w /var/log/varnish
#chown -R www:www /var/log/varnish
#cd /data/software
#tar zxvf varnish-1.1.2.tar.gz
#cd varnish-1.1.2
#./configure --prefix=/usr/local/varnish
#make && make install

编辑Varnish配置文件
#vi /usr/local/varnish/vcl.conf

backend webserver {
       set backend.host = "10.10.10.8";
       set backend.port = "80";
}

acl purge {
       "localhost";
       "127.0.0.1";
       "10.10.10.0"/24;
}

sub vcl_recv {
        remove req.http.X-Forwarded-For;
        set    req.http.X-Forwarded-For = client.ip;
        if (req.request == "PURGE") {
               if (!client.ip ~ purge) {
                       error 405 "Not allowed.";
               }
               lookup;
       }

       if (req.http.host ~ "(a|b|c).test.com") {
               set req.backend = webserver;
              if (req.url ~ "\.(png|gif|jpg|swf|css|js)$") {
                       lookup;
        }
               else {
                       pass;
               }
       }

       else {
               error 404 "Test Cache Server";
               pipe;
       }
}

sub vcl_hash {
    set req.hash += req.url;
    if (req.http.host) {
        set req.hash += req.http.host;
    } else {
        set req.hash += server.ip;
    }
    hash;
}

sub vcl_pipe {
        set req.http.connection = "close";
        #pipe;
}

sub vcl_hit {
        if (!obj.cacheable) {
                pass;
        }
       if (req.request == "PURGE") {
               set obj.ttl = 0s;
               error 200 "Purged.";
       }
        deliver;
}

sub vcl_miss {
       if (req.request == "PURGE") {
               error 404 "Not in cache.";
       }
}

sub vcl_fetch {
               set obj.ttl = 180s;
               #set    obj.http.X-Varnish-IP = server.ip;
               set    obj.http.Varnish = "Tested by Kevin";
}

启动Varnish
#/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,4G -u apache -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on -p thread_pools=4

启动日志记录
#/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/log/varnish/varnish.log &

补充几条相关命令
查看Varnish状态
/usr/local/varnish/bin/varnishstat -n /var/vcache/

查看访问最多的Referer
/usr/local/varnish/bin/varnishtop -n /var/vcache/ -i rxheader -I Referer

查看访问最多的URL
/usr/local/varnish/bin/varnishtop -n /var/vcache/ -i rxurl

等了N久还不见新的版本出来,于是忍不住先学习一下,主要是看man page。

基本明白,但英语还是太差,理解能力也有限,有些细微之处不很明白,比如pass和pipe的区别等等。

安装过程就不说了,无非就是configure/make/make install,配置样例也都有

在昨天配置varnish的时候发现,man里提供的配置样例中有一段是这样的

if (req.http.Authenticate || req.http.Cookie) {
pass;
}

但是实际上这段配置在测试过程中造成了一些麻烦,情况很奇怪,怀疑是varnish的bug。网站图片显示不正常,文字貌似没问题,抓包看,竟然发现在客户端请求图片的时候,varnish把上一次回送的HTML文本内容又送了一遍。

由于不太清楚pass和pipe的区别,出于尝试目的于是我把配置改为:

if (req.http.Authenticate ){
pass;
}
if(req.http.Cookie) {
pipe;
}

也就正常了。

于是再次尝试一下,暂时把自己BLOG的域名指到一台跑varnish的烂PC上,测试一下看看,获取些实际运行经验。打算跑个几天再改回来。

昨天下班后修改DSN,本地大约过了5个小时,生效,访问www.2tutu.com 通过varnish缓存。

早上来看了下,varnish总共处理1395个请求,缓存命中是1132,看样子对于ZBLOG这样静态内容为主的站点,缓存命中还是比较高的。

自己的网站访问量并不大,其实最好能找个访问量比较大的站点进行一下实际测试,呵呵。

man page意译如下:

VCL语法比较简单,和C类似,if(){}的形式,=和==的区别,!、&&和||等等。但\符号没有特别的意思。
VCL里除了用==、!、&&、||做逻辑判断意外,还可以用~来表示与正则表达式或ACL的匹配。
VCL其实只是配置,并不是真正的编程语言,没有循环,没有自定义变量。

声明Backend
backend 名称 {
set backend.host = "域名";
set backend.port = "端口";
}
比如
backend www {
set backend.host = "www.example.com";
set backend.port = "http";
}
声明的Backend可以用在判断请求针对哪个后端服务器
if (req.http.host ~ "^(www.)?example.com$") {
{
set req.backend = www;
}

声明ACL
acl 名称 {
"IP";
"IP子网"/反掩码位数;
! "IP或IP子网"/反掩码位数;
}
比如
acl local {
"locahost"; /* myself */
"10.0.0.1"/8; /* and everyone on the local network */
! "10.0.0.23"; /* except for the dialin router */
}
判断ACL也很简单
if (client.ip ~ local) {
pipe;
}

还可以定义子程序
sub pipe_if_local {
if (client.ip ~ local) {
pipe;
}
}
用call来调用
call pipe_if_local;

内置的例程
vcl_recv
有请求到达后成功接收并分析时被调用,一般以以下几个关键字结束。
error code [reason] 返回code给客户端,并放弃处理该请求
pass 进入pass模式,把控制权交给vcl_pass
pipe 进入pipe模式,把控制权交给vcl_pipe
lookup 在缓存里查找被请求的对象,根据查找结果把控制权交给vcl_hit或vcl_miss

vcl_pipe
进入pipe模式时被调用。请求被直接发送到backend,后端和客户端之间的后继数据不进行处理,只是简单传递,直到一方关闭连接。一般以以下几个关键字结束。
error code [reason]
pipe

vcl_pass
进入pass模式时被调用。请求被送到后端,后端应答数据送给客户端,但不进入缓存。同一连接的后继请求正常处理。一般以以下几个关键字结束。
error code [reason]
pass

vcl_hash
目前不使用

vcl_hit
在lookup以后如果在cache中找到请求的内容事调用。一般以以下几个关键字结束。
error code [reason]
pass
deliver 将找到的内容发送给客户端,把控制权交给vcl_deliver.

vcl_miss
lookup后但没有找到缓存内容时调用,可以用于判断是否需要从后端服务器取内容。一般以以下几个关键字结束。
error code [reason]
pass
fetch 从后端取得请求的内容,把控制权交给vcl_fetch.

vcl_fetch
从后端取得内容后调用。一般以以下几个关键字结束。
error code [reason]
pass
insert 将取到的内容插入缓存,然后发送给客户端,把控制权交给vcl_deliver

vcl_deliver
缓存内容发动给客户端前调用。一般以以下几个关键字结束。
error code [reason]
deliver 内容发送给客户端

vcl_timeout
在缓存内容到期前调用。一般以以下几个关键字结束。
fetch 从后端取得该内容
discard 丢弃该内容

vcl_discard
由于到期或者空间不足而丢弃缓存内容时调用。一般以以下几个关键字结束。
discard 丢弃
keep 继续保留在缓存里

如果这些内置例程没有被定义,则执行缺省动作

一些内置的变量
now 当前时间,标准时间点(1970?)到现在的秒数

backend.host 后端的IP或主机名
backend.port 后端的服务名或端口

请求到达后有效的变量
client.ip 客户端IP
server.ip 服务端IP
req.request 请求类型,比如GET或者HEAD或者POST
req.url 请求的URL
req.proto 请求的HTTP版本号
req.backend 请求对应的后端
req.http.header 对应的HTTP头

往后段的请求时有效的变量
bereq.request 比如GET或HEAD
bereq.url URL
bereq.proto 协议版本
bereq.http.header HTTP头

从cache或后端取到内容后有效的变量
obj.proto HTTP协议版本
obj.status HTTP状态代码
obj.response HTTP状态信息
obj.valid 是否有效的HTTP应答
obj.cacheable 是否可以缓存的内容,也就是说如果HTTP返回是200、203、300、301、302、404、410并且有非0的生存期,则为可缓存
obj.ttl 生存期,秒
obj.lastuse 上一次请求到现在间隔秒数

对客户端应答时有效的变量
resp.proto response的HTTP版本
resp.status 回给客户端的HTTP状态代码
resp.response 回给客户端的HTTP状态信息
resp.http.header HTTP头

变量可以通过set来赋值或通过remove来删除(清空)
sub vcl_recv {
if (req.http.host ~ "^(www.)?example.com$") {
set req.http.host = "www.example.com";
}
}

sub vcl_fetch {
remove obj.http.Set-Cookie;
}

- -------------------------------------------------------------------------------------------------
 

我在设计系统架构时,进行了大胆的尝试,只用6台Web服务器(除开FLV视频存储服务器),达到了可承受4000万PV(页面访问量)的性能:

抛弃了 Apache,因为它能承受的并发连接相对较低;
抛弃了 Squid,因为它在内存利用、访问速度、并发连接、清除缓存等方面不如 Varnish;
抛弃了 PHP4,因为 PHP5 处理面向对象代码的速度要比 PHP4 快,另外,PHP4 已经不再继续开发;
抛弃了 F5 BIG-IP 负载均衡交换机,F5 虽然是个好东西,但由于价格不菲,多个部门多个产品都运行在其之上,流量大、负载高,从而导致性能大打折扣;

利用 Varnish cache 减少了90%的数据库查询,解决了MySQL数据库瓶颈;
利用 Varnish cache 的内存缓存命中加快了网页的访问速度;
利用 Nginx + PHP5(FastCGI) 的胜过Apache 10倍的高并发性能,以最少的服务器数量解决了PHP动态程序访问问题;
利用 Memcached 处理实时数据读写;
利用 HAProxy 做接口服务器健康检查;

经过压力测试,每台Web服务器能够处理3万并发连接数,承受4千万PV完全没问题。

保证4千万PV的并发连接数:(40000000PV / 86400秒 * 10个派生连接数 * 5秒内响应 * 5倍峰值) / 6台Web服务器 = 19290连接数

-------------------------------------------------------------------------------------------------------

创建Varnish配置文件:
vi /usr/local/varnish/vcl.conf

输入以下内容:
backend myblogserver {
set backend.host = "192.168.0.5";
set backend.port = "80";
}

acl purge {
"localhost";
"127.0.0.1";
"192.168.1.0"/24;
}

sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
lookup;
}

if (req.http.host ~ "^blog.s135.com") {
set req.backend = myblogserver;
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
else {
lookup;
}
}
else {
error 404 "Zhang Yan Cache Server";
lookup;
}
}

sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}

sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}

sub vcl_fetch {
if (req.request == "GET" && req.url ~ "\.(txt|js)$") {
set obj.ttl = 3600s;
}
else {
set obj.ttl = 30d;
}
}

这里,我对这段配置文件解释一下:
(1)、Varnish通过反向代理请求后端IP为192.168.0.5,端口为80的web服务器;
(2)、Varnish允许localhost、127.0.0.1、192.168.0.***三个来源IP通过PURGE方法清除缓存;
(3)、Varnish对域名为blog.s135.com的请求进行处理,非blog.s135.com域名的请求则返回“Zhang Yan Cache Server”;
(4)、Varnish对HTTP协议中的GET、HEAD请求进行缓存,对POST请求透过,让其直接访问后端Web服务器。之所以这样配置,是因为POST请求一般是发送数据给服务器的,需要服务器接收、处理,所以不缓存;
(5)、Varnish对以.txt和.js结尾的URL缓存时间设置1小时,对其他的URL缓存时间设置为30天。
5、启动Varnish

ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on

6、启动varnishncsa用来将Varnish访问日志写入日志文件:

/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/varnish.log &

7、如果想配置成开机自动启动Varnish

vi /etc/rc.local

在末尾增加以下内容:

ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/youvideo.log &

8、优化Linux内核参数

vi /etc/sysctl.conf

在末尾增加以下内容:

net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000    65000

再看看如何管理Varnish:
1、查看Varnish服务器连接数与命中率:

/usr/local/varnish/bin/varnishstat -n /var/vcache

输出的结果如下图显示: 

点击查看原图
2、通过Varnish管理端口进行管理:
用help看看可以使用哪些Varnish命令:

/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 help

3、通过Varnish管理端口,使用正则表达式批量清除缓存:
(1)、例:清除类似http://blog.s135.com/a/zhangyan.html的URL地址):

/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge /a/

(2)、例:清除类似http://blog.s135.com/tech的URL地址:

/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge w*$

(3)、例:清除所有缓存:
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge *$

附1:2007年12月10日,我写了一个每天0点运行,按天切割Varnish日志,生成一个压缩文件,同时删除上个月旧日志的脚本(/var/logs/cutlog.sh):
/var/logs/cutlog.sh文件内容如下:

#!/bin/sh
# This file run at 00:00
date=$(date -d "yesterday" +"%Y-%m-%d")
pkill -9 varnishncsa
mv /var/logs/youvideo.log /var/logs/${date}.log
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/youvideo.log &
mkdir -p /var/logs/youvideo/
gzip -c /var/logs/${date}.log > /var/logs/youvideo/${date}.log.gz
rm -f /var/logs/${date}.log
rm -f /var/logs/youvideo/$(date -d "-1 month" +"%Y-%m*").log.gz

设置在每天00:00定时执行:

/usr/bin/crontab -e
0 0 * * * /bin/sh /var/logs/cutlog.sh
 

发表在 web server | 标签为 | 68条评论

nginx+php+memcache+xcache+mysql安装与配置

nginx+php+memcache+xcache+mysql安装与配置

笔记:犹

链接:http://hi.baidu.com/avyou/blog/item/3ed08350f94516898c5430a9.html

安装系统的程序库-->安装数据库-->php需要的支持库-->安装php-->安装php扩展(memcache,xcache)-->安装nginx.

1.安装系统的程序库
yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel

一般的,如果安装系统时选择了系统的开发库,只要再安装以下三个包就可以了,gd包也可以用rpm 安装,但gd-devel所依赖的其它包太多,所以后面将用源码包安装.

# rpm -ivh freetype-devel-2.2.1-19.el5.i386.rpm
# rpm -ivh libpng-devel-1.2.10-7.0.2.i386.rpm
# rpm -ivh libjpeg-devel-6b-37.i386.rpm
------------------------------------------------------------------------------
2.安装mysql数据库

为了方便,这里选择rpm包来安装.

# rpm -ivh perl-DBD-MySQL-3.0007-1.fc6.i386.rpm
# rpm -ivh mysql-server-5.0.22-2.1.0.1.i386.rpm
# rpm -ivh mysql-devel-5.0.22-2.1.0.1.i386.rpm //编译安装的php需要的mysql库

# /etc/rc.d/init.d/mysqld start
# mysqladmin -u root -p password yourpass
-------------------------------------------------------------------

3.编译安装PHP 5.2.6所需的支持库:

3.1. 安装libiconv

# tar zxvf libiconv-1.12.tar.gz
# cd libiconv-1.12/
# ./configure --prefix=/usr/local

# make && make install
-------------------------------------------------
3.2. 安装libmcrypt

# tar zxvf libmcrypt-2.5.8.tar.gz
# cd libmcrypt-2.5.8/
# ./configure
# make && make install
# ldconfig
# cd libltdl/
# ./configure --enable-ltdl-install
# make && make install
-------------------------------------------------
3.3.安装mhash

# tar zxvf mhash-0.9.9.tar.gz
# cd mhash-0.9.9/
# ./configure
# make && make install

# cp /usr/local/lib/libmcrypt.* /usr/lib
# ln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2
# ldconfig
-----------------------------------------------------
3.4.安装mcrypt
# tar zxvf mcrypt-2.6.7.tar.gz
# cd mcrypt-2.6.7/
# ./configure
# make && make install
----------------------------------------------------
3.5.安装gd

# tar xvf gd-2.0.32.tar.tar
# cd gd2.0.32
# ./configure
# make && make install
--------------------------------------------------------------------
4.安装php(FastCGI模式)

说明:php-fpm-是 php-5.26的一个fpm管理补丁,在启用FastCGI模式时,可以平滑变更php.ini配置而无需重启php-cgi。没有php5.0 的php-fpm补丁包

# tar zxvf php-5.26.tar.gz
# gzip -cd php-5.2.6-fpm-0.5.8.diff.gz | patch -d php-5.2.6 -p1
# cd php-5.2.6/
# ./configure \
--prefix=/usr/local/php5 \ //php的安装路径
--with-mysql \ //与mysql库相关联
--with-iconv-dir=/usr/local \ //这里的路径要以前面libconv编译包一致
--with-freetype-dir \
--with-jpeg-dir \
--with-png-dir \
--with-zlib
--with-libxml-dir \
--with-gd \
--with-openssl \
--with-mcrypt \
--with-gd \
--enable-gd-native-ttf \
--enable-xml \
--enable-fastcgi \ //启用fastcgi模式
--enable-fpm \ //启用fpm管理
--enable-force-cgi-redirect \
--enable-mbstring \
--enable-inline-optimization \
--disable-debug

# make
# make install
# cp php.ini-dist /usr/local/php5/lib/php.ini

5.安装php5扩展模块

说明:
.Memcached是一个高性能的分布式的内存对象缓存系统。本文中的memcache.so是Memcached的客户端PHP扩展,与Xcache、eaccelerator、APC不是同一类东西,没有本质的联系。

.XCache 是一个开源的 opcode 缓存器/优化器, 这意味着他能够提高您服务器上的 PHP 性能. 他通过把编译 PHP 后的数据缓冲到共享内存从而避免重复的编译过程, 能够直接使用缓冲区已编译的代码从而提高速度. 通常能够提高您的页面生成速率 2 到5 倍, 降低服务器负载。eaccelerator、APC 也是 opcode 缓存器/优化器,跟xcache的功能类似,不能跟xcache一起使用。

.xcache还有数据缓存功能,功能跟Memcache类似,但效果不如Memcached。
--------------------------------------------------------------------------------------------
5.1 安装 memcache-2.23.tgz
# tar zxvf memcache-2.23.tgz
# /usr/local/php5/bin/phpize //生成Api版本号,Zend Module Api 号和Zend Extension Api号
#./configure --with-php-config=/usr/local/php5/bin/php-config
# make && make install //生成smemcache.so的路径:/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/
--------------------------------------------------------------
5.2 安装xcache-1.2.2.tar.gz

# tar zxvf xcache-1.2.2.tar.gz
# cd xcache-1.2.2
# /usr/local/php5/bin/phpize
# ./configure --with-php-config=/usr/local/php5/bin/php-config --enable-xcache
# make && make install //生成xcache.so的路径:/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/
--------------------------------------------------------------------------------------------
6.配置php5扩展模块

6.1 配置memcache

# vi /usr/local/php5/lib/php.ini

;/usr/local/webserver/php/etc/php.ini中的extension_dir = "./" //修改模块路径
/usr/local/webserver/php/etc/php.ini中的extension_dir = "/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/"

extension = "memcache.so" //添加memcache.so模块

;display_errors = On
display_errors = Off //修改显示错误为off
---------------------------------------------------------
6.2 配置xcache

# vi xcache-1.2.2/xcache.ini

[xcache-common]
zend_extension = /usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/xcache.so

[xcache.admin]
xcache.admin.enable_auth = On //启用xcache管理认证
xcache.admin.user = "xcache" //验证名
; xcache.admin.pass = md5($your_password)
xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e" //md5 后的验证密码, 亦即 md5(您的密码), 留空则禁用管理页面.

[xcache]
xcache.shm_scheme = "mmap" // 选择低级别的共享存储器/分配算符安排执行
xcache.size = 32M //0 禁止, 非 0 则启用缓存器. 请注意您系统所允许的 mmap 最大值.
xcache.count = 1 //指定将 cache 切分成多少块. 参考 SplittedCache,可以用(cat /proc/cpuinfo |grep -c processor)命令查看
xcache.slots = 8K // 只是作为 hash 槽个数的参考值, 您可以放心地缓冲超过这个个数的项目
xcache.ttl = 0 //设置缓冲项目的 Ttl (Time To Live) 值, 0=永不过期
xcache.gc_interval = 0 //检查过期项目, 回收内存空间的间隔.

//同上, 不过用于数据缓冲而不是 opcode 缓冲.
xcache.var_size = 2M
xcache.var_count = 1
xcache.var_slots = 8K
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
xcache.readonly_protection = Off
xcache.mmap_path = "/dev/zero" //对于 *nix, xcache.mmap_path 是 文件路径, 不是目录.
;xcache.cacher = On
;xcache.stat = On
;xcache.optimizer = On //启用优化器 (目前无效).

# cp xcache-1.2.2/xcache.ini /usr/local/php5/etc/xcache.ini
# cat /usr/local/php5/etc/xcache.ini >> /usr/local/php5/lib/php.ini
---------------------------------------------------------------------------------------------------------
6.3 安装xcache的web管理界面

说明:这一步留到安装完成nginx后来再来做,写在这里只为了顺着xcache的流程

# vi /var/data/www/md.php //获取md密码,在浏览器输入http://192.168.1.5/md.php,显示e10adc3949ba59abbe56e057f20f883e,得到后删除.

<?php
echo md5("password");
?>

--------------------------------

# rm -rf /var/data/www/md.php

# vi /usr/local/php5/lib/php.ini //修改php.ini文件
xcache.admin.user = "xcache"
xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e"

# cp -a xcache/admin /var/data/www/xcache
# chown -R www:www /var/data/www/xcache
# chmod -R +x /var/data/xcache

-------------------------------------------------------------------------
7.创建nginx的用户和组,并给虚拟主机目录分配权限

# groupadd www -g 101
# useradd -u 101 -g www www -s /bin/false
# mkdir -p /var/data/www/error
# chmod 755 /var/data/www
# chown -R www:www /var/data/www

---------------------------------------------------------------------

8.修改php-fpm配置文件,启动php-cgi进程

# vi /usr/local/php5/etc/php-fpm.conf //这里主要做几处修改即可,记得去掉里面的注释,否则启动出错!

--> <value name="pid_file">/usr/local/php5/logs/php-fpm.pid</value>
--> <value name="error_log">/usr/local/php5/logs/php-fpm.log</value>
--> <value name="user">www</value>
--> <value name="group">www</value>
--> <value name="max_children">25</value>
--> <value name="MaxSpareServers">35</value>
--> <value name="rlimit_files">10240</value>
--> <value name="max_requests">10240</value>

# ulimit -SHn 10240
# /usr/local/php5/sbin/php-fpm start //参数start|stop|quit|restart|reload|logrotate

-------------------------------------------------------------

9.安装与配置nginx

说明:
.gzip 模块需要 zlib 库
.rewrite 模块需要 pcre 库
.ssl 功能需要 openssl 库
----------------------------
9.1 安装pcre库

# tar zxvf pcre-7.7.tar.gz
# cd pcre-7.7/
# ./configure
# make && make install
-----------------------------------
9.2 安装nginx

# tar zxvf nginx-0.6.31.tar.gz
# cd nginx-0.6.31/
# ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
# make && make install
-----------------------------------------
9.3 配置nginx

# mkdir /var/log/nginx
# chmod +w /var/log/nginx
# chown -R www:www /var/log/nginx
# cd /usr/local/nginx/conf
# cp nginx.conf nginx.conf.bak

# vi nginx.conf
-------------------------------------------------------------------------------------------------
user www www;
worker_processes 1;
error_log /var/log/nginx/error.log crit;
pid /var/log/nginx/nginx.pid;

events {
use epoll; //规定使用的I/O复用模式,Linux 2.6内核的epoll,FreeBSD用kqueue
worker_connections 2048;
}

http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 60;
sendfile on;
tcp_nopush on; //allows or forbids socket options TCP_NOPUSH on FreeBSD or TCP_CORK on Linux.
This option is only available when using sendfile.
tcp_nodelay on; //This directive allows or forbids the use of the socket option TCP_NODELAY. Only included in keep-alive connections.

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_temp_path /dev/shm;

gzip on;
gzip_min_length 1k;
gzip_buffers 48k;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/html application/xml;

server {
listen 80;
server_name localhost;
index index.php index.html index.htm;
root /var/data/www;
charset utf8,gb2312;
log_format main '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

if (-d $request_filename){ //如果在浏览中输入"http://xxx/yy"会在目录yy后面加上"/"即"http://xxx/yy/"

rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}

location ~ .*\.php?$ { //matches any request ending in .php?
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
error_page 404 http://192.168.1.5/error/404.html;
error_page 500 502 503 504 http://192.168.1.5/error/50x.html;

server {
listen 5200;
server_name localhost;
allow 192.168.1.101/32;
deny all;

location / {
root /var/www2/xcache;
index index.html index.htm;
}
location ~ .*\.php?$ {
root /var/www2/xcache;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}

# server {
# listen 192.168.1.5;
# listen 192.168.1.5:80;
# server_name www.test3.com;
# location / {
# root /var/data/www3;
# index index.html index.htm;
# }
#
# }
}

---------------------------------------------------

# vi /usr/local/nginx/conf/fastcgi.conf //fastcgi的配置文件需要它,nginx才能支持php.也可以对fastcgi_params 进行简单修改

#fastcgi.conf
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
#fastcgi_param REDIRECT_STATUS 200;

--------------------------------------------------------------------------------------------------------------------------------
10.管理web服务

10.1管理命令

# /usr/local/php5/sbin/php-fmp restart
# /usr/local/nginx/sbin/nginx -t //测试配置文件,-c指定配置文件路径,-v显示 nginx 的版本,-V 显示 nginx 的版本,编译器版本和配置参数。
# /usr/local/nginx/sbin/nginx //启动nginx
# ps aux | grep '(PID|nginx)' //显示nginx的PID号2213
# kill -HUP 2213 //不用重启nginx,直接重新加载配置
# kill -HUP /var/log/nginx/nginx.pid //或者更新nginx.pid
------------------------------------------------------------------------
说明:

首先,使用新的可执行程序替换旧的,然后,发送USR2(kill –USR2 ROOT_PID)信号给主进程,主进程将重新命名它的.pid文件为nginx.pid..oldbin,然后执行新的可执行程序,依次启动新的主进程和工作进程。在这时,两个nginx实例会同时运行,一起处理输入的请求。需要逐步停止旧的实例,此时需要发送WINCH信号给就的主进程,然后它的工作进程开始关闭。一段时间后,旧的工作进程处理了所有已连接的请求后退出,就仅由新的工作进程来处理输入的请求。这时,因为旧的服务器还尚未关闭它监听的套接字,所以通过下面几步仍然可以恢复旧的服务器。

. 发送 HUP 信号给旧的主进程 - 它将在不重载配置文件的情况下启动它的工作进程
. 发送 QUIT 信号给新的主进程,要求其从容关闭其工作进程
. 发送 TERM 信号给新的主进程,迫使其退出
. 如果因为某些原因新的工作进程不能退出,向其发送 KILL 信号
------------------------------------------------------------------------
10.2管理日志

# vi /usr/local/nginx/sbin/nginxlog //日志截断脚本

#!/bin/sh
# This file run at 00:00
logdate=$(date -d "yesterday" +"%Y-%m-%d") //昨天的年月日
logdir=/var/log/nginx

gzip -c ${logdir}/access.log>${logdir}/${logdate}.log.gz

------------------------------------------------------

# echo ""> ${logdate}/access.log
# chmod +x /var/local/nginx/sbin/nginxlog
# crontab -e

0 0 * * * /usr/local/nginx/sbin/nginxlog>>/dev/null 2>&1

发表在 web server | 标签为 , , | nginx+php+memcache+xcache+mysql安装与配置已关闭评论

squid负载过高,必然DOWN机,垦请高手来分析

操作系统:solaris 10
服务器:SUN E2900   16G内存    4CPU   2个10000转SCSI硬盘
df -h

QUOTE:
/dev/dsk/c1t0d0s3       20G   4.4G    15G    23%    /var
swap                    27G     0K    27G     0%    /tmp
swap                    27G    16K    27G     1%    /var/run
/dev/dsk/c1t1d0s1       16G    11G   4.3G    73%    /proxy
/dev/dsk/c1t1d0s3       20G    14G   5.6G    72%    /cache1

squid版本是2.6,安装在/proxy下
squid.conf配置如下:

QUOTE:
http_port 10.1.1.1:8081
hierarchy_stoplist cgi-bin ?
hierarchy_stoplist -i ^https:\\ ?
acl QUERY urlpath_regex -i cgi-bin \? \.asp \.php \.jsp \.cgi
acl denyssl urlpath_regex -i ^https:\\
cache deny QUERY
cache deny denyssl
acl apache rep_header Server ^Apache
broken_vary_encoding allow apache

cache_mem 1024 MB
cache_swap_low 90
cache_swap_high 95
maximum_object_size 8192 KB
maximum_object_size_in_memory 32 KB

cache_dir ufs /proxy/var/cache 12000 48 256
cache_dir ufs /cache1 15000 48 256
access_log none
cache_log /cmproxy/var/logs/cache.log
cache_store_log none
mime_table /proxy/etc/mime.conf
pid_filename /proxy/var/logs/squid.pid
refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .               0       20%     4320

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563
acl Safe_ports port 80                # http
acl Safe_ports port 21                # ftp
acl Safe_ports port 443 563           # https, snews
acl Safe_ports port 70                # gopher
acl Safe_ports port 210               # wais
acl Safe_ports port 1025-65535        # unregistered ports
acl Safe_ports port 280                # http-mgmt
acl Safe_ports port 488                # gss-http
acl Safe_ports port 591                # filemaker
acl Safe_ports port 777                # multiling http
acl CONNECT method CONNECT
acl SSL_gmcc_port port 81 443 563 7001 8080 8888 9087 9088 9315
acl our_networks src 10.0.0.0/8 192.168.0.0/16
http_access allow our_networks
http_access allow manager localhost
http_access deny manager
http_access allow SSL_gmcc_port
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
http_reply_access allow all

logfile_rotate 7
visible_hostname none
forwarded_for off
store_objects_per_bucket 50
icon_directory /proxy/share/icons
coredump_dir /cache1

 

同时在线连接数超过3K后,终端打开网页极慢,且squid进程僵死,无法通过squid -k shutdown停止,即使用squid -k kill 或kill -9 进程id也无效,只有重启机器

连接数

 

QUOTE:
netstat -an|grep 8081|grep EST|wc -l
3096

等待TIME_WAIT数

 

QUOTE:
netstat -an|grep TIME_WAIT|wc -l
5300

CPU占用率并不高

 

QUOTE:
#sar -u 3 5

SunOS 5.10 Generic_118833-02 sun4u    03/21/2007

08:16:10    %usr    %sys    %wio   %idle
08:16:13       3       5       0      92
08:16:16       3       5       0      92
08:16:19       2       6       0      92
08:16:22       2       4       0      94
08:16:25       2       4       0      93

Average        2       5       0      93

磁盘IO使用率较高

 

QUOTE:
iostat -cxn 5
                 extended device statistics              
    r/s    w/s   kr/s   kw/s wait actv wsvc_t asvc_t  %w  %b device
    0.0    0.0    0.0    0.0  0.0  0.0    0.0    0.0   0   0 d20
    0.0    0.0    0.0    0.0  0.0  0.0    0.0    0.0   0   0 d21
    0.0    0.0    0.0    0.0  0.0  0.0    0.0    0.0   0   0 d22
    0.0    0.6    0.0    0.4  0.0  0.0    0.0    9.1   0   0 c1t0d0
   18.6  128.2   70.8 1440.9  0.0  3.8    0.0   25.9   0  81 c1t1d0

内存使用及机器负荷

 

QUOTE:
prstat
PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP      
   279 root     1577M 1573M cpu1     0    0   3:45:19 3.7% squid/1
   125 named      10M 7752K sleep   59    0   0:04:56 0.1% named/11
   280 nobody   1168K  840K sleep   60    0   0:04:15 0.1% unlinkd/1

Total: 26 processes, 134 lwps, load averages: 0.50, 0.55, 0.54

squid的信息

 

QUOTE:
squidclient -p 8081 mgr:info

HTTP/1.0 200 OK
Server: squid/2.6.STABLE10
Date: Wed, 21 Mar 2007 00:23:01 GMT
Content-Type: text/plain
Expires: Wed, 21 Mar 2007 00:23:01 GMT
Last-Modified: Wed, 21 Mar 2007 00:23:01 GMT
X-Cache: MISS from none
Via: 1.0 none:8081 (squid/2.6.STABLE10)
Proxy-Connection: close

Squid Object Cache: Version 2.6.STABLE10
Start Time:     Tue, 20 Mar 2007 04:32:03 GMT
Current Time:   Wed, 21 Mar 2007 00:23:01 GMT
Connection information for squid:
        Number of clients accessing cache:      4514
        Number of HTTP requests received:       7291534
        Number of ICP messages received:        0
        Number of ICP messages sent:    0
        Number of queued ICP replies:   0
        Request failure ratio:   0.00
        Average HTTP requests per minute since start:   6122.4
        Average ICP messages per minute since start:    0.0
        Select loop called: 39501660 times, 1.809 ms avg
Cache information for squid:
        Request Hit Ratios:     5min: 46.8%, 60min: 47.8%
        Byte Hit Ratios:        5min: 14.7%, 60min: 14.5%
        Request Memory Hit Ratios:      5min: 17.4%, 60min: 21.3%
        Request Disk Hit Ratios:        5min: 13.4%, 60min: 11.9%
        Storage Swap size:      24968613 KB
        Storage Mem size:       1048296 KB
        Mean Object Size:       22.17 KB
        Requests given to unlinkd:      871980
Median Service Times (seconds)  5 min    60 min:
        HTTP Requests (All):   0.19742  0.12106
        Cache Misses:          0.44492  0.30459
        Cache Hits:            0.07014  0.04277
        Near Hits:             0.30459  0.22004
        Not-Modified Replies:  0.05046  0.03427
        DNS Lookups:           0.04854  0.02809
        ICP Queries:           0.00000  0.00000
Resource usage for squid:
        UP Time:        71457.499 seconds
        CPU Time:       13602.398 seconds
        CPU Usage:      19.04%
        CPU Usage, 5 minute avg:        30.82%
        CPU Usage, 60 minute avg:       30.37%
        Process Data Segment Size via sbrk(): 1596379 KB
        Maximum Resident Size: 0 KB
        Page faults with physical i/o: 10096743
Memory usage for squid via mallinfo():
        Total space in arena:  1596379 KB
        Ordinary blocks:       1471660 KB 258638 blks
        Small blocks:               0 KB      0 blks
        Holding blocks:         10928 KB     10 blks
        Free Small blocks:          0 KB
        Free Ordinary blocks:  124718 KB
        Total in use:          1482588 KB 92%
        Total free:            124718 KB 8%
        Total size:            1607307 KB
Memory accounted for:
        Total accounted:       1287875 KB
        memPoolAlloc calls: 753300395
        memPoolFree calls: 746272417
File descriptor usage for squid:
        Maximum number of file descriptors:   32768
        Largest file desc currently in use:   5321
        Number of file desc currently in use: 4396
        Files queued for open:                   0
        Available number of file descriptors: 28372
        Reserved number of file descriptors:   100
        Store Disk files open:                  26
        IO loop method:                     poll
Internal Data Structures:
        1133385 StoreEntries
        143938 StoreEntries with MemObjects
        143638 Hot Object Cache Items
        1126459 on-disk objects

发表在 article | 标签为 | squid负载过高,必然DOWN机,垦请高手来分析已关闭评论

清除指定squid缓存文件的脚本

Squid
web缓存加速软件目前已经是新浪、搜狐、网易等各大网站广泛应用。Squid会在设置的缓存目录下建立多个目录,每一个目录下又建立多个目录,然后才在最里层的目录中存放缓存文件(object)。squid会根据用户请求网页的URL进行哈希,生成缓存文件,存放在某一个目录中。squid启动之后,将在内存中建立一个哈希表,记录硬盘中缓存文件配置的情形。

  对于类似http://you.video.sina.com.cn/index.html
之类的网页,squid只会生成一个缓存文件。可以用squid附带的squidclient工具清除:
 

引用
squidclient -m PURGE -p 80 "http://you.video.sina.com.cn/index.html"

  而对于带有参数的网页,例如新浪播客的Flash播放器http://vhead.blog.sina.com.cn/player/outer_player.swf?auto=0&vid=4469852&uid=1278987704
,因“?”后面的参数不同,导致URL也不同,squid会生成多个缓存文件,哈希分散存放在不同的目录。如果修改了这个outer_player.swf文件,要更新squid缓存就要去清除不同目录下及内存中的很多个缓存文件,十分麻烦,于是我编写了一个Linux下的shell脚本,去完成这件麻烦的事:

  脚本文件名:clear_squid_cache.sh(8月2日修正了UC网友“城市中的寂寞”反馈的BUG)
 

引用
#!/bin/sh
squidcache_path="/data1/squid/var/cache"
squidclient_path="/usr/local/squid/bin/squidclient"
grep -a -r $1 $squidcache_path/* | strings | grep "http:" | awk -F'http:' '{print "http:"$2;}' > cache_list.txt
for url in `cat cache_list.txt`; do
$squidclient_path -m PURGE -p 80 $url
done

  注意:请赋予clear_squid_cache.sh可执行权限(命令:chmod +x ./clear_squid_cache.sh)。请确保脚本所在目录可写。

  设置:
  squidcache_path= 表示squid缓存目录的路径
  squidclient_path= 表示squidclient程序所在的路径,默认为squid安装目录下的bin/squidclient

  用法:
  1、清除所有Flash缓存(扩展名.swf):
  ./clear_squid_cache.sh swf

  2、清除URL中包含sina.com.cn的所有缓存:
  ./clear_squid_cache.sh sina.com.cn

  3、清除文件名为zhangyan.jpg的所有缓存:
  ./clear_squid_cache.sh zhangyan.jpg

  效率:
  经测试,在DELL 2950上清除26000个缓存文件用时2分钟左右。平均每秒可清除缓存文件177个。

发表在 article | 标签为 | 清除指定squid缓存文件的脚本已关闭评论

电信/联通/全国DNS列表/PUBLIC DNS

Global DNS Server List

  • 1.1.1.1 – CloudFlare
  • 2.2.2.2 – 法国电信/ Orange
  • 3.3.3.3 – 通用电气
  • 4.4.4.4 – Level3 通信
  • 5.5.5.5 – E-Plus(德国第三大的手机运营商)
  • 6.6.6.6 – 美国陆军
  • 7.7.7.7 – 未使用的理论上属于美国国防部
  • 8.8.8.8 – 谷歌
  • 9.9.9.9 – IBM

教育网DNS服务器:

北京邮电大学DNS服务器
2001:da8:202:10::36
2001:da8:202:10::37

北京科技大学DNS服务器
2001:da8:208:10::6

”Google Over IPv6”计划的DNS:
Hurricane Electric DNS

ordns.he.net 2001:470:20::2 74.82.42.42
tserv1.fmt2.he.net 2001:470:0:45::2 72.52.104.74
tserv1.dal1.he.net 2001:470:0:78::2 216.218.224.42
tserv1.ams1.he.net 2001:470:0:7d::2 216.66.84.46
tserv1.mia1.he.net 2001:470:0:8c::2 209.51.161.58
tserv1.tor1.he.net 2001:470:0:c0::2 216.66.38.58
ns.ipv6.uni-leipzig.de 2001:638:902:1::10 139.18.25.34

Google Public DNS

google-public-dns-a.google.com 2001:4860:4860::8888 8.8.8.8
google-public-dns-b.google.com 2001:4860:4860::8844 8.8.4.4

Cloudflare DNS

2606:4700:4700::1111 1.1.1.1
2606:4700:4700::1001 1.0.0.1

公众 DNS 测试:

Google 8.8.8.8 私有和未过滤,最受欢迎。
CloudFlare 1.1.1.1 私有和未过滤的新玩家。
Quad 9 9.9.9.9 私有和安全意识很高的新玩家。
OpenDNS 208.67.222.222 阻止恶意网域并提供阻止成人内容的旧玩家。
Norton DNS 199.85.126.20 阻止恶意域名并与其防病毒软件集成的旧玩家。
CleanBrowsing 185.228.168.168 私有和阻止访问成人内容,新玩家。
Yandex DNS 77.88.8.7 阻止恶意域名的旧玩家,在俄罗斯非常受欢迎。
Comodo DNS 8.26.56.26 阻止恶意域名的旧玩家

结果摘要

测试非常简单,针对不同流行的域名(google, facebook, twitter, gmail 等)在整个一小时内执行了 70 次DNS 查询。对每个位置的所有请求进行平均,以获得每个 DNS 解析程序的整体性能指标。

TLDR /摘要

  • 所有供应商(Yandex 除外)在北美和欧洲表现非常好。他们在美国,加拿大和欧洲的响应时间均小于 15 毫秒。然而,亚洲和南美洲在总体平均数上有所不同,因为一些提供商在那里连接不好。
  • CloudFlare 是所有位置中最快的 DNS。它在全球的平均值为 4.98 毫秒,令人惊叹。
  • 谷歌和 Quad9 分别接近第二和第三。Quad9 在北美和欧洲比谷歌速度快,但在亚洲/南美洲表现不佳。
  • CloudFlare 在任何地方都有强大的存在。尽管 Google 和 Quad9 在某些地方的响应时间很高,但CloudFlare 在各个地方都表现良好。
  • Yandex 仅适用于俄罗斯。它不像其他提供商那样使用 Anycast,并且在任何地方都非常缓慢。
  • CleanBrowsing 是成人(色情)内容过滤的最快速的提供商。

全球平均

#1 CloudFlare:4.98 ms
#2 Google:16.44 ms
#3 Quad9:18.25 ms
#4 CleanBrowsing:19.14 ms
#5 Norton:34.75 ms
#6 OpenDNS:46.51 ms
#7 Comodo:71.90
#8 Yandex:169.91

北美平均水平

#1 CloudFlare:3.93 ms
#2 Quad9:7.21 ms
#3 Norton:8.32 ms
#4 Google:8.53 ms
#5 CleanBrowsing:11.83 ms
#6 OpenDNS:14.66 ms
#7 Comodo:25.91 ms
#8 Yandex:119.09 ms

欧洲平均

#1 CloudFlare:2.96
#2 Quad9:4.35
#3 CleanBrowsing:5.74
#4 Google:7.17
#5 OpenDNS:8.99
#6 Norton:10.35
#7 Comodo:13.06
#8 Yandex:35.74

测试结果来自:medium

China Global DNS Server List

全国各地电信 DNS 服务器 IP 地址

名称 DNS 服务器 IP 地址
安徽电信 DNS 61.132.163.68 202.102.213.68
北京电信 DNS 219.141.136.10 219.141.140.10
重庆电信 DNS 61.128.192.68 61.128.128.68
福建电信 DNS 218.85.152.99 218.85.157.99
甘肃电信 DNS 202.100.64.68 61.178.0.93
广东电信 DNS 202.96.128.86 202.96.128.166
202.96.134.33 202.96.128.68
广西电信 DNS 202.103.225.68 202.103.224.68
贵州电信 DNS 202.98.192.67 202.98.198.167
河南电信 DNS 222.88.88.88 222.85.85.85
黑龙江电信 219.147.198.230 219.147.198.242
湖北电信 DNS 202.103.24.68 202.103.0.68
湖南电信 DNS 222.246.129.80 59.51.78.211
江苏电信 DNS 218.2.2.2 218.4.4.4
61.147.37.1 218.2.135.1
江西电信 DNS 202.101.224.69 202.101.226.68
内蒙古电信 219.148.162.31 222.74.39.50
山东电信 DNS 219.146.1.66 219.147.1.66
陕西电信 DNS 218.30.19.40 61.134.1.4
上海电信 DNS 202.96.209.133 116.228.111.118
202.96.209.5 108.168.255.118
四川电信 DNS 61.139.2.69 218.6.200.139
天津电信 DNS 219.150.32.132 219.146.0.132
云南电信 DNS 222.172.200.68 61.166.150.123
浙江电信 DNS 202.101.172.35 61.153.177.196
61.153.81.75 60.191.244.5

全国各地联通 DNS 服务器 IP 地址

名称 DNS 服务器 IP 地址
北京联通 DNS 202.106.196.115 202.106.46.151
202.106.0.20 202.106.195.68
重庆联通 DNS 221.5.203.98 221.7.92.98
广东联通 DNS 210.21.196.6 221.5.88.88
河北联通 DNS 202.99.160.68 202.99.166.4
河南联通 DNS 202.102.224.68 202.102.227.68
黑龙江联通 202.97.224.69 202.97.224.68
吉林联通 DNS 202.98.0.68 202.98.5.68
江苏联通 DNS 221.6.4.66 221.6.4.67
内蒙古联通 202.99.224.68 202.99.224.8
山东联通 DNS 202.102.128.68 202.102.152.3
202.102.134.68 202.102.154.3
山西联通 DNS 202.99.192.66 202.99.192.68
陕西联通 DNS 221.11.1.67 221.11.1.68
上海联通 DNS 210.22.70.3 210.22.84.3
四川联通 DNS 119.6.6.6 124.161.87.155
天津联通 DNS 202.99.104.68 202.99.96.68
浙江联通 DNS 221.12.1.227 221.12.33.227
辽宁联通 DNS 202.96.69.38 202.96.64.68

全国各地移动 DNS 服务器 IP 地址

名称 DNS 服务器 IP 地址
江苏移动 DNS 221.131.143.69 112.4.0.55
安徽移动 DNS 211.138.180.2 211.138.180.3
山东移动 DNS 218.201.96.130 211.137.191.26

Apple TV DNS 服务器 IP 地址

名称 DNS 服务器 IP 地址
上海电信 180.153.225.136
杭州电信 115.29.189.118
广东电信 203.195.182.150
北方联通 118.244.224.124

全国电信DNS列表

58.217.249.160 58.217.249.161 江苏省南京市 南京信风网络科技有限公司DNS服务器电信节点
59.51.78.210 59.51.78.211 湖南省 电信DNS服务器
60.191.244.5 60.191.244.5 浙江省金华市 电信DNS服务器
60.207.196.198 60.207.196.198 北京市 电信通DNS服务器
61.128.114.133 61.128.114.134 新疆乌鲁木齐市 电信DNS服务器
61.128.114.166 61.128.114.167 新疆乌鲁木齐市 电信DNS服务器
61.128.128.68 61.128.128.68 重庆市 电信DNS服务器
61.128.192.68 61.128.192.68 重庆市 电信DNS服务器
61.130.254.34 61.130.254.36 浙江省湖州市 电信DNS服务器
61.132.163.68 61.132.163.68 安徽省 电信DNS服务器
61.134.1.4 61.134.1.4 陕西省西安市 电信DNS
61.134.1.5 61.134.1.5 陕西省西安市 电信DNS服务器
61.139.2.69 61.139.2.69 四川省成都市 电信DNS服务器
61.139.39.73 61.139.39.73 四川省泸州市 电信DNS服务器
61.139.54.66 61.139.54.66 四川省凉山州西昌市 电信DNS服务器
61.147.37.1 61.147.37.1 江苏省徐州市 电信DNS服务器
61.166.150.101 61.166.150.101 云南省昆明市 电信DNS服务器
61.166.150.123 61.166.150.123 云南省 电信DNS服务器
61.166.150.139 61.166.150.139 云南省昆明市 电信DNS服务器
61.177.7.1 61.177.7.1 江苏省苏州市 电信DNS服务器
61.187.98.3 61.187.98.3 湖南省株洲市 电信DNS服务器
61.187.98.6 61.187.98.6 湖南省株洲市 电信DNS服务器
67.138.116.2 67.138.116.2 美国 俄勒冈州波特兰市Integra电信股份有限公司DNS服务器
76.10.67.2 76.10.67.2 美国 北达科他州卡斯县法戈市IdeaOne电信公司DNS服务器
76.14.0.8 76.14.0.9 美国 北达科他州卡斯县法戈市IdeaOne电信公司DNS服务器
76.14.96.13 76.14.96.14 美国 北达科他州卡斯县法戈市IdeaOne电信公司DNS服务器
76.14.192.8 76.14.192.9 美国 北达科他州卡斯县法戈市IdeaOne电信公司DNS服务器
106.59.255.234 106.59.255.239 云南省昆明市 电信DNS服务器
106.59.255.241 106.59.255.242 云南省昆明市 电信DNS服务器
112.100.100.100 112.100.100.100 黑龙江省 电信DNS
113.111.211.22 113.111.211.22 广东省广州市 电信DNS服务器
116.228.111.18 116.228.111.18 上海市 电信DNS服务器
116.228.111.118 116.228.111.118 上海市 电信DNS服务器
118.118.118.1 118.118.118.1 四川省雅安市 电信DNS服务器
118.123.202.215 118.123.202.218 四川省成都市 阿里巴巴(中国)有限公司阿里公共DNS电信节点
119.84.104.215 119.84.104.218 重庆市 阿里巴巴(中国)有限公司阿里公共DNS电信节点
124.207.160.106 124.207.160.106 北京市 电信通DNS服务器
124.207.160.110 124.207.160.110 北京市 电信通DNS服务器
143.90.130.11 143.90.130.11日本 软银电信公司DNS服务器
143.90.130.166 143.90.130.166 日本 软银电信公司DNS服务器
165.21.83.88 165.21.83.88 新加坡 新加坡电信数字媒体私人有限公司DNS服务器
165.21.83.100 165.21.83.100 新加坡 新加坡电信数字媒体私人有限公司DNS服务器
165.21.100.88 165.21.100.88 新加坡 新加坡电信数字媒体私人有限公司DNS服务器
168.126.63.1 168.126.63.2 韩国 KT电信DNS服务器
180.168.255.18 180.168.255.18 上海市 电信DNS服务器
202.96.96.68 202.96.96.68 浙江省杭州市 电信DNS服务器
202.96.103.36 202.96.103.36 浙江省 电信DNS服务器
202.96.104.15 202.96.104.16 浙江省宁波市 电信DNS服务器
202.96.104.26 202.96.104.26 浙江省宁波市 电信DNS服务器
202.96.107.27 202.96.107.29 浙江省绍兴市 电信DNS服务器
202.96.128.68 202.96.128.68 广东省广州市 电信DNS服务器
202.96.128.86 202.96.128.86 广东省广州市 电信DNS服务器
202.96.128.166 202.96.128.166 广东省广州市 电信DNS服务器
202.96.134.33 202.96.134.33 广东省深圳市 电信DNS服务器
202.96.134.133 202.96.134.133 广东省深圳市 电信DNS服务器
202.96.144.47 202.96.144.47 广东省汕头市 电信DNS服务器
202.96.154.15 202.96.154.15 广东省深圳市 电信DNS服务器
202.96.209.5 202.96.209.6 上海市 电信DNS服务器
202.96.209.133 202.96.209.133 上海市 电信DNS服务器
202.98.96.68 202.98.96.68 四川省成都市 电信DNS服务器
202.98.192.67 202.98.192.67 贵州省 电信DNS服务器
202.98.198.167 202.98.198.167 贵州省 电信DNS服务器
202.98.224.68 202.98.224.68 西藏拉萨市 电信DNS服务器
202.100.96.68 202.100.96.68 宁夏银川市 电信DNS服务器
202.100.192.68 202.100.192.68 海南省 电信DNS服务器
202.100.199.8 202.100.199.8 海南省三亚市 电信DNS服务器
202.101.6.2 202.101.6.2 上海市 电信DNS服务器
202.101.98.55 202.101.98.55 福建省福州市 电信DNS服务器
202.101.107.85 202.101.107.85 福建省泉州市 电信DNS服务器
202.101.172.35 202.101.172.35 浙江省杭州市 电信DNS服务器
202.101.172.47 202.101.172.47 浙江省杭州市 电信DNS服务器
202.101.224.68 202.101.224.71 江西省 电信DNS服务器
202.101.226.68 202.101.226.69 江西省九江市 电信DNS服务器
202.102.3.141 202.102.3.141 江苏省常州市 电信DNS服务器
202.102.3.144 202.102.3.144 江苏省常州市 电信DNS服务器
202.102.7.90 202.102.7.90 江苏省扬州市 电信DNS服务器
202.102.8.141 202.102.8.141 江苏省南通市 电信DNS服务器
202.102.199.68 202.102.199.68 安徽省芜湖市 电信DNS服务器
202.102.200.101 202.102.200.101 安徽省蚌埠市 电信DNS服务器
202.102.213.68 202.102.213.68 安徽省 电信DNS服务器
202.103.0.68 202.103.0.68 湖北省武汉市 电信DNS服务器
202.103.0.117 202.103.0.117 湖北省武汉市 电信DNS服务器
202.103.24.68 202.103.24.68 湖北省武汉市 电信DNS服务器
202.103.44.150 202.103.44.150 湖北省武汉市 电信DNS服务器
202.103.176.22 202.103.176.22 广东省茂名市 电信DNS服务器
202.103.224.68 202.103.224.68 广西南宁市 电信DNS服务器
202.103.225.68 202.103.225.68 广西柳州市 电信DNS服务器
210.200.211.193 210.200.211.193 台湾省 亚太电信股份有限公司DNS服务器
210.200.211.225 210.200.211.225 台湾省 亚太电信股份有限公司DNS服务器
211.147.6.3 211.147.6.4 北京市 电信通DNS服务器
211.167.242.34 211.167.242.34 北京市 电信通DNS服务器
216.8.196.88 216.8.196.89 美国 印第安纳州里普利县亚当斯地区桑曼镇Enhanced电信集团公司DNS服务器
216.8.209.88 216.8.209.88 美国 印第安纳州里普利县亚当斯地区桑曼镇Enhanced电信集团公司DNS服务器
216.8.228.88 216.8.228.88 美国 印第安纳州里普利县亚当斯地区桑曼镇Enhanced电信集团公司DNS服务器
218.2.2.2 218.2.2.2 江苏省淮安市 电信DNS服务器
218.2.135.1 218.2.135.1 江苏省南京市 电信DNS服务器
218.4.4.4 218.4.4.4 江苏省苏州市 电信DNS服务器
218.6.200.139 218.6.200.139 四川省成都市 电信DNS服务器
218.30.19.50 218.30.19.50 陕西省西安市 电信DNS服务器
218.76.192.100 218.76.192.101 湖南省邵阳市 电信DNS服务器
218.85.152.99 218.85.152.99 福建省福州市 电信DNS服务器
218.85.157.99 218.85.157.99 福建省福州市 电信DNS服务器
218.89.0.124 218.89.0.124 四川省乐山市 电信DNS服务器
219.141.136.10 219.141.136.10 北京市 电信DNS服务器
219.141.140.10 219.141.140.10 北京市 电信DNS服务器
219.141.148.37 219.141.148.37 北京市 电信DNS服务器
219.141.148.39 219.141.148.39 北京市 电信DNS服务器
219.146.0.130 219.146.0.130 山东省济南市 电信DNS服务器
219.146.1.66 219.146.1.66 山东省济南市 电信DNS服务器
219.147.198.230 219.147.198.230 黑龙江省齐齐哈尔市 电信DNS服务器
219.148.204.66 219.148.204.66 辽宁省沈阳市 电信DNS服务器
219.149.6.99 219.149.6.99 辽宁省大连市 电信DNS服务器
219.149.194.55 219.149.194.56 吉林省长春市 电信DNS服务器
219.150.32.132 219.150.32.132 天津市 电信DNS服务器
219.239.26.42 219.239.26.42 北京市 电信通DNS服务器
220.168.208.3 220.168.208.3 湖南省常德市 电信DNS服务器
220.168.208.6 220.168.208.6 湖南省常德市 电信DNS服务器
220.170.64.68 220.170.64.68 湖南省衡阳市 电信DNS服务器
220.181.70.210 220.181.70.210 北京市 电信互联网数据中心公众DNS服务器
220.187.24.2 220.187.24.2 浙江省舟山市 电信DNS服务器
220.187.24.6 220.187.24.6 浙江省舟山市 电信DNS服务器
221.228.255.1 221.228.255.1 江苏省无锡市 电信DNS服务器
221.232.129.30 221.232.129.30 湖北省武汉市 电信DNS服务器
222.75.152.129 222.75.152.129 宁夏银川市 电信DNS服务器
222.85.85.85 222.85.85.85 河南省 电信DNS服务器
222.88.88.88 222.88.88.88 河南省洛阳市 电信DNS服务器
222.172.200.68 222.172.200.68 云南省 电信DNS服务器
222.221.0.9 222.221.0.12 云南省昆明市 电信DNS服务器
222.221.5.240 222.221.5.241 云南省昆明市 云南电信公众信息产业有限公司DNS服务器
222.222.222.222 222.222.222.222 河北省石家庄市 电信DNS
222.243.129.81 222.243.129.81 湖南省 电信DNS服务器
222.246.129.80 222.246.129.81 湖南省 电信DNS服务器

全国联通DNS列表

58.22.96.66 58.22.96.66 福建省 联通DNS服务器
58.240.57.33 58.240.57.33 江苏省南京市 联通DNS服务器
58.241.208.46 58.241.208.46 江苏省盐城市 联通DNS服务器
58.242.2.2 58.242.2.2 安徽省合肥市 联通DNS服务器
60.12.166.166 60.12.166.166 浙江省金华市 联通DNS服务器
61.135.164.13 61.135.164.18 北京市 联通DNS服务器
113.207.20.15 113.207.20.18 重庆市 阿里巴巴(中国)有限公司公共DNS服务器联通节点
119.6.6.6 119.6.6.6 四川省成都市 联通DNS服务器
123.125.81.6 123.125.81.6 北京市 上海聚流软件科技有限公司公共DNS服务器联通节点
124.161.97.234 124.161.97.234 四川省 联通DNS服务器
124.161.97.238 124.161.97.238 四川省 联通DNS服务器
124.161.97.242 124.161.97.242 四川省 联通DNS服务器
140.207.198.6 140.207.198.6 上海市 上海聚流软件科技有限公司公共DNS服务器联通节点
202.96.64.68 202.96.64.68 辽宁省沈阳市 联通DNS服务器
202.96.69.38 202.96.69.38 辽宁省大连市 联通DNS服务器
202.96.75.68 202.96.75.68 辽宁省沈阳市 联通DNS服务器
202.96.86.18 202.96.86.18 辽宁省抚顺市 联通DNS服务器
202.97.224.68 202.97.224.69 黑龙江省 联通DNS服务器
202.98.0.68 202.98.0.68 吉林省长春市 联通DNS服务器
202.98.1.11 202.98.1.11 吉林省长春市 联通DNS服务器
202.98.5.68 202.98.5.68 吉林省长春市 联通DNS服务器
202.99.96.68 202.99.96.68 天津市 联通DNS
202.99.104.68 202.99.104.68 天津市 联通DNS
202.99.160.68 202.99.160.68 河北省 联通DNS服务器
202.99.166.4 202.99.166.4 河北省 联通DNS服务器
202.99.168.8 202.99.168.8 河北省保定市 联通DNS服务器
202.99.192.66 202.99.192.66 山西省太原市 联通DNS服务器
202.99.192.68 202.99.192.68 山西省太原市 联通DNS服务器
202.99.224.8 202.99.224.8 内蒙古呼和浩特市 联通DNS服务器(netcool)
202.99.224.67 202.99.224.67 内蒙古呼和浩特市 联通DNS服务器(cns)
202.99.224.68 202.99.224.68 内蒙古呼和浩特市 联通DNS服务器(nmdns)
202.102.134.68 202.102.134.70 山东省青岛市 联通DNS服务器
202.102.152.3 202.102.152.3 山东省济南市 联通DNS服务器
202.102.154.3 202.102.154.3 山东省济南市 联通DNS服务器
202.102.224.68 202.102.224.68 河南省 联通DNS服务器
202.102.227.68 202.102.227.68 河南联通xDSL DNS
202.106.0.20 202.106.0.20 北京市 联通DNS服务器
202.106.46.151 202.106.46.151 北京市 联通DNS服务器
202.106.196.233 202.106.196.234 北京市 联通DNS服务器
210.21.196.6 210.21.196.6 广东省深圳市 联通DNS服务器
210.22.70.3 210.22.70.3 上海市 联通DNS服务器
211.90.72.65 211.90.72.65 内蒙古呼和浩特市 联通DNS服务器
211.90.80.65 211.90.80.65 山西省太原市 联通DNS服务器
211.91.88.129 211.91.88.129 安徽省合肥市 联通DNS服务器
211.92.136.81 211.92.136.81 贵州省贵阳市 联通DNS服务器
211.92.144.161 211.92.144.161 云南省昆明市 联通DNS服务器
211.93.0.81 211.93.0.81 宁夏银川市 联通DNS服务器
211.93.24.129 211.93.24.129 黑龙江省哈尔滨市 联通DNS服务器
211.93.64.129 211.93.64.129 吉林省 联通DNS服务器(全省通用)
211.95.1.97 211.95.1.97 上海市 联通DNS服务器
211.95.72.1 211.95.72.1 上海市 联通DNS服务器
211.95.193.97 211.95.193.97 广东省广州市 联通DNS服务器
211.97.64.129 211.97.64.130 广西南宁市 联通DNS服务器
211.97.96.65 211.97.96.65 海南省海口市 联通DNS服务器
218.24.249.2 218.24.249.2 辽宁省盘锦市 联通DNS服务器
218.24.249.18 218.24.249.18 辽宁省盘锦市 联通DNS服务器
218.29.4.227 218.29.4.227 河南省南阳市 联通DNS服务器
218.29.4.249 218.29.4.249 河南省南阳市 联通DNS服务器
218.29.5.148 218.29.5.148 河南省南阳市 联通DNS服务器
218.29.7.233 218.29.7.233 河南省南阳市 联通DNS服务器
218.29.12.166 218.29.12.166 河南省南阳市 联通DNS服务器
218.29.39.19 218.29.39.19 河南省南阳市 联通DNS服务器
218.29.42.233 218.29.42.233 河南省南阳市 联通DNS服务器
218.29.72.22 218.29.72.22 河南省郑州市 联通DNS服务器
218.29.90.149 218.29.90.149 河南省郑州市 联通DNS服务器
218.29.106.250 218.29.106.250 河南省郑州市 联通DNS服务器
218.29.117.126 218.29.117.126 河南省郑州市 联通DNS服务器
218.29.122.70 218.29.122.70 河南省郑州市 联通DNS服务器
218.29.156.138 218.29.156.138 河南省三门峡市 联通DNS服务器
218.29.172.149 218.29.172.149 河南省濮阳市 联通DNS服务器
218.29.174.166 218.29.174.166 河南省濮阳市 联通DNS服务器
218.29.188.210 218.29.188.210 河南省郑州市 联通DNS服务器
218.29.188.243 218.29.188.243 河南省郑州市 联通DNS服务器
218.29.193.118 218.29.193.118 河南省郑州市 联通DNS服务器
218.29.203.18 218.29.203.18 河南省郑州市 联通DNS服务器
218.29.209.106 218.29.209.106 河南省郑州市 联通DNS服务器
218.29.222.108 218.29.222.108 河南省郑州市新密市 联通DNS服务器
218.29.223.150 218.29.223.150 河南省郑州市新密市 联通DNS服务器
218.29.228.70 218.29.228.70 河南省郑州市巩义市 联通DNS服务器
218.29.236.14 218.29.236.14 河南省郑州市 联通DNS服务器
218.29.237.82 218.29.237.82 河南省郑州市 联通DNS服务器
218.29.254.154 218.29.254.154 河南省漯河市 联通DNS服务器
218.104.32.106 218.104.32.106 江苏省苏州市 联通DNS服务器
218.104.78.2 218.104.78.2 安徽省合肥市 联通DNS服务器
218.104.111.114 218.104.111.114 湖北省武汉市 联通DNS服务器
218.104.111.122 218.104.111.122 湖北省武汉市 联通DNS服务器
218.104.128.106 218.104.128.106 福建省 联通DNS服务器
220.248.192.12 220.248.192.13 江西省南昌市 联通DNS服务器
221.3.131.11 221.3.131.12 云南省 联通DNS服务器
221.4.66.66 221.4.66.66 广东省广州市 联通DNS服务器
221.5.88.88 221.5.88.88 广东省肇庆市 联通DNS服务器
221.5.203.86 221.5.203.86 重庆市 联通DNS服务器
221.5.203.90 221.5.203.90 重庆市 联通DNS服务器
221.5.203.98 221.5.203.99 重庆市 联通DNS服务器
221.6.4.66 221.6.4.67 江苏省南京市 联通DNS服务器
221.7.1.20 221.7.1.21 新疆 联通DNS服务器
221.7.34.10 221.7.34.10 甘肃省兰州市 联通DNS服务器
221.7.92.86 221.7.92.86 重庆市 联通DNS服务器
221.7.92.98 221.7.92.98 重庆市 联通DNS服务器
221.7.128.68 221.7.128.68 广西南宁市 联通DNS服务器
221.7.136.68 221.7.136.68 广西柳州市 联通DNS服务器
221.11.132.2 221.11.132.2 海南省海口市 联通DNS服务器
221.12.1.226 221.12.1.228 浙江省杭州市 联通DNS服务器
221.12.33.227 221.12.33.228 浙江省宁波市 联通DNS服务器
221.12.65.227 221.12.65.228 浙江省温州市 联通DNS服务器
发表在 article | 标签为 , | 电信/联通/全国DNS列表/PUBLIC DNS已关闭评论

常用正则表达式

 

表达式全集

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
. 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。
(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern) 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?<=pattern) 反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern) 反向否定预查,与正向否定预查类拟,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d 匹配一个数字字符。等价于[0-9]。
\D 匹配一个非数字字符。等价于[^0-9]。
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09和\cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.
\num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
\nml 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

 

常用正则表达式

用户名 /^[a-z0-9_-]{3,16}$/
密码 /^[a-z0-9_-]{6,18}$/
十六进制值 /^#?([a-f0-9]{6}|[a-f0-9]{3})$/
电子邮箱 /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/
URL /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
IP 地址 /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML 标签 /^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/
删除代码\\注释 (?<!http:|\S)//.*$
Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/

 

正则表达式是一种通用的标准,大部分计算机语言都支持正则表达式,包括as3,这里转摘出了一些常用的正则表达式语句,大家用到的时候就不用自己写了

^\d+$  //匹配非负整数(正整数 + 0)
^[0-9]*[1-9][0-9]*$  //匹配正整数
^((-\d+)|(0+))$  //匹配非正整数(负整数 + 0)
^-[0-9]*[1-9][0-9]*$  //匹配负整数
^-?\d+$    //匹配整数
^\d+(\.\d+)?$  //匹配非负浮点数(正浮点数 + 0)
^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$  //匹配正浮点数
^((-\d+(\.\d+)?)|(0+(\.0+)?))$  //匹配非正浮点数(负浮点数 + 0)
^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$  //匹配负浮点数
^(-?\d+)(\.\d+)?$  //匹配浮点数
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$    //匹配email地址
^[a-zA-z]+://匹配(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$  //匹配url

匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空行的正则表达式:\n[\s| ]*\r
匹配HTML标记的正则表达式:/<(.*)>.*<\/>|<(.*) \/>/
匹配首尾空格的正则表达式:(^\s*)|(\s*$)
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址URL的正则表达式:^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?
匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$

 

 

发表在 article | 标签为 | 92条评论

windows下memcached的安装

Memcached是什么:
Memcached是高性能的,分布式的内存对象缓存系统 ,用于在动态应用中减少数据

负载 ,提升访问速度。
Memcached由Danga Interactive开发,用于提升LiveJournal.com访问速度的。LJ

每秒动态页面访问量几千次,用户700万。Memcached将数据库 负载大幅度降低,

更好的分配资源,更快速访问。
首先我在windows下实现它,过后再在linux试试.
下载memcached-win32 和php_memcache.dll(要和php的版本对应上)
1.memcahced下载后,压缩之前发现不到100K,压缩后也不到200K,这东西居然有这

么神奇,放到C盘,进入目录里面有一个memcached.exe,双击就启动了,让窗口开着,

或者在cmd里面c:\memcached\memcached.exe -d start 都可以启动
2.修改php.ini的配制文件
加入extension=php_memcache.dll 这一行代码,位置无所谓
3.php_memcache.dll放到php的安装文件中,一般在php源码的ext目录下
4.重启apache后,查看一下phpinfo(写一个phpinfo()函数就可以看到),如果有

memcache,那么就说明安装成功
开始测试一下代码
$mem = new Memcache;
$mem->connect(”127.0.0.1″, 11211);
$mem->set(’key’, ‘This is a memcached test!’, 0, 60);
$val = $mem->get(’key’);
echo $val;
如果输出This is a memcached test!刚表明安装成功

--------------------------------------------------------------------------------
也在本地做了一下测试,用的是windows系统
1.下载Memcache for win32

下载地址: http://jehiah.cz/projects/memcached-win32/
选择memcached 1.2.1 for Win32 binaries (Dec 23, 2006) 是exe的程序

2.下载php_memcache.dll

下载地址: http://pecl4win.php.net/ext.php/php_memcache.dll
选择和Php版本对应的,我php版本是5.2.6的,里边没有,索性down了个5.2.1的也能用

打开php.ini文件,添加扩展extension=php_memcache.dll(没有分号)
重启apache
phpinfo看一下,现在应该有memcached的了

memcache主要应用方法:
(1) Memcache::getVersion 返回memcache的版本信息.

(2) Memcache::connect 创建一个memcache连接对象.

(3) Memcache::pconnect 创建一个memcacher持久连接对象.

(4) Memcache::close 关闭一个Memcache对象.

(5) Memcache::set 用来添加一个值.
有四个参数,第一个参数是key,第二个参数是value,第三个参数可选,表示是否压缩保存,第四个参数可选,用来设

置一个过期自动销毁的时间.

(6) Memcache::add 作用和Memcache::set方法类似.
两个方法的区别是如果Memcache::add方法的返回值为false,表示这个key已经存在,而Memcache::set方法则会直

接覆写.

(7) Memcache::get 用来获取一个值.
只有一个参数(key,在Memcache::set时设置)

(8) Memcache::replace 对一个已有的key进行覆写操作.
有四个参数,与 Memcache::set 相同.

(9) Memcache::increment 对保存的某个key中的值进行加法操作.

(10) Memcache::decremen 对保存的某个key中的值进行减法操作.

(11) Memcache::setCompressThreshold 对大于某一大小的数据进行压缩。

(12) Memcache::delete 删除一个key
有两个参数,第一个是key名称.第二个是删除延迟时间

(13) Memcache::flush 清除所有缓存的数据,但是不会削去使用的内存空间.

(14) Memcache::addServer 添加一个可供使用的服务器地址.

(15) Memcache::setServerParams 在运行时修改服务器的参数.
写个php程序测试一下:

复制PHP 内容到剪贴板

PHP代码:


<?php
    
/*创建memcached对象*/
    
$mem  = new  Memcache ();
    
/*创建一个链接,memcache默认端口是11211*/
    
$mem -> connect ( '127.0.0.1' , 11211 );
    
/*查询数据*/
    
$sql  "select `username` from `hao_users` where 1=1 limit 5000" ;
    
/*缓存键*/
    
$key  md5 ( $sql );
    if(!(
$mem -> get ( $key )))
    {
        
$link  mysql _connect ( "219.153.41.215" , 'root' , '**' );
        
mysql_select_db ( 'oldhaocpc' );
        
$res  mysql_query ( $sql );
        while(
$row  mysql_fetch_array ( $res ))
        {
            
$arrdata [] =  $row ;
        }
        
$mem -> set ( $key , $arrdata );
    }
    
$data  $mem -> get ( $key )? $mem -> get ( $key ): $arrdata ;
    
/*输出测试*/
    
echo  '<pre>' ;
    
print_r ( $data );
    
/*关闭memcached连接*/
    
$mem -> close ();
?>

 

为了做测试,连接的是远程数据库 。看到的效果比较明显。

 

---------------------------------------------------------------------

要想在windows中使用memcached,必须先下载memcached for win32安装。

 

下载Windows的Server端

下载地址:http://code.jellycan.com/memcached/

安装Memcache Server(也可以不安装直接启动)

1. 下载memcached的windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在CMD下输入 "c:\memcached\memcached.exe -d install" 安装.
3. 再输入:"c:\memcached\memcached.exe -d start" 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。

如果下载的是二进制的版本,直接运行就可以了,可以加上参数来加以设置。

常用设置:
-p <num>          监听的端口
-l <ip_addr>      连接的IP地址, 默认是本机
-d start          启动memcached服务
-d restart        重起memcached服务
-d stop|shutdown  关闭正在运行的memcached服务
-d install        安装memcached服务
-d uninstall      卸载memcached服务
-u <username>     以<username>的身份运行 (仅在以root运行的时候有效)
-m <num>          最大内存使用,单位MB。默认64MB
-M                内存耗尽时返回错误,而不是删除项
-c <num>          最大同时连接数,默认是1024
-f <factor>       块大小增长因子,默认是1.25
-n <bytes>        最小分配空间,key+value+flags默认是48
-h                显示帮助

 

启动该服务后,memcached服务默认占用的端口是11211,占用的最大内存默认是64M。

  在修改这2个配置选项就碰到了一些问题,网上搜索了很多资料,都说使用下面的命令启动服务就可以:

  c:memcachedmemcached.exe -p 12345 -m 1024 -d start  ,  -p 表示要修改的端口, -m表示占用的最大内存(单位为M)。

  但是无论怎么调用这个命令,发现端口一直还是11211。

  打开windows服务控制面板一看,发现memcached.exe 默认安装的服务器启动参数中根本没写-p -m的参数,只有1个 -d runservice参数。

  所以不管用什么命令启动服务都是没用的,见下图:

点击查看原图

  于是就想到直接修改windows服务的启动参数,操作如下,打开注册表,找到:

  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server

  其中的ImagePath项的值为:"c:memcachedmemcached.exe" -d runservice

  改成:"c:memcachedmemcached.exe" -p 12345 -m 128 -d runservice

  保存后重新启动memcached服务,然后在命令行中输入netstat -n -a  看看现在端口是不是改啦,^_^。

 

 

 

 

发表在 article | 标签为 | 29条评论

多服务器session共享之mysql共享

一、PHP SESSION 的工作原理

在解决问题之前,先来了解一下 PHP SESSION 的工作原理。在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用 session_start() 打开 SESSION,这样就会产生客户端的唯一标识 SESSION ID(此 ID 可通过函数 session_id() 获取/设置)。SESSION ID 可以通过两种方式保留在客户端,使得请求不同的页面时,PHP 程序可以获知客户端的 SESSION ID;一种是将 SESSION ID 自动加入到 GET 的 URL 中,或者 POST 的表单中,默认情况下,变量名为 PHPSESSID;另一种是通过 COOKIE,将 SESSION ID 保存在 COOKIE 中,默认情况下,这个 COOKIE 的名字为 PHPSESSID。这里我们主要以 COOKIE 方式进行说明,因为应用比较广泛。

那么 SESSION 的数据保存在哪里呢?当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。默认情况下,php.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,而 SESSION 文件保存的目录由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION 数据了。如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path=”N;/save_path”,N 为分级的级数,save_path 为开始目录。当写入 SESSION 数据的时候,PHP 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件。读取 SESSION 数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。

二、多服务器共享 SESSION 的主要障碍及解决办法

通过了解 SESSION 的工作原理,我们可以发现,在默认情况下,各个服务器会各自分别对同一个客户端产生 SESSION ID,如对于同一个用户浏览器,A 服务器产生的 SESSION ID 是 30de1e9de3192ba6ce2992d27a1b6a0a,而 B 服务器生成的则是 c72665af28a8b14c0fe11afe3b59b51b。另外,PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。如下图所示:

 

确定了问题所在之后,就可以着手进行解决了。想要共享 SESSION 数据,那就必须实现两个目标:一个是各个服务器对同一个客户端产生的 SESSION ID 必须相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的 COOKIE;另一个是 SESSION 数据的存储方式/位置必须保证各个服务器都能够访问到。简单地说就是多服务器共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。

第一个目标的实现其实很简单,只需要对 COOKIE 的域(domain)进行特殊地设置即可,默认情况下,COOKIE 的域是当前服务器的域名/IP 地址,而域不同的话,各个服务器所设置的 COOKIE 是不能相互访问的,如 www.aaa.com

的服务器是不能读写 www.bbb.com

服务器设置的 COOKIE 的。这里我们所说的同一网站的服务器有其特殊性,那就是他们同属于同一个一级域,如:aaa.infor96.com 和 www.infor96.com

都属于域 .infor96.com,那么我们就可以设置 COOKIE 的域为 .infor96.com,这样 aaa.infor96.com、www.infor96.com

等等都可以访问此 COOKIE。PHP 代码中的设置方法如下:

<?php
ini_set(’session.cookie_domain’, ‘.infor96.com’);
?>

这样各个服务器共享同一客户端 SESSION ID 的目的就达到了。

第二个目标的实现可以使用文件共享方式,如 NFS 方式,但设置、操作上有些复杂。我们可以参考先前所说的统一用户系统的方式,即使用数据库来保存 SESSION 数据,这样各个服务器就可以方便地访问同一个数据源,获取相同的 SESSION 数据了。

解决办法如下图所示:

三、代码实现

首先创建数据表,MySQL 的 SQL 语句如下:

   CREATE TABLE `sess` (
     `sesskey` varchar(32) NOT NULL default ”,
      `expiry` bigint(20) NOT NULL default ‘0′,
      `data` longtext NOT NULL,
      PRIMARY KEY  (`sesskey`),
      KEY `expiry` (`expiry`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

sesskey 为 SESSION ID,expiry 为 SESSION 过期时间,data 用于保存 SESSION 数据。

默认情况下 SESSION 数据是以文件方式保存,想要使用数据库方式保存,就必须重新定义 SESSION 各个操作的处理函数。PHP 提供了session_set_save_handle() 函数,可以用此函数自定义 SESSION 的处理过程,当然首先要先将 session.save_handler 改成 user,可在 PHP 中进行设置:
<?php
session_module_name(’user’);
?>

接下来着重讲一下 session_set_save_handle() 函数,此函数有六个参数:
session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )

各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,在这里我们使用 OO 的方式来实现这些操作,详细代码如下:
<?php
define(’MY_SESS_TIME’, 3600);   //SESSION 生存时长
//类定义
class My_Sess
{
    function init()
    {
        $domain = ‘.infor96.com’;
        //不使用 GET/POST 变量方式
        ini_set(’session.use_trans_sid’,    0);
        //设置垃圾回收最大生存时间
        ini_set(’session.gc_maxlifetime’,   MY_SESS_TIME);

        //使用 COOKIE 保存 SESSION ID 的方式
        ini_set(’session.use_cookies’,      1);
        ini_set(’session.cookie_path’,      ‘/’);
        //多主机共享保存 SESSION ID 的 COOKIE
        ini_set(’session.cookie_domain’,    $domain);

        //将 session.save_handler 设置为 user,而不是默认的 files
        session_module_name(’user’);
        //定义 SESSION 各项操作所对应的方法名:
        session_set_save_handler(
            array(’My_Sess’, ‘open’),   //对应于静态方法 My_Sess::open(),下同。
            array(’My_Sess’, ‘close’),
            array(’My_Sess’, ‘read’),
            array(’My_Sess’, ‘write’),
            array(’My_Sess’, ‘destroy’),
            array(’My_Sess’, ‘gc’)
        );
    }   //end function

    function open($save_path, $session_name) {
        return true;
    }   //end function

    function close() {
        global $MY_SESS_CONN;

        if ($MY_SESS_CONN) {    //关闭数据库连接
            $MY_SESS_CONN->Close();
        }
        return true;
    }   //end function

    function read($sesskey) {
        global $MY_SESS_CONN;

        $sql = ‘SELECT data FROM sess WHERE sesskey=’ . $MY_SESS_CONN->qstr($sesskey) . ‘ AND expiry>=’ . time();
        $rs =& $MY_SESS_CONN->Execute($sql);
        if ($rs) {
            if ($rs->EOF) {
                return “;
            } else {   
  //读取到对应于 SESSION ID 的 SESSION 数据
                $v = $rs->fields[0];
                $rs->Close();
  //返回的数据是类似name|s:5:”wujun”;这种格式,不需要处理,PHP会处理。
                return $v;
            }   //end if
        }   //end if
        return “;
    }   //end function

    function write($sesskey, $data) {
        global $MY_SESS_CONN;
       
        $qkey = $MY_SESS_CONN->qstr($sesskey);
        $expiry = time() + My_SESS_TIME;    //设置过期时间
       
        //写入 SESSION
        $arr = array(
            ’sesskey’ => $qkey,
            ‘expiry’  => $expiry,
            ‘data’    => $data);
        $MY_SESS_CONN->Replace(’sess’, $arr, ’sesskey’, $autoQuote = true);
        return true;
    }   //end function

    function destroy($sesskey) {
        global $MY_SESS_CONN;

        $sql = ‘DELETE FROM sess WHERE sesskey=’ . $MY_SESS_CONN->qstr($sesskey);
        $rs =& $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function

    function gc($maxlifetime = null) {
        global $MY_SESS_CONN;

        $sql = ‘DELETE FROM sess WHERE expiry<’ . time();
        $MY_SESS_CONN->Execute($sql);
        //由于经常性的对表 sess 做删除操作,容易产生碎片,
        //所以在垃圾回收中对该表进行优化操作。
        $sql = ‘OPTIMIZE TABLE sess’;
        $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function
}   ///:~

//使用 ADOdb 作为数据库抽象层。
require_once(’adodb/adodb.inc.php’);
//数据库配置项,可放入配置文件中(如:config.inc.php)。
$db_type = ‘mysql’;
$db_host = ‘192.168.212.1′;
$db_user = ’sess_user’;
$db_pass = ’sess_pass’;
$db_name = ’sess_db’;
//创建数据库连接,这是一个全局变量。
$GLOBALS['MY_SESS_CONN'] =& ADONewConnection($db_type);
$GLOBALS['MY_SESS_CONN']->Connect( $db_host, $db_user, $db_pass, $db_name);
//初始化 SESSION 设置,必须在 session_start() 之前运行!!
My_Sess::init();
?>

五、遗留问题

如果网站的访问量很大的话,SESSION 的读写会频繁地对数据库进行操作,这样效率就会明显降低。建议使用mysql的memory表,这样效率会高很多。

发表在 article | 标签为 , | 41条评论

sql server 语句执行时间

set statistics profile on
set statistics io on
set statistics time on
go
/*你要执行的语句*/
go
set statistics profile off
set statistics io off
set statistics time off

发表在 article | 标签为 , | sql server 语句执行时间已关闭评论

UUID

######### PHP ##############

/**
* Generates an UUID
*
* @author Anis uddin Ahmad <admin@ajaxray.com>
* @param string an optional prefix
* @return string the formatted uuid
*/
function uuid($prefix='')
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr($chars,0,8) . '-';
$uuid .= substr($chars,8,4) . '-';
$uuid .= substr($chars,12,4) . '-';
$uuid .= substr($chars,16,4) . '-';
$uuid .= substr($chars,20,12);
return $prefix . $uuid;
}

Example of using the function
-
//Using without prefix.

echo uuid();
//Returns like ‘1225c695-cfb8-4ebb-aaaa-80da344e8352′

//Using with prefix
echo uuid(‘urn:uuid:’);
//Returns like ‘urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344e8352′

 

######### Javascript ##############



function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}

..

function guid() {
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}

..

function uuid(len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length;

if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
} else {
// rfc4122, version 4 form
var r;

// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';

// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}

return uuid.join('');
}

 

// 8 character ID (base=2)
uuid(8, 2) // "01001010"
// 8 character ID (base=10)
uuid(8, 10) // "47473046"
// 8 character ID (base=16)
uuid(8, 16) // "098F4D35"

 

..

 

function uuid() {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";

var uuid = s.join("");
return uuid;
}

 

 

..

 

 

 

 

发表在 article | 标签为 | UUID已关闭评论

在网页中加高亮显示源代码的工具

刚刚发现一个老外用Javascrīpt编写的好东西:dp.SyntaxHighlighter。它可以在网页中对各种程序源代码
语法进行加亮显示。支持当前流行的各种编程语言:C#、CSS
、C++、Delphi、Java
、Javascrīpt、PHP
、Python、Ruby、SQL、 Visual Basic、XML
/ HTML

  下载地址:http://www.dreamprojections.com/syntaxhighlighter/

  演示地址:http://www.dreamprojections.com/syntaxhighlighter/Tests/PHP.html

下载
1

下载
2

  使用方法:
  1、假设网页文件test.htm存放在一个目录,则将dp.SyntaxHighlighter解压缩到该目录下的子目录,假设为images
  2、在网页的<head></head>之间插入以下代码:

 

 
  1. <link type=
    "text/css"
     rel=
    "stylesheet"
     href=
    "images/Styles/SyntaxHighlighter.css"
    ></link>  


      3、在网页要显示程序源代码的地方插入以下代码(其中的class="js"表示以js语法显示源代码,其他可设定的class值分别为c#、css、c、delphi、java、js、php、python、ruby、sql、vb、xml):
  1. <textarea name=
    "code"
     
    class
    =
    "js"
     rows=
    "15"
     cols=
    "100"
    >  
  2. 程序源代码放在这儿  
  3. </textarea>  



  4、在网页尾部的</body>之前插入以下代码:

  1. <scrīpt 
    class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shCore.js"
    ></scrīpt>  
  2. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushCSharp.js"
    ></scrīpt>  
  3. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushPhp.js"
    ></scrīpt>  
  4. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushJscrīpt.js"
    ></scrīpt>  
  5. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushJava.js"
    ></scrīpt>  
  6. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushVb.js"
    ></scrīpt>  
  7. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushSql.js"
    ></scrīpt>  
  8. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushXml.js"
    ></scrīpt>  
  9. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushDelphi.js"
    ></scrīpt>  
  10. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushPython.js"
    ></scrīpt>  
  11. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushRuby.js"
    ></scrīpt>  
  12. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushCss.js"
    ></scrīpt>  
  13. <scrīpt class
    =
    "javascrīpt"
     src=
    "images/scrīpts/shBrushCpp.js"
    ></scrīpt>  
  14. <scrīpt class
    =
    "javascrīpt"
    >  
  15. dp.SyntaxHighlighter.HighlightAll('code'
    );  
  16. </scrīpt> 
发表在 article | 标签为 | 在网页中加高亮显示源代码的工具已关闭评论

Apache虚拟主机配置

Apache虚拟主机配置

虚拟主机的几种实现方法
虚拟主机有许多方法来实现,比如多IP,多域名,多端口等。这里主要将多域名和多端口的实现步骤。
第一种:多端口的实现

#监听的端口号,如果想一个IP地址多端口控制访问的话必须填写端口
Listen 

81

Listen 

82

#端口81的虚拟主机

<
VirtualHost 
*
:
81
>

    DocumentRoot 

"
Webroot/port01
"


</
VirtualHost
>

#端口82的虚拟主机

<
VirtualHost 
*
:
82
>

    DocumentRoot 

"
Webroot/port02
"


</
VirtualHost
>

第二种:多域名的实现

NameVirtualHost 
*
:
80

#域名www.domain01.com的虚拟主机

<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain01"


    ServerName www.domain01.com

</
VirtualHost
>


#域名www.domain02.com的虚拟主机

<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain02"


    ServerName www.domain02.com

</
VirtualHost
>

 

如何使虚拟主机生效
第一种:使扩展文件httpd-vhosts.conf生效:
1. 打开 apache/conf/httpd.conf
文件
2. 找到 # Include conf/extra/httpd-vhosts.conf

3. 去掉前面的注释符#号
4. 打开 apache/conf/extra/httpd-vhosts.conf

5. 添加以上的多端口或多域名代码(这里以多域名为例):

NameVirtualHost 
*
:
80


<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain01"


    ServerName www.domain01.com

</
VirtualHost
>


<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain02"


    ServerName www.domain02.com

</
VirtualHost
>

 

第二种:另类的办法
1. 在conf
目录中建立vhosts
目录,并建立两个文件,分别为host1.com
host2.com

2. 在 apache/conf/httpd.conf
适当的位置添加下面两行代码
NameVirtualHost *:80
Include conf/vhosts
3. 修改 host1.com
文件

<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain01"


    ServerName www.domain01.com

</
VirtualHost
>

4. 修改 host2.com
文件

<
VirtualHost 
*
:
80
>

    DocumentRoot "Webroot/domain02"


    ServerName www.domain02.com

</
VirtualHost
>

 

关于虚拟主机的扩展属性
 

<
VirtualHost 
*
:
80
>

    ServerAdmin webmaster@admin.com        

//
管理员邮箱,当出现域名相关的错误时则会发送到此邮箱


    DocumentRoot 
"
/Webroot/host
"
              
//
网站文档所在位置,可以是绝对位置


    ServerName www.host.com                   
//
绑定域名


    ServerAlias www.host.com                    
//
CNAME别名


    ErrorLog logs
/
host.com
-
error_log            
//
错误日志


    CustomLog logs
/
host.com
-
access_log common 
//
访问日志



    #虚拟主机目录的访问权限
    

<
Directory 
"
/Webroot/host
"
>

        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    

</
Directory
>


</
VirtualHost
>

学习 Apache 的一些心得体会

Apache 将目录作为单元来进行存取控制,每个目录在/etc/httpd/conf/httpd.conf 中

  使用一个段落,首先的是/目录,这实际是设置缺省值:

  Options FollowSymLinks
  AllowOverride None

  每个段落都是由这样的两组尖括号构成的行夹起来的,其中最主要的句子是Options,AllowOverride,Allow/Deny,Order 等。

  Options这个子句用来说明一些主要的设置,目前可以使用的设置有Indexes,Includes,FollowSymLinks,ExecCGI,MultiView,当然还有两个最简单的选择就是None和All。

  None是禁止所有选择,而All 允许上面的所有Options。一般我们主要关心的是Indexes 和FollowSymLinks。Indexes 是设定是否允许在目录下面没有index.html 的时候显示目录,而FollowSymLinks 决定是否可以通过符号连接跨越DocumentRoot。例如,尽管/ftp 不在/home/httpd/html 下面,但是我们仍然可以使用符号连接建立一个/home/httpd/html/ftp使得可以直接输入http://mydomain.com/ftp
来访问这个目录。

  使用FollowSymLinks 的办法很简单,就是首先在合适的目录段落里面Options Follow SymLinks,(符号连接的上层就可以)然后建立一个别名:

  Alias /ftp/ “home/httpd/html/ftp/”

  后面的是你建立的到/ftp 的符号连接。注意这一行应该位于所有目录段落之外。

  AllowOverride

  AllowOverride 定义是否允许各个目录用目录中的.htaccess(后面解释)覆盖这里设定的Options。它的选择有Options,FileInfo,AuthConfig,Limit 或者它们的组合,当然还有None 和All。

  由于/是缺省设置,所以这里没有设置太多的内容,相反,我们应该在/之后独立设置各个目录的控制,例如:

  Options Indexes FollowSymLinks
  AllowOverride None
  Order allow,deny
  Allow from all

  出现了两个新的选项:Order 和Allow。

  Order

  它有两种用法,即Order allow,deny 或者Order deny,allow。简单地说,它用来设置是先执行deny 还是先执行allow,例如,Order deny,allow 意味着先看deny 行,再看allow 行,这样如果deny from all 再allow from 202.112.58.0/24 后来的allow子句就会超越deny 而对202.112.58.x 打开访问。

  Allow/Deny from

  这两个选项和Order 一起使用,Allow 允许某个地址来的连接请求,Deny 则禁止这个请求,例如在Order deny,allow 的情况下,Deny from all,Allow from 192.168.12.0/24 表示只有192.168.12.x 的用户可以访问这个目录。

  现在我们来看看下面的一个设定:

  UserDir public_html
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  Order allow,deny
  Allow from all
  Order deny,allow
  Deny from all

  这个有什么用处?UserDir 是一个特殊的选项,用来在用户的宿主目录下设置主页,比如,有一个名字叫wanghy 的用户,其宿主目录是/home/wanghy,而且UserDir 象我们刚才那样设定,那么,你可以在浏览器中输入http://www.mydomain.com/~wanghy
,它将对应的是宿主目录+UserDir,也就是/home/wanghy/public_html。当然,为了使这个功能生效,你得将这个目录设置为大家都可以读。(现在知道http://xxx.net/~yourname
是怎么回事了吧,P)

  下面的行就是对这个功能的限制,注意要使得某人的这个功能生效,必须有这个段落,这个段落里别的东西都是熟知的,唯一新的东西是Limit 段,它用来提供存取限制,例如对应的段落设置GET 和POST 权限,诸如此类。上面的段落表示所有人都可以通过www 进行GET 和POST,而任何人都不能PUT 和DELETE、MOVE 等等。

  Limit

  对某个路径进行存取限制。

  现在我们来看看下面的一个设定:

  UserDir public_html
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  Order allow,deny
  Allow from all
  Order deny,allow
  Deny from all

  这个有什么用处?UserDir 是一个特殊的选项,用来在用户的宿主目录下设置主页,比如,有一个名字叫wanghy 的用户,其宿主目录是/home/wanghy,而且UserDir 象我们刚才那样设定,那么,你可以在浏览器中输入http://www.mydomain.com/~wanghy
,它将对应的是宿主目录+UserDir,也就是/home/wanghy/public_html。当然,为了使这个功能生效,你得将这个目录设置为大家都可以读。(现在知道http://xxx.net/~yourname
是怎么回事了吧,P)

  下面的行就是对这个功能的限制,注意要使得某人的这个功能生效,必须有这个段落,这个段落里别的东西都是熟知的,唯一新的东西是Limit 段,它用来提供存取限制,例如对应的段落设置GET 和POST 权限,诸如此类。上面的段落表示所有人都可以通过www 进行GET 和POST,而任何人都不能PUT 和DELETE、MOVE 等等。

  Limit

  对某个路径进行存取限制。

  实际配置如下:

  mkdir /home/rd2/leon
  chmod 755 /home/rd2
  chmod 755 /home/rd2/leon
  cp index.html /home/rd2/leon

  然后就可以在浏览器中输入http://10.12.2.82/~rd2
,它将对应的是/宿主目录/UserDir(我们设置位leon),也就是显示/home/wanghy/leon下的index.html。

  <IfModule mod_userdir.c>
  #
  # UserDir is disabled by default since it can confirm the presence
  # of a username on the system (depending on home directory
  # permissions).
  #
  #UserDir disable 注释掉
  #
  # To enable requests to /~user/ to serve the user's public_html
  # directory, remove the "UserDir disable" line above, and uncomment
  # the following line instead:
  #
  UserDir leon 改为自己喜欢的
  # UserDir public_html 注视掉原句
  </IfModule>
  #
  # Control access to UserDir directories. The following is an example
  # for a site where these directories are restricted to read-only.
  #
  <Directory /home/*/leon> 改为自己喜欢的
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  <Limit GET POST OPTIONS>
  Order allow,deny
  Allow from all
  </Limit>
  <LimitExcept GET POST OPTIONS>
  Order deny,allow
  Deny from all
  </LimitExcept>
  </Directory>

  FollowSymLinks决定是否可以通过符号连接跨越DocumentRoot。例如,尽管/home不在/var/www/html下面,但是我们仍然可以使用符号连接也就是说可以直接输入http://mydomain.com/myhome
来访问这个目录。

  使用FollowSymLinks的办法很简单,就是目录段落里面Options Follow SymLinks,然后建立一个别名:

  Alias /myhome “/home”
  Alias /myhome "/home"(不能是/myhome/)
  <Directory "/home">
  Options Indexes FollowSymLinks MultiViews
  AllowOverride None
  Order allow,deny
  Allow from all
  </Directory>

  虚拟主机:

  NameVirtualHost 10.12.2.82
  <VirtualHost 10.12.2.84> 需要复制一个eth0:0 #访问时候用:10.12.2.84,不可用leon1.abit.cn???????
  DocumentRoot /home/leon
  ServerName leon1.abit.cn
  </VirtualHost>
  <VirtualHost 10.12.2.82>访问时候用:leon(leon1).abit.cn
  DocumentRoot /var/www/html
  ServerName leon.abit.cn
  </VirtualHost>
  <VirtualHost 10.12.2.82>
  DocumentRoot /home
  ServerName leon2.abit.cn
  </VirtualHost>

发表在 web server | 标签为 | Apache虚拟主机配置已关闭评论

squid纯内存缓存

看见网上不少介绍squid的使用经验,说可以用ramdisk/tmpfs内存文件系统来加速squid. 个人认为完全没有必要,直接简单配置一下,就可以让Squid直接充分利用大内存:
maximum_object_size 32768 KB
cache_mem 1512 MB # Cache使用的最大内存
maximum_object_size_in_memory 128 KB # Cache在memory中最大Object的大小
memory_pools_limit 150 MB # 小对象内存池的大小
cache_dir null /tmp # 使用null disk
一些需要注意的事项: squid在编译的时候,要支持nullfs. maximum_object_size_in_memory应该尽量大于最大的object的尺寸,但是也不要太大,否则会影响内存分配的效率.

考虑一下实际应用的情况: 平均页面对象都不是很大,对象个数也不是很多,同时又有充足的内存余量,内容跟新还算频繁,这个时候,1.5G和20G或者40G的cache的请求命中率其实相差非常细微,不过是99%和99.9%的区别,这个时候,完全有理由,抛下缓慢的disk cache,直接使用memory cache,这样不但能有效降低系统load,还能使squid自身更加轻快便捷.


 

Comments»

1.
Frank Liu - January 10, 2007

非常好

2.
slls - January 16, 2007

受教!
但不知cache_mem和memory_pools_limit的大小是何关系。请指教!
谢谢!

3.
scaner - January 20, 2007

我以前对memory_pool_limit理解也有错误, memory_pool_limit并不是小对象池的大小,相当于malloc的cache,squid并不直接对释放的对象调用free操作,而是等到这个大小超过到这个大小超过memory_pool_limit才会真正释放. 感觉比较合适的大小是cache_mem + memory_pool_limit < 实际内存量, memory_pool_limit在150M左右就差不多了.当然还有为系统别的程序留一点余量。比如说如果是2G内存我的cache_mem是 1648M,memory_pool_limit是120M

4.
charles
- March 10, 2007

不知道你有没有留意到,如果用 null 方式的存储,全部放内存后,SQUID 的 response time 会变成非常高。

在我的应用,是 2ms 升到 30ms,这有可能是因为 SQUID 主进程不单止要接受请求,还要去从存储(null 的方式是存在内存)里面查找相应的数据,再返回。

而用 aufs 或 diskd 方式,squid 可以马上响应下一个请求,而将查找的工作交给 diskd 进程去处理。

5.
scaner - March 13, 2007

真还没注意过这个现象。30ms这个好像有点夸张啊,我现在一个主squid的峰值请求处理数能到1200hits/s了。对象信息都是保存在内存中的,直接内存处理,再怎么也要比aufs/diskd再倒一次手要快很多吧,我的意思是说,有submit任务到aufs/diskd的功夫,内存查找早就搞定了。

6.
charles
- March 19, 2007

你可能架一个 MRTG 来查看一下就知道了。只要压力很大,response 的值就会非常高。

在我的应用中,也是将数据保存到内存里面的,使用 diskd 直接读写 /dev/shm 等。

7.
scaner - March 19, 2007

赫赫,你看得是那一个图阿?

client_http.requests = 1271.172566/sec
client_http.hits = 1209.615937/sec
client_http.all_median_svc_time = 0.000000 seconds
client_http.miss_median_svc_time = 0.000911 seconds
client_http.nm_median_svc_time = 0.000000 seconds
client_http.nh_median_svc_time = 0.001789 seconds
client_http.hit_median_svc_time = 0.000000 seconds

8.
charles
- March 31, 2007

你先确定一下,是不是用了 epoll ?

如果是用了 epoll,我觉得有这样的响应时间,我觉得正常。在不支持 epoll 的环境下,squid 的响应时间会慢,而且 CPU 占用较高。

另外,我现在在关注这个:http://varnish.projects.linpro.no

用squid就是因为epoll阿.没有epoll连接数一多CPU就跑上去了.varnish这个东西看着不错啊,不过看了上面一个评测的链接,lighttpd居然是吞吐量最强的,寒一个.还是祈求上天Light 1.5赶快release吧.

9.
scaner - April 3, 2007
发表在 article | 标签为 | squid纯内存缓存已关闭评论

mysql数据库受到破坏的修复

修复数据表

多数情况下,数据库被破坏只是指索引文件受到了破坏,真正的数据被破坏掉的情况非常少。大多数形式的数据库破坏的的修复相当简单。
和前面的校验一样,修复的方式也有三种。

下面讲的方法只对MyISAM格式的表有效。其他类型的损坏需要从备份中恢复。

1。REPAIR TABLE SQL statement(mysql服务必须处于运行状态)。
2。命令mysqlcheck(mysql服务可以处于运行状态)。
3。命令myisamchk(必须停掉mysql服务,或者所操作的表处于不活动状态)。

在修复表的时候,最好先作一下备份。所以你需要两倍于原始表大小的硬盘空间。请确保在进行修复前你的硬盘空间还没有用完。

1>用”repair table”方式修复
语法:repair table 表名 [选项]
选项如下:
QUICK 用在数据表还没被修改的情况下,速度最快
EXTENDED 试图去恢复每个数据行,会产生一些垃圾数据行,万般无奈的情况下用
USE_FRM 用在.MYI文件丢失或者头部受到破坏的情况下。利用.frm的定义来重建索引

多数情况下,简单得用”repair table tablename”不加选项就可以搞定问题。但是当.MYI文件丢失或者头部受到破坏时,这样的方式不管用,例如:
mysql> REPAIR TABLE fixtures;
+————————-+——–+———-+———————————————+
| Table | Op | Msg_type | Msg_text |
+————————-+——–+———-+———————————————+
| sports_results.fixtures | repair | error | Can’t find file: ‘fixtures.MYI’ (errno: 2) |
+————————-+——–+———-+———————————————+

修复失败的原因时索引文件丢失或者其头部遭到了破坏,为了利用相关定义文件来修复,需要用USE_FRM选项。例如:
mysql> REPAIR TABLE fixtures USE_FRM;
+————————-+——–+———-+————————————+
| Table | Op | Msg_type | Msg_text |
+————————-+——–+———-+————————————+
| sports_results.fixtures | repair | warning | Number of rows changed from 0 to 2 |
| sports_results.fixtures | repair | status | OK |
+————————-+——–+———-+————————————+

我们可以看到Msg_test表项的输出信息”ok”,表名已经成功修复受损表。

2>用mysql内建命令mysqlcheck来修复
当mysql服务在运行时,也可以用mysql内建命令mysqlcheck来修复。
语法:mysqlcheck -r 数据库名 表名 -uuser -ppass
%mysqlcheck -r sports_results fixtures -uuser -ppass
sports_results.fixtures OK

利用mysqlcheck可以一次性修复多个表。只要在数据库名后列出相应表名即可(用空格隔开)。或者数据库名后不加表名,将会修复数据库中的所有表,例如:

%mysqlcheck -r sports_results fixtures events -uuser -ppass
sports_results.fixtures OK
sports_results.events OK

%mysqlcheck -r sports_results -uuser -ppass
sports_results.fixtures OK
sports_results.events OK

3>用myisamchk修复
用这种方式时,mysql服务必须停掉,或者所操作的表处于不活动状态(选项skip-external-locking没被使用)。记着一定要在相关.MYI文件的路径下或者自己定义其路径。
语法:myisamchk [选项] [表名]
下面是其选项和描述
–backup, -B 在进行修复前作相关表得备份
–correct-checksum 纠正校验和
–data-file-length=#, -D # 重建表时,指定数据文件得最大长度
–extend-check, -e 试图去恢复每个数据行,会产生一些垃圾数据行,万般无奈的情况下用
–force, -f 当遇到文件名相同的.TMD文件时,将其覆盖掉。
keys-used=#, -k # 指定所用的keys可加快处理速度,每个二进制位代表一个key.第一个key为0
–recover, -r 最常用的选项,大多数破坏都可以通过它来修复。如果你的内存足够大,可以增大
参数sort_buffer_size的值来加快恢复的速度。但是遇到唯一键由于破坏而不唯一
的表时,这种方式不管用。
–safe-recover -o 最彻底的修复方式,但是比-r方式慢,一般在-r修复失败后才使用。这种方式读出所有的行,并以行为基础来重建索引。它的硬盘空间需求比-r方式稍微小一点,因为它没创建分类缓存。你可以增加key_buffer_size的值来加快修复的速度。
–sort-recover, -n mysql用它类分类索引,尽管结果是临时文件会非常大
–character-sets-dir=… 包含字符集设置的目录
–set-character-set=name 为索引定义一个新的字符集
–tmpdir=path, -t 如果你不想用环境变量TMPDIR的值的话,可以自定义临时文件的存放位置
–quick, -q 最快的修复方式,当数据文件没有被修改时用,当存在多键时,第二个-q将会修改 数据文件
–unpack, -u 解开被myisampack打包的文件

myisamchk应用的一个例子

% myisamchk -r fixtures
- recovering (with keycache) MyISAM-table ‘fixtures.MYI’
Data records: 0

 

------------------------------------------------------------------------------------------------------

假设有个myisam表:tbl,为了备份方便,直接把 frm 和 MYD 文件拷贝到其他目录。在还原时,就需要重新下创建索引,只需要执行以下命令:

mysql> REPAIR TABLE `tbl` USE_FRM;

即可根据 frm 和 MYD 文件,产生一个新的 MYI 索引文件。这在索引文件较大时备份还原比较有用。

---------------------------------------------------------------------------------------------------------

防止客户机的请求互相干扰或者服务器与维护程序相互干扰的方法主要有多种。如果你关闭数据库,就可以保证服务器和myisamchk和isamchk之间没有交互作用。但是停止服务器的运行并不是一个好注意,因为这样做会使得没有故障的数据库和表也不可用。本节主要讨论的过程,是避免服务器和myisamchk或isamchk之间的交互作用。实现这种功能的方法是对表进行锁定。

服务器由两种表的锁定方法:

1.内部锁定

内部锁定可以避免客户机的请求相互干扰——例如,避免客户机的SELECT查询被另一个客户机的UPDATE查询所干扰。也可以利用内部锁定机制防止服务器在利用myisamchk或isamchk检查或修复表时对表的访问。

语法:

锁定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},…]

解锁表:UNLOCK TABLES

LOCK TABLES为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。

如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READ或WRITE表,其他线程被阻止。

每个线程等待(没有超时)直到它获得它请求的所有锁。

WRITE锁通常比READ锁有更高的优先级,以确保更改尽快被处理。这意味着,如果一个线程获得READ锁,并且然后另外一个线程请求一个WRITE锁, 随后的READ锁请求将等待直到WRITE线程得到了锁并且释放了它。

显然对于检查,你只需要获得读锁。再者钟情跨下,只能读取表,但不能修改它,因此他也允许其它客户机读取表。对于修复,你必须获得些所以防止任何客户机在你对表进行操作时修改它。

2.外部锁定

服务器还可以使用外部锁定(文件级锁)来防止其它程序在服务器使用表时修改文件。通常,在表的检查操作中服务器将外部锁定与myisamchk或isamchk作合使用。但是,外部锁定在某些系统中是禁用的,因为他不能可靠的进行工作。对运行myisamchk或isamchk所选择的过程取决于服务器是否能使用外部锁定。如果不使用,则必修使用内部锁定协议。
如果服务器用--skip-locking选项运行,则外部锁定禁用。该选项在某些系统中是缺省的,如Linux。可以通过运行mysqladmin variables命令确定服务器是否能够使用外部锁定。检查skip_locking变量的值并按以下方法进行:

◆ 如果skip_locking为off,则外部锁定有效您可以继续并运行人和一个实用程序来检查表。服务器和实用程序将合作对表进行访问。但是,运行任何一个实用程序之前,应该使用mysqladmin flush-tables。为了修复表,应该使用表的修复锁定协议。

◆ 如果skip_locaking为on,则禁用外部锁定,所以在myisamchk或isamchk检查修复表示服务器并不知道,最好关闭服务器。如果坚持是服务器保持开启状态,月确保在您使用此表示没有客户机来访问它。必须使用卡党的锁定协议告诉服务器是该表不被其他客户机访问。

检查表的锁定协议

本节只介绍如果使用表的内部锁定。对于检查表的锁定协议,此过程只针对表的检查,不针对表的修复。

1.调用mysql发布下列语句:

$mysql –u root –p db_namemysql>LOCK TABLE tbl_name READ;mysql>FLUSH TABLES;

该锁防止其它客户机在检查时写入该表和修改该表。FLUSH语句导致服务器关闭表的文件,它将刷新仍在告诉缓存中的任何为写入的改变。

2.执行检查过程

$myisamchk tbl_name$ isamchk tbl_name

3.释放表锁

mysql>UNLOCK TABLES;

如果myisamchk或isamchk指出发现该表的问题,将需要执行表的修复。

修复表的锁定协议

这里只介绍如果使用表的内部锁定。修复表的锁定过程类似于检查表的锁定过程,但有两个区别。第一,你必须得到写锁而非读锁。由于你需要修改表,因此根本不允许客户机对其进行访问。第二,必须在执行修复之后发布FLUSH TABLE语句,因为myisamchk和isamchk建立的新的索引文件,除非再次刷新改表的高速缓存,否则服务器不会注意到这个改变。本例同样适合优化表的过程。

1.调用mysql发布下列语句:

$mysql –u root –p db_namemysql>LOCK TABLE tbl_name WRITE;mysql>FLUSH TABLES;

2.做数据表的拷贝,然后运行myisamchk和isamchk:

$cp tbl_name.* /some/other/dir$myisamchk --recover tbl_name$ isamchk --recover tbl_name

--recover选项只是针对安装而设置的。这些特殊选项的选择将取决与你执行修复的类型。

3.再次刷新高速缓存,并释放表锁:

mysql>FLUSH TABLES;mysql>UNLOCK TABLES;

-----------------------------------------------------------------------------------------------

问题1: mysql 磁盘满

问题2: mysql repair 多个表

repair table: 需要按周以下步骤

1: lock table EE write ;

2: flush table EE ;

3: repair table EE ;

4: flush table EE ;

5: unlock table EE ;

// 在使用mysql过程中发现了一个奇怪的问题:

我的磁盘空间快要满了(%90),df du 看了一下, 是mysql 占用了大量的空间,于是我把mysql中每个表中的数据删除了一半,但是硬盘空间仍然被占用%90 。

我但是没有管, 但是过了半个月,磁盘仍然没有满,按理说很快就会超过%90 报警的 。

于是我想找出原因:

办法一: 怀疑是有进程在想里面些数据, 不能delete 。
./mysqladmin shutdown
./mysqld-safe

重启mysql , 没有任何效果

办法二: flush 每个表, 也不行

办法三: repair 其中一个表, 看来以下, 原来700M 的空间编程了200M左右。

但是问题又来了, 我有256个表, 我写了C++程序, 顺序repair 每一个表,但是会产生Commands out of sync; you can't run this command now 错误, 不能同步

后来, 我随便试了以下, repair table1 , table2, table3 ; 这样是可以的。

原来 repair 可以一次可以repair 多个表, 问题解决了。

发表在 article | 标签为 , | mysql数据库受到破坏的修复已关闭评论