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

Java實(shí)現(xiàn)多級(jí)緩存的方法詳解

 更新時(shí)間:2024年02月20日 16:18:35   作者:Java中文社群  
對(duì)于高并發(fā)系統(tǒng)來(lái)說(shuō),有三個(gè)重要的機(jī)制來(lái)保障其高效運(yùn)行,它們分別是:緩存、限流和熔斷,所以本文就來(lái)和大家探討一下多級(jí)緩存的實(shí)現(xiàn)方法,希望對(duì)大家有所幫助

對(duì)于高并發(fā)系統(tǒng)來(lái)說(shuō),有三個(gè)重要的機(jī)制來(lái)保障其高效運(yùn)行,它們分別是:緩存、限流和熔斷。而緩存是排在最前面也是高并發(fā)系統(tǒng)之所以高效運(yùn)行的關(guān)鍵手段,那么問(wèn)題來(lái)了:緩存只使用 Redis 就夠了嗎?

1.冗余設(shè)計(jì)理念

當(dāng)然不是,不要把所有雞蛋放到一個(gè)籃子里,成熟的系統(tǒng)在關(guān)鍵功能實(shí)現(xiàn)時(shí)一定會(huì)考慮冗余設(shè)計(jì),注意這里的冗余設(shè)計(jì)不是貶義詞。

冗余設(shè)計(jì)是在系統(tǒng)或設(shè)備完成任務(wù)起關(guān)鍵作用的地方,增加一套以上完成相同功能的功能通道(or 系統(tǒng))、工作元件或部件,以保證當(dāng)該部分出現(xiàn)故障時(shí),系統(tǒng)或設(shè)備仍能正常工作,以減少系統(tǒng)或者設(shè)備的故障概率,提高系統(tǒng)可靠性。

例如,飛機(jī)的設(shè)計(jì),飛機(jī)正常運(yùn)行只需要兩個(gè)發(fā)動(dòng)機(jī),但在每臺(tái)飛機(jī)的設(shè)計(jì)中可能至少會(huì)設(shè)計(jì)四個(gè)發(fā)動(dòng)機(jī),這就有冗余設(shè)計(jì)的典型使用場(chǎng)景,這樣設(shè)計(jì)的目的是為了保證極端情況下,如果有一個(gè)或兩個(gè)發(fā)動(dòng)機(jī)出現(xiàn)故障,不會(huì)因?yàn)槟硞€(gè)發(fā)動(dòng)機(jī)的故障而引起重大的安全事故。

2.多級(jí)緩存概述

緩存功能的設(shè)計(jì)也是一樣,我們?cè)诟卟l(fā)系統(tǒng)中通常會(huì)使用多級(jí)緩存來(lái)保證其高效運(yùn)行,其中的多級(jí)緩存就包含以下這些:

  • 瀏覽器緩存:它的實(shí)現(xiàn)主要依靠 HTTP 協(xié)議中的緩存機(jī)制,當(dāng)瀏覽器第一次請(qǐng)求一個(gè)資源時(shí),服務(wù)器會(huì)將該資源的相關(guān)緩存規(guī)則(如 Cache-Control、Expires 等)一同返回給客戶(hù)端,瀏覽器會(huì)根據(jù)這些規(guī)則來(lái)判斷是否需要緩存該資源以及該資源的有效期。
  • Nginx 緩存:在 Nginx 中配置中開(kāi)啟緩存功能。
  • 分布式緩存:所有系統(tǒng)調(diào)用的中間件都是分布式緩存,如 Redis、MemCached 等。
  • 本地緩存:JVM 層面,單系統(tǒng)運(yùn)行期間在內(nèi)存中產(chǎn)生的緩存,例如 Caffeine、Google Guava 等。

以下是它們的具體使用。

2.1 開(kāi)啟瀏覽器緩存

在 Java Web應(yīng)用中,實(shí)現(xiàn)瀏覽器緩存可以使用 HttpServletResponse 對(duì)象來(lái)設(shè)置與緩存相關(guān)的響應(yīng)頭,以開(kāi)啟瀏覽器的緩存功能,它的具體實(shí)現(xiàn)分為以下幾步。

① 配置 Cache-Control

Cache-Control 是 HTTP/1.1 中用于控制緩存策略的主要方式。它可以設(shè)置多個(gè)指令,如 max-age(定義資源的最大存活時(shí)間,單位秒)、no-cache(要求重新驗(yàn)證)、public(指示可以被任何緩存區(qū)緩存)、private(只能被單個(gè)用戶(hù)私有緩存存儲(chǔ))等,設(shè)置如下:

response.setHeader("Cache-Control", "max-age=3600, public"); // 緩存一小時(shí)

② 配置 Expires

設(shè)置一個(gè)絕對(duì)的過(guò)期時(shí)間,超過(guò)這個(gè)時(shí)間點(diǎn)后瀏覽器將不再使用緩存的內(nèi)容而向服務(wù)器請(qǐng)求新的資源,設(shè)置如下:

response.setDateHeader("Expires", System.currentTimeMillis() + 3600 * 1000); // 緩存一小時(shí)

③ 配置 ETag

ETag(實(shí)體標(biāo)簽)一種驗(yàn)證機(jī)制,它為每個(gè)版本的資源生成一個(gè)唯一標(biāo)識(shí)符。當(dāng)客戶(hù)端發(fā)起請(qǐng)求時(shí),會(huì)攜帶上先前接收到的 ETag,服務(wù)器根據(jù) ETag 判斷資源是否已更新,若未更新則返回 304 Not Modified 狀態(tài)碼,通知瀏覽器繼續(xù)使用本地緩存,設(shè)置如下:

String etag = generateETagForContent(); // 根據(jù)內(nèi)容生成ETag
response.setHeader("ETag", etag);

④ 配置 Last-Modified

指定資源最后修改的時(shí)間戳,瀏覽器下次請(qǐng)求時(shí)會(huì)帶上 If-Modified-Since 頭,服務(wù)器對(duì)比時(shí)間戳決定是否返回新內(nèi)容或發(fā)送 304 狀態(tài)碼,設(shè)置如下:

long lastModifiedDate = getLastModifiedDate();
response.setDateHeader("Last-Modified", lastModifiedDate);

整體配置

在 Spring Web 框架中,可以通過(guò) HttpServletResponse 對(duì)象來(lái)設(shè)置這些頭信息。例如,在過(guò)濾器中設(shè)置響應(yīng)頭以啟用緩存:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
       throws IOException, ServletException {
   HttpServletResponse httpResponse = (HttpServletResponse) response;
   // 設(shè)置緩存策略
   httpResponse.setHeader("Cache-Control", "max-age=3600");

   // 其他響應(yīng)頭設(shè)置...
   chain.doFilter(request, response);
}

以上就是在 Java Web 應(yīng)用程序中利用 HTTP 協(xié)議特性控制瀏覽器緩存的基本方法。

2.2 開(kāi)啟 Nginx 緩存

Nginx 中開(kāi)啟緩存的配置總共有以下 5 步。

① 定義緩存配置

在 Nginx 配置中定義一個(gè)緩存路徑和配置,通過(guò) proxy_cache_path 指令完成,例如,以下配置:

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

其中:

  • /path/to/cache:這是緩存文件的存放路徑。
  • levels=1:2:定義緩存目錄的層級(jí)結(jié)構(gòu)。
  • keys_zone=my_cache:10m:定義一個(gè)名為 my_cache 的共享內(nèi)存區(qū)域,大小為 10MB。
  • max_size=10g:設(shè)置緩存的最大大小為 10GB。
  • inactive=60m:如果在 60 分鐘內(nèi)沒(méi)有被訪問(wèn),緩存將被清理。
  • use_temp_path=off:避免在文件系統(tǒng)中進(jìn)行不必要的數(shù)據(jù)拷貝。

② 啟用緩存

在 server 或 location 塊中,使用 proxy_cache 指令來(lái)啟用緩存,并指定要使用的 keys zone,例如,以下配置:

server {  
    ...  
    location / {  
        proxy_cache my_cache;  
        ...  
    }  
}

③ 設(shè)置緩存有效期

使用 proxy_cache_valid 指令來(lái)設(shè)置哪些響應(yīng)碼的緩存時(shí)間,例如,以下配置:

location / {  
    proxy_cache my_cache;  
    proxy_cache_valid 200 304 12h;  
    proxy_cache_valid any 1m;  
    ...  
}

④ 配置反向代理

確保你已經(jīng)配置了反向代理,以便 Nginx 可以將請(qǐng)求轉(zhuǎn)發(fā)到后端服務(wù)器。例如,以下配置:

location / {  
    proxy_pass http://backend_server;  
    ...  
}

⑤ 重新加載配置

保存并關(guān)閉 Nginx 配置文件后,使用 nginx -s reload 命令重新加載配置,使更改生效。

2.3 使用分布式緩存

在 Spring Boot 項(xiàng)目中使用注解的方式來(lái)操作分布式緩存 Redis 的實(shí)現(xiàn)步驟如下。

① 添加依賴(lài)

在你的 pom.xml 文件中添加 Spring Boot 的 Redis 依賴(lài),如下所示:

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

② 配置 Redis 連接信息

在 application.properties 或 application.yml 文件中配置 Redis 的相關(guān)信息,如下所示。

# application.properties  
spring.redis.host=localhost  
spring.redis.port=6379

③ 啟動(dòng)緩存

在 Spring Boot 主類(lèi)或者配置類(lèi)上添加 @EnableCaching 注解來(lái)啟用緩存。

import org.springframework.cache.annotation.EnableCaching;  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
  
@SpringBootApplication  
@EnableCaching  
public class Application {  
  
    public static void main(String[] args) {  
        SpringApplication.run(Application.class, args);  
    }  
  
}

④ 使用緩存

在服務(wù)類(lèi)或方法上使用 @Cacheable,@CacheEvict,@CachePut 等注解來(lái)定義緩存行為。

例如,使用 @Cacheable 注解來(lái)緩存方法的返回值:

import org.springframework.cache.annotation.Cacheable;  
import org.springframework.stereotype.Service;  
  
@Service  
public class UserService {  
    @Cacheable("users")  
    public User findUserById(Long id) {  
        // 模擬從數(shù)據(jù)庫(kù)中查詢(xún)用戶(hù)  
        return new User(id, "Alice");  
    }  
}

也可以使用 @CacheEvict 注解來(lái)刪除緩存:

import org.springframework.cache.annotation.CacheEvict;  
import org.springframework.stereotype.Service;  
  
@Service  
public class UserService {  
    @CacheEvict(value = "users", key = "#id")  
    public void deleteUser(Long id) {  
        // 模擬從數(shù)據(jù)庫(kù)中刪除用戶(hù)  
    }  
}

在這個(gè)例子中,deleteUser 方法會(huì)刪除 "users" 緩存中 key 為 id 的緩存項(xiàng)。

可以使用 @CachePut 注解來(lái)更新緩存:

import org.springframework.cache.annotation.CachePut;  
import org.springframework.stereotype.Service;  
  
@Service  
public class UserService {  
  
    @CachePut(value = "users", key = "#user.id")  
    public User updateUser(User user) {  
        // 模擬更新數(shù)據(jù)庫(kù)中的用戶(hù)信息  
        return user;  
    }  
  
}

在這個(gè)例子中,updateUser 方法會(huì)更新 "users" 緩存中 key 為 user.id 的緩存項(xiàng),緩存的值是方法的返回值。

2.4 使用本地緩存

以 Caffeine 本地緩存的使用為例,它在 Spring Boot 項(xiàng)目中的使用如下。

① 添加依賴(lài)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

② 配置 Caffeine 緩存

在 application.properties 或 application.yml 文件中配置 Caffeine 緩存的相關(guān)參數(shù)。例如:

# application.properties
spring.cache.type=caffeine
spring.cache.caffeine.spec=initialCapacity=100,maximumSize=1000,expireAfterWrite=10s

這里 spring.cache.caffeine.spec 是一個(gè) Caffeine 規(guī)范字符串,用于設(shè)置初始容量、最大容量和寫(xiě)入后過(guò)期時(shí)間等緩存策略,其中:

  • initialCapacity:初始容器容量。
  • maximumSize:最大容量。
  • expireAfterWrite:寫(xiě)入緩存后 N 長(zhǎng)時(shí)間后過(guò)期。

③ 自定義 Caffeine 配置類(lèi)(可選步驟)

如果需要更復(fù)雜的配置,可以創(chuàng)建一個(gè) Caffeine CacheManager 的配置類(lèi):

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CaffeineCacheConfig extends CachingConfigurerSupport {

    @Bean
    public CacheManager cacheManager() {
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                .initialCapacity(100)
                .maximumSize(1000)
                .expireAfterWrite(10, TimeUnit.SECONDS) // 10 秒后過(guò)期
                .recordStats(); // 記錄緩存統(tǒng)計(jì)信息

        return new CaffeineCacheManager("default", caffeine::build);
    }

    @Override
    public CacheResolver cacheResolver() {
        // 自定義緩存解析器(如果需要)
        // ...
        return super.cacheResolver();
    }
}

④ 開(kāi)啟緩存

若要利用 Spring Cache 抽象層,以便通過(guò)注解的方式更方便地管理緩存,需要在啟動(dòng)類(lèi)上添加 @EnableCaching 注解,如下所示:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableCaching
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

⑤ 使用注解進(jìn)行緩存操作

在業(yè)務(wù)邏輯類(lèi)中使用 @Cacheable、@CacheEvict 等注解實(shí)現(xiàn)數(shù)據(jù)的緩存讀取和更新,和上面分布式緩存的使用相同,具體示例如下:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id") // 假設(shè)我們有一個(gè)名為"users"的緩存區(qū)域
    public User getUserById(Long id) {
        // 這里是真實(shí)的數(shù)據(jù)庫(kù)查詢(xún)或其他耗時(shí)操作
        return userRepository.findById(id).orElse(null);
    }

    @CacheEvict(value = "users", key = "#user.id")
    public void updateUser(User user) {
        userRepository.save(user);
    }
}

課后思考

除了以上的緩存之外,還有哪些緩存可以加速程序的執(zhí)行效率呢?

到此這篇關(guān)于Java實(shí)現(xiàn)多級(jí)緩存的方法詳解的文章就介紹到這了,更多相關(guān)Java多級(jí)緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis 過(guò)期鍵刪除策略的實(shí)現(xiàn)示例

    Redis 過(guò)期鍵刪除策略的實(shí)現(xiàn)示例

    Redis的過(guò)期數(shù)據(jù)刪除策略主要有三種,包括定時(shí)刪除、惰性刪除和定期刪除,本文主要介紹了Redis 過(guò)期鍵刪除策略的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • win 7 安裝redis服務(wù)【筆記】

    win 7 安裝redis服務(wù)【筆記】

    Redis是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫(xiě)、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的API。
    2016-05-05
  • Redis2.8配置文件中文詳解

    Redis2.8配置文件中文詳解

    這篇文章主要介紹了Redis2.8配置文件中文詳解,本文提供的是是Redis2.8.9的配置文件各項(xiàng)的中文解釋,需要的朋友可以參考下
    2015-06-06
  • redis在Linux系統(tǒng)下的環(huán)境配置和redis的全局命令大全

    redis在Linux系統(tǒng)下的環(huán)境配置和redis的全局命令大全

    在Linux系統(tǒng)中我們經(jīng)常使用Redis作為高性能的緩存數(shù)據(jù)庫(kù),然而有時(shí)候我們需要在系統(tǒng)中多個(gè)地方使用Redis命令,這就需要將Redis的全局命令設(shè)置好,這篇文章主要給大家介紹了關(guān)于redis在Linux系統(tǒng)下的環(huán)境配置和redis的全局命令大全的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • 配置redis的序列化,注入RedisTemplate方式

    配置redis的序列化,注入RedisTemplate方式

    這篇文章主要介紹了配置redis的序列化,注入RedisTemplate方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Redis 數(shù)據(jù)庫(kù)忘記密碼找回或重置的解決方法

    Redis 數(shù)據(jù)庫(kù)忘記密碼找回或重置的解決方法

    對(duì)于 Redis 數(shù)據(jù)庫(kù),如果忘記了密碼,可以通過(guò)密碼重置來(lái)找回密碼,今天通過(guò)本文給大家分享Redis 數(shù)據(jù)庫(kù)忘記密碼找回或重置的解決方法,感興趣的朋友一起看看吧
    2024-01-01
  • 手把手教你使用redis實(shí)現(xiàn)排行榜功能

    手把手教你使用redis實(shí)現(xiàn)排行榜功能

    使用Redis中有序集合的特性來(lái)實(shí)現(xiàn)排行榜是又好又快的選擇,一般排行榜都是有實(shí)效性的,比如“用戶(hù)積分榜”,下面這篇文章主要給大家介紹了關(guān)于使用redis實(shí)現(xiàn)排行榜功能的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Redis6 主從復(fù)制及哨兵機(jī)制的實(shí)現(xiàn)

    Redis6 主從復(fù)制及哨兵機(jī)制的實(shí)現(xiàn)

    本文主要介紹了Redis6 主從復(fù)制及哨兵機(jī)制的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn)

    Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn)

    本文主要介紹了Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Redis SETEX命令實(shí)現(xiàn)鍵值對(duì)管理

    Redis SETEX命令實(shí)現(xiàn)鍵值對(duì)管理

    本文主要介紹了Redis SETEX命令實(shí)現(xiàn)鍵值對(duì)管理,SETEX命令用于設(shè)置具有過(guò)期時(shí)間的鍵值對(duì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06

最新評(píng)論