Linux服务器使用Redis作为数据缓存,并用log4j2进行日志记录 ...

打印 上一主题 下一主题

主题 944|帖子 944|积分 2832

前言
个人网站使用Vue作为前端,SpringBoot作为后端,MySQL作为数据库,但前端每次请求都会从MySQL数据库中读取数据,而MySQL数据库的数据是存储于服务器磁盘中,所以响应速度有一定影响。之前了解过一点Redis数据库,该数据库数据存储于内存中(也可以持久化于磁盘中),数据读取速度就会比存储于磁盘中的MySQL快很多,故想把Redis数据库应用于该网站项目中。
一、安装Redis

Linux系统安装Redis比较简单,可以直接通过命令行安装,安装过程比较简单,在此就不赘述,下列出一些常用命令
  1. # 更新apt
  2. sudo apt update
  3. # 安装Redis
  4. sudo apt-get install redis-server
  5. # 设置密码(在配置文件redis.conf中,位置在 /etc/redis/redis.conf)
  6. requirepass ******
  7. # 启动Redis服务
  8. service redis-server start
  9. # 停止Redis服务
  10. service redis-server stop
  11. # 重启Redis服务
  12. service redis-server restart
  13. # 启动Redis客户端
  14. redis-cli
  15. # 测试Redis是否连接
  16. 127.0.0.1:6379> ping
复制代码
注意:需要修改Redis配置文件中的保护模式“protected-mode"为修改为no,否则会出现无法连接的情况
  1. # 修改保护模式为no
  2. # protected-mode yes
  3. protected-mode no
  4. # 若不修改可能无法连接Redis,出现以下错误
  5. org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379
  6.         at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689)
  7.         at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597)
  8. ······
  9. ······
  10. ······
  11. Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379
  12.         at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
  13.         at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
  14. ······
  15. ······
  16. ······
  17. Caused by: java.lang.IllegalStateException: RedisHandshakeHandler not registered
  18.         at io.lettuce.core.AbstractRedisClient.lambda$initializeChannelAsync0$6(AbstractRedisClient.java:431)
  19.         at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
  20. ······
  21. ······
  22. ······
复制代码
二、SpringBoot项目集成Redis

1、pom.xml添加依赖
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
复制代码
2、Redis数据库连接配置 application.yml
  1. # Redis
  2. redis:
  3. # 服务器地址
  4. host: 127.0.0.1
  5. # 服务器端口号
  6. port: 6379
  7. # 使用的数据库索引
  8. database: 0
  9. # 连接超时时间
  10. timeout: 10000
  11. # 设置密码
  12. password: ******
  13. lettuce:
  14.   # 连接池
  15.   pool:
  16.     # 最大阻塞等待时间,负数表示没有限制
  17.     max-wait: -1
  18.     # 连接池中最大空闲
  19.     max-idle: 5
  20.     # 连接池中最小空闲
  21.     min-idle: 0
  22.     # 连接池最大连接数
  23.     max-active: 20
复制代码
3、Redis配置类RedisConfig
  1. package cn.huskysir.Config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import org.springframework.cache.annotation.CachingConfigurerSupport;
  6. import org.springframework.cache.annotation.EnableCaching;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.data.redis.connection.RedisConnectionFactory;
  10. import org.springframework.data.redis.core.*;
  11. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  12. import org.springframework.data.redis.serializer.StringRedisSerializer;
  13. @Configuration
  14. @EnableCaching //开启注解
  15. public class RedisConfig extends CachingConfigurerSupport {
  16.     /**
  17.      * retemplate相关配置
  18.      */
  19.     @Bean
  20.     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
  21.         RedisTemplate<String, Object> template = new RedisTemplate<>();
  22.         // 配置连接工厂
  23.         template.setConnectionFactory(factory);
  24.         //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
  25.         Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
  26.         ObjectMapper om = new ObjectMapper();
  27.         // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
  28.         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  29.         // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
  30.         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  31.         jacksonSeial.setObjectMapper(om);
  32.         // 值采用json序列化
  33.         template.setValueSerializer(jacksonSeial);
  34.         //使用StringRedisSerializer来序列化和反序列化redis的key值
  35.         template.setKeySerializer(new StringRedisSerializer());
  36.         // 设置hash key 和value序列化模式
  37.         template.setHashKeySerializer(new StringRedisSerializer());
  38.         template.setHashValueSerializer(jacksonSeial);
  39.         template.afterPropertiesSet();
  40.         return template;
  41.     }
  42.     /**
  43.      * 对hash类型的数据操作
  44.      */
  45.     @Bean
  46.     public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
  47.         return redisTemplate.opsForHash();
  48.     }
  49.     /**
  50.      * 对redis字符串类型数据操作
  51.      */
  52.     @Bean
  53.     public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
  54.         return redisTemplate.opsForValue();
  55.     }
  56.     /**
  57.      * 对链表类型的数据操作
  58.      */
  59.     @Bean
  60.     public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
  61.         return redisTemplate.opsForList();
  62.     }
  63.     /**
  64.      * 对无序集合类型的数据操作
  65.      */
  66.     @Bean
  67.     public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
  68.         return redisTemplate.opsForSet();
  69.     }
  70.     /**
  71.      * 对有序集合类型的数据操作
  72.      */
  73.     @Bean
  74.     public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
  75.         return redisTemplate.opsForZSet();
  76.     }
  77. }
复制代码
4、Redis工具类RedisUtil
  1. package cn.huskysir.Utils;
  2. import org.springframework.data.redis.core.RedisTemplate;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.util.CollectionUtils;
  5. import javax.annotation.Resource;
  6. import java.util.Collection;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Set;
  10. import java.util.concurrent.TimeUnit;
  11. @Component
  12. public class RedisUtil {
  13.     @Resource
  14.     private RedisTemplate<String, Object> redisTemplate;
  15.     public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
  16.         this.redisTemplate = redisTemplate;
  17.     }
  18.     /**
  19.      * 指定缓存失效时间
  20.      *
  21.      * @param key  键
  22.      * @param time 时间(秒)
  23.      * @return
  24.      */
  25.     public boolean expire(String key, long time) {
  26.         try {
  27.             if (time > 0) {
  28.                 redisTemplate.expire(key, time, TimeUnit.SECONDS);
  29.             }
  30.             return true;
  31.         } catch (Exception e) {
  32.             e.printStackTrace();
  33.             return false;
  34.         }
  35.     }
  36.     /**
  37.      * 根据key 获取过期时间
  38.      *
  39.      * @param key 键 不能为null
  40.      * @return 时间(秒) 返回0代表为永久有效
  41.      */
  42.     public long getExpire(String key) {
  43.         return redisTemplate.getExpire(key, TimeUnit.SECONDS);
  44.     }
  45.     /**
  46.      * 判断key是否存在
  47.      *
  48.      * @param key 键
  49.      * @return true 存在 false不存在
  50.      */
  51.     public boolean hasKey(String key) {
  52.         try {
  53.             return redisTemplate.hasKey(key);
  54.         } catch (Exception e) {
  55.             e.printStackTrace();
  56.             return false;
  57.         }
  58.     }
  59.     /**
  60.      * 删除缓存
  61.      *
  62.      * @param key 可以传一个值 或多个
  63.      */
  64.     @SuppressWarnings("unchecked")
  65.     public void del(String... key) {
  66.         if (key != null && key.length > 0) {
  67.             if (key.length == 1) {
  68.                 redisTemplate.delete(key[0]);
  69.             } else {
  70.                 redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
  71.             }
  72.         }
  73.     }
  74.     //============================String=============================
  75.     /**
  76.      * 普通缓存获取
  77.      *
  78.      * @param key 键
  79.      * @return 值
  80.      */
  81.     public Object get(String key) {
  82.         return key == null ? null : redisTemplate.opsForValue().get(key);
  83.     }
  84.     /**
  85.      * 普通缓存放入
  86.      *
  87.      * @param key   键
  88.      * @param value 值
  89.      * @return true成功 false失败
  90.      */
  91.     public boolean set(String key, Object value) {
  92.         try {
  93.             redisTemplate.opsForValue().set(key, value);
  94.             return true;
  95.         } catch (Exception e) {
  96.             e.printStackTrace();
  97.             return false;
  98.         }
  99.     }
  100.     /**
  101.      * 普通缓存放入并设置时间
  102.      *
  103.      * @param key   键
  104.      * @param value 值
  105.      * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
  106.      * @return true成功 false 失败
  107.      */
  108.     public boolean set(String key, Object value, long time) {
  109.         try {
  110.             if (time > 0) {
  111.                 redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
  112.             } else {
  113.                 set(key, value);
  114.             }
  115.             return true;
  116.         } catch (Exception e) {
  117.             e.printStackTrace();
  118.             return false;
  119.         }
  120.     }
  121.     /**
  122.      * 递增
  123.      *
  124.      * @param key   键
  125.      * @param delta 要增加几(大于0)
  126.      * @return
  127.      */
  128.     public long incr(String key, long delta) {
  129.         if (delta < 0) {
  130.             throw new RuntimeException("递增因子必须大于0");
  131.         }
  132.         return redisTemplate.opsForValue().increment(key, delta);
  133.     }
  134.     /**
  135.      * 递减
  136.      *
  137.      * @param key   键
  138.      * @param delta 要减少几(小于0)
  139.      * @return
  140.      */
  141.     public long decr(String key, long delta) {
  142.         if (delta < 0) {
  143.             throw new RuntimeException("递减因子必须大于0");
  144.         }
  145.         return redisTemplate.opsForValue().increment(key, -delta);
  146.     }
  147.     //================================Map=================================
  148.     /**
  149.      * HashGet
  150.      *
  151.      * @param key  键 不能为null
  152.      * @param item 项 不能为null
  153.      * @return 值
  154.      */
  155.     public Object hget(String key, String item) {
  156.         return redisTemplate.opsForHash().get(key, item);
  157.     }
  158.     /**
  159.      * 获取hashKey对应的所有键值
  160.      *
  161.      * @param key 键
  162.      * @return 对应的多个键值
  163.      */
  164.     public Map<Object, Object> hmget(String key) {
  165.         return redisTemplate.opsForHash().entries(key);
  166.     }
  167.     /**
  168.      * HashSet
  169.      *
  170.      * @param key 键
  171.      * @param map 对应多个键值
  172.      * @return true 成功 false 失败
  173.      */
  174.     public boolean hmset(String key, Map<String, Object> map) {
  175.         try {
  176.             redisTemplate.opsForHash().putAll(key, map);
  177.             return true;
  178.         } catch (Exception e) {
  179.             e.printStackTrace();
  180.             return false;
  181.         }
  182.     }
  183.     /**
  184.      * HashSet 并设置时间
  185.      *
  186.      * @param key  键
  187.      * @param map  对应多个键值
  188.      * @param time 时间(秒)
  189.      * @return true成功 false失败
  190.      */
  191.     public boolean hmset(String key, Map<String, Object> map, long time) {
  192.         try {
  193.             redisTemplate.opsForHash().putAll(key, map);
  194.             if (time > 0) {
  195.                 expire(key, time);
  196.             }
  197.             return true;
  198.         } catch (Exception e) {
  199.             e.printStackTrace();
  200.             return false;
  201.         }
  202.     }
  203.     /**
  204.      * 向一张hash表中放入数据,如果不存在将创建
  205.      *
  206.      * @param key   键
  207.      * @param item  项
  208.      * @param value 值
  209.      * @return true 成功 false失败
  210.      */
  211.     public boolean hset(String key, String item, Object value) {
  212.         try {
  213.             redisTemplate.opsForHash().put(key, item, value);
  214.             return true;
  215.         } catch (Exception e) {
  216.             e.printStackTrace();
  217.             return false;
  218.         }
  219.     }
  220.     /**
  221.      * 向一张hash表中放入数据,如果不存在将创建
  222.      *
  223.      * @param key   键
  224.      * @param item  项
  225.      * @param value 值
  226.      * @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
  227.      * @return true 成功 false失败
  228.      */
  229.     public boolean hset(String key, String item, Object value, long time) {
  230.         try {
  231.             redisTemplate.opsForHash().put(key, item, value);
  232.             if (time > 0) {
  233.                 expire(key, time);
  234.             }
  235.             return true;
  236.         } catch (Exception e) {
  237.             e.printStackTrace();
  238.             return false;
  239.         }
  240.     }
  241.     /**
  242.      * 删除hash表中的值
  243.      *
  244.      * @param key  键 不能为null
  245.      * @param item 项 可以使多个 不能为null
  246.      */
  247.     public void hdel(String key, Object... item) {
  248.         redisTemplate.opsForHash().delete(key, item);
  249.     }
  250.     /**
  251.      * 判断hash表中是否有该项的值
  252.      *
  253.      * @param key  键 不能为null
  254.      * @param item 项 不能为null
  255.      * @return true 存在 false不存在
  256.      */
  257.     public boolean hHasKey(String key, String item) {
  258.         return redisTemplate.opsForHash().hasKey(key, item);
  259.     }
  260.     /**
  261.      * hash递增 如果不存在,就会创建一个 并把新增后的值返回
  262.      *
  263.      * @param key  键
  264.      * @param item 项
  265.      * @param by   要增加几(大于0)
  266.      * @return
  267.      */
  268.     public double hincr(String key, String item, double by) {
  269.         return redisTemplate.opsForHash().increment(key, item, by);
  270.     }
  271.     /**
  272.      * hash递减
  273.      *
  274.      * @param key  键
  275.      * @param item 项
  276.      * @param by   要减少记(小于0)
  277.      * @return
  278.      */
  279.     public double hdecr(String key, String item, double by) {
  280.         return redisTemplate.opsForHash().increment(key, item, -by);
  281.     }
  282.     //============================set=============================
  283.     /**
  284.      * 根据key获取Set中的所有值
  285.      *
  286.      * @param key 键
  287.      * @return
  288.      */
  289.     public Set<Object> sGet(String key) {
  290.         try {
  291.             return redisTemplate.opsForSet().members(key);
  292.         } catch (Exception e) {
  293.             e.printStackTrace();
  294.             return null;
  295.         }
  296.     }
  297.     /**
  298.      * 根据value从一个set中查询,是否存在
  299.      *
  300.      * @param key   键
  301.      * @param value 值
  302.      * @return true 存在 false不存在
  303.      */
  304.     public boolean sHasKey(String key, Object value) {
  305.         try {
  306.             return redisTemplate.opsForSet().isMember(key, value);
  307.         } catch (Exception e) {
  308.             e.printStackTrace();
  309.             return false;
  310.         }
  311.     }
  312.     /**
  313.      * 将数据放入set缓存
  314.      *
  315.      * @param key    键
  316.      * @param values 值 可以是多个
  317.      * @return 成功个数
  318.      */
  319.     public long sSet(String key, Object... values) {
  320.         try {
  321.             return redisTemplate.opsForSet().add(key, values);
  322.         } catch (Exception e) {
  323.             e.printStackTrace();
  324.             return 0;
  325.         }
  326.     }
  327.     /**
  328.      * 将set数据放入缓存
  329.      *
  330.      * @param key    键
  331.      * @param time   时间(秒)
  332.      * @param values 值 可以是多个
  333.      * @return 成功个数
  334.      */
  335.     public long sSetAndTime(String key, long time, Object... values) {
  336.         try {
  337.             Long count = redisTemplate.opsForSet().add(key, values);
  338.             if (time > 0) {
  339.                 expire(key, time);
  340.             }
  341.             return count;
  342.         } catch (Exception e) {
  343.             e.printStackTrace();
  344.             return 0;
  345.         }
  346.     }
  347.     /**
  348.      * 获取set缓存的长度
  349.      *
  350.      * @param key 键
  351.      * @return
  352.      */
  353.     public long sGetSetSize(String key) {
  354.         try {
  355.             return redisTemplate.opsForSet().size(key);
  356.         } catch (Exception e) {
  357.             e.printStackTrace();
  358.             return 0;
  359.         }
  360.     }
  361.     /**
  362.      * 移除值为value的
  363.      *
  364.      * @param key    键
  365.      * @param values 值 可以是多个
  366.      * @return 移除的个数
  367.      */
  368.     public long setRemove(String key, Object... values) {
  369.         try {
  370.             Long count = redisTemplate.opsForSet().remove(key, values);
  371.             return count;
  372.         } catch (Exception e) {
  373.             e.printStackTrace();
  374.             return 0;
  375.         }
  376.     }
  377.     //===============================list=================================
  378.     /**
  379.      * 获取list缓存的内容
  380.      *
  381.      * @param key   键
  382.      * @param start 开始
  383.      * @param end   结束  0 到 -1代表所有值
  384.      * @return
  385.      */
  386.     public List<Object> lGet(String key, long start, long end) {
  387.         try {
  388.             return redisTemplate.opsForList().range(key, start, end);
  389.         } catch (Exception e) {
  390.             e.printStackTrace();
  391.             return null;
  392.         }
  393.     }
  394.     /**
  395.      * 获取list缓存的长度
  396.      *
  397.      * @param key 键
  398.      * @return
  399.      */
  400.     public long lGetListSize(String key) {
  401.         try {
  402.             return redisTemplate.opsForList().size(key);
  403.         } catch (Exception e) {
  404.             e.printStackTrace();
  405.             return 0;
  406.         }
  407.     }
  408.     /**
  409.      * 通过索引 获取list中的值
  410.      *
  411.      * @param key   键
  412.      * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
  413.      * @return
  414.      */
  415.     public Object lGetIndex(String key, long index) {
  416.         try {
  417.             return redisTemplate.opsForList().index(key, index);
  418.         } catch (Exception e) {
  419.             e.printStackTrace();
  420.             return null;
  421.         }
  422.     }
  423.     /**
  424.      * 将list放入缓存
  425.      *
  426.      * @param key   键
  427.      * @param value 值
  428.      * @return
  429.      */
  430.     public boolean lSet(String key, Object value) {
  431.         try {
  432.             redisTemplate.opsForList().rightPush(key, value);
  433.             return true;
  434.         } catch (Exception e) {
  435.             e.printStackTrace();
  436.             return false;
  437.         }
  438.     }
  439.     /**
  440.      * 将list放入缓存
  441.      *
  442.      * @param key   键
  443.      * @param value 值
  444.      * @param time  时间(秒)
  445.      * @return
  446.      */
  447.     public boolean lSet(String key, Object value, long time) {
  448.         try {
  449.             redisTemplate.opsForList().rightPush(key, value);
  450.             if (time > 0) {
  451.                 expire(key, time);
  452.             }
  453.             return true;
  454.         } catch (Exception e) {
  455.             e.printStackTrace();
  456.             return false;
  457.         }
  458.     }
  459.     /**
  460.      * 将list放入缓存
  461.      *
  462.      * @param key   键
  463.      * @param value 值
  464.      * @return
  465.      */
  466.     public boolean lSet(String key, List<Object> value) {
  467.         try {
  468.             redisTemplate.opsForList().rightPushAll(key, value);
  469.             return true;
  470.         } catch (Exception e) {
  471.             e.printStackTrace();
  472.             return false;
  473.         }
  474.     }
  475.     /**
  476.      * 将list放入缓存
  477.      *
  478.      * @param key   键
  479.      * @param value 值
  480.      * @param time  时间(秒)
  481.      * @return
  482.      */
  483.     public boolean lSet(String key, List<Object> value, long time) {
  484.         try {
  485.             redisTemplate.opsForList().rightPushAll(key, value);
  486.             if (time > 0) {
  487.                 expire(key, time);
  488.             }
  489.             return true;
  490.         } catch (Exception e) {
  491.             e.printStackTrace();
  492.             return false;
  493.         }
  494.     }
  495.     /**
  496.      * 根据索引修改list中的某条数据
  497.      *
  498.      * @param key   键
  499.      * @param index 索引
  500.      * @param value 值
  501.      * @return
  502.      */
  503.     public boolean lUpdateIndex(String key, long index, Object value) {
  504.         try {
  505.             redisTemplate.opsForList().set(key, index, value);
  506.             return true;
  507.         } catch (Exception e) {
  508.             e.printStackTrace();
  509.             return false;
  510.         }
  511.     }
  512.     /**
  513.      * 移除N个值为value
  514.      *
  515.      * @param key   键
  516.      * @param count 移除多少个
  517.      * @param value 值
  518.      * @return 移除的个数
  519.      */
  520.     public long lRemove(String key, long count, Object value) {
  521.         try {
  522.             Long remove = redisTemplate.opsForList().remove(key, count, value);
  523.             return remove;
  524.         } catch (Exception e) {
  525.             e.printStackTrace();
  526.             return 0;
  527.         }
  528.     }
  529. }
复制代码
三、SpringBoot项目集成log4j2

SpringBoot项目在运行的时候可能会产生一些运行信息,如果能将这些信息记录下来,那么对于该项目的运行状态以及错误排查会起到一个非常好的帮助,所以采用log4j2进行日志记录
1、pom.xml添加依赖
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-web</artifactId>
  4.     <exclusions>
  5.         
  6.         <exclusion>
  7.             <groupId>org.springframework.boot</groupId>
  8.             <artifactId>spring-boot-starter-logging</artifactId>
  9.         </exclusion>
  10.     </exclusions>
  11. </dependency>
  12. <dependency>
  13.     <groupId>org.springframework.boot</groupId>
  14.     <artifactId>spring-boot-starter-log4j2</artifactId>
  15. </dependency>
复制代码
2、log4j2.xml配置文件,放置于resources文件夹下
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Configuration status="fatal">
  3.     <Properties>
  4.         <Property name="baseDir" value="/home/leilee/Projects/back/logs"/>
  5.     </Properties>
  6.     <Appenders>
  7.         <Console name="Console" target="SYSTEM_OUT">
  8.             
  9.             <ThresholdFilter level="info" onMatch="ACCEPT"
  10.                              onMismatch="DENY"/>
  11.             <PatternLayout
  12.                     pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
  13.         </Console>
  14.         
  15.         <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
  16.                      filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
  17.             
  18.             <Filters>
  19.                
  20.                 <ThresholdFilter level="debug"/>
  21.                 <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
  22.             </Filters>
  23.             
  24.             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  25.             
  26.             <Policies>
  27.                
  28.                 <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
  29.                
  30.                 <SizeBasedTriggeringPolicy size="100 MB"/>
  31.             </Policies>
  32.         </RollingFile>
  33.         
  34.         <RollingFile name="info_appender" fileName="${baseDir}/info.log"
  35.                      filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
  36.             
  37.             <Filters>
  38.                
  39.                 <ThresholdFilter level="info"/>
  40.                 <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
  41.             </Filters>
  42.             
  43.             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  44.             
  45.             <Policies>
  46.                
  47.                 <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
  48.                
  49.                 <SizeBasedTriggeringPolicy size="100 MB"/>
  50.             </Policies>
  51.         </RollingFile>
  52.         
  53.         <RollingFile name="error_appender" fileName="${baseDir}/error.log"
  54.                      filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
  55.             
  56.             <Filters>
  57.                
  58.                 <ThresholdFilter level="error"/>
  59.             </Filters>
  60.             
  61.             <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  62.             <Policies>
  63.                
  64.                 <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
  65.                
  66.                 <SizeBasedTriggeringPolicy size="100 MB"/>
  67.             </Policies>
  68.         </RollingFile>
  69.     </Appenders>
  70.     <Loggers>
  71.         <Root level="debug">
  72.             <AppenderRef ref="Console"/>
  73.             <AppenderRef ref="debug_appender"/>
  74.             <AppenderRef ref="info_appender"/>
  75.             <AppenderRef ref="error_appender"/>
  76.         </Root>
  77.     </Loggers>
  78. </Configuration>
复制代码
注意:第四行中value的值即输出的log文件的存放路径
3、自定义log信息

如果自己想存入一些自定义的信息,那么采用@Log4j2对类进行注解,然后在类中使用log的方法即可,以该网站的数据库读取过程为例
  1. package cn.huskysir.Service.Impl;
  2. import cn.huskysir.Dao.DynastyMapper;
  3. import cn.huskysir.Dao.EmperorMapper;
  4. import cn.huskysir.Entity.MySQL.Dynasty;
  5. import cn.huskysir.Entity.MySQL.Emperor;
  6. import cn.huskysir.Service.EmperorService;
  7. import cn.huskysir.Utils.RedisUtil;
  8. import cn.huskysir.Vo.EmperorVo;
  9. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  10. import lombok.extern.log4j.Log4j2;
  11. import org.springframework.beans.BeanUtils;
  12. import org.springframework.stereotype.Service;
  13. import javax.annotation.Resource;
  14. import java.util.Date;
  15. import java.util.LinkedList;
  16. import java.util.List;
  17. /**
  18. * Emperor Service层(实现类)
  19. */
  20. @Log4j2
  21. @Service
  22. public class EmperorServiceImpl implements EmperorService {
  23.     @Resource
  24.     EmperorMapper emperorMapper;
  25.     @Resource
  26.     DynastyMapper dynastyMapper;
  27.     @Resource
  28.     RedisUtil redisUtil;
  29.     /**
  30.      * 获得所有EmperorVo对象列表
  31.      *
  32.      * @return
  33.      */
  34.     @Override
  35.     public List<EmperorVo> getAllEmperorVoList() {
  36.         // 判断Redis是否存在该结果
  37.         String key = "getAllEmperorVoList";
  38.         if (redisUtil.hasKey(key)) {
  39.             List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
  40.             System.out.println("由Redis得到" + key + "结果");
  41.             // 日志记录
  42.             log.info(new Date() + " 由Redis得到" + key + "数据");
  43.             return emperorVoList;
  44.         }
  45.         List<Emperor> emperorList = emperorMapper.selectList(null);
  46.         List<EmperorVo> emperorVoList = new LinkedList<>();
  47.         for (Emperor emperor : emperorList) {
  48.             EmperorVo emperorVo = new EmperorVo();
  49.             BeanUtils.copyProperties(emperor, emperorVo);
  50.             Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
  51.             emperorVo.setDynastyName(dynasty.getName());
  52.             emperorVo.calculateTime();
  53.             emperorVoList.add(emperorVo);
  54.         }
  55.         System.out.println("由MySQL得到" + key + "结果");
  56.         // 日志记录
  57.         log.info(new Date() + " 由MySQL得到" + key + "数据");
  58.         if (redisUtil.set(key, emperorVoList, 600)) {
  59.             System.out.println("Redis已存入" + key + "数据");
  60.             // 日志记录
  61.             log.info(new Date() + " Redis已存入" + key + "数据");
  62.         }
  63.         return emperorVoList;
  64.     }
  65.     /**
  66.      * 根据id获得EmperorVo对象
  67.      *
  68.      * @param id
  69.      * @return
  70.      */
  71.     @Override
  72.     public EmperorVo getEmperorVoById(Integer id) {
  73.         // 判断Redis是否存在该结果
  74.         String key = "getEmperorVoById_" + String.valueOf(id);
  75.         if (redisUtil.hasKey(key)) {
  76.             EmperorVo emperorVo = (EmperorVo) redisUtil.get(key);
  77.             System.out.println("由Redis得到" + key + "结果");
  78.             // 日志记录
  79.             log.info(new Date() + " 由Redis得到" + key + "数据");
  80.             return emperorVo;
  81.         }
  82.         Emperor emperor = emperorMapper.selectById(id);
  83.         EmperorVo emperorVo = new EmperorVo();
  84.         BeanUtils.copyProperties(emperor, emperorVo);
  85.         Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
  86.         emperorVo.setDynastyName(dynasty.getName());
  87.         emperorVo.calculateTime();
  88.         System.out.println("由MySQL得到" + key + "结果");
  89.         // 日志记录
  90.         log.info(new Date() + " 由MySQL得到" + key + "数据");
  91.         if (redisUtil.set(key, emperorVo, 600)) {
  92.             System.out.println("Redis已存入" + key + "数据");
  93.             // 日志记录
  94.             log.info(new Date() + " Redis已存入" + key + "数据");
  95.         }
  96.         return emperorVo;
  97.     }
  98.     /**
  99.      * 根据dynastyId获得所有EmperorVo对象列表
  100.      *
  101.      * @param dynastyId
  102.      * @return
  103.      */
  104.     @Override
  105.     public List<EmperorVo> getEmperorListByDynastyId(Integer dynastyId) {
  106.         // 判断Redis是否存在该结果
  107.         String key = "getEmperorListByDynastyId_" + String.valueOf(dynastyId);
  108.         if (redisUtil.hasKey(key)) {
  109.             List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
  110.             System.out.println("由Redis得到" + key + "结果");
  111.             // 日志记录
  112.             log.info(new Date() + " 由Redis得到" + key + "数据");
  113.             return emperorVoList;
  114.         }
  115.         QueryWrapper<Emperor> queryWrapper = new QueryWrapper<>();
  116.         queryWrapper.eq("dynasty_id", dynastyId);
  117.         List<Emperor> emperorList = emperorMapper.selectList(queryWrapper);
  118.         List<EmperorVo> emperorVoList = new LinkedList<>();
  119.         String nastyName = dynastyMapper.selectById(dynastyId).getName();
  120.         for (Emperor emperor : emperorList) {
  121.             EmperorVo emperorVo = new EmperorVo();
  122.             BeanUtils.copyProperties(emperor, emperorVo);
  123.             emperorVo.setDynastyName(nastyName);
  124.             emperorVo.calculateTime();
  125.             emperorVoList.add(emperorVo);
  126.         }
  127.         System.out.println("由MySQL得到" + key + "结果");
  128.         // 日志记录
  129.         log.info(new Date() + " 由MySQL得到" + key + "数据");
  130.         if (redisUtil.set(key, emperorVoList, 600)) {
  131.             System.out.println("Redis已存入" + key + "数据");
  132.             // 日志记录
  133.             log.info(new Date() + " Redis已存入" + key + "数据");
  134.         }
  135.         return emperorVoList;
  136.     }
  137. }
复制代码
以“getEmperorListByDynastyId(Integer dynastyId)”方法为例,该方法是根据dynastyId获得List对象,首先会根据方法名及dynastyIdRedis数据库中查找,若存在则直接返回,否则从MySQL数据库中读取,并将结果存入Redis数据库中然后返回。使用log.info()记录数据库读取过程,该记录会存储于info.log文件中
该网站后台的info.log日志记录如下
  1. [00:54:31:770] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:31 CST 2023 由MySQL得到getEmperorListByDynastyId_1数据
  2. [00:54:31:773] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:31 CST 2023 Redis已存入getEmperorListByDynastyId_1数据
  3. [00:54:35:853] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:35 CST 2023 由MySQL得到getEmperorListByDynastyId_2数据
  4. [00:54:35:863] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:35 CST 2023 Redis已存入getEmperorListByDynastyId_2数据
  5. [00:54:37:363] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:37 CST 2023 由Redis得到getEmperorListByDynastyId_1数据
  6. [00:54:38:043] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:38 CST 2023 由Redis得到getEmperorListByDynastyId_2数据
  7. [00:54:39:214] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:39 CST 2023 由Redis得到getEmperorListByDynastyId_1数据
  8. [00:54:39:936] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:39 CST 2023 由Redis得到getEmperorListByDynastyId_2数据
复制代码
四、总结

关于SpringBoot项目配置Redis与log4j2是查询官方文档以及他人博客得到的,本文中的Redis配置类、Redis工具类以及log4j2.xml配置文件来自网络,查证源自何处比较麻烦,所以在此感谢所有人的分享!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

汕尾海湾

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表