欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存并用log4j2進行日志記錄的過程分享

 更新時間:2023年09月20日 08:51:53   作者:HuskySir  
這篇文章主要介紹了Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存并用log4j2日志記錄,關(guān)于SpringBoot項目配置Redis與log4j2是查詢官方文檔,本文中的Redis配置類、Redis工具類以及l(fā)og4j2.xml配置文件來自網(wǎng)絡(luò),查證源自何處比較麻煩,所以在此感謝所有人的分享

前言

個人網(wǎng)站使用Vue作為前端,SpringBoot作為后端,MySQL作為數(shù)據(jù)庫,但前端每次請求都會從MySQL數(shù)據(jù)庫中讀取數(shù)據(jù),而MySQL數(shù)據(jù)庫的數(shù)據(jù)是存儲于服務(wù)器磁盤中,所以響應(yīng)速度有一定影響。之前了解過一點Redis數(shù)據(jù)庫,該數(shù)據(jù)庫數(shù)據(jù)存儲于內(nèi)存中(也可以持久化于磁盤中),數(shù)據(jù)讀取速度就會比存儲于磁盤中的MySQL快很多,故想把Redis數(shù)據(jù)庫應(yīng)用于該網(wǎng)站項目中。

一、安裝Redis

Linux系統(tǒng)安裝Redis比較簡單,可以直接通過命令行安裝,安裝過程比較簡單,在此就不贅述,下列出一些常用命令

# 更新apt
sudo apt update
# 安裝Redis
sudo apt-get install redis-server
# 設(shè)置密碼(在配置文件redis.conf中,位置在 /etc/redis/redis.conf)
requirepass ******
# 啟動Redis服務(wù)
service redis-server start
# 停止Redis服務(wù)
service redis-server stop
# 重啟Redis服務(wù)
service redis-server restart
# 啟動Redis客戶端
redis-cli
# 測試Redis是否連接
127.0.0.1:6379> ping

注意:需要修改Redis配置文件中的保護模式“protected-mode"為修改為no,否則會出現(xiàn)無法連接的情況

# 修改保護模式為no
# protected-mode yes
protected-mode no
# 若不修改可能無法連接Redis,出現(xiàn)以下錯誤
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
        at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689)
        at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597)
······
······
······
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379
        at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
        at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
······
······
······
Caused by: java.lang.IllegalStateException: RedisHandshakeHandler not registered
        at io.lettuce.core.AbstractRedisClient.lambda$initializeChannelAsync0$6(AbstractRedisClient.java:431)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
······
······
······

二、SpringBoot項目集成Redis

1、pom.xml添加依賴

<!-- Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、Redis數(shù)據(jù)庫連接配置 application.yml

# Redis
redis:
# 服務(wù)器地址
host: 127.0.0.1
# 服務(wù)器端口號
port: 6379
# 使用的數(shù)據(jù)庫索引
database: 0
# 連接超時時間
timeout: 10000
# 設(shè)置密碼
password: ******
lettuce:
  # 連接池
  pool:
    # 最大阻塞等待時間,負數(shù)表示沒有限制
    max-wait: -1
    # 連接池中最大空閑
    max-idle: 5
    # 連接池中最小空閑
    min-idle: 0
    # 連接池最大連接數(shù)
    max-active: 20

3、Redis配置類RedisConfig

package cn.huskysir.Config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching //開啟注解
public class RedisConfig extends CachingConfigurerSupport {
    /**
     * retemplate相關(guān)配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置連接工廠
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        // 設(shè)置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        return template;
    }
    /**
     * 對hash類型的數(shù)據(jù)操作
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }
    /**
     * 對redis字符串類型數(shù)據(jù)操作
     */
    @Bean
    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }
    /**
     * 對鏈表類型的數(shù)據(jù)操作
     */
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }
    /**
     * 對無序集合類型的數(shù)據(jù)操作
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }
    /**
     * 對有序集合類型的數(shù)據(jù)操作
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }
}

4、Redis工具類RedisUtil

package cn.huskysir.Utils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    /**
     * 指定緩存失效時間
     *
     * @param key  鍵
     * @param time 時間(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根據(jù)key 獲取過期時間
     *
     * @param key 鍵 不能為null
     * @return 時間(秒) 返回0代表為永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判斷key是否存在
     *
     * @param key 鍵
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 刪除緩存
     *
     * @param key 可以傳一個值 或多個
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
    //============================String=============================
    /**
     * 普通緩存獲取
     *
     * @param key 鍵
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通緩存放入
     *
     * @param key   鍵
     * @param value 值
     * @return true成功 false失敗
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通緩存放入并設(shè)置時間
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期
     * @return true成功 false 失敗
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 遞增
     *
     * @param key   鍵
     * @param delta 要增加幾(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("遞增因子必須大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 遞減
     *
     * @param key   鍵
     * @param delta 要減少幾(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("遞減因子必須大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    //================================Map=================================
    /**
     * HashGet
     *
     * @param key  鍵 不能為null
     * @param item 項 不能為null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 獲取hashKey對應(yīng)的所有鍵值
     *
     * @param key 鍵
     * @return 對應(yīng)的多個鍵值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     *
     * @param key 鍵
     * @param map 對應(yīng)多個鍵值
     * @return true 成功 false 失敗
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并設(shè)置時間
     *
     * @param key  鍵
     * @param map  對應(yīng)多個鍵值
     * @param time 時間(秒)
     * @return true成功 false失敗
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     *
     * @param key   鍵
     * @param item  項
     * @param value 值
     * @return true 成功 false失敗
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     *
     * @param key   鍵
     * @param item  項
     * @param value 值
     * @param time  時間(秒)  注意:如果已存在的hash表有時間,這里將會替換原有的時間
     * @return true 成功 false失敗
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 刪除hash表中的值
     *
     * @param key  鍵 不能為null
     * @param item 項 可以使多個 不能為null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判斷hash表中是否有該項的值
     *
     * @param key  鍵 不能為null
     * @param item 項 不能為null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * hash遞增 如果不存在,就會創(chuàng)建一個 并把新增后的值返回
     *
     * @param key  鍵
     * @param item 項
     * @param by   要增加幾(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * hash遞減
     *
     * @param key  鍵
     * @param item 項
     * @param by   要減少記(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
    //============================set=============================
    /**
     * 根據(jù)key獲取Set中的所有值
     *
     * @param key 鍵
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根據(jù)value從一個set中查詢,是否存在
     *
     * @param key   鍵
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 將數(shù)據(jù)放入set緩存
     *
     * @param key    鍵
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 將set數(shù)據(jù)放入緩存
     *
     * @param key    鍵
     * @param time   時間(秒)
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 獲取set緩存的長度
     *
     * @param key 鍵
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值為value的
     *
     * @param key    鍵
     * @param values 值 可以是多個
     * @return 移除的個數(shù)
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //===============================list=================================
    /**
     * 獲取list緩存的內(nèi)容
     *
     * @param key   鍵
     * @param start 開始
     * @param end   結(jié)束  0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 獲取list緩存的長度
     *
     * @param key 鍵
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 通過索引 獲取list中的值
     *
     * @param key   鍵
     * @param index 索引  index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數(shù)第二個元素,依次類推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 將list放入緩存
     *
     * @param key   鍵
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 將list放入緩存
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 將list放入緩存
     *
     * @param key   鍵
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 將list放入緩存
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根據(jù)索引修改list中的某條數(shù)據(jù)
     *
     * @param key   鍵
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 移除N個值為value
     *
     * @param key   鍵
     * @param count 移除多少個
     * @param value 值
     * @return 移除的個數(shù)
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

三、SpringBoot項目集成log4j2

SpringBoot項目在運行的時候可能會產(chǎn)生一些運行信息,如果能將這些信息記錄下來,那么對于該項目的運行狀態(tài)以及錯誤排查會起到一個非常好的幫助,所以采用log4j2進行日志記錄

1、pom.xml添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!-- 排除自帶的logback依賴 -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- log4j2 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

2、log4j2.xml配置文件,放置于resources文件夾下

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
    <Properties>
        <Property name="baseDir" value="/home/leilee/Projects/back/logs"/>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <!--控制臺只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT"
                             onMismatch="DENY"/>
            <PatternLayout
                    pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
        </Console>
        <!--debug級別日志文件輸出-->
        <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
                     filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
            <!-- 過濾器 -->
            <Filters>
                <!-- 限制日志級別在debug及以上在info以下 -->
                <ThresholdFilter level="debug"/>
                <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!-- 日志格式 -->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <!-- 策略 -->
            <Policies>
                <!-- 每隔一天轉(zhuǎn)存 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 文件大小 -->
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
        <!-- info級別日志文件輸出 -->
        <RollingFile name="info_appender" fileName="${baseDir}/info.log"
                     filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
            <!-- 過濾器 -->
            <Filters>
                <!-- 限制日志級別在info及以上在error以下 -->
                <ThresholdFilter level="info"/>
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!-- 日志格式 -->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <!-- 策略 -->
            <Policies>
                <!-- 每隔一天轉(zhuǎn)存 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 文件大小 -->
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
        <!-- error級別日志文件輸出 -->
        <RollingFile name="error_appender" fileName="${baseDir}/error.log"
                     filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
            <!-- 過濾器 -->
            <Filters>
                <!-- 限制日志級別在error及以上 -->
                <ThresholdFilter level="error"/>
            </Filters>
            <!-- 日志格式 -->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <!-- 每隔一天轉(zhuǎn)存 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 文件大小 -->
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="debug_appender"/>
            <AppenderRef ref="info_appender"/>
            <AppenderRef ref="error_appender"/>
        </Root>
    </Loggers>
</Configuration>

注意:第四行中value的值即輸出的log文件的存放路徑

3、自定義log信息

如果自己想存入一些自定義的信息,那么采用@Log4j2對類進行注解,然后在類中使用log的方法即可,以該網(wǎng)站的數(shù)據(jù)庫讀取過程為例

package cn.huskysir.Service.Impl;
import cn.huskysir.Dao.DynastyMapper;
import cn.huskysir.Dao.EmperorMapper;
import cn.huskysir.Entity.MySQL.Dynasty;
import cn.huskysir.Entity.MySQL.Emperor;
import cn.huskysir.Service.EmperorService;
import cn.huskysir.Utils.RedisUtil;
import cn.huskysir.Vo.EmperorVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
 * Emperor Service層(實現(xiàn)類)
 */
@Log4j2
@Service
public class EmperorServiceImpl implements EmperorService {
    @Resource
    EmperorMapper emperorMapper;
    @Resource
    DynastyMapper dynastyMapper;
    @Resource
    RedisUtil redisUtil;
    /**
     * 獲得所有EmperorVo對象列表
     *
     * @return
     */
    @Override
    public List<EmperorVo> getAllEmperorVoList() {
        // 判斷Redis是否存在該結(jié)果
        String key = "getAllEmperorVoList";
        if (redisUtil.hasKey(key)) {
            List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
            System.out.println("由Redis得到" + key + "結(jié)果");
            // 日志記錄
            log.info(new Date() + " 由Redis得到" + key + "數(shù)據(jù)");
            return emperorVoList;
        }
        List<Emperor> emperorList = emperorMapper.selectList(null);
        List<EmperorVo> emperorVoList = new LinkedList<>();
        for (Emperor emperor : emperorList) {
            EmperorVo emperorVo = new EmperorVo();
            BeanUtils.copyProperties(emperor, emperorVo);
            Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
            emperorVo.setDynastyName(dynasty.getName());
            emperorVo.calculateTime();
            emperorVoList.add(emperorVo);
        }
        System.out.println("由MySQL得到" + key + "結(jié)果");
        // 日志記錄
        log.info(new Date() + " 由MySQL得到" + key + "數(shù)據(jù)");
        if (redisUtil.set(key, emperorVoList, 600)) {
            System.out.println("Redis已存入" + key + "數(shù)據(jù)");
            // 日志記錄
            log.info(new Date() + " Redis已存入" + key + "數(shù)據(jù)");
        }
        return emperorVoList;
    }
    /**
     * 根據(jù)id獲得EmperorVo對象
     *
     * @param id
     * @return
     */
    @Override
    public EmperorVo getEmperorVoById(Integer id) {
        // 判斷Redis是否存在該結(jié)果
        String key = "getEmperorVoById_" + String.valueOf(id);
        if (redisUtil.hasKey(key)) {
            EmperorVo emperorVo = (EmperorVo) redisUtil.get(key);
            System.out.println("由Redis得到" + key + "結(jié)果");
            // 日志記錄
            log.info(new Date() + " 由Redis得到" + key + "數(shù)據(jù)");
            return emperorVo;
        }
        Emperor emperor = emperorMapper.selectById(id);
        EmperorVo emperorVo = new EmperorVo();
        BeanUtils.copyProperties(emperor, emperorVo);
        Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
        emperorVo.setDynastyName(dynasty.getName());
        emperorVo.calculateTime();
        System.out.println("由MySQL得到" + key + "結(jié)果");
        // 日志記錄
        log.info(new Date() + " 由MySQL得到" + key + "數(shù)據(jù)");
        if (redisUtil.set(key, emperorVo, 600)) {
            System.out.println("Redis已存入" + key + "數(shù)據(jù)");
            // 日志記錄
            log.info(new Date() + " Redis已存入" + key + "數(shù)據(jù)");
        }
        return emperorVo;
    }
    /**
     * 根據(jù)dynastyId獲得所有EmperorVo對象列表
     *
     * @param dynastyId
     * @return
     */
    @Override
    public List<EmperorVo> getEmperorListByDynastyId(Integer dynastyId) {
        // 判斷Redis是否存在該結(jié)果
        String key = "getEmperorListByDynastyId_" + String.valueOf(dynastyId);
        if (redisUtil.hasKey(key)) {
            List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
            System.out.println("由Redis得到" + key + "結(jié)果");
            // 日志記錄
            log.info(new Date() + " 由Redis得到" + key + "數(shù)據(jù)");
            return emperorVoList;
        }
        QueryWrapper<Emperor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dynasty_id", dynastyId);
        List<Emperor> emperorList = emperorMapper.selectList(queryWrapper);
        List<EmperorVo> emperorVoList = new LinkedList<>();
        String nastyName = dynastyMapper.selectById(dynastyId).getName();
        for (Emperor emperor : emperorList) {
            EmperorVo emperorVo = new EmperorVo();
            BeanUtils.copyProperties(emperor, emperorVo);
            emperorVo.setDynastyName(nastyName);
            emperorVo.calculateTime();
            emperorVoList.add(emperorVo);
        }
        System.out.println("由MySQL得到" + key + "結(jié)果");
        // 日志記錄
        log.info(new Date() + " 由MySQL得到" + key + "數(shù)據(jù)");
        if (redisUtil.set(key, emperorVoList, 600)) {
            System.out.println("Redis已存入" + key + "數(shù)據(jù)");
            // 日志記錄
            log.info(new Date() + " Redis已存入" + key + "數(shù)據(jù)");
        }
        return emperorVoList;
    }
}

以“getEmperorListByDynastyId(Integer dynastyId)”方法為例,該方法是根據(jù)dynastyId獲得List對象,首先會根據(jù)方法名及dynastyIdRedis數(shù)據(jù)庫中查找,若存在則直接返回,否則從MySQL數(shù)據(jù)庫中讀取,并將結(jié)果存入Redis數(shù)據(jù)庫中然后返回。使用log.info()記錄數(shù)據(jù)庫讀取過程,該記錄會存儲于info.log文件中

該網(wǎng)站后臺的info.log日志記錄如下

[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)
[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數(shù)據(jù)

四、總結(jié)

關(guān)于SpringBoot項目配置Redis與log4j2是查詢官方文檔以及他人博客得到的,本文中的Redis配置類、Redis工具類以及l(fā)og4j2.xml配置文件來自網(wǎng)絡(luò),查證源自何處比較麻煩,所以在此感謝所有人的分享!

到此這篇關(guān)于Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存,并用log4j2進行日志記錄的文章就介紹到這了,更多相關(guān)Redis數(shù)據(jù)緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis中l(wèi)ua腳本使用教程

    redis中l(wèi)ua腳本使用教程

    在使用redis的過程中,發(fā)現(xiàn)有些時候需要原子性去操作redis命令,而redis的lua腳本正好可以實現(xiàn)這一功能。這篇文章主要介紹了redis中l(wèi)ua腳本的簡單使用,需要的朋友可以參考下
    2021-10-10
  • Redis實現(xiàn)優(yōu)惠券限一單限制詳解

    Redis實現(xiàn)優(yōu)惠券限一單限制詳解

    這篇文章主要介紹了Redis解決優(yōu)惠券秒殺應(yīng)用案例,本文先講了搶購問題,指出其中會出現(xiàn)的多線程問題,提出解決方案采用悲觀鎖和樂觀鎖兩種方式進行實現(xiàn),然后發(fā)現(xiàn)在搶購過程中容易出現(xiàn)一人多單現(xiàn)象,需要的朋友可以參考下
    2022-12-12
  • Redis慢查詢的實現(xiàn)

    Redis慢查詢的實現(xiàn)

    本文主要介紹了Redis慢查詢的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • 實現(xiàn)在線?+?離線模式進行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南

    實現(xiàn)在線?+?離線模式進行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南

    這篇文章主要介紹了實現(xiàn)在線?+?離線模式進行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Redis搶單預(yù)熱的實現(xiàn)示例

    Redis搶單預(yù)熱的實現(xiàn)示例

    本文主要介紹了Redis搶單預(yù)熱的實現(xiàn)示例,以應(yīng)對搶單活動帶來的高并發(fā)訪問壓力,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Redis緩存高可用集群詳解

    Redis緩存高可用集群詳解

    Redis集群提供了哨兵模式和高可用集群模式兩種方案,前者適合低并發(fā),配置復(fù)雜,主從切換可能導致瞬斷;后者通過多主多從結(jié)構(gòu)提高可用性和性能,支持線性擴展,配置簡單,搭建Redis集群至少需要三個主節(jié)點
    2024-10-10
  • 解讀Redis秒殺優(yōu)化方案(阻塞隊列+基于Stream流的消息隊列)

    解讀Redis秒殺優(yōu)化方案(阻塞隊列+基于Stream流的消息隊列)

    該文章介紹了使用Redis的阻塞隊列和Stream流的消息隊列來優(yōu)化秒殺系統(tǒng)的方案,通過將秒殺流程拆分為兩條流水線,使用Redis緩存緩解數(shù)據(jù)庫壓力,并結(jié)合Lua腳本進行原子性判斷,使用阻塞隊列和消息隊列異步處理訂單,有效提高了系統(tǒng)的并發(fā)處理能力和可用性
    2025-02-02
  • Redis集群的搭建圖文教程

    Redis集群的搭建圖文教程

    下面小編就為大家分享一篇Redis集群的搭建圖文教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • Redis increment 函數(shù)處理并發(fā)序列號案例

    Redis increment 函數(shù)處理并發(fā)序列號案例

    這篇文章主要介紹了Redis increment 函數(shù)處理并發(fā)序列號案例,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Linux下Redis集群搭建全過程(主從+哨兵)

    Linux下Redis集群搭建全過程(主從+哨兵)

    這篇文章主要介紹了Linux下Redis集群搭建全過程(主從+哨兵),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論