简述
本文中,将改进数据服务。使用redis集群来提供缓存服务。
源代码
iarc-data
环境
IDE: IntelliJ IDEA
JDK: 1.8.0_u162
Framework: spring boot, dubbo
Cache: Redis
WebServer: Tomcat (本地端口8088)
开发
pom dependency
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
|
appliation.properties redis配置
通用
1 2 3 4 5 6
| spring.redis.database=2 spring.redis.timeout=10000 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=1 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1
|
单实例
1 2 3
| spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=****
|
Sentinel集群
1 2
| spring.redis.sentinel.master=mymaster spring.redis.sentinel.nodes=192.168.56.103:29000,192.168.56.103:29001,192.168.56.103:29002
|
配置类
RedisCacheConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| package cn.icmyfuture.iarc.data.common;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map;
public class RedisCacheConfig extends CachingConfigurerSupport { private static final Map<String, Long> cacheMap = new HashMap<String, Long>();
public static void setCacheTime(String key, Long cacheTime){ cacheMap.put(key, cacheTime); }
@Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append("v2:"); sb.append(target.getClass().getName()+":"); sb.append(method.getName()+":"); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; }
@SuppressWarnings("rawtypes") @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); cacheManager.setExpires(cacheMap); return cacheManager; }
@Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
|
CacheConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package cn.icmyfuture.iarc.data.config;
import cn.icmyfuture.iarc.data.common.RedisCacheConfig; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Configuration;
@Configuration @EnableCaching public class CacheConfig extends RedisCacheConfig { public static final String getAllUsers = "getAllUsers";
static { setCacheTime(getAllUsers, 180L); } }
|
SpringBoot开启缓存
1 2
| @EnableCaching public class DataApplication extends SpringBootServletInitializer
|
Service实现中,使用redis缓存
由于dubbo不支持使用注解@Cacheable,只能选择以下2种解决方式之一(本文使用第一种方式,对key的设置有更大的灵活性)
- 使用@Service注解,在代码中获取/设置缓存
- 不使用@Service注解,使用dubbo配置的方式来注册服务,同时开启缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Service public class UserServiceImpl implements UserService { @Autowired UserDao userDao;
@Autowired private CacheManager cacheManager;
@Override public List<User> getAllUsers() { Cache cache = cacheManager.getCache(CacheConfig.getAllUsers); String key = String.format("%s", CacheConfig.getAllUsers); Cache.ValueWrapper wrapper = cache.get(key); List<User> users; if (wrapper == null) { users = userDao.getAllUsers(); cache.put(key, users); return users; } return (List<User>) wrapper.get(); }
|
调试
- 访问
http://localhost:8002/user/getAllUsers来验证redis缓存的有效性
- 访问
http://localhost:8002/druid/index.html来查看SQL监控以验证sql仅被执行了一次
部署
centos下配置好redis。maven工程根目录下执行命令mvn clean install,然后将iarc-data与iarc-service部署到tomcat中,访问http://localhost:8080/service/user/getAllUsers
参考