当前位置: 首页 > news >正文

汕尾北京网站建设/下载百度免费

汕尾北京网站建设,下载百度免费,网站建设有利于,别人帮自己做网站有后门吗说明:项目中使用到Redis,正常情况,我们会在用户首次查询数据的同时把该数据按照一定命名规则,存储到Redis中,称为冷启动(如下图),这种方式在一些情况下可能会给数据库带来较大的压力…

说明:项目中使用到Redis,正常情况,我们会在用户首次查询数据的同时把该数据按照一定命名规则,存储到Redis中,称为冷启动(如下图),这种方式在一些情况下可能会给数据库带来较大的压力。

因此,我们可以使用另一种方式,在项目启动的时候就提前把一些热点数据提前查询并保存到Redis中,称为缓存预热

(冷启动)

在这里插入图片描述

环境准备

例如,现在我数据库中有以下用户的信息,我想在项目启动的时候就把这些数据存入到数据库中;

在这里插入图片描述

以下操作在CentOS系统中完成;

代码实现

第一步:安装OpenResty

OpenResty是基于Nginx的高性能Web平台,可方便地搭建能够超过并发、扩展性极高的动态Web应用、Web服务和动态网关。OpenResty具备以下特点:

  • Nginx的完整功能;

  • 基于Lua语言,集成了大量精良的Lua库、第三方模块;

  • 允许使用Lua自定义业务逻辑、自定义库;

可参考安装OpenResty,这不是本文的重点;

第二步:配置环境变量

安装完OpenResty之后,先配置一下Nginx的环境变量;

vi /etc/profile

在文件最下面,加入下面两行配置

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

在这里插入图片描述

保存退出,在敲下面的命令,使配置生效

source /etc/profile

在这里插入图片描述

第三步:修改配置

OpenResty会默认安装在/usr/local/openresty路径下,可在该目录在看到一个Nginx目录,也就是说OpenResty拥有Nginx的功能。进入到Nginx目录,找到配置文件,进行自适应修改:

在这里插入图片描述


如下修改:

#user  nobody;
worker_processes  1;
error_log  logs/error.log;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       8081;server_name  localhost;location / {root   html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}# 设置捕捉的请求路径location  /user {# 默认的响应类型default_type application/json;# 响应结果由lua/user.lua文件来决定,待会儿我们来编写这个文件content_by_lua_file lua/user.lua;}}#lua 模块lua_package_path "/usr/local/openresty/lualib/?.lua;;";#c模块     lua_package_cpath "/usr/local/openresty/lualib/?.so;;";  # 共享字典,就是本地缓存,名称为user_cache,大小150mlua_shared_dict user_cache 150m; 
}

第四步:启动测试

OpenResty启动、停止、重新加载配置的命令与Nginx基本一样,敲nginx启动OpenResty;

# 启动服务
nginx# 停止服务
ngxin -s stop# 重新加载配置
ngxin -s stop

在这里插入图片描述

敲IP地址加端口号,看到以下内容,即为安装成功

在这里插入图片描述

第五步:启动MySQL、Redis服务

接下来,使用Docker启动mysql、redis服务,注意使用云服务器需要开放相关端口,使用虚拟机需要关闭防火墙;

在启动mysql之前,先在/tmp目录下创建一个mysql文件夹,用于挂载容器的数据和配置文件目录;

# 进入/tmp目录
cd /tmp# 创建文件夹
mkdir mysql# 进入mysql目录
cd mysql

在这里插入图片描述

启动mysql服务,账号密码设置为:root、123456(注意以下命令需要在mysql目录下执行)

docker run \-p 3306:3306 \--name mysql \-v $PWD/conf:/etc/mysql/conf.d \-v $PWD/logs:/logs \-v $PWD/data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=123456 \--privileged \-d \mysql:5.7.25

在这里插入图片描述

敲下面的命令,使用docker启动redis服务;

docker run --name redis -p 6379:6379 -d redis redis-server --appendonly yes

在这里插入图片描述

第六步:编写代码

服务启动后,来进行代码的编写,以下是一个简单的SpringBoot项目,DAO层使用的是Mybatis-plus,只有两个接口,一个查询所有用户信息,一个根据用户ID查询用户信息。

controller层代码

import java.util.List;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 查询所有用户信息* @return*/@GetMapping("list")public List<User> getUsers() {return userService.list();}/*** 根据ID查询用户信息* @param id* @return*/@GetMapping("{id}")public User getUserById(@PathVariable Long id) {return userService.getById(id);}
}

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.hzy</groupId><artifactId>caffeine_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/></parent><dependencies><!--web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!--mysql驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!--druid数据库连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><!--测试类--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--hutool工具包依赖--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.6</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

配置文件,注意IP地址和端口号,如果使用的是云服务器,注意MySQL连接时需要加上useSSL=false

server:port: 8081
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://IP地址:3306/db_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: 123456mvc:pathmatch:matching-strategy: ant_path_matcherredis:host: IP地址
mybatis-plus:type-aliases-package: com.hzy.pojoconfig-locations: classpath/mapper/*.xml

第七步:启动测试

这些环境搭建完成后,应该启动一下项目,看是否能正常跑起来;

(启动正常)

在这里插入图片描述

(测试接口,也没问题)
在这里插入图片描述

第八步:缓存预热实现

创建一个RedisHandler类,该类的作用是,在项目启动时访问数据库,查询所有用户信息并存入到数据库中;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hzy.pojo.User;
import com.hzy.service.UserService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.List;@Component
public class RedisHandler implements InitializingBean {@Autowiredprivate StringRedisTemplate redisTemplate;@Autowiredprivate UserService userService;private static final ObjectMapper MAPPER = new ObjectMapper();@Overridepublic void afterPropertiesSet() throws Exception {// 初始化缓存// 1.查询所有用户信息List<User> userList = userService.list();// 2.放入缓存for (User user : userList) {// 2.1.将user对象序列化为JSONString json = MAPPER.writeValueAsString(user);// 2.2.设置key前缀,存入redisredisTemplate.opsForValue().set("user:id:" + user.getId(), json);}}
}

第九步:编写lua文件

接下来,需要编写两个lua文件,一个是通用操作(common.lua),一个是redis的查询操作(user.lua),内容分别如下:

common.lua文件在 /usr/local/openresty/lualib/common.lua 里面,使用以下命令编辑,如下:

vi /usr/local/openresty/lualib/common.lua

内容如下:

-- 导入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 thenngx.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 thenngx.log(ngx.ERR, "连接redis失败 : ", err)return nilend-- 查询redislocal resp, err = red:get(key)-- 查询失败处理if not resp thenngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)end--得到的数据为空处理if resp == ngx.null thenresp = nilngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)endclose_redis(red)return resp
end-- 封装函数,发送http请求,并解析响应
local function read_http(path, params)local resp = ngx.location.capture(path,{method = ngx.HTTP_GET,args = params,})if not resp then-- 记录错误信息,返回404ngx.log(ngx.ERR, "http查询失败, path: ", path , ", args: ", args)ngx.exit(404)endreturn resp.body
end
-- 将方法导出
local _M = {  read_http = read_http,read_redis = read_redis
}  
return _M

user.lua文件是自定义的,我们在openresty目录下创建一个lua文件夹,用于存放该文件夹

cd /usr/local/openrestymkdir lua

在这里插入图片描述

user.lua文件内容如下:

-- 导入common函数库
local common = require('common')
local read_http = common.read_http
local read_redis = common.read_redis
-- 导入cjson库
local cjson = require('cjson')
-- 导入共享词典,本地缓存
local user_cache = ngx.shared.user_cache-- 封装查询函数
function read_data(key, expire, path, params)-- 查询本地缓存local val = user_cache:get(key)if not val thenngx.log(ngx.ERR, "本地缓存查询失败,尝试查询Redis, key: ", key)-- 查询redisval = read_redis("127.0.0.1", 6379, key)-- 判断查询结果if not val thenngx.log(ngx.ERR, "redis查询失败,尝试查询http, key: ", key)-- redis查询失败,去查询httpval = read_http(path, params)endend-- 查询成功,把数据写入本地缓存user_cache:set(key, val, expire)-- 返回数据return val
end-- 获取路径参数
local id = ngx.var[1]-- 查询商品信息
local userJSON = read_data("user:id:" .. id, 1800,  "/user/" .. id, nil)-- JSON转化为lua的table
local user = cjson.decode(userJSON)-- 把user序列化为json 返回结果
ngx.say(cjson.encode(user))

第十步:重启项目

此时在云服务器上进入redis容器,打开redis客户端,查看数据内容;

# 进入redis容器
docker exec -it redis bash
# 打开redis客户端
redis-cli
# 查看redis所有的键值
keys *

什么都没有,nothing;

在这里插入图片描述

此时,我们重启项目;

在这里插入图片描述

再敲命令,查看redis所有值,可以看到所有的数据都已经存入了,可根据key查询到每一条用户的信息;

在这里插入图片描述

到此,Redis缓存预热已完成;

总结

Redis缓存预热的执行是与项目启动一起的,不需要用户发送请求,是在项目启动时自发的操作。

http://www.jmfq.cn/news/5317957.html

相关文章:

  • 铁岭网站建设/中国十大seo
  • 教育部网站 专业建设方案/磁力链
  • 太原网站建设与维护/成功的营销案例及分析
  • baidu网站建设/军事新闻最新
  • 石家庄正规网站建设公司/站长基地
  • 网站建设明薇通网络服务好/企业网站官网
  • 陕西省建设工程监理协会网站 查询/seo外包一共多少钱
  • 物流建设网站总结/十大接单推广平台
  • 上海网安网站建设/竞价恶意点击报案
  • 政府网站建设要求 国务院/网络营销模式案例
  • php 网站建设流程/如何优化关键词的排名
  • 云南省保山建设网站/东莞市网络seo推广服务机构
  • 网站建设费 无形资产/网站怎么快速被百度收录
  • 怎样让网站显示网站建设中/交换链接营销的经典案例
  • php网站建设题目/如何推广app让别人注册
  • 凡科建设网站靠谱吗/百度一下首页问问
  • 网站建设认准猪八戒网/网络营销与直播电商专业介绍
  • 邢台市路桥建设公司网站/宣传推广方案
  • 中国城市建设控股集团有限公司网站/百度推广关键词怎么优化
  • 福州光电网站建设/惠州网站排名提升
  • 网站建设任务分解/网络营销策划方案怎么做
  • 晋城建设局官方网站/福州seo代理商
  • 劳务派遣东莞网站建设/精准信息预测
  • 优质高等职业院校建设网站/营销推广有哪些形式
  • 广东网站建设制作价格/2024年阳性最新症状
  • 新乡网站建设设计公司哪家好/怎样做网站平台
  • 广东高职一流专业建设专题网站/百度广告开户
  • 体育网站建设视频/种子搜索引擎torrentkitty
  • 傻瓜网站建设软件/seo排名优化技巧
  • 朝阳网站建设 高碑店/爱站长工具