本文是在Nginx+lua实现本地HTML页面动态渲染文章的基础上进行的。
在Nginx+lua实现本地HTML页面动态渲染中我们已经解决了在Nginx本地动态渲染HTML以及数据在Nginx中进行存取,现在就来解决下一个问题,在Nginx中向后台服务发送请求获取数据。
添加HTTP依赖
进入到OpenResty安装目录根目录下的lualib/resty目录下
wget https://github.com/ledgetech/lua-resty-http/raw/master/lib/resty/http_headers.lua
wget https://github.com/ledgetech/lua-resty-http/raw/master/lib/resty/http.lua
编写后台服务
代码非常简单,一个People对象,一个根据username获取People实例的get方法,这里为了方便,就直接使用堆内存预先存放一些对象。
public class PeopleModel {
private String username;
private Integer age;
private String hobby;
public PeopleModel(String username, Integer age, String hobby) {
this.username = username;
this.age = age;
this.hobby = hobby;
}
... 省略get/get
}
@RestController
@RequestMapping("peopleaction")
public class PeopleAction {
private static final Map<String, PeopleModel> map = new HashMap<String, PeopleModel>();
static {
map.put("张三", new PeopleModel("张三", 18, "爱好打篮球"));
map.put("李四", new PeopleModel("李四", 28, "爱好听音乐"));
}
@GetMapping("peopleInfo")
public PeopleModel getPeopleInfo(String username) {
PeopleModel peopleInfo = map.get(username);
return peopleInfo;
}
}
编辑lua脚本
local name = ngx.var.arg_name
local nameKey = "name_"..name
local cjson = require("cjson")
local cache = ngx.shared.cache
local peopleInfo = cache:get(nameKey)
if peopleInfo == "" or peopleInfo == nil then
--引入http依赖
local http = require("resty.http")
--创建http实例
local httpc = http:new()
--向后台发送请求
local resp, err = httpc:request_uri("http://192.168.199.177:8080", {
method = "GET",
path = "/peopleaction/peopleInfo?username="..name
})
--如果失败就向客户端返回一个请求出错
if err then
ngx.say("请求出错:", err)
return
end
-- 缓存过期时间设置为10分钟
cache:set(nameKey, resp.body, 60 * 10)
--反序列化
peopleInfo = cjson.decode(resp.body)
else
local peopleInfoJSON = cjson.decode(peopleInfo)
peopleInfo = {
username = peopleInfoJSON.username,
age = peopleInfoJSON.age,
hobby = peopleInfoJSON.hobby
}
end
local template = require("resty.template")
template.render("hellotpl.html", peopleInfo)
在HTML模板中添加一个爱好字段
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello</title>
</head>
<body>
姓名, {* username *}
<br>
年龄, {* age *}
<br>
爱好, {* hobby *}
</body>
</html>
实验
获取李四的信息:http://192.168.199.104/hello?name=李四
获取张三的信息:http://192.168.199.104/hello?name=张三
10分钟内多次请求相同用户名的信息,观察后端服务请求日志,发现已经不会有请求进入了,nginx层缓存成功。
总结
其实到这里为止,我们已经完成了多级缓存架构中的Nginx应用层的开发和部署。整体流程图如下,从后端服务拉取数据是基于HTTP的,所以具有广泛的适用性,只要你的服务提供了HTTP服务接口即可。另外也可以使用OpenResty中的其他模块,直接从Redis、MySQL中拉取数据,根据自己的业务去定。