码迷,mamicode.com
首页 > Web开发 > 详细

LAMP+haproxy+varnish实现网站访问的动静分离及静态资源缓存

时间:2015-01-12 07:01:45      阅读:539      评论:0      收藏:0      [点我收藏+]

标签:lamp   varnish   haproxy   会话保持   

系统架构图:

技术分享

 

主机规划列表:

全部的主机:

CPUIntel(R) Core(TM)i5-2410M CPU @ 2.30GHz

内存:MemTotal:         502160 kB

 

技术分享

 

实验目标:

  1. LAMP节点提供用户动态请求访问,数据库单独有数据库节点提供;

  2. LAMP动态网站有两台服务器,提供负载均衡;

  3. 静态网站服务器节点提供用户的静态资源请求访问;存在两台静态web服务器,其网站静态资源在静态服务器上存放;

  4. 用户的静态请求访问后缓存在varnish服务器上,实现访问加速

  5. 前端的haproxy提供反向代理功能,将用户的动态资源请求发送给后端LAMP节点,静态资源请求发往后端静态web服务器;

  6. 该架构考虑还不健全,如静态内容的一致性,数据库的单点故障,只是一个不成熟的架构实现简单的动静分离及缓存服务器实现;

 

实现过程:

一.             LAMP构建

全部节点的hosts文件如下:

[root@ha ~]# cat /etc/hosts
127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4
::1        localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.0.1 server.magelinux.com server
172.16.31.10 ha.stu31.com ha
172.16.31.11 node1.stu31.com node1
172.16.31.12 node2.stu31.com node2
172.16.31.13 node3.stu31.com node3
172.16.31.14 node4.stu31.com node4
172.16.31.15 mysql.stu31.com mysql
172.16.31.16 node5.stu31.com node5
172.16.31.17 node6.stu31.com node6

 

管理端是ha.stu31.com

对其他节点实现ssh无密钥通信,将hosts文件拷贝到其他节点:

[root@ha ~]# ssh-keygen -t rsa -P""     
[root@ha ~]# for i in {1..6}; dossh-copy-id -i .ssh/id_rsa.pub node$i; done
[root@ha ~]# for i in {1..6} ; do scp/etc/hosts node$i:/etc/hosts; done

 

1.节点1和节点2 安装LAMP平台

节点无密钥通信测试:

[root@ha ~]# for i in {1..6}; do ssh node$i date; done
Fri Jan 9 20:54:34 CST 2015
Fri Jan 9 20:54:34 CST 2015
Fri Jan 9 20:54:34 CST 2015
Fri Jan 9 20:54:33 CST 2015
Fri Jan 9 20:54:35 CST 2015
Fri Jan 9 20:54:35 CST 2015

节点1和节点2安装LAMP:

[root@ha ~]#  for i in {1..2}; do ssh node$i "yum -yinstall php  mysql  php-mysql" ; done

 

 

2.测试节点1和节点2httpd服务器

启动web服务器:

[root@ha ~]# for i in {1..2} ; do sshnode$i "service httpd start" ; done

测试访问:

技术分享

技术分享

 

节点1和节点2加入phpinfo测试页:

[root@node1 ~]# cat /var/www/html/index.php
<?php
       phpinfo();
?>

 

测试访问php测试页:

技术分享

 

技术分享

 

3.数据库服务器安装数据库

[root@ha ~]# ssh mysql "yum install -y mysql-server mysql"

启动mysqld服务:

[root@mysql ~]# service mysqld restart

 

添加Discuz论坛的管理帐号,密码,库。

[root@mysql ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.73 Source distribution
 
Copyright (c) 2000, 2013, Oracle and/or itsaffiliates. All rights reserved.
 
Oracle is a registered trademark of OracleCorporation and/or its
affiliates. Other names may be trademarksof their respective
owners.
 
Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ toclear the current input statement.
#创建discuz使用的数据库;
mysql> create schema bbsdb;
Query OK, 1 row affected (0.00 sec)
#赋予discuz使用的数据库管理员和管理员密码;
mysql> grant all on bbsdb.* to ‘bbsadmin‘@‘172.16.%.%‘identified by ‘oracle‘;
Query OK, 0 rows affected (0.00 sec)
#全局刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
#退出
mysql> \q
Bye

 

4.安装Discuz论坛

节点1一份:

# unzip -d /var/www/html/ Discuz_X3.2_SC_UTF8.zip

权限设置:

# chmod -R go+w /var/www/html/upload/config/
# chmod -R go+w /var/www/html/upload/data/
# chmod -R go+w /var/www/html/upload/uc_*

安装discuz论坛,输入图中的地址安装即可:

技术分享

检查安装环境:

技术分享

设置运行环境:点击选择全新安装

技术分享

安装数据库,将数据库服务器指向数据库服务器节点,数据库名称和数据库用户名即密码:

技术分享

设置好数据库后点击安装即可:

技术分享

安装完成后如图:

技术分享

 

 

安装完成后拷贝一份到node2

[root@node1 ~]# scp -r/var/www/html/upload/ /var/www/html/readme/ /var/www/html/utility/node2:/var/www/html/

建议重新解压软件包到node2,重新安装一遍,删除数据库重新安装,因为数据库中无重要内容。

 

 

5.访问测试:

技术分享

技术分享


访问成功后,访问证明LAMP平台构建成功。

 

二.             静态web服务器构建

1.获取discuz程序包

Discuz_X3.2_SC_UTF8.zip


2.将其解压至httpd网站网页存放目录:节点5和节点6都同样操作

#unzip -d /var/www/html/ Discuz_X3.2_SC_UTF8.zip

3.启动httpd服务即可

# ls /var/www/html/
error.html index.html  index.php  readme upload  utility
#service httpd start

 

4.访问测试

技术分享

技术分享

测试的web网站节点未做其它高级设置,请见谅。

 

三.             HAProxy反向代理构建

我们在haproxy节点构建HAProxy反向代理服务器

1.安装HAProxy软件

[root@ha ~]# yum install haproxy -y

安装完成后进入haproxy的配置文件存放目录:

[root@ha ~]# cd /etc/haproxy/

[root@ha haproxy]# ls

haproxy.cfg

配置haproxy的日志环境

[root@ha ~]# cat /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
local7.*                                               /var/log/boot.log
local2.*                                                /var/log/haproxy.log

重启日志服务器:

[root@ha ~]# service rsyslog restart
Shutting down system logger:                               [  OK  ]
Starting system logger:                                    [  OK  ]

 

2.查看haproxy的默认配置文件:

[root@haproxy haproxy]# cat haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible webapplication.  See the
# full configuration options online.
#
#---------------------------------------------------------------------
# Global settings #全局配置文件
#---------------------------------------------------------------------
global
    #to have these messages end up in /var/log/haproxy.log you will
    #need to:  #配置日志
    #
    #1) configure syslog to accept network log events.  This is done
   #    by adding the ‘-r‘ option tothe SYSLOGD_OPTIONS in
   #    /etc/sysconfig/syslog #修改syslog配置文件
    #
    #2) configure local2 events to go to the /var/log/haproxy.log
    #  file. A line like the following can be added to
   #   /etc/sysconfig/syslog  #定义日志设备
    #
   #    local2.*                       /var/log/haproxy.log
    #
   log         127.0.0.1 local2 #
#全局的日志配置 其中日志级别是[err warninginfo debug]
#local0 是日志设备,必须为如下24种标准syslog设备的一种:
#kern user mail daemon auth syslog lpr news
#uucp cron auth2 ftp ntp audit alert cron2
#local0 local1 local2 local3 local4 local5local6 local7
   chroot      /var/lib/haproxy
   pidfile     /var/run/haproxy.pid #将所有进程的pid写入文件启动进程的用户必须有权限访问此文件。
   maxconn     4000 #最大连接数,默认4000
   user        haproxy #用户
   group       haproxy #组
   daemon ##创建1个进程进入deamon模式运行。此参数要求将运行模式设置为"daemon"
    #turn on stats unix socket  #unix socket 文件
   stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the ‘listen‘ and‘backend‘ sections will
# use if not designated in their block  #默认的全局设置,这些参数可以被利用配置到frontend,backend,listen组件
#---------------------------------------------------------------------
defaults
   mode                    http  #默认的模式mode {tcp|http|health },tcp是4层,http是7层,health只会返回OK
   log                     global #采用全局定义的日志
   option                  httplog #日志类别http日志格式
   option                  dontlognull #不记录健康检查的日志信息
   option http-server-close #每次请求完毕后主动关闭http通道
   option forwardfor       except127.0.0.0/8 #不记录本机转发的日志
   option                  redispatch#serverId对应的服务器挂掉后,强制定向到其他健康的服务器
   retries                 3 #3次连接失败就认为服务不可用,也可以通过后面设置
   timeout http-request    10s  #请求超时
   timeout queue           1m #队列超时
   timeout connect         10s #连接超时
   timeout client          1m #客户端连接超时
   timeout server          1m #服务器连接超时
   timeout http-keep-alive 10s #长连接超时
    timeoutcheck           10s  #检查超时
   maxconn                 3000 #最大连接数
#---------------------------------------------------------------------
# main frontend which proxys to thebackends #frontend 与backends  代理配置
#---------------------------------------------------------------------
frontend main *:5000
#acl策略配置
   acl url_static       path_beg       -i /static /images /javascript/stylesheets
   acl url_static       path_end       -i .jpg .gif .png .css .js
   use_backend static          ifurl_static  #满足策略要求,则响应策略定义的backend页面
   default_backend             app #不满足则响应backend的默认页面
#---------------------------------------------------------------------
# static backend for serving up images,stylesheets and such #定义使用静态后端图像,样式表等
#---------------------------------------------------------------------
backend static
   balance     roundrobin #负载均衡模式轮询
   server      static 127.0.0.1:4331check #服务器定义
#---------------------------------------------------------------------
# round robin balancing between the variousbackends
#---------------------------------------------------------------------
backend app
   balance     roundrobin #负载均衡模式轮询
   server  app1 127.0.0.1:5001 check#服务器定义,check进行健康检查
   server  app2 127.0.0.1:5002 check
   server  app3 127.0.0.1:5003 check
   server  app4 127.0.0.1:5004 check

 

3.修改配置文件

我将配置文件备份后修改配置文件:

[root@ha haproxy]# cp haproxy.cfg{,.bak}
[root@ha haproxy]# ls
haproxy.cfg haproxy.cfg.bak

由于varnish缓存服务器未配置,所以将配置文件中的静态网站注释:

[root@ha haproxy]# vim haproxy.cfg
global
   log         127.0.0.1 local2
   chroot      /var/lib/haproxy
   pidfile     /var/run/haproxy.pid
   maxconn     4000
   user        haproxy
   group       haproxy
   daemon
   stats socket /var/lib/haproxy/stats
 
defaults
   mode                    http
   log                     global
   option                  httplog
   option                 dontlognull
   option http-server-close
   option forwardfor       except127.0.0.0/8
   option                  redispatch
   retries                 3
   timeout http-request    10s
   timeout queue           1m
   timeout connect         10s
   timeout client          1m
   timeout server          1m
   timeout http-keep-alive 10s
   timeout check           10s
    maxconn                 3000
 
listen stats
       mode http
       bind 0.0.0.0:1080
       stats enable
       stats hide-version
       stats uri     /haproxyadmin?stats
       stats realm   Haproxy\ Statistics
       stats auth    admin:admin
       stats admin if TRUE
 
frontend http-in
       bind *:80
       mode http
       log global
       option httpclose
       option logasap
       option dontlognull
       capture request  header Host len20
       capture request  header Refererlen 60
       acl url_static       path_beg       -i /upload/static/image/
       acl url_static       path_end       -i .html .jpeg .gif .png 
       acl url_dynamic      path_end       -i .php .css .js .jsp .jpg
       #use_backend static_servers         if url_static
       use_backend dynamic_servers        if url_dynamic
       default_backend static_servers
 
#backend static_servers
#       balance roundrobin
#       server staticsrv1 172.16.31.13:80 check maxconn 3000
#       server staticsrv2 172.16.31.14:80 check maxconn 3000
 
backend dynamic_servers
       balance source
       server dynamicsrv1 172.16.31.11:80 check maxconn 3000
       server dynamicsrv2 172.16.31.12:80 check maxconn 3000

 

 

4.配置完成后启动haproxy服务:

[root@ha haproxy]# service haproxy start

 

5.访问测试

技术分享

访问可以看出返回的是动态内容,而静态内容未返回,动态服务器配置完成。

 

四.             Varnish缓存服务器构建

 

1.varnish软件获取

varnish-3.0.6-1.el6.x86_64.rpm 
varnish-docs-3.0.6-1.el6.x86_64.rpm 
varnish-libs-3.0.6-1.el6.x86_64.rpm

 

2.安装varnish

[root@node3 ~]# yum -y install varnish-3.0.6-1.el6.x86_64.rpm varnish-docs-3.0.6-1.el6.x86_64.rpm varnish-libs-3.0.6-1.el6.x86_64.rpm

 

3.Varnish主配置文件介绍

[root@node3 ~]# grep -v ^#/etc/sysconfig/varnish |sed ‘/^$/d‘
NFILES=131072        # 所能够打开的最大文件数
MEMLOCK=82000        # 用多大内存空间保存日志信息
DAEMON_COREFILE_LIMIT="unlimited"    # 进程核心转储所使用的内存空间,unlimited表示无上限
RELOAD_VCL=1        # 重新启动服务时是否重新读取VCL并重新编译的
VARNISH_VCL_CONF=/etc/varnish/default.vcl    # 默认读取的VCL文件
VARNISH_LISTEN_PORT=80    # 监听的端口,默认监听6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1    # 管理接口监听的地址
VARNISH_ADMIN_LISTEN_PORT=6082    # 管理接口监听的端口
VARNISH_SECRET_FILE=/etc/varnish/secret    # 使用的密钥文件
VARNISH_MIN_THREADS=1    # 最少线程数
VARNISH_MAX_THREADS=1000    # 最大线程数
VARNISH_THREAD_TIMEOUT=120    # 线程的超时时间
VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin    # 基于文件存储时的文件路径
VARNISH_STORAGE_SIZE=1G    # 存储文件的大小
VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"    # 存储的文件格式
VARNISH_TTL=120    # 联系后端服务器的超时时间
DAEMON_OPTS="-a${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT}            -f ${VARNISH_VCL_CONF}            -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT}            -t ${VARNISH_TTL}            -w${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT}            -u varnish -g varnish            -S ${VARNISH_SECRET_FILE}            -s ${VARNISH_STORAGE}"    # 使用定义的各高级配置的参数


 

4.VarnishVCL配置说明

[root@Varnish ~]# cat /etc/varnish/default.vcl          
#定义后端默认的服务器
backend default {
 .host = "127.0.0.1";
 .port = "80";       
}            
 
#定义一个vcl_recv函数         
sub vcl_recv {
 
#req.restarts可以解释为如果客户端第一次开始请求时,
#如果请求的http中含有X-Forwarded-For信息,不管如何都在该信息后面附加客户端的ip地址信息;
#若不含有X-Forwarded-For信息,则直接附加client.ip地址信息。
#X-Forwarded-For通常表示代理服务器的地址
#为什么要补充client.ip呢?因为varnish做了反向代理,为了使后端服务器记录客户端的ip地址而非varnish的地址
   if (req.restarts == 0) {
     if (req.http.x-forwarded-for) {
         set req.http.X-Forwarded-For =
              req.http.X-Forwarded-For +", " + client.ip;
     } else {
         set req.http.X-Forwarded-For = client.ip;
     }
    }
#定义http请求的方法;如果客户端请求的http的方法不是GET/HEAD/PUT/POST/TRAGE/OPTIONS/DELETE,
#那么我们的varnish就不会去把请求传递给varnish的vcl_hash,直接交给pipe,表示varnish无法理解或者认为是非法的请求。
   if (req.request != "GET" &&
     req.request != "HEAD" &&
     req.request != "PUT" &&
     req.request != "POST" &&
     req.request != "TRACE" &&
     req.request != "OPTIONS" &&
     req.request != "DELETE") {
       /* Non-RFC2616 or CONNECT which is weird. */
       return (pipe);
    }
#如果请求的方法不是GET,也不是HEAD,那么有可能就是PUT,POST,这些都是上传数据的,
#对于上传的数据,我们没有必要缓存,直接跟后端服务器交互。
   if (req.request != "GET" && req.request !="HEAD") {
       /* We only deal with GET and HEAD by default */
       return (pass); #不查找缓存,直接从后端服务器获取数据
    }
#如果请求的内容中包括Authorization授权的,包括Cookie认证的,这些都是用户的敏感数据,一定不能缓存的。
   if (req.http.Authorization || req.http.Cookie) {
       /* Not cacheable by default */
       return (pass);
    }
   return (lookup);   #lookup表示从缓存中查找
}           
    
#从后端服务器fetch数据
sub vcl_pass {
   return (pass);
}
 
sub vcl_hash {                    #定义vcl_hash函数
   hash_data(req.url);         #默认是根据用户请求的url做hash
   if (req.http.host) {      #如果用户的请求http的首部中有host,那么就对此做hash
       hash_data(req.http.host);
    }else {
       hash_data(server.ip);   #否则根据服务器端的地址做hash
    }
   return (hash);             #最终返回hash数据
}
#如果命中的则直接从本地缓存中返回数据给用户
sub vcl_hit {
   return (deliver);
}
 
#如果没有命中,则从后端服务器取数据
sub vcl_miss {
   return (fetch);
}
 
#如果没有命中,那么从后端服务器取数据应该怎样取呢?
#在响应客户端之前,如果ttl头部值小于等于0秒,表示缓存已经过期了,
#并且其中包含有"Set-Cookie","Vary"这些字段,那么就直接设定这些过期的缓存信息的缓存期限为120秒
#如果其中没有这些字段的话就直接缓存下来了。
sub vcl_fetch {
   if (beresp.ttl <= 0s ||            
       beresp.http.Set-Cookie ||    
       beresp.http.Vary == "*") {
              /*
              * Mark as"Hit-For-Pass" for the next 2 minutes
               */
              set beresp.ttl = 120 s;
              return (hit_for_pass);
    }
   return (deliver);
}
 
sub vcl_deliver {
   return (deliver);
}
 
#客户端请求某个页面,如果服务器上不存在这个页面,就请求错误
#对于后端服务器没有这个文件的,直接交由varnish响应一个错误信息
sub vcl_error {
   set obj.http.Content-Type = "text/html; charset=utf-8";
   set obj.http.Retry-After = "5";
   synthetic {"
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
 <head>
   <title>"} + obj.status + " " + obj.response +{"</title>
 </head>
 <body>
   <h1>Error "} + obj.status + " " + obj.response +{"</h1>
   <p>"} + obj.response + {"</p>
   <h3>Guru Meditation:</h3>
   <p>XID: "} + req.xid + {"</p>
   <hr>
   <p>Varnish cache server</p>
 </body>
</html>
"};
   return (deliver);
}
 
sub vcl_init {
     return (ok);
}
 
sub vcl_fini {
     return (ok);
}

 

5.自定义VCL配置文件

[root@node3 ~]# cat /etc/varnish/web.vcl
######定义ACL
acl purgers {                    #定义acl,实现IP地址过滤
   "127.0.0.1";
   "172.16.0.0"/16;
}
######定义健康状态检测
probe dynamic {                  #设置动态网站服务器健康状态检测
   .url = "/index.html";
   .interval = 5s;
   .timeout = 1s;
    .expected_response= 200;
}           #这里设置了两个健康状态检测主要是为了区分动、静网站
probe static {                   #设置动态网站服务器健康状态检测
   .url = "/index.html";       #定义检测的页面
   .interval = 5s;              #探测请求的发送周期,默认为5秒
   .timeout = 1s;               #每次探测请求的过期时间
   .expected_response = 200;
}
######定义后端服务器
backend app1 {                  #定义一个后端服务器
   .host = "172.16.31.11";     #服务器地址
   .port = "80";              #服务器监听端口
   .probe = dynamic;           #健康状态检测
}
backend app2 {
   .host = "172.16.31.12";
    .port = "80";
   .probe = dynamic;
}
backend web1 {         
   .host = "172.16.31.16";
   .port = "80";
   .probe = static;
}
backend web2 {
   .host = "172.16.31.17";
   .port = "80";
   .probe = static;
}
######定义后端动态服务器组,实现负载均衡效果
director apps random {          #定义一个后端服务器组,实现负载均衡效果
    {
        .backend = app1;       #调用前面已定义过的后端主机
    .weight = 2;           #设置权重
    }
    {
    .backend = app2;
    .weight = 2;
    }
}
######定义后端静态服务器组,实现负载均衡效果
director webs random {
    {
       .backend = web1;
       .weight = 2 ;
    }
    {
       .backend = web2;
       .weight = 2 ;
    }
}
######定义vcl_recv函数,实现请求到达并成功接收后调用此函数中定义的规则
sub vcl_recv {
######定义动、静分离,以".php"或".php?后面跟所有文件"结尾的请求都发送到动态服务器,其他请求都发送到静态服务器
   if (req.url ~ "\.php(\?\.*|$)") {
   set req.backend = apps;
    }else {
   set req.backend = webs;
    }
   return(lookup);
######定义允许清除缓存的IP地址,调用的是前面定义的ACL
   if (req.request == "PURGE") {
       if (!client.ip ~ purgers) {
       error 405 "Method not allowed";
    }
       return(lookup);
    }
######重新定义http请求首部,让后端服务器可以记录请求客户端的真实IP地址
       if (req.restarts == 0) {
           if (req.http.x-forwarded-for) {
               set req.http.X-Forwarded-For =
               req.http.X-Forwarded-For +", " + client.ip;
           } else {
                 set req.http.X-Forwarded-For =client.ip;
           }
        }
######除了定义的请求方法外,其他请求都到后端服务器
   if (req.request != "GET" &&
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
       return (pipe);
    }
   if (req.request != "GET" && req.request !="HEAD") {
       return (pass);
    }
######定义不缓存认证与Cookie信息
   if (req.http.Authorization || req.http.Cookie) {
       return (pass);
    }
######定义压缩功能
   if (req.http.Accept-Enconding) {
      if (req.url ~ "\.(jpg|jpeg|gif|bmp|png|flv|gz|tgz|tbz|mp3)$"){
          remove req.http.Accept-Encoding;
      remove req.http.Cookie;
      } else if (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
      } else if (req.http.Accept-Encoding ~ "deflate") {
      set req.http.Accept-Encoding = "deflate";
      } else { remove req.http.Accept-Encoding;
      }
    }
######定义指定格式结尾的文件去除Cookie信息
   if (req.request == "GET" && req.url ~"\.(jpeg|jpg|gif|png|bmp|swf)$") {
   unset req.http.cookie;
    }
######定义防盗链设置
   if (req.http.referer ~ "http://.*") {
       if (!(req.http.referer ~ "http://.*\.baidu\.com" ||req.http.referer ~ "http://.*\.google\.com.*")) {
              set req.http.host ="www.stu31.com";
         set req.url = "http://172.16.31.10/error.html";
    }
    }
}
######定义vcl_hash函数
sub vcl_hash {
    hash_data(req.url);
   if (req.http.host) {
       hash_data(req.http.host);
    }else {
       hash_data(server.ip);
    }
   return(hash);
}
######定义vcl_hit函数
sub vcl_hit {
   if (req.request == "PURGE") { #语法方法为"PURGE"
      purge;                     #清除缓存
      error 200 "Purged.";      #返回错误状态码为"200"
    }
   return(deliver);
}
######定义vcl_miss函数
sub vcl_miss {
   if (req.request == "PURGE") {
   purge;
   error 404 "Not In Cache.";
    }
   return(fetch);
}
######定义vcl_psss函数
sub vcl_pass {
   if (req.request == "PURGE") {
      error 502 "Purged On A Passed Object.";
    }
   return(pass);
}
######定义vcl_fetch函数
sub vcl_fetch {
######定义缓存,如果匹配到已定义文件结尾的缓存1天,其他则缓存1小时
   if (req.request == "GET" && req.url ~"\.(html|jpg|png|bmp|jpeg|gif|js|ico|swf|css)$") {
      set beresp.ttl = 1d;
      set beresp.http.expires = beresp.ttl;
    }else {
      set beresp.ttl = 1h;
    }
   return(deliver);
}
######定义在http首部中,如果请求命中显示"HIT",未命中则显示"MISS",通过F12可查看缓存命中状态及varnish服务器IP
sub vcl_deliver {
   if (obj.hits > 0) {
      set resp.http.X-Cache = "Hit from " + server.ip;
    }else {
      set resp.http.X-Cache = "MISS";
    }
}

 

6.启动varnish服务

[root@node3 ~]# /etc/rc.d/init.d/varnish  start

 

7.查看varnish监听的端口

[root@node3 ~]# netstat -tnlp |grepvarnish 
tcp       0      0 127.0.0.1:6082              0.0.0.0:*                   LISTEN      6019/varnishd      
tcp       0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      6020/varnishd       
tcp       0      0 :::80                       :::*                        LISTEN      6020/varnishd

 

 

8.varnishadm的管理工具命令

# 登录管理命令行

[root@node3 varnish]# varnishadm -S/etc/varnish/secret -T 127.0.0.1:6082
200       
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,2.6.32-504.el6.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-3.0.6 revision 1899836
 
Type ‘help‘ for command list.
Type ‘quit‘ to close CLI session.
# 加载编译新配置, cache是配置名,web.vcl是定义的vcl配置文件
varnish> vcl.load cache web.vcl
200       
VCL compiled.
# 列出所有的配置
varnish> vcl.list
200       
active      2000 boot
available       0 cache
# 使用配置,需指定配置名,当前使用的配置以最后一次
varnish> vcl.use cache
200       
#配置完成后退出管理命令行
varnish> quit
500       
Closing CLI connection

 

节点4varnish同样配置,过程略。

 

如果我们希望后端的web服务器记录客户端访问的真实IP地址,我们需要配置httpd的配置文件中的日志格式:

所有的web服务器节点都需要配置:

[root@node1 ~]# vim/etc/httpd/conf/httpd.conf   
LogFormat "%{X-Forwarded-For}i %l %u%t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""combined

 

 

五.             测试访问


1.上述配置完成后我们就可以访问论坛网站了:

技术分享


2.访问haproxy的状态页面

输入用户名和密码:

技术分享

可以查看haproxy的状态页面:

技术分享

 

 

3.查看静态内容缓存命中情况,我新增了几篇图片文章,访问刷新几次:

在谷歌浏览器中按F12来查看响应报文头部:

技术分享

 

4.我们可以在varnish缓存服务器上查看日志,应该会有健康检查:

[root@node3 ~]# varnishlog
    0Backend_health - web1 Still healthy 4--X-RH 8 3 8 0.005443 0.005806 HTTP/1.1200 OK
    0Backend_health - app2 Still healthy 4--X-RH 8 3 8 0.007379 0.004278 HTTP/1.1200 OK
    0Backend_health - app1 Still healthy 4--X-RH 8 3 8 0.003918 0.003243 HTTP/1.1200 OK
    0Backend_health - web2 Still healthy 4--X-RH 8 3 8 0.006985 0.005762 HTTP/1.1200 OK
    0Backend_health - web1 Still healthy 4--X-RH 8 3 8 0.006877 0.006074 HTTP/1.1200 OK
0 Backend_health- app2 Still healthy 4--X-RH 8 3 8 0.006422 0.004814 HTTP/1.1 200 OK

 

5.查看后端web服务器记录的访问日志,可以查看到真实的客户端IP

[root@node1 ~]# tail/var/log/httpd/access_log
172.16.31.254 - - [11/Jan/2015:12:43:25+0800] "GET /upload/data/cache/style_1_widthauto.css?Raa HTTP/1.1"200 1491 "http://172.16.31.10/upload/forum.php" "Mozilla/5.0(Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/37.0.2062.124 Safari/537.36"
172.16.31.254 - - [11/Jan/2015:12:43:25+0800] "GET /upload/static/js/forum.js?Raa HTTP/1.1" 200 22844"http://172.16.31.10/upload/forum.php" "Mozilla/5.0 (Windows NT6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124Safari/537.36"
172.16.31.254 - - [11/Jan/2015:12:43:25+0800] "GET /upload/static/js/logging.js?Raa HTTP/1.1" 200 603"http://172.16.31.10/upload/forum.php" "Mozilla/5.0 (Windows NT6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124Safari/537.36"
172.16.31.254 - - [11/Jan/2015:12:43:25+0800] "GET /upload/static/js/forum_slide.js?Raa HTTP/1.1" 200 4953"http://172.16.31.10/upload/forum.php" "Mozilla/5.0 (Windows NT6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124Safari/537.36"
172.16.31.254 - - [11/Jan/2015:12:43:26+0800] "GET/upload/data/attachment/forum/201501/10/215000a7kg8mlkg68ukpgk.jpgHTTP/1.1" 200 210377 "http://172.16.31.10/upload/forum.php""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/37.0.2062.124 Safari/537.36"
172.16.31.254 - - [11/Jan/2015:12:43:26+0800] "GET /upload/data/attachment/forum/201501/10/212443q6pg06px77j6drld.jpgHTTP/1.1" 200 960332 "http://172.16.31.10/upload/forum.php""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/37.0.2062.124 Safari/537.36"

 

 6.实现了用户会话保持

技术分享

 

 至此,本次实验就完美结束!


本文出自 “飞雪连天射白鹿” 博客,请务必保留此出处http://sohudrgon.blog.51cto.com/3088108/1601842

LAMP+haproxy+varnish实现网站访问的动静分离及静态资源缓存

标签:lamp   varnish   haproxy   会话保持   

原文地址:http://sohudrgon.blog.51cto.com/3088108/1601842

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!