宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動(dòng)態(tài)
精選推薦

使用EhCache緩存集群

管理 管理 編輯 刪除

上一篇我們介紹了在Spring Boot中整合EhCache的方法。既然用了ehcache,我們自然要說說它的一些高級(jí)功能,不然我們用默認(rèn)的ConcurrentHashMap就好了。本篇不具體介紹EhCache緩存如何落文件、如何配置各種過期參數(shù)等常規(guī)細(xì)節(jié)配置,不熟悉的朋友可以看看這里的官方文檔。

那么我們今天具體講什么呢?先思考一個(gè)場(chǎng)景,當(dāng)我們使用了EhCache,在緩存過期之前可以有效的減少對(duì)數(shù)據(jù)庫的訪問,但是通常我們將應(yīng)用部署在生產(chǎn)環(huán)境的時(shí)候,為了實(shí)現(xiàn)應(yīng)用的高可用(有一臺(tái)機(jī)器掛了,應(yīng)用還需要可用),肯定是會(huì)部署多個(gè)不同的進(jìn)程去運(yùn)行的,那么這種情況下,當(dāng)有數(shù)據(jù)更新的時(shí)候,每個(gè)進(jìn)程中的緩存都是獨(dú)立維護(hù)的,如果這些進(jìn)程緩存同步機(jī)制,那么就存在因緩存沒有更新,而一直都用已經(jīng)失效的緩存返回給用戶,這樣的邏輯顯然是會(huì)有問題的。所以,本文就來說說當(dāng)使用EhCache的時(shí)候,如果來組建進(jìn)程內(nèi)緩存EnCache的集群以及配置配置他們的同步策略。

由于下面是組建集群的過程,務(wù)必采用多機(jī)的方式調(diào)試,避免不必要的錯(cuò)誤發(fā)生。

動(dòng)手試試

本篇的實(shí)現(xiàn)將基于上一篇的基礎(chǔ)工程來進(jìn)行。先來回顧下上一篇中的程序要素:

User實(shí)體的定義

@Entity
@Data
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

User實(shí)體的數(shù)據(jù)訪問實(shí)現(xiàn)(涵蓋了緩存注解)

@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository<User, Long> {

    @Cacheable
    User findByName(String name);

}

下面開始改造這個(gè)項(xiàng)目:

第一步:為需要同步的緩存對(duì)象實(shí)現(xiàn)Serializable接口

@Entity
@Data
@NoArgsConstructor
public class User implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}
注意:如果沒有做這一步,后續(xù)緩存集群通過過程中,因?yàn)橐獋鬏擴(kuò)ser對(duì)象,會(huì)導(dǎo)致序列化與反序列化相關(guān)的異常

第二步:重新組織ehcache的配置文件。我們嘗試手工組建集群的方式,不同實(shí)例在網(wǎng)絡(luò)相關(guān)配置上會(huì)產(chǎn)生不同的配置信息,所以我們建立不同的配置文件給不同的實(shí)例使用。比如下面這樣:

實(shí)例1,使用ehcache-1.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd">

    <cache name="users"
           maxEntriesLocalHeap="200"
           timeToLiveSeconds="600">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=true,
            replicatePuts=true,
            replicateUpdates=true,
            replicateUpdatesViaCopy=false,
            replicateRemovals=true "/>
    </cache>

    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="hostName=10.10.0.100,
                        port=40001,
                        socketTimeoutMillis=2000,
                        peerDiscovery=manual,
                        rmiUrls=//10.10.0.101:40001/users" />

</ehcache>

實(shí)例2,使用ehcache-2.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd">

    <cache name="users"
           maxEntriesLocalHeap="200"
           timeToLiveSeconds="600">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=true,
            replicatePuts=true,
            replicateUpdates=true,
            replicateUpdatesViaCopy=false,
            replicateRemovals=true "/>
    </cache>

    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="hostName=10.10.0.101,
                        port=40001,
                        socketTimeoutMillis=2000,
                        peerDiscovery=manual,
                        rmiUrls=//10.10.0.100:40001/users" />

</ehcache>

配置說明:

  • cache標(biāo)簽中定義名為users的緩存,這里我們?cè)黾恿艘粋€(gè)子標(biāo)簽定義cacheEventListenerFactory,這個(gè)標(biāo)簽主要用來定義緩存事件監(jiān)聽的處理策略,它有以下這些參數(shù)用來設(shè)置緩存的同步策略:
    • replicatePuts:當(dāng)一個(gè)新元素增加到緩存中的時(shí)候是否要復(fù)制到其他的peers。默認(rèn)是true。
    • replicateUpdates:當(dāng)一個(gè)已經(jīng)在緩存中存在的元素被覆蓋時(shí)是否要進(jìn)行復(fù)制。默認(rèn)是true。
    • replicateRemovals:當(dāng)元素移除的時(shí)候是否進(jìn)行復(fù)制。默認(rèn)是true。
    • replicateAsynchronously:復(fù)制方式是異步的指定為true時(shí),還是同步的,指定為false時(shí)。默認(rèn)是true。
    • replicatePutsViaCopy:當(dāng)一個(gè)新增元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
    • replicateUpdatesViaCopy:當(dāng)一個(gè)元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
  • 新增了一個(gè)cacheManagerPeerProviderFactory標(biāo)簽的配置,用來指定組建的集群信息和要同步的緩存信息,其中:
    • hostName:是當(dāng)前實(shí)例的主機(jī)名
    • port:當(dāng)前實(shí)例用來同步緩存的端口號(hào)
    • socketTimeoutMillis:同步緩存的Socket超時(shí)時(shí)間
    • peerDiscovery:集群節(jié)點(diǎn)的發(fā)現(xiàn)模式,有手工與自動(dòng)兩種,這里采用了手工指定的方式
    • rmiUrls:當(dāng)peerDiscovery設(shè)置為manual的時(shí)候,用來指定需要同步的緩存節(jié)點(diǎn),如果存在多個(gè)用|連接

第三步:打包部署與啟動(dòng)。打包沒啥大問題,主要緩存配置內(nèi)容存在一定差異,所以在指定節(jié)點(diǎn)的模式下,需要單獨(dú)拿出來,然后使用啟動(dòng)參數(shù)來控制讀取不同的配置文件。比如這樣:

-Dspring.cache.ehcache.config=classpath:ehcache-1.xml
-Dspring.cache.ehcache.config=classpath:ehcache-2.xml

第四步:實(shí)現(xiàn)幾個(gè)接口用來驗(yàn)證緩存的同步效果

@RestController
static class HelloController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/create")    
    public void create() {
        userRepository.save(new User("AAA", 10));
    }

    @GetMapping("/find")
    public User find() {
        User u1 = userRepository.findByName("AAA");
        System.out.println("查詢AAA用戶:" + u1.getAge());
        return u1;
    }

}

驗(yàn)證邏輯:

  1. 啟動(dòng)通過第三步說的命令參數(shù),啟動(dòng)兩個(gè)實(shí)例
  2. 調(diào)用實(shí)例1的/create接口,創(chuàng)建一條數(shù)據(jù)
  3. 調(diào)用實(shí)例1的/find接口,實(shí)例1緩存User,同時(shí)同步緩存信息給實(shí)例2,在實(shí)例1中會(huì)存在SQL查詢語句
  4. 調(diào)用實(shí)例2的/find接口,由于緩存集群同步了User的信息,所以在實(shí)例2中的這次查詢也不會(huì)出現(xiàn)SQL語句

進(jìn)一步思考

有的朋友會(huì)問數(shù)據(jù)更新之后怎么辦?

其實(shí)當(dāng)構(gòu)建了緩存集群之后,就比較好辦了。比如這里的例子,需要做兩件事:

  1. save操作增加@CachePut注解,讓更新操作完成之后將結(jié)果再put到緩存中
  2. 保證緩存事件監(jiān)聽的replicateUpdates=true,這樣數(shù)據(jù)在更新之后可以保證復(fù)制到其他節(jié)點(diǎn)

這樣就可以防止緩存的臟數(shù)據(jù)了,但是這種方法還并不是很好,因?yàn)榫彺婕旱耐揭廊恍枰獣r(shí)間,會(huì)存在短暫的不一致。同時(shí)進(jìn)程內(nèi)的緩存要在每個(gè)實(shí)例上都占用,如果大量存儲(chǔ)的話始終不那么經(jīng)濟(jì)。所以,很多時(shí)候進(jìn)程內(nèi)緩存不會(huì)作為主要的緩存手段。

注:本文轉(zhuǎn)載自“程序猿DD”,如有侵權(quán),請(qǐng)聯(lián)系刪除!

請(qǐng)登錄后查看

哈哈哈醬 最后編輯于2025-01-14 16:27:45

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡(jiǎn)介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
730
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動(dòng)態(tài) 精選推薦 首頁頭條 首頁動(dòng)態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請(qǐng)輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊(cè)

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊(cè)
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服