javascript
使用Hibernate和Spring设置分布式Infinispan缓存
一個非常典型的設置–需要分布式緩存的spring / hibernate應用程序。 但是事實證明,設置并不是那么簡單。
您顯然需要緩存。 可以使用EhCache,Hazelcast,Infinispan,memcached,Redis,AWS的Elasticache以及其他一些方法來執行此操作。 但是,EhCache僅支持復制的緩存,不支持分布式緩存,并且Hazelcast尚未與最新版本的Hibernate一起使用。 Infinispan和Hazelcast支持一致的哈希,因此這些條目僅存在于特定實例上,而不是在每個實例的堆上具有所有緩存的完整副本。 Elasticache是??特定于AWS的,因此Infinispann似乎是彈簧/休眠設置中最平衡的選項。
因此,讓我們首先設置休眠二級緩存。 infinispan的官方文檔并不是Google排名最高的結果-它通常是非常舊的文檔,或者只是2個版本的舊文檔。 您最好從首頁打開最新的一個 。
下面的某些選項相當“隱藏”,在文檔或現有的“操作方法”中我很難找到它們。
首先,將相關的依賴項添加到您的依賴項管理器配置中。 您需要infinispan-core , infinispan-spring和hibernate-infinispan 。 然后在您的configuratoin文件中(無論是哪個文件-在我的情況下是jpa.xml,這是一個定義JPA屬性的彈簧文件)配置以下內容:
<prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.infinispan.InfinispanRegionFactory</prop> <prop key="hibernate.cache.inifinispan.statistics">true</prop> <prop key="hibernate.cache.infinispan.cfg">infinispan.xml</prop> <prop key="hibernate.cache.infinispan.query.cfg">distributed-query</prop>這些設置使用默認的區域工廠啟用二級緩存和查詢緩存(我們將看到為什么以后可能需要將其更改為自定義的),啟用統計信息,指向infinispan.xml配置文件并更改默認名稱。查詢緩存,以便能夠使用分布式緩存(默認情況下為“本地緩存”)。 當然,您可以將所有這些外部化為.properties文件。
然后,在類路徑的根目錄(src / main / resources)中創建infinispan.xml:
<?xml version="1.0" encoding="UTF-8"?> <infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="urn:infinispan:config:8.1 http://www.infinispan.org/schemas/infinispan-config-8.1.xsdurn:infinispan:config:store:jdbc:8.0 http://www.infinispan.org/schemas/infinispan-cachestore-jpa-config-8.0.xsd"xmlns="urn:infinispan:config:8.1"><jgroups><stack-file name="external-file" path="${jgroups.config.path:jgroups-defaults.xml}" /> </jgroups><cache-container default-cache="default" statistics="true"><transport stack="external-file" /><distributed-cache-configuration name="entity" statistics="true" /><distributed-cache-configuration name="distributed-query" statistics="true" /></cache-container> </infinispan>這期望將-Djgroups.config.path傳遞給JVM,以指向jgroups配置。 根據您使用的是自己的設置還是AWS,有多個選項。 在這里,您可以找到 EC2,Google云以及基本UDP和TCP機制的配置文件 。 這些應該放置在項目本身之外,因為在本地您很可能不想使用S3_PING(用于節點檢測的基于S3的機制),并且值在環境之間可能會有所不同。
如果您需要統計信息(最好有它們),則必須在緩存容器級別和緩存級別都啟用它們。 我實際上不知道休眠屬性中的statistics選項在做什么–它對我沒有任何改變。
然后定義每個緩存。 您的實體應使用類似的注釋
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "user") public class User { .. }然后Infinispan自動創建緩存。 它們都可以共享一些默認設置,并且這些默認值是為名為“實體”的緩存定義的。 花了我一段時間才找到答案 , 最后得到關于stackoverflow的答案 。 最后一件事是查詢緩存(使用我們在休眠屬性中定義的名稱)。 請注意“ distributed-cache-configuration”元素-這樣,您可以明確地說“此(或所有)緩存必須是分布式的”(它們將使用jgroups文件中指定的傳輸機制)。 如果您不想強制開發人員指定jvm參數,則可以在jgroups-defaults.xml中配置默認??值,并指向如上例所示的默認值。
例如,您可以使用<distributed-cache-configuration name="user" />定義特定于實體的屬性(檢查XSD的自動完成功能以查看具有哪些配置選項( XML是一種非常方便的配置DSL,不是它嗎?)。
到目前為止,一切都很好。 現在,只要我們在本地配置了正確的訪問密鑰,我們的緩存就可以在本地和AWS(EC2,S3)上運行。 從技術上講,最好為本地和生產使用不同的infinispan.xml文件,并默認定義<local-cache>而不是分布式文件,因為使用TCP或UDP設置,您可能最終會與同一個網絡中的其他隊友組成的集群(盡管我不確定,但是可能會出現一些意外問題)。
現在,春天。 如果僅設置spring,則可以使用SpringEmbeddedCacheManagerFactoryBean創建一個bean,將classpath:infinispan.xml作為資源位置傳遞,它將起作用。 如果您想要完全分離的緩存管理器,則仍然可以這樣做。 但是緩存管理器是棘手的。 我已經概述了EhCache的問題 ,在這里我們必須做一些變通辦法,以便在hibernate和spring之間共享緩存管理器。 那是否是個好主意,取決于情況。 但是,即使您需要單獨的緩存管理器,也可能需要引用休眠基礎緩存管理器,因此仍需要執行以下部分步驟。 使用單獨的緩存的問題是它們在其下注冊的JMX名稱,但是我想也可以對其進行配置。
因此,如果我們需要共享的緩存管理器,則必須創建兩個工廠類的子類:
/*** A region factory that exposes the created cache manager as a static variable, so that* it can be reused in other places (e.g. as spring cache)* * @author bozho**/ public class SharedInfinispanRegionFactory extends InfinispanRegionFactory {private static final long serialVersionUID = 1126940233087656551L;private static EmbeddedCacheManager cacheManager;public static EmbeddedCacheManager getSharedCacheManager() {return cacheManager;}@Overrideprotected EmbeddedCacheManager createCacheManager(ConfigurationBuilderHolder holder) {EmbeddedCacheManager manager = super.createCacheManager(holder);cacheManager = manager;return manager;}@Overrideprotected EmbeddedCacheManager createCacheManager(Properties properties, ServiceRegistry serviceRegistry)throws CacheException {EmbeddedCacheManager manager = super.createCacheManager(properties, serviceRegistry);cacheManager = manager;return manager;} }是的,一個靜態變量。 整,我知道,所以要小心。
然后,我們將其重新用于Spring:
/*** A spring cache factory bean that reuses a previously instantiated infinispan embedded cache manager* @author bozho**/ public class SharedInfinispanCacheManagerFactoryBean extends SpringEmbeddedCacheManagerFactoryBean {private static final Logger logger = ...;@Overrideprotected EmbeddedCacheManager createBackingEmbeddedCacheManager() throws IOException {EmbeddedCacheManager sharedManager = SharedInfinispanRegionFactory.getSharedCacheManager();if (sharedManager == null) {logger.warn("No shared EmbeddedCacheManager found. Make sure the hibernate 2nd level "+ "cache provider is configured and instantiated.");return super.createBackingEmbeddedCacheManager();}return sharedManager;} }然后,將hibernate配置中的hibernate.cache.region.factory_class屬性更改為新的自定義類,并在我們的spring配置文件中執行以下操作:
<bean id="cacheManager" class="com.yourcompany.util.SharedInfinispanCacheManagerFactoryBean" /> <cache:annotation-driven />Spring緩存與方法級別的@Cacheable批注一起使用,該批注允許我們緩存方法調用,我們還可以通過簡單的注入訪問CacheManager 。
然后,“最后”部分是檢查它是否有效。 即使您的應用程序啟動正常并且看起來運行良好,您也應該運行集成或硒測試套件,并通過JMX檢查統計信息。 您甚至可能進行了使用MBean來獲取有關高速緩存的某些統計數據的測試,以確保正在使用它們。
翻譯自: https://www.javacodegeeks.com/2016/02/setting-distributed-infinispan-cache-hibernate-spring.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的使用Hibernate和Spring设置分布式Infinispan缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工行维护公告在哪里?
- 下一篇: 黄金期货有过夜费吗?