CGB2004-京淘项目Day12

1.还原系统配置

1.1 释放Linux资源

1.1.1 停止数据库主从服务

在这里插入图片描述

1.1.2 关闭数据库服务

说明:关闭数据库服务器.
在这里插入图片描述

1.1.3 关闭tomcat/mycat服务器

在这里插入图片描述

1.1.4关闭nginx服务器

在这里插入图片描述

1.2 修改代码中的配置

1.2.1 修改YML配置文件

说明:切换端口号和url地址.
在这里插入图片描述

1.2.2 修改图片上传地址

在这里插入图片描述

1.3 修改环境配置

1.3.1 修改hosts文件

在这里插入图片描述

1.3.2 修改windows中的Nginx

修改完成之后,启动nginx服务器.
在这里插入图片描述
在这里插入图片描述

1.3.3 访问测试

检查修改的服务是否有效
在这里插入图片描述

2.Redis缓存

2.1 京淘项目架构优化

说明:为了提高数据库"查询"能力.引入缓存服务器.
在这里插入图片描述

2.2 缓存机制的介绍

说明:使用缓存机制主要的目的就是为了降低用户访问物理设备的频次.从缓存服务器中直接获取数据,快速的响应用户,提高整体的查询速度.用户体验更好.

如何实现:
1.缓存机制应该采用什么样的数据结构 进行构建? K-V结构 K必须唯一
2.应该使用什么语言进行开发? C语言
3.缓存的运行环境是哪? 内存
4.内存断电即擦除, 如何保证数据的安全性?? 实现持久化(写入磁盘)操作
5.内存中的数据如何进行优化 (不能一直存? ) 内存优化的算法 LRU算法

2.3 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).
速度快:
tomcat: 150-220/秒
nginx: 3-5万/秒
redis: 写 8.6万/秒 读 11.2万/秒 ~ 平均10万次/秒

2.3 Redis安装

2.3.1 上传Redis

在这里插入图片描述

2.3.1 解压Redis

在这里插入图片描述

2.3.2 解压Redis

在这里插入图片描述

2.3.2 编译安装Redis

1.执行编译操作 make
在这里插入图片描述
2.安装redis make install
在这里插入图片描述

2.3.3 修改redis配置文件

1).修改IP绑定
在这里插入图片描述
2).取消保护模式
在这里插入图片描述

3).开启后台启动
在这里插入图片描述

2.3.3 Redis常规命令

要求:进入redis根目录中执行.
特点:redis每次启动时都会读取配置文件. 如果需要准备多台redis则需要准备多个配置文件

1.启动命令 redis-server redis.conf
没有开启后台运行的效果
在这里插入图片描述
开启后台运行的效果
在这里插入图片描述
2.检索redis服务
在这里插入图片描述
3. 进入redis客户端中
在这里插入图片描述
4.关闭redis
方式1: redis-cli -p 6379 shutdown
方式2:
在这里插入图片描述

2.4 Redis入门案例

2.4.1 添加jar包

<!--spring整合redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

2.4.2 编辑测试API

package com.jt.test;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

//@SpringBootTest //需要依赖spring容器,从容器中动态的获取对象
public class TestRedis {

    /**
     * 完成Redis入门案例测试
     * 报错说明:
     *      1.检查Linux防火墙
     *      2.检查Redis3项配置
     *      3.重启redis.
     */
    @Test
    public void test01(){
        Jedis jedis = new Jedis("192.168.126.129",6379);
        //1.向redis中保存数据
        jedis.set("2004", "哈哈哈 今天下雨了 不负众望");
        //2.从redis中获取数据
        String value = jedis.get("2004");
        System.out.println(value);
    }

    @Test
    public void test02(){
        Jedis jedis = new Jedis("192.168.126.129",6379);

        //1.判断redis中是否存在key
        if(jedis.exists("2004")){
            //2.如果存在则设定超时时间
            jedis.expire("2004", 100);
            //3.线程暂停2秒
            try {
                Thread.sleep(2000);
                //4.获取剩余的存活时间
                Long time = jedis.ttl("2004");
                System.out.println("还能活:"+time);
                //5.撤销删除操作
                jedis.persist("2004");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 需求说明:
     *  1.redis.set操作,后面的操作会将之前的value覆盖
     *  要求:如果key已经存在,则不允许赋值.
     *  注意环境: 检查redis中是否有改数据.
     *  */
    @Test
    public void test03() {
        //A  潘石屹    B 马云
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.flushAll();   //清空redis缓存
        //如果key存在则不执行赋值操作.
        jedis.setnx("boss", "潘石屹");
        jedis.setnx("boss", "马云");
        System.out.println(jedis.get("boss"));
    }

    /**
     * 为数据添加超时时间.保证原子性操作
     * 原子性: 一起完成一起回滚
     * 锁机制: 保证原子性   死锁!!!!
     * 小结: setnx 如果key存在则不赋值
     *       setex  保证原子性操作,并且添加超时时间.
     * * */
    @Test
    public void test04() {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.setex("aaa", 20, "xxxxx"); //满足原子性需求.
    }

    /**
     * 需求:
     *  1.要求赋值操作时,如果数据已经存在则不允许赋值.
     *  2.同时要求添加超时时间 并且满足原子性要求.
     *   private static final String XX = "xx";   只有key存在时,才能赋值
     *   private static final String NX = "nx";   只有key不存在时,赋值
     *   private static final String PX = "px";   毫秒
     *   private static final String EX = "ex";   秒
     */
    @Test
    public void test05() {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        SetParams setParams = new SetParams();
        setParams.nx().ex(20);
        jedis.set("AAA", "CCCCC", setParams); //原子性要求
        System.out.println(jedis.get("AAA"));
    }

	 /*测试hash数据类型*/
    @Test
    public void testHash() {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.hset("person", "name", "tomcat");
        jedis.hset("person", "age", "100");
        Map<String,String> map = jedis.hgetAll("person");
        System.out.println(map);
    }
	
	@Test
    public void testList() {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.lpush("list", "1","2","3","4");
        String value = jedis.rpop("list");
        System.out.println(value);
    }

	 /**
     * 实现Redis 事务控制
     */
    @Test
    public void testMulti() {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        Transaction transaction = jedis.multi();
        try {
            transaction.set("AAA", "XXX");
            transaction.set("BBB", "XXX");
            transaction.exec(); //提交事务
        }catch (Exception exception){
            exception.printStackTrace();
            transaction.discard();//回滚事务
        }

    }
}

2.5 SpringBoot整合Redis

2.5.1 编辑配置文件

# 配置单台redis
redis.host=192.168.126.129
redis.port=6379

2.5.2 编辑配置类

package com.jt.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Jedis;

@Configuration  //标识我是配置类
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {

    @Value("${redis.host}")
    private String  host;
    @Value("${redis.port}")
    private Integer port;

    @Bean
    public Jedis jedis(){
        //数据写死?????????
        return new Jedis(host,port);
    }
}

2.5.3 编辑测试类

说明:校验springBoot整合是否正确

@SpringBootTest //需要依赖spring容器,从容器中动态的获取对象
public class TestRedis {

    @Autowired
    private Jedis jedis;
    /**
     * 完成Redis入门案例测试
     * 报错说明:
     *      1.检查Linux防火墙
     *      2.检查Redis3项配置
     *      3.重启redis.
     */
    @Test
    public void test01(){
        //Jedis jedis = new Jedis("192.168.126.129",6379);
        //1.向redis中保存数据
        jedis.set("2004", "哈哈哈 今天下雨了 不负众望");
        //2.从redis中获取数据
        String value = jedis.get("2004");
        System.out.println(value);
    }
}

2.6 数据如何保存到Redis中

2.6.1 业务说明

说明:由于redis中一般使用String数据类型保存业务数据.但是代码中java对象Redis没办法直接保存,所以需要中间的转化的过程.使用JSON方式进行数据中转.
List java对象 --------- JSON ------------ Redis中 使用String数据类型保存.

2.6.2 ObjectMapper API介绍

package com.jt.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TestObjectMapper {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Test
    public void test01(){
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("测试JSON转化").setCreated(new Date())
                .setUpdated(itemDesc.getCreated());

        try {
            //1.将java对象转化为JSON
            String json = MAPPER.writeValueAsString(itemDesc);
            System.out.println(json);
            //2.将JSON转化为对象 利用反射机制实例化对象 利用get/set方法为对象赋值
            ItemDesc itemDesc2 = MAPPER.readValue(json, ItemDesc.class);
            System.out.println(itemDesc2.toString()); //只输出当前对象的数据

            //3.将集合信息转化为JSON  List
            List<ItemDesc> list = new ArrayList<>();
            list.add(itemDesc);
            String listJSON = MAPPER.writeValueAsString(list);
            System.out.println(listJSON);
            //将json转化为List集合
            List<ItemDesc> list2 = MAPPER.readValue(listJSON,list.getClass());
            System.out.println(list2);


        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}


2.6.3 编辑工具API

说明:改工具API主要负责将用户参数转化为JSON,或者将JSON串转化为对象. 简化客户端调用

package com.jt.unit;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperUtil {

    //1.创建工具API对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    //2.封装API 将对象转化为JSON
    public static String toJSON(Object object){

        if(object == null){
            throw new RuntimeException("传入对象不能为null");
        }

        try {
            String json = MAPPER.writeValueAsString(object);
            return json;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 3.将JSON串转化为对象  用户传递什么类型,则返回什么对象
     *                      user.class        User对象
     *
     */
    public static <T> T toObject(String json,Class<T> target){

        //1.校验参数是否有效
        if(json == null || "".equals(json) || target == null){
            //参数有误.
            throw new RuntimeException("参数不能为null");
        }

        //2.执行业务处理
        try {
            T t = MAPPER.readValue(json, target);
            return t;
        } catch (JsonProcessingException e) {
            //将报错信息通知其他人
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }


}

2.6.4 编辑工具API测试

//工具API测试
    @Test
    public void test02(){
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("测试JSON转化").setCreated(new Date())
                .setUpdated(itemDesc.getCreated());
        String json = ObjectMapperUtil.toJSON(itemDesc);
        ItemDesc itemDesc2 = ObjectMapperUtil.toObject(json, ItemDesc.class);
        System.out.println(itemDesc2);
    }

作业

1.利用已知的知识将商品分类实现缓存. (必做)
2.利用AOP形式实现商品分类缓存. (提高)
复习AOP相关知识.

猜你喜欢

转载自blog.csdn.net/qq_16804847/article/details/107949835