热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

nginx+memcache增加全站缓存系统

项目背景:当生产产生异常流量而又无法快速定位流量来源,为减少数据库负载,通过全局缓存预热,以及快速切缓存开关,来控制全站流量导入缓存,减少异常情况下对数据库的压力。总体实现为ng

项目背景:

    当生产产生异常流量而又无法快速定位流量来源,为减少数据库负载,通过全局缓存预热,以及快速切缓存开关,来控制全站流量导入缓存,减少异常情况下对数据库的压力。

 

总体实现为nginx+memcache+Lua

 

1 首先查看一下nginx版本:

 

  [root@squid1 sbin]# /usr/local/nginx/sbin/nginx -v

Tengine version: Tengine/2.1.2 (nginx/1.6.2)

 

此处nginx使用的是tengine版,nginx版本必须1.6.0以上。不是则到 http://tengine.taobao.org 下载tengine最新版本。

 

2 安装Lua环境

 

  到官网http://luajit.org/download.html 下载安装包到本地并解压

  tar –zxvf /usr/local/src/LuaJIT-2.0.4.tar.gz

  cd LuaJIT-2.0.4

  make&&make install

  查看是否成功:

  [root@puppetmaster LuaJIT-2.0.4]# ls /usr/local/lib

libluajit-5.1.a  libluajit-5.1.so  libluajit-5.1.so.2  libluajit-5.1.so.2.0.4  lua  pkgconfig

 

[root@puppetmaster LuaJIT-2.0.4]# ls /usr/local/include/luajit-2.0

lauxlib.h  luaconf.h  lua.h  lua.hpp  luajit.h  lualib.h

 

编辑/etc/profile文件添加环境变量:

export LUAJIT_LIB=/usr/local/lib

export LUAJIT_INC=/usr/local/include/luajit-2.0

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

 

3 下载nginx所需模块源码包到/usr/local/src下,并解压

      

 https://github.com/simpl/ngx_devel_kit (nginx开发环境模块)

https://github.com/openresty/set-misc-nginx-module (nginx变量函数,算法模块)

https://github.com/openresty/srcache-nginx-module (缓存http请求,响应定制模块)

https://github.com/openresty/memc-nginx-module (memcached缓存模块)

https://github.com/openresty/lua-nginx-module (lua脚本开发框架模块)

 

 4  tengine再编译

      Tengine的dso_tool是动态加载的工具,用法为:

         /usr/local/nginx/sbin/dso_tool --add-module=/usr/local/src/memc-nginx-module-master

但是并不是所有模块都可以动态加载,所以这里用再编译静态加载。

 

编译前查看一下现在程序的编译参数:

[root@puppetmaster sbin]# /usr/local/nginx/sbin/nginx –V

 

tar -zxvf /usr/local/src/tengine-2.1.2.tar.gz

cd /usr/local/src/tengine-2.1.2

在之前编译参数上再将下载的nginx模块参数添加上编译:

./configure --prefix=/usr/local/nginx --user=nginx --group=nginx

--with-http_concat_module

--with-http_addition_module

--with-http_dav_module

--with-http_gzip_static_module

--with-http_image_filter_module

--with-http_realip_module

--with-http_stub_status_module

--with-http_ssl_module

--with-http_sub_module

--with-ipv6

--with-file-aio

--with-sha1=/usr/include/openssl

--with-md5=/usr/include/openssl

--with-mail

--with-mail_ssl_module

--with-http_xslt_module

--with-http_geoip_module

--with-http_flv_module

--with-http_mp4_module

--with-http_gzip_static_module

--with-http_random_index_module

--with-http_secure_link_module

--with-http_degradation_module

--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

--with-ld-opt=-Wl,-E

--add-module=/usr/local/src/ngx_devel_kit-master --add-module=/usr/local/src/set-misc-nginx-module-master --add-module=/usr/local/src/srcache-nginx-module-master --add-module=/usr/local/src/memc-nginx-module-master --add-module=/usr/local/src/lua-nginx-module-master

 

    make

    make install

        

         tengine的再编译并不会将原来自建的配置文件如nginx.conf删除。

         可以查看一下是否已将模块编译进去

         [root@puppetmaster sbin]# /usr/local/nginx/sbin/nginx –V

 

 5    将lua源码并上传到nginx服务器

        /data/nfsroot/client/ngx_lua/

   

 6    新建nginx的配置文件cache.conf用于nginx调用各个模块

         Vim /usr/local/nginx/conf/cache.conf

         set $cache_fetch_skip 1;

   set $cache_store_skip 1;

   set $cmd_key $host$request_uri;

   srcache_response_cache_control off;

   rewrite_by_lua_file /data/nfsroot/client/ngx_lua/cache_config.lua;

   srcache_methods GET; #GET POST

   srcache_fetch_skip $cache_fetch_skip;

   srcache_store_skip $cache_store_skip;

   srcache_store_statuses 200 201 301 302; #200 201 301 302 500

   srcache_fetch GET /memc $cmd_key;

   srcache_store PUT /memc $cmd_key;

   add_header X-Cached-From $srcache_fetch_status;

 

 7    修改配置文件nginx.cof

       添加upstream,主机为memcache服务器

     upstream memc_server1 {

     server 192.168.0.1:12000;

     keepalive 512;

   }

 

    upstream memc_server2 {

      server 192.168.0.2:12000;

      keepalive 512;

    }

 

    upstream_list memc_servers memc_server1 memc_server2;

 

在所需要的虚拟主机下添加:如www.hello.com

location /memc {

#允许内网访问

internal;

memc_connect_timeout 100ms;

memc_send_timeout 100ms;

memc_read_timeout 100ms;

set $memc_key $host$request_uri;

#一致性hash算法和java客户端类似

set_hashed_upstream $memc_backends memc_servers $memc_key;

#设置缓存时间 10分钟

set $memc_exptime 600;

memc_pass $memc_backends;

}

 

在所需要缓存的应用下添加配置文件路径,如:

location /local/{

                include /usr/local/nginx/conf/cache.conf;

                proxy_pass   http://hello_servers/hello/route/;

}

 

 

 8    pkill nginx

       /usr/local/nginx/sbin/nginx -c /etc/nginx/conf/nginx.conf

 

主要原理:

通过lua 脚本控制缓存的存开关和取开关

/data/nfsroot/client/ngx_lua/cache_config.lua;

ngx.var.cache_fetch_skip=0 标示抓取缓存

ngx.var.cache_store_skip=0 标示缓存被代理的缓存

ngx.var.cache_fetch_skip=1 跳过GET缓存

ngx.var.cache_store_skip=1 跳过PUT缓存

一般我们只需要设置成这样既可

ngx.var.cache_fetch_skip=1 标示抓取缓存 需要的时候 修改为0 reload nginx 全站缓存开启,抵御流量

ngx.var.cache_store_skip=0 预热到缓存

 

 

附lua源码

[root@squid1 client]# tree ngx_lua
ngx_lua
├── cache_config.lua
├── module
│   ├── limit_share.lua
│   ├── mySqlClient.lua
│   ├── redisClient.lua
│   └── share.lua
├── README.md
└── test.lua

cache_config.lua

1 ngx.var.cache_fetch_skip=1
2 ngx.var.cache_store_skip=0

limit_share.lua

 1 local _M = {}
 2 local lrucache = require "lrucache"
 3 local c = lrucache.new(600)  -- allow up to 200 items in the cache
 4 if not c then
 5     return error("failed to create the cache: " .. (err or "unknown"))
 6 end
 7 --开启全站缓存
 8 c:set("full_cache",0)
 9 c:set("CACHE_POST",0)
10 function _M.go()
11     c:set("dog", 32)
12     c:set("cat", 56)
13     -- ngx.say("dog: ", c:get("dog"))
14     -- ngx.say("cat: ", c:get("cat"))
15 
16     -- c:set("dog", { age = 10 }, 0.1)  -- expire in 0.1 sec
17     -- c:delete("dog")
18 end
19 
20 function _M.getC()
21 return c
22 end
23 
24 return _M

mySqlClient.lua

redisClient.lua

 1 local redis = require("redis")
 2 local _Redis ={}
 3 function _Redis:client()
 4 
 5     local red = redis:new()
 6 
 7     red:set_timeout(1000) -- 1 sec
 8 
 9 
10         local ok, err = red:connect("192.168.59.103", 6379)
11             if not ok then
12                  ngx.say("failed to connect to redis: ", err)
13             else
14                  ngx.ctx.redis=red
15             end
16 
17         return ngx.ctx.redis
18 end
19 
20 --- 关闭连接
21 function _Redis:close()
22     if ngx.ctx.redis then
23         ngx.ctx.redis:set_keepalive(10000, 100)
24         ngx.ctx.redis = nil
25     end
26 end
27 
28 return _Redis

share.lua

 1 local _M = {}
 2 local lrucache = require "lrucache"
 3 local c = lrucache.new(200)  -- allow up to 200 items in the cache
 4 if not c then
 5     return error("failed to create the cache: " .. (err or "unknown"))
 6 end
 7 
 8 function _M.go()
 9    
10     -- ngx.say("dog: ", c:get("dog"))
11     -- ngx.say("cat: ", c:get("cat"))
12 
13     -- c:set("dog", { age = 10 }, 0.1)  -- expire in 0.1 sec
14     -- c:delete("dog")
15 end
16 
17 function _M.check(args)
18         ngx.say(args)
19         return c:get(args)
20 end
21 
22 function _M.getC()
23         if ngx.ctx.c then
24         return ngx.ctx.c
25     end
26          
27          ngx.ctx.c=c
28         return ngx.ctx.c
29 end
30 
31 return _M

 


推荐阅读
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • Windows 7 部署工具DISM学习(二)添加补丁的步骤详解
    本文详细介绍了在Windows 7系统中使用部署工具DISM添加补丁的步骤。首先需要将光驱中的安装文件复制到指定文件夹,并进行挂载。然后将需要的MSU补丁解压并集成到系统中。文章给出了具体的命令和操作步骤,帮助读者完成补丁的添加过程。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了关于smarty自定义缓存名的解决思路,通过放弃生成缓存,直接生成html的静态页面来提高速度。同时提供了一个参考链接供参考。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • 网卡工作原理及网络知识分享
    本文介绍了网卡的工作原理,包括CSMA/CD、ARP欺骗等网络知识。网卡是负责整台计算机的网络通信,没有它,计算机将成为信息孤岛。文章通过一个对话的形式,生动形象地讲述了网卡的工作原理,并介绍了集线器Hub时代的网络构成。对于想学习网络知识的读者来说,本文是一篇不错的参考资料。 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
author-avatar
U友48805799
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有