一,为什么要使用redis作本地缓存?

1,使用缓存通常会有三层

当使用openresty作为web服务器时,我们更看重是的它可以通过lua编程的扩展能力,就openresty而言,它可以实现的功能非常多,

提高响应速度是web服务中非常重要的功能,

使用缓存通常会有三层:

本地缓存:存在于本地机器上,直接通过nginx访问,避免网络io;

redis cluster:存储更多的供lua访问的数据,也是通过nginx访问直接返回,相比前一层缓存,增加了网络io,但仍然避免了对业务系统的访问;

业务缓存:供运行在tomcat/php-fpm/go http中内的业务代码访问。

可以比较得到本地缓存是响应速度最快的,通常可以在10ms内对请求进行响应。

我们看到的很多经过优化的BAT等大厂的站点都能在极短时间内响应请求,就是经过了层层优化的结果。

2,这里会提供一个例子:使用redis做商品详情页的cache:

流程:当用户访问时,

先从redis中获取cache内容,

如果redis中不存在此value,则会改为访问后端业务系统获取cache

说明:在生产环境中,为方便更新,通常会采用redis的主从架构,

每台业务nginx上所配备的redis的数据能得到实时更新

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,nginx的配置文件:

  1. upstream backenditem {
  2. server 127.0.0.1:8000;
  3. }
  4.  
  5. server {
  6. listen 8000;
  7. server_name 8000.test.com;
  8.  
  9. location / {
  10. default_type 'text/html';
  11. content_by_lua_block {ngx.say("hello world,this is path backend from 8000:uri:"..ngx.var.request_uri)}
  12. }
  13. }
  14.  
  15. server {
  16. listen 82;
  17. server_name test.com;
  18. location ~ /backenditem/(.*) {
  19. rewrite /backenditem(/.*) $1 break;
  20. proxy_next_upstream error timeout;
  21. proxy_pass http://backenditem;
  22. }
  23. location /item {
  24. default_type text/html;
  25. content_by_lua_file /data/luacache/webroot/item_redis_cache.lua;
  26. }
  27.  
  28. location / {
  29. default_type 'text/html';
  30. content_by_lua_block {ngx.say("default path:uri:"..ngx.var.request_uri)}
  31. }
  32. }

说明:1,端口8000的server是一个demo,生产环境中,它应该是使用tomcat/php-fpm/django之类的业务系统

2,location ~ /backenditem/(.*) :负责upstream到后端业务系统,

注意这里要做一次 rewrite /backenditem(/.*) $1 break;   ,作用是去掉用来标识要跳转到后端的backenditem字串

3,content_by_lua_file    此处用绝对路径指定了lua代码的程序文件

三,lua程序文件:   item_redis_cache.lua

  1. --指定要访问的lua包所在的路径
  2. package.path = package.path..";/data/luacache/webroot/config/?.lua;/data/luacache/webroot/lib/?.lua"
  3. local config = require "config_constant"
  4. local readhttp = require "read_http"
  5. local returnjson = require "return_json"
  6. --redis连接池工厂
  7. local redis_factory = require('redis_factory')(config.redisConfig)
  8. --获取redis的连接实例
  9. local ok, redis_a = redis_factory:spawn('redis_a')
  10.  
  11. --用于接收前端数据的对象
  12. local args=nil
  13. --获取前端的请求方式 并获取传递的参数
  14. local request_method = ngx.var.request_method
  15. --判断是get请求还是post请求并分别拿出相应的数据
  16. if "GET" == request_method then
  17. args = ngx.req.get_uri_args()
  18. elseif "POST" == request_method then
  19. ngx.req.read_body()
  20. args = ngx.req.get_post_args()
  21. --兼容请求使用post请求,但是传参以get方式传造成的无法获取到数据的bug
  22. if (args == nil or args.data == null) then
  23. args = ngx.req.get_uri_args()
  24. end
  25. end
  26.  
  27. --ngx.log(ngx.ERR,"args.key:",args.key)
  28.  
  29. if args.itemid == nil or args.itemid=="" then
  30.  
  31. local json = returnjson.getjson("1",'key not exist or key is empty',"")
  32. --ngx.log(ngx.ERR,"json:",json)
  33. ngx.say(json)
  34.  
  35. else
  36.  
  37. --获取前端传递的itemid
  38. local itemid = args.itemid
  39.  
  40. --在redis中获取itemid对应的值
  41. local va = redis_a:get(itemid)
  42.  
  43. if va == ngx.null or va == nil then
  44.  
  45. --ngx.log(ngx.ERR, "redis not found content, back to http, itemid : ", itemid)
  46. local url="/backenditem/item"
  47. va = readhttp.read(url,itemid)
  48. ngx.print(returnjson.getjson(0,itemid,va))
  49. else
  50. --响应前端
  51. ngx.say(returnjson.getjson(0,itemid,va))
  52. end
  53.  
  54. end

四,lua访问redis的配置文件: config_constant.lua

  1. config = {}
  2.  
  3. config.redisConfig = {
  4. redis_a = { -- your connection name
  5. --ip
  6. host = '127.0.0.1',
  7. --端口
  8. port = 6379,
  9. --密码
  10. pass = '',
  11. --超时时间,如果是测试环境debug的话,这个值可以给长一点;如果是正式环境,可以设置为200
  12. timeout = 120000,
  13. --redis的库
  14. database = 0,
  15. },
  16. }
  17. return config

五,lua程序文件:read_http.lua:用来从后端业务系统得到response

  1. local read_http = {}
  2. function read_http.read(url,id)
  3. local resp = ngx.location.capture(url, {
  4. method = ngx.HTTP_GET,
  5. args = {id = id}
  6. })
  7. if not resp then
  8. ngx.log(ngx.ERR, "request error :", err)
  9. return
  10. end
  11. if resp.status ~= 200 then
  12. ngx.log(ngx.ERR, "request error, status :", resp.status)
  13. return
  14. end
  15. return resp.body
  16. end
  17.  
  18. return read_http

六,lua程序:return_json.lua :返回json字串

  1. local return_json = {}
  2. function return_json.getjson(status,msg,data)
  3. local json = '{"status":"'..status..'","msg":"'..msg..'","data":"'..data..'"}'
  4. return json
  5. end
  6.  
  7. return return_json

七,此项目的github地址:

  1. https://github.com/liuhongdi/luacache

八,测试效果:

1,当有商品存在于redis中的返回 :如图

2,当商品不存在于redis中的返回:   如图

3,当参数错误时的返回 :如图

九,文中涉及到的各平台的版本查看:

  1. [root@localhost luacache]# cat /etc/redhat-release
  2. CentOS Linux release 8.1.1911 (Core)
  1. [root@localhost luacache]# /usr/local/openresty/bin/openresty -V
  2. nginx version: openresty/1.15.8.2
  3. built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
  4. built with OpenSSL 1.1.0k 28 May 2019
  5. TLS SNI support enabled
  1. [root@localhost luacache]# /usr/local/soft/redis5/bin/redis-server --version
  2. Redis server v=5.0.7 sha=00000000:0 malloc=libc bits=64 build=8e31d2ed9a4c9593

openresty使用redis作本地缓存的更多相关文章

  1. springboot+mybatis 用redis作二级缓存

    1.加入相关依赖包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  2. 本地缓存google.guava及分布式缓存redis 随笔

    近期项目用到了缓存,我选用的是主流的google.guava作本地缓存,redis作分布式 缓存,先说说我对本地缓存和分布式缓存的理解吧,可能不太成熟的地方,大家指出,一起 学习.本地缓存的特点是速度 ...

  3. lua模块demo(redis,http,mysql,cjson,本地缓存)

    1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...

  4. 本地缓存,Redis缓存,数据库DB查询(结合代码分析)

    问题背景 为什么要使用缓存?本地缓存/Redis缓存/数据库查询优先级? 一.为什么要使用缓存 原因:CPU的速度远远高于磁盘IO的速度问题:很多信息存在数据库当中的,每次查询数据库就是一次IO操作所 ...

  5. redis订阅发布消息操作本地缓存

    Redis 本地缓存+远程缓存方案 使用纯java的ehcache作为本地缓存 Reids 作为远程分布式缓存 解决redis缓存压力过大,提高缓存速度,以及缓存性能. Redis和ehcache缓存 ...

  6. 使用本地缓存快还是使用redis缓存好?

    使用本地缓存快还是使用redis缓存好? Redis早已家喻户晓,其性能自不必多说. 但是总有些时候,我们想把性能再提升一点,想着redis是个远程服务,性能也许不够,于是想用本地缓存试试!想法是不错 ...

  7. 缓存子系统如何设计(Cachable tag, Memcache/redis support, xml config support, LRU/LFU/本地缓存命中率)

    大家对这段代码肯定很熟悉吧: public List<UserInfo> SearchUsers(string userName) { string cacheKey=string.For ...

  8. 用Redis作Mysql数据库缓存

    使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按 ...

  9. redis(二)--用Redis作MySQL数据库缓存

    用Redis作MySQL数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...

随机推荐

  1. 【小程序】---- 使用 Echarts 的方式

    1.下载 GitHub 上的 ecomfe/echarts-for-weixin 项目,Echarts微信版. 地址:https://github.com/ecomfe/echarts-for-wei ...

  2. git 快速入门及常用命令

    身为技术人员,都知道Git是干嘛的.从服务端角度它是代码仓库,可以多人协作.版本控制.高效处理大型或小型项目所有内容:从客户端讲,它能够方便管理本地分支.且与服务端代码的同步,从拉取.合并.提交等等管 ...

  3. nmap端口扫描工具下载和安装使用

    1.下载地址 https://nmap.org/download.html 2.下载之后进行安装 选择I Agree 后,建议全选,特别是zenmap,这个是图形化界面,不喜欢命令行格式的可以用zen ...

  4. linux 多进程

    Linux下的多进程编程初步 Linux下的多进程编程初步 多进程编程 1 Linux下进程的结构 2 Linux下的进程控制 21 僵尸进程 22 fork 23 exec 函数族 3 Linux下 ...

  5. 第2课 - 搭建Lua开发环境

    第2课 - 搭建Lua开发环境 1. Lua 的优点 (1)Lua 使用标准的 ANSI C 进行开发,可以无缝集成到宿主程序,且几乎支持所有平台. (2)Lua 是开源且免费的软件,以源码的方式直接 ...

  6. Docker端口映射及创建镜像演示(二)

    Docker暴露容器方法 第一种:将容器中的一个端口映射成宿主机中的一个随机端口 第二种:将容器中的一个端口映射成宿主机中的一个端口 第三种:将容器中的一个端口映射成宿主机中的一个特定网卡上的随机端口 ...

  7. matlab数字图像处理-冈萨雷斯-数据类和图像类之间的转换

    亮度图像 二值图像 属于注释 数据类间的转换 图像类和类型间的转化 把一个double类的任意数组转换成[0,1]的归一化double类数组----->mat2gray 图像类和类型间的转化例题 ...

  8. hystrix源码小贴士之Yammer Publisher

    HystrixYammerMetricsPublisher 继承HystrixMetricsPublisher,创建HystrixYammerMetricsPublisherCommand.Hystr ...

  9. 番外篇 - Linux环境准备

     这是一个比较早的系列,最近发现一直没有更新...    asp.net core跨平台,所以我们首先需要一个linux来验证,所以第一篇就是准备我们的环境   .netcore尝试在centos6. ...

  10. php第七天-文件处理系统

    0x01 文件系统概述 1.1文件类型 在程序运行时,程序本身和数据一般都存在内存中,当程序运行结束后,存放在内存中的数据被释放. 如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就必须 ...