# 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; }
Copied!
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);
Copied!
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); }
Copied!
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"
Copied!
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 })
Copied!
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
Copied!
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; }
Copied!
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>
Copied!
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
Copied!
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
Copied!
2
3
4
5
6
7
8
9
10
11