首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FF4J:功能存储的服务器端缓存

FF4J:功能存储的服务器端缓存
EN

Stack Overflow用户
提问于 2021-04-09 04:46:39
回答 1查看 291关注 0票数 0

我正在使用带有f4j-store-springjdbcff4j-spring-boot-starter来设置我的ff4j服务器。我的所有其他微服务都使用ff4j提供的端点来访问这个特性存储,并在JSON中返回响应。

由于数据不会频繁更改,并且我们正在尝试保存不必要的数据库调用,因此我尝试在服务器上缓存我的要素存储。此外,如果功能标志DB关闭(用于刷新/维护),我们仍然希望使用缓存中的这些值成功启动其他服务。

我们在pom.xml中导入了ff4j-store-ehcache

代码语言:javascript
复制
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.RC2</spring-cloud.version>
        <ff4j.version>1.8.7</ff4j.version>
        <odbc.version>19.6.0.0.0</odbc.version>
    </properties>
    <dependency>
            <groupId>org.ff4j</groupId>
            <artifactId>ff4j-spring-boot-starter</artifactId>
            <version>${ff4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.ff4j</groupId>
            <artifactId>ff4j-store-springjdbc</artifactId>
            <version>${ff4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.ff4j</groupId>
            <artifactId>ff4j-web</artifactId>
            <version>${ff4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.ff4j</groupId>
            <artifactId>ff4j-store-ehcache</artifactId>
            <version>${ff4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.ff4j</groupId>
            <artifactId>ff4j-webapi-jersey2x</artifactId>
            <version>1.8.11</version>
        </dependency>
        <!-- FF4J dependencies - end -->

我们在FF4jConfig.java中的FeatureCacheProviderEhCache实现如下所示。

代码语言:javascript
复制
@ConditionalOnClass({​​​​ ConsoleServlet.class, FF4jDispatcherServlet.class }​​​​)
public class Ff4jConfig extends SpringBootServletInitializer {​​​​

    @Autowired
    private DataSource dataSource;

    @Bean
    public ServletRegistrationBean<FF4jDispatcherServlet> ff4jDispatcherServletRegistrationBean(
            FF4jDispatcherServlet ff4jDispatcherServlet) {​​​​
        ServletRegistrationBean<FF4jDispatcherServlet> bean = new ServletRegistrationBean<FF4jDispatcherServlet>(
                ff4jDispatcherServlet, "/web-console/*");
        bean.setName("ff4j-console");
        bean.setLoadOnStartup(1);
        return bean;
    }​​​​

    @Bean
    @ConditionalOnMissingBean
    public FF4jDispatcherServlet getFF4jDispatcherServlet() {​​​​
        FF4jDispatcherServlet ff4jConsoleServlet = new FF4jDispatcherServlet();
        ff4jConsoleServlet.setFf4j(getFF4j());
        return ff4jConsoleServlet;
    }​​​​

    @Bean
    public FF4j getFF4j() {​​​​
        FF4j ff4j = new FF4j();
        FF4JCacheManager cacheManager = new FeatureCacheProviderEhCache();
        ff4j.setPropertiesStore(new PropertyStoreSpringJdbc(dataSource));
        ff4j.setFeatureStore(new FeatureStoreSpringJdbc(dataSource));
        ff4j.setEventRepository(new EventRepositorySpringJdbc(dataSource));
        ff4j.cache(cacheManager);
        

        // Enable audit mode
        ff4j.audit(true);

        return ff4j;
    }​​​​

}​​​​

WebConsole会在数据库更改提交时立即反映这些更改,并且看起来缓存并未命中或缓存中存储了任何数据。

我希望能够使用这个缓存,而不必在每次查找时都访问数据库。

我们还尝试使用InMemoryCacheManager作为FeatureCacheProviderEhCache的替代品,但结果相同。在这两个实现中,我们确实在web控制台上看到了clear cache按钮。

另外,有没有更好的方法来测试我的api调用是否真的是从缓存而不是从数据库中获取数据,而不必关闭数据库?

更新:在实现我们自己的FeatureCacheProviderEhCache并登录之后,我尝试访问api/ff4j,featureNames在响应中是空的。请参考日志:

代码语言:javascript
复制
METHOD=getCacheFeatures, LINENO=160, MSG=getCacheFeatures :: [ name = ff4jCacheFeatures status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 10000 maxEntriesLocalDisk = 10000000 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 120 timeToIdleSeconds = 120 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: ; orderedCacheEventListeners:  maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]
METHOD=listCachedFeatureNames, LINENO=59, MSG=listCachedFeatureNames[]
METHOD=getCacheFeatures, LINENO=160, MSG=getCacheFeatures :: [ name = ff4jCacheFeatures status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 10000 maxEntriesLocalDisk = 10000000 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 120 timeToIdleSeconds = 120 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: ; orderedCacheEventListeners:  maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]

缓存已创建,但其中没有存储任何值。我按照第一个答案中所说的方式设置缓存。当我打印listCachedFeatures()时,日志也打印为空。我仍然无法在缓存中看到featureNames。我配置的哪个部分不正确?

EN

回答 1

Stack Overflow用户

发布于 2021-04-10 04:30:32

首先,我想确认您是否正确地使用了缓存。ff4j.cache(cacheManager)是您想要做的事情。在幕后,这就是正在发生的事情:

代码语言:javascript
复制
public FF4j cache(FF4JCacheManager cm) {
    FF4jCacheProxy cp = new FF4jCacheProxy(getFeatureStore(), getPropertiesStore(), cm);
    setFeatureStore(cp);
    setPropertiesStore(cp);
    return this;
}

  1. FeatureCacheProviderEhCacheInMemoryCacheManager的工作方式相同。第一个使用JSR107。这是个人喜好,也许以后使用ehcache你可以切换到像Terracotta这样的分布式缓存。

  1. 如何知道只使用缓存而不使用数据库(读取时)?

  1. 您可以考虑在微服务级别使用缓存(如果使用Java语言实现的话),而不仅仅是在web控制台中。如果这样做,您可以不执行REST调用来获取JSON,从而节省一些时间。

  1. EhCache和InMemory缓存的工作方式与内存中的名称相同,这意味着两个微服务在缓存中可能具有不同的值。如果您希望微服务之间的缓存保持一致(非强制),则需要使用分布式缓存,如REDIS或HAZELCAST。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67011643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档