nginix+openresty+redis+tomcat实现多级缓存

首先win中的nginx配置文件

 upstream nginx-cluster{
        #nginx业务集群,redis集群,Tomcat集群;
        server 192.168.216.169:8081;
    }
    server {
        listen       80;
        server_name  localhost;

	location /api {
            proxy_pass http://nginx-cluster;
        }

安装OpenResty

1)安装开发库

首先要安装OpenResty的依赖开发库,执行命令:

yum install -y pcre-devel openssl-devel gcc --skip-broken

2)安装OpenResty仓库

你可以在你的 CentOS 系统中添加 openresty 仓库,这样就可以便于未来安装或更新我们的软件包(通过 yum check-update 命令)。运行下面的命令就可以添加我们的仓库:

yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

如果提示说命令不存在,则运行:

yum install -y yum-utils 

然后再重复上面的命令

3)安装OpenResty

然后就可以像下面这样安装软件包,比如 openresty

yum install -y openresty

4)安装opm工具

opm是OpenResty的一个管理工具,可以帮助我们安装一个第三方的Lua模块。

如果你想安装命令行工具 opm,那么可以像下面这样安装 openresty-opm 包:

yum install -y openresty-opm

6)配置nginx的环境变量

打开配置文件:

vi /etc/profile

在最下面加入两行:

export NGINX_HOME=/usr/local/openresty/nginx
export PATH=${NGINX_HOME}/sbin:$PATH

NGINX_HOME:后面是OpenResty安装目录下的nginx的目录

然后让配置生效:

source /etc/profile

OpenResty中的nginx配置文件

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    #lua 模块
    lua_package_path "/usr/local/openresty/lualib/?.lua;;";
    #c模块     
    lua_package_cpath "/usr/local/openresty/lualib/?.so;;";  
    #nginx开启本地缓存
    lua_shared_dict item_cache 150m;

    #tomcat集群
    upstream tomcat-cluster{
        #根据hash固定访问同一台tomcat(为了命中缓存)
        hash $request_uri;
        server 192.168.216.1:8081;
        server 192.168.216.1:8082;
    }

    server {
        listen       8081;
        server_name  localhost;
        #监听到/item请求,代理到ip端口,然后由lua模块工具包给出请求参数
        location /item{
            proxy_pass http://tomcat-cluster;
        }
        location ~ /api/item/(\d+) {
            #默认的响应类型
            default_type application/json;
            #响应的结果由lua/item.lua决定!
            content_by_lua_file lua/item.lua;
        }

封装的请求处理函数代码common.lua代码:

-- 封装函数,发送http请求,并解析响应(tomcat请求)
local function read_http(path, params)
    local resp = ngx.location.capture(path,{
        method = ngx.HTTP_GET,
        args = params,
    })
    if not resp then
        -- 记录错误信息,返回404
        ngx.log(ngx.ERR, "http not found, path: ", path , ", args: ", args)
        ngx.exit(404)
    end
    return resp.body
end



--封装redis请求
--导入redis 
local redis = require("resty.redis")
--初始化redis对象
local  red =redis:new ()
--超时时间
red:set_timeouts(1000,1000,1000)
-- 关闭redis连接的工具方法,其实是放入连接池
local function close_redis(red)
    local pool_max_idle_time = 10000 -- 连接的空闲时间,单位是毫秒
    local pool_size = 100 --连接池大小
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    if not ok then
        ngx.log(ngx.ERR, "放入redis连接池失败: ", err)
    end
end
-- 查询redis的方法 ip和port是redis地址,key是查询的key
local function read_redis(ip, port, key)
    -- 获取一个连接
    local ok, err = red:connect(ip, port)
    if not ok then
        ngx.log(ngx.ERR, "连接redis失败 : ", err)
        return nil
    end
    -- 查询redis
    local resp, err = red:get(key)
    -- 查询失败处理
    if not resp then
        ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
    end
    --得到的数据为空处理
    if resp == ngx.null then
        resp = nil
        ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
    end
    close_redis(red)
    return resp
end


-- 将方法导出
local _M = {  
    read_http = read_http,
    read_redis= read_redis
}  
return _M

 lua/item.lua代码:

--导入工具包
local common = require('common')
--导入转json工具包
local cjson=require('cjson')
-- 导入本地缓存
local item_cache=ngx.shared.item_cache
-- 取到函数
local read_redis=common.read_redis
local read_http=common.read_http

--查询封装为一个
function read_data(key,outime,path,params)
    -- 查nginx本地缓存
    local val=item_cache:get(key)
    if not val then
        ngx.log(ngx.ERR,"nginx无本地缓存,尝试查询redis,key",key)
        --查redis
        val=read_redis("192.168.216.169",6379,key)
        --判断结果
        if not val then
            ngx.log(ngx.ERR,"redis查询失败,尝试http查询,key:",key)
            --http查询
            val=read_http(path,params)
        end
    end
    -- 查询成功,存到本地
    item_cache:set(key,val,outime)
    -- 返回数据
    return val
end

--参数路径
local id = ngx.var[1]
--商品
local itemJSON = read_data("item:id"..id,18000,"/item/"..id,nil)
--库存
local itemStockJSON = read_data("stock:id"..id,60,"/item/stock/"..id,nil)
--转化为lua的table
local item =cjson.decode(itemJSON)
local stock =cjson.decode(itemStockJSON)
--组合
item.stock=stock.stock
item.sold=stock.sold
--item转json返回
ngx.say(cjson.encode(item))

tomcat实现线程缓存

1)引入依赖

 
            com.github.ben-manes.caffeine
            caffeine
        

2)初始化线程池

@Configuration
public class CaffineCongif {
    @Bean//初始化本地缓存库!
    public Cache itemCache() {
        return Caffeine.newBuilder()
                .initialCapacity(100)
                .maximumSize(10_000)
                .build();
    }

3)装配到controller

 @Autowired
    private Cache itemCache;

4)使用缓存;

  @GetMapping("/{id}")
    public Item findById(@PathVariable("id") Long id){
        return itemCache.get(id,key -> itemService.query()
                .ne("status", 3)
                .eq("id", id)
                .one());
    }

5)redis预热处理

@Component//redis预热处理
public class RedisHandTemple implements InitializingBean {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ItemService itemService;
    @Autowired
    private ItemStockService stockService;
    @Override
    public void afterPropertiesSet() throws Exception {
        //初始化缓存
//        1查商品
        List items= itemService.list();
        for (Item item:items){
//            1.1 item序列化为json
            String itemJson = JSON.toJSONString(item);
//            1.2 存redis
            redisTemplate.opsForValue().set("item:id"+item.getId(),itemJson);
        }

潦草记录一下,继续学习.

你可能感兴趣的:(redis,nginx,缓存)