- 多服務架構下,依舊使用本地緩存
- 減少第三方緩存服務的壓力
- 減少網路 I/O 和建構物件的CPU消耗,提高效能
- 相容 Spring Cacheable
由於緩存通常應用在不頻繁異動的資料上,所以不應該每次都向第三方緩存服務取得資料,而是透過 MQ Service 廣播和訂閱訊息功能,發布註銷的事件,將對應的資料清除,大幅提高系統效能,降低龐大架構的維護成本
- 由於緩存通常應用在不頻繁異動的資料上
- 透過 Message Queue Server 發布和訂閱訊息功能,通知所有服務註銷本地的緩存
SpringBootApplication
@EnablePolarBearCache
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
CacheConfig
public class CacheConfig {
@Bean
@Primary
public PolarBearCacheManager polarBearCacheManager() {
return new BasicCacheManager();
}
}
The architecture of multiple services needs to send evict events to other services through EventService.
SpringBootApplication
@EnablePolarBearCache
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
CacheEventServiceImpl
Redis example.
public class CacheEventServiceImpl extends PolarBearCacheEventService implements InitializingBean {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisMessageListenerContainer redisMessageListenerContainer;
@Autowired
private DefaultClientResources defaultClientResources;
private final String topic = "cache";
@Override
public void afterPropertiesSet() throws Exception {
defaultClientResources.eventBus().get().subscribe((event) -> {
if (event instanceof ConnectedEvent) {
publishConnectedEvent();
}
});
}
@Override
public void send(String body) {
stringRedisTemplate.convertAndSend(topic, body);
}
@Override
public void addListener(Consumer<String> listener) {
redisMessageListenerContainer.addMessageListener((message, pattern) -> {
log.info("pattern:{},message:{}", new String(pattern), message);
listener.accept(new String(message.getBody()));
}, new PatternTopic(topic));
}
}
CacheConfig
public class CacheConfig {
@Bean
public PolarBearCacheEventService polarBearCacheEventService() {
return new CacheEventServiceImpl();
}
@Bean
@Primary
public PolarBearCacheManager polarBearCacheManager() {
return new BasicCacheManager();
}
}
Reference Spring Cacheable
-
@Cacheable
-
一般
public class UserService { @Cacheable( cacheNames = "User" , key = "#id" , condition = "#id != null" , unless = "#result==null" ) public User find(Integer id) { // TODO } }
-
時效性
import pers.clare.polarbearcache.annotation.CacheAlive; public class UserService { @CacheAlive("PT30S") @Cacheable( cacheNames = "User" , key = "#id" , condition = "#id != null" , unless = "#result==null" ) public User find(Integer id) { // TODO } }
-
-
@CacheEvict
如果有配置 Event Service 時,會將 Evict Event 廣播給其他使用相同配置的服務
一般
public class UserService { @CacheEvict( cacheNames = "User" , key = "#user.id" , condition = "#user.id != null" ) public void update(User user) { //TODO } }
-
BeeCacheDependencies
It also clears itself when dependency cache triggers the evict event.
public class TestService implements InitializingBean { @Autowired private PolarBearCacheDependencies cacheDependencies; @Override public void afterPropertiesSet() { // Test cache depends on user cache cacheDependencies.depend("Test", (key) -> { // Convert key return key; }, "User"); } }
-
註冊 Evict 的事件處理
當本地有該緩存資源時,則會觸發 handler 取得最新資料,直接更新緩存,避免同時請求造成多次查詢或者鎖的等待。
public class UserService implements InitializingBean { @Autowired private PolarBearCacheManager cacheManager; @Override public void afterPropertiesSet() { cacheManager.<User>onEvict(UserCacheKey, (key, data) -> find(data.getId())); } }