# 055. 基于 nginx + lua + java 完成多级缓存架构的核心业务逻辑(二)
# 缓存服务实现
cn.mrcode.cachepdp.eshop.cache.controller.CacheController
/**
* 这里的代码别看着奇怪,简单回顾下之前的流程: 1. nginx 获取 redis 缓存 2. 获取不到再获取服务的堆缓存(也就是这里的 ecache) 3.
* 还获取不到就需要去数据库获取并重建缓存
*/
@RequestMapping("/getProductInfo")
@ResponseBody
public ProductInfo getProductInfo(Long productId) {
ProductInfo productInfo = cacheService.getProductInfoOfReidsCache(productId);
log.info("从 redis 中获取商品信息");
if (productInfo == null) {
productInfo = cacheService.getProductInfoFromLocalCache(productId);
log.info("从 ehcache 中获取商品信息");
}
if (productInfo == null) {
// 两级缓存中都获取不到数据,那么就需要从数据源重新拉取数据,重建缓存
// 但是这里暂时不讲
log.info("缓存重建 商品信息");
}
return productInfo;
}
@RequestMapping("/getShopInfo")
@ResponseBody
public ShopInfo getShopInfo(Long shopId) {
ShopInfo shopInfo = cacheService.getShopInfoOfReidsCache(shopId);
log.info("从 redis 中获取店铺信息");
if (shopInfo == null) {
shopInfo = cacheService.getShopInfoFromLocalCache(shopId);
log.info("从 ehcache 中获取店铺信息");
}
if (shopInfo == null) {
// 两级缓存中都获取不到数据,那么就需要从数据源重新拉取数据,重建缓存
// 但是这里暂时不讲
log.info("缓存重建 店铺信息");
}
return shopInfo;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
cn.mrcode.cachepdp.eshop.cache.service.CacheService
/**
* 从 redis 中获取商品
*/
ProductInfo getProductInfoOfReidsCache(Long productId);
/**
* 从 redis 中获取店铺信息
*/
ShopInfo getShopInfoOfReidsCache(Long shopId);
2
3
4
5
6
7
8
9
10
cn.mrcode.cachepdp.eshop.cache.service.impl.CacheServiceImpl
@Override
public ProductInfo getProductInfoOfReidsCache(Long productId) {
String key = "product_info_" + productId;
String json = jedisCluster.get(key);
return JSON.parseObject(json, ProductInfo.class);
}
@Override
public ShopInfo getShopInfoOfReidsCache(Long shopId) {
String key = "shop_info_" + shopId;
String json = jedisCluster.get(key);
return JSON.parseObject(json, ShopInfo.class);
}
2
3
4
5
6
7
8
9
10
11
12
13
# 测试应用层
访问地址:http://eshop-cache02/product?productId=1&shopId=1
tail -f /usr/servers/nginx/logs/error.log
可以看到如下的错误:
2019/05/06 22:46:59 [error] 8834#0: *46 lua entry thread aborted: runtime error: /usr/hello/lualib/resty/http.lua:929: bad argument #2 to 'set_keepalive' (number expected, got nil)
stack traceback:
coroutine 0:
[C]: in function 'set_keepalive'
/usr/hello/lualib/resty/http.lua:929: in function 'request_uri'
/usr/hello/lua/product.lua:24: in function </usr/hello/lua/product.lua:1>, client: 192.168.99.1, server: _, request: "GET /product?productId=1&shopId=1 HTTP/1.1", host: "eshop-cache02"
2
3
4
5
6
7
8
9
这次通过 debug 后端服务,服务中能请求到了,响应之后报错 bad argument #2 to 'set_keepalive'
这个问题在前面记忆中已经解决过了,设置下 keepalive=false
即可
local resp, err = httpc:request_uri("http://192.168.99.111:6002",{
method = "GET",
path = "/getShopInfo?shopId="..shopId,
keepalive=false
})
2
3
4
5
再次访问:http://eshop-cache02/product?productId=1&shopId=1
product id: 1
product name: iphone7手机
product picture list: a.jpg,b.jpg
product specification: iphone7的规格
product service: iphone7的售后服务
product color: 红色,白色,黑色
product size: 5.5
shop id: 1
shop name: 小王的手机店
shop level: 5
shop good cooment rate: 0.99
2
3
4
5
6
7
8
9
10
11
如果响应的中文乱码,需要在拦截的地方添加编码
location /product {
default_type 'text/html';
charset utf-8;
content_by_lua_file /usr/hello/lua/product.lua;
}
2
3
4
5
# 优化模板文件
vi /usr/hello/templates/product.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品详情页</title>
</head>
<body>
商品 ID: {* productId *}<br/>
商品名称: {* productName *}<br/>
商品图片列表: {* productPictureList *}<br/>
商品规格: {* productSpecification *}<br/>
商品售后服务: {* productService *}<br/>
商品颜色: {* productColor *}<br/>
商品尺寸: {* productSize *}<br/>
店铺 ID: {* shopId *}<br/>
店铺名称: {* shopName *}<br/>
店铺级别: {* shopLevel *}<br/>
店铺评分: {* shopGoodCommentRate *}<br/>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
记得重启 /usr/servers/nginx/sbin/nginx -s reload
再次访问:http://eshop-cache02/product?productId=1&shopId=1
商品 ID: 1
商品名称: iphone7手机
商品图片列表: a.jpg,b.jpg
商品规格: iphone7的规格
商品售后服务: iphone7的售后服务
商品颜色: 红色,白色,黑色
商品尺寸: 5.5
店铺 ID: 1
店铺名称: 小王的手机店
店铺级别: 5
店铺评分: 0.99
2
3
4
5
6
7
8
9
10
11
# 测试分发层
刚刚应用层已经测试通过,现在来从分发层测试
访问:http://eshop-cache03/product?method=product&productId=1&shopId=1
TIP
注意,由于使用的是 hash 分发,可以在 eshop-cache01 和 eshop-cache02 上显示访问日志
tail -f /usr/servers/nginx/logs/access.log
这样就能看到被分发到哪台机器上去了。
成功响应 html 信息
商品 ID: 1
商品名称: iphone7手机
商品图片列表: a.jpg,b.jpg
商品规格: iphone7的规格
商品售后服务: iphone7的售后服务
商品颜色: 红色,白色,黑色
商品尺寸: 5.5
店铺 ID: 1
店铺名称: 小王的手机店
店铺级别: 5
店铺评分: 0.99
2
3
4
5
6
7
8
9
10
11