1).关闭Linux数据库服务器 systemctl stop mariadb
2).关闭Linux中的tomcat服务器
3).关闭Linux中的Nginx服务器
[root@localhost sbin]# ./nginx -s stop
5).修改数据库链接地址
spring:
datasource:
#引入druid数据源
#type: com.alibaba.druid.pool.DruidDataSource
#driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
6).修改图片上传的路径
image.localDir=D:/JT-SOFT/images
#image.localDir=/usr/local/src/images
image.imageUrl=http://image.jt.com
image.imageTypes=.jpg,.png,.gif,.jpeg
说明:使用缓存可以有效的降低用户访问物理设备的频次,有效的减少并发的压力。保护后端真实的服务器。
1.缓存应该使用什么样的数据结构. K-V KEY必须唯一
2.如果需要缓存进行快速的读取,首先开发语言如何选择? C语言 软件的运行环境如何选择. 内存中
3.如何防止内存数据丢失! 缺点: 断电即擦除 内存数据的持久化操作(内存数据保存到磁盘中)
4.缓存的空间大小如何维护. 不能一直存,有时也会删除数据 如何操作? 内存优化算法: LRU算法/LFU算法
5.缓存使用如何防止宕机带来的影响 (HA)高可用 部署redis集群.
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)
nosql: 非关系型数据库 redis ,mongdb,hbase;
消息中间件: 主要的作用是为了实现数据的平滑过渡,让程序调用更加流畅(润滑剂)
性能问题: 读速度 11.2万次/秒 写 8.6万次/秒 平均 10万次/秒
说明:在redis的根目录中执行
1). make
2). make install
1).补充知识
如果修改配置文件时,出现了.swp文件,则表示上一次改文件没有正确的保存,生成了保护性文件.所以一般删除改文件即可
方式1: 如果提示按D删除,则按D
方式2: 如果没有按D提示,则 采用 rm -rf .xxxxx.swp
1).命令 vim redis.conf
2).修改ip绑定
3).修改保护模式
4).开启后台启动
1.启动redis redis-server redis.conf
2.进入客户端 redis-cli -p 6379
3.关闭redis redis-cli -p 6379 shutdown
简化操作: 如果操作的redis是默认的端口 则可以省略不写.
redis-cli & redis-cli shutdown
<!--spring整合redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
package com.jt.test;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;
public class TestRedis {
/**
* 1.spring整合redis
* 报错说明:
* 1).如果测试过程中报错 则检查redis配置文件 改3处
* 2).检查redis启动方式 redis-server redis.conf
* 3).检查Linux的防火墙
* 做完的 测试其他命令.
*/
@Test
public void testString01() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
//2.操作redis
jedis.set("a", "redis入门案例");
String value = jedis.get("a");
System.out.println(value);
}
@Test
public void testString02() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
//2.判断当前数据是否存在
if(jedis.exists("a")) {
System.out.println(jedis.get("a"));
}else {
jedis.set("a", "测试是否存在的方法");
}
}
/**
* 1.能否简化是否存在的判断
* 2.如果该数据不存在时修改数据,否则不修改
* setnx方法: 只有当数据不存在时赋值.
*/
@Test
public void testString03() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.setnx("a", "测试setnx方法1");
jedis.setnx("a", "测试setnx方法2");
System.out.println(jedis.get("a"));
}
/**
* 为数据添加超时时间
* @throws InterruptedException
* setex方法 保证赋值操作和添加超时时间的操作的原子性
* 原子性: 要么同时成功,要么同时失败(类似事务)
*/
@Test
public void testString04() throws InterruptedException {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.set("a", "aaaa"); //如果程序报错,则超时方法将不会执行,改数据将永不超时
//程序报错,意外终止!!!!!!!
jedis.expire("a", 20); //添加超时时间 不是原子性操作
Thread.sleep(2000);
System.out.println("剩余存活时间:"+jedis.ttl("a"));
//2.实现原子性操作
jedis.setex("b", 20, "原子性测试");
System.out.println(jedis.get("b"));
}
/**
*
* 1.只有数据不存在时允许修改
* 2.要求实现添加超时时间,并且是原子性操作
* SetParams 参数说明:
* 1.NX 只有key不存在时才能修改
* 2.XX 只有key存在时,才能修改
* 3.PX 添加的时间单位是毫秒
* 4.EX 添加的时间单位是秒
*/
@Test
public void testString05(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
SetParams params = new SetParams();
params.xx().ex(20);
jedis.set("aa", "测试A", params);
jedis.set("aa", "测试B", params);
System.out.println(jedis.get("aa"));
}
/**
* 存储一类数据时,可以使用hash.
*/
@Test
public void testHASH(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.hset("user", "name", "tomcat");
jedis.hset("user", "id", "100");
System.out.println(jedis.hgetAll("user"));
}
@Test
public void testList(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.lpush("list", "1","2","3","4");
System.out.println(jedis.rpop("list"));
}
//控制事务
@Test
public void testTx(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
Transaction transaction = jedis.multi(); //2.开启事务
try {
transaction.set("aaa", "aaa");
transaction.set("bbb", "bbbbb");
transaction.set("ccc", "cccccc");
transaction.exec(); //事务提交
} catch (Exception e) {
e.printStackTrace();
transaction.discard(); //事务回滚
}
}
}
说明:将jedis对象交给spring容器进行管理.之后哪里需要直接注入即可.
步骤:
1.编辑redis.properties文件,指定redis节点的ip:port
2.由于redis比较重要,很多业务系统都需要调用,所以将redis整合写入common
3.通过配置类(配置文件)形式整合redis.
redis.host=192.168.126.129
redis.port=6379
@Configuration //我是一个配置类 一般都会与@Bean联用
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;
//将返回值的结果交给spring容器进行管理,如果以后想要使用该对象则可以直接注入.
@Bean
public Jedis jedis() {
return new Jedis(host, port);
}
}
package com.jt.test;
import java.util.Date;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;
public class TestObjectMapper {
//改对象就是工具api 有且只有一份即可.并且不允许别人修改.
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 目的: 实现对象与json串之间的转化
* 步骤1: 将对象转化为json
* 步骤2: 将json转化为对象
* 利用ObjectMapper 工具API实现
* @throws JsonProcessingException
*/
@Test
public void test01() throws JsonProcessingException {
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(101L).setItemDesc("json转化测试")
.setCreated(new Date()).setUpdated(itemDesc.getCreated());
//1.将对象转化为JSON 调用的是对象的get方法
String json = MAPPER.writeValueAsString(itemDesc);
System.out.println(json);
//2.将json转化为对象 传递需要转化之后的class类型 调用是对象的set方法
ItemDesc itemDesc2 = MAPPER.readValue(json, ItemDesc.class);
System.out.println(itemDesc2.getItemDesc());
}
}
说明:改API主要负责将对象转化为JSON,将JSON转化为对象,同时优化异常处理.
package com.jt.util;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperUtil {
//json与对象的转化 优化异常处理
private static final ObjectMapper MAPPER = new ObjectMapper();
//1.将对象转化为JSON
public static String toJSON(Object target) {
if(target == null) {
throw new NullPointerException("taget数据为null");
}
try {
return MAPPER.writeValueAsString(target);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException(e); //如果转化过程中有问题则直接抛出异常
}
}
//2. 将json串转化为对象 用户传递什么样的类型,就返回什么样的对象!!!
// 定义了一个泛型对象 代表任意类型
public static <T> T toObject(String json,Class<T> targetClass) {
if(StringUtils.isEmpty(json) || targetClass == null) {
throw new NullPointerException("参数不能为null");
}
try {
return MAPPER.readValue(json, targetClass);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
业务说明:商品分类信息可以使用redis缓存实现该功能.
步骤:
1.当用户点击商品分类按钮时开始获取服务端数据.
2.先查询redis缓存是否有数据
3.如果redis中没有数据,则查询数据库.之后将查询的结果保存到redis中
4.如果redis中有数据,则直接返回缓存记录.
数据库存储结构问题:
K-V结构 key=“包含parentId” value= 查询之后的返回值结果 List
String数据类型 redis使用频率最高.
问题: List----JSON—>Stirng
1.试着完成redis缓存 修改源码即可
2.复习AOP 利用aop形式实现redis缓存