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

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

使用EhCache緩存集群

管理 管理 編輯 刪除

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

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

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

動手試試

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

User實體的定義

@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ù)據(jù)訪問實現(xiàn)(涵蓋了緩存注解)

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

    @Cacheable
    User findByName(String name);

}

下面開始改造這個項目:

第一步:為需要同步的緩存對象實現(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ù)緩存集群通過過程中,因為要傳輸User對象,會導(dǎo)致序列化與反序列化相關(guān)的異常

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

實例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>

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

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

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

第四步:實現(xià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;
    }

}

驗證邏輯:

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

進一步思考

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

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

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

這樣就可以防止緩存的臟數(shù)據(jù)了,但是這種方法還并不是很好,因為緩存集群的同步依然需要時間,會存在短暫的不一致。同時進程內(nèi)的緩存要在每個實例上都占用,如果大量存儲的話始終不那么經(jīng)濟。所以,很多時候進程內(nèi)緩存不會作為主要的緩存手段。

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

請登錄后查看

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

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

{{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 || '暫無簡介'}}
附件

{{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}}
802
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

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

微信登錄/注冊

切換手機號登錄

{{ bind_phone ? '綁定手機' : '手機登錄'}}

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

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

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