美文网首页
【轻知识】想想你工作中用到的Openresty+lua

【轻知识】想想你工作中用到的Openresty+lua

作者: 言十年 | 来源:发表于2019-04-16 17:54 被阅读0次

对项目的梳理总结。
涉及到的关键字会大概说明或者换个名字。比如:动态xx改成动态数据。不然一看xx就知道是干啥的了。
会用极简的demo,告诉你主要逻辑。

项目一: 动态数据替换

功能使用场景:一个搭建活动页面的后台。生成静态json数据(方便h5、rn使用)。有的活动页面的部分数据需要变化。

具体的实现大致写了一篇用openResty做一个小功能:实现数据替换跟缓存

架构图如下:

Openresty+lua架构图.jpg

下面是一个原理极简demo。并不直接请求接口与反向代理到s3。为了练习方便。

首先准备了两个文件,一个叫stock.lua,一个是page.json(我们的json存在了亚马逊s3上,也就是你可以proxy_pass到s3)。

功能如下:

stock.lua

local cjson = require "cjson"
local uri = '/page.json'
local res = ngx.location.capture(uri)
local body = res.body
-- 下面做一个假装从其他服务器上拿到了一个库存,然后做替换。
-- 解析 body 成table
local body_table = cjson.decode(body)
-- 假设下面是从其他地方拿到的stock
local stock_list = {{product_id = 123,stock = 2000}, {product_id = 456, stock = 3000}}
for k, v in pairs(body_table.product_list) do
    for sk, sv in pairs(stock_list) do
        if sv.product_id == v.product_id then
            v.stock = sv.stock
        end
    end
end
local response_body = cjson.encode(body_table)
ngx.say(response_body)

page.json (就把它当做是生成存到s3上的json吧)

{"product_list":[{"product_id":123,"product_img":"xxxx.com.png","title":"球鞋", "stock": 13},{"product_id":456,"product_img":"xxxx.com.png","title":"球拍", "stock": 14},{"product_id":789,"product_img":"xxxx.com.png","title":"球衣", "stock": 15}]}

nginx.conf 如下

proxy_cache_path /home/nobody/cache levels=1:2 keys_zone=my-cache:8m inactive=1h max_size=10m;

lua-project.com.conf nginx 配置如下:

location /page {
    proxy_pass http://127.0.0.1:9527/page_cache;
    proxy_cache my-cache;
    proxy_cache_lock on;
    proxy_cache_valid 200 10s;
    proxy_cache_key $uri$is_args$args;
    add_header Nginx-Cache "$upstream_cache_status";
}
location /page_cache {
    content_by_lua_file /home/nobody/lua-project/stock.lua;
}
location ~ \.json$ {
    root /home/nobody/lua-project/;
}   

于是请求

[root@bogon ~]# curl -v lua-project.com/page
* About to connect() to lua-project.com port 80 (#0)
*   Trying 127.0.0.1...
* Connected to lua-project.com (127.0.0.1) port 80 (#0)
> GET /page HTTP/1.1
> User-Agent: curl/7.29.0
> Host: lua-project.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: openresty
< Date: Mon, 15 Apr 2019 14:18:27 GMT
< Content-Type: application/octet-stream
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
{"product_list":[{"stock":2000,"product_img":"xxxx.com.png","title":"球鞋","product_id":123},{"stock":3000,"product_img":"xxxx.com.png","title":"球拍","product_id":456},{"stock":15,"product_img":"xxxx.com.png","title":"球衣","product_id":789}]}
* Connection #0 to host lua-project.com left intact
[root@bogon ~]# curl -v lua-project.com/page
* About to connect() to lua-project.com port 80 (#0)
*   Trying 127.0.0.1...
* Connected to lua-project.com (127.0.0.1) port 80 (#0)
> GET /page HTTP/1.1
> User-Agent: curl/7.29.0
> Host: lua-project.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: openresty
< Date: Mon, 15 Apr 2019 14:26:32 GMT
< Content-Type: application/octet-stream
< Content-Length: 251
< Connection: keep-alive
< Nginx-Cache: HIT
< 
{"product_list":[{"stock":2000,"product_img":"xxxx.com.png","title":"球鞋","product_id":123},{"stock":3000,"product_img":"xxxx.com.png","title":"球拍","product_id":456},{"stock":15,"product_img":"xxxx.com.png","title":"球衣","product_id":789}]}
* Connection #0 to host lua-project.com left intact

项目二: 投放接口的缓存预案

功能使用场景:排期投放后台,运营推广一些商品、banner、入口、收藏等等。大促活动有时候接口会挂掉。预案就是万一挂掉。打开预案然后走离线缓存。

项目三:短链(生成、跳转)、小程序码

功能使用场景:

项目四:商品详情、商品列表等的fastcgi_cache

功能使用场景:对商品详情页、商品列表进行 fastcgi_cache。

架构图如下:

image.png

先来看看fast_cgi 怎么用。

首先准备了两个文件,一个叫product.php。mt_rand 是方便看效果。

<?php

//假装从数据库(或者redis之类)拿出来商品的数据

$productDetail = ["title"=>"球衣", "product_img"=> "http://xxxx.com/xxx.png", "detail"=>"纯棉吸汗,迪卡侬限量版", "stock"=>mt_rand(100,1000)]; 

exit(json_encode($productDetail, JSON_UNESCAPED_UNICODE));

nginx.conf 配置

 fastcgi_cache_path /home/nobody/fastcgicache levels=1:2 keys_zone=fastcgi-cache:8m inactive=1h max_size=10m
location /product.php {
    fastcgi_pass 127.0.0.1:9000; # 指定FastCGI服务器监听端口与地址
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_sc
ript_name;
    include fastcgi_params;
    # 缓存策略
    fastcgi_cache fastcgi-cache;
    fastcgi_cache_key "$scheme$request_method$host$request_
uri"; # 缓存key规则
    fastcgi_cache_methods POST; # 默认GET HEAD 即便你不列出来也支持。但是其他的就不行了。如果你不指定POST就不能用。curl -X POST lua-project.com/product.php
    fastcgi_cache_valid 200 10s; # 指定http返回代码指定缓存时间
}

cd /home/nobody/fastcgicache && watch tree。看下缓存文件是否生成了。

curl lua-project.com/product.php

看到

.
└── b
    └── c5
    └── 8d104512ade8f7d3ecb73df78da3cc5b

如果你想验证内容的话。可以cat下。当然你也可以watch cat 这个文件。上面缓存是10s。10s后再curl,watch cat 的内容就变更了。

串下流程

1.先用fiddler抓包。详情页。

image.png

一个详情页调用了三个接口。以第一个为例。我们看QueryString 里面的几个关键字(红框),methodproduct_id

2.fastcgi_cache 那台服务器上看日志。tail -f 日志 | grep 商品id

3.再看下nginx配置文件。

看到有一个key叫做fastcgi_cache_key $bus_cache_key;,文件里没找到。那在哪里呢?看到一个rewrite_by_lua_file 指令指向了一个rewrite.lua(项目文件,这个项目文件是用来设置各种缓存key)。追了追代码。找到了 $bus_cache_key设置地方。以上面详情页为例self.busCacheKey = self.busCacheKey .. '-' .. prd,也就是querystring的method字段值product_detail-商品id(product_detail-1233344)

去缓存的目录输出下缓存文件的信息。看到里面有一个Key值(其实就是你的缓存key名呗)。

一个商品详情api代码执行流程。

1.请求接口。接口fastcgi_pass 到 fasctcgi_cache集群。
2.fasctcgi_cache 服务器,先执行 init_by_lua_file 指定的init.lua,加载一些常量与包。(比如:FASTCGI_CACHE_UPSTREAM = "/shop_fastcgi_cache")
3.接着走rewrite_by_lua_file指定的rewrite.lua文件,主要干的就是准备fastcgi_cache用的key(用到后面缓存)。还有bus_location(用给location /)。
4.走location /。echo_location $bus_location。调用子请求。
5.走location = /product_detail ,执行content_by_lua_file 指定的content.lua文件。
6.content.lua执行 productDetailBodyFilter方法。
7.productDetailBodyFilter调用FASTCGI_CACHE_UPSTREAM (值为/shop_fastcgi_cache)(capture的方式)。当然这里面还做了一些动态数据的替换哈。大致是,把其他的公共参数替换了。
8.接着执行 location = /shop_fastcgi_cache ,这里做了php程序处理,顺带做了fastcgi_cache。所以下次请求进入就走缓存。缓存时间10m。

参考资料:

相关文章

  • 【轻知识】想想你工作中用到的Openresty+lua

    对项目的梳理总结。涉及到的关键字会大概说明或者换个名字。比如:动态xx改成动态数据。不然一看xx就知道是干啥的了。...

  • 【轻知识】递归、想想你工作用到的递归

    可能想到递归,就想到了生兔子、走台阶(这两个应该都是斐波那契吧)、阶乘、二叉树的前中后(深度遍历)、无限分类、打印...

  • 想你

    想你 深深的想 浅浅的想 深得暗无天日 浅得云淡风轻 深得暗无天日 浅浅的想 深深的想 想你

  • 那是你的损失。

    最近有点郁闷,每天学很多知识,但是有时候从书本上学来的知识想应用到工作中感觉又用不上。就拿我在工厂上班来说吧,我说...

  • #30天专注成长计划#R2Day17专注陪伴

    学到的知识如何应用到工作中? 被问到了~求答案!!! Moreover,I need tothink about ...

  • 读后感

    当你想要将通过读书获得的知识和感悟活用到工作中时,重点其实在“读后”

  • 待整理内容

    *: 记录工作中用到但是没时间深入了解的知识点 把对象直接写入文件中, ObjectOutputStream ex...

  • Json 基础知识

    Json 基础知识,工作中用到,简单了解下 一、 json 相关概念 json 插队学习 json是什么? jso...

  • 工作中用到的Marshmallow

    最近在Nomad Health实习,当从前端返回json object的时候,我们要通过mongoengine存到...

  • 工作中用到的命令

    查询导流日志中4716广告位的dpl链接:grep -a '4716' 2020-06-22.0.log |gre...

网友评论

      本文标题:【轻知识】想想你工作中用到的Openresty+lua

      本文链接:https://www.haomeiwen.com/subject/kcogiqtx.html