最近恰逢高考,整个社会都处于一种亢奋状态。今年也是比较特殊的一年,首先疫情影响,高考推迟了一个月,接着部分地区又迎来的大暴雨,地震,(江苏卷更是永久性推出了历史的舞台)属实不易。尽管如此,但是大家对于这份考卷的态度让人更加动容。全程护航,连夜搭建浮桥帐篷...大家都心照不宣的默默地为考生加油,为一个个梦想让步。社会对考生的关注,也是对未来社会的托付。
鹏北海,凤朝阳。又携书剑路茫茫。
言归正传,整理下最近把插件后端增加了缓存redis,查询速度由原先的10多s转变为现在的1s不到。
后端用的是springboot,redis和springboot组合网上能搜到很多文章。当然由于插件是轻量级的,而且我们的目的也是为了加快查询结果,因此只用到了redis的少部分功能。
首先在application.properties里加入redis的配置:
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
...
然后编写RedisConfig.java文件,将redis的相关配置加入到springboot管理中。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
接着我们编写一个简单的工具类,RedisUtil.java用来处理相关缓存的操作。比如如何加入key,key的有效期等等。
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.MINUTES);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
准备工作完毕,我们就可以在循环请求github获取pr状态的部分加上缓存。原先是用多线程的方式,但是一次请求rest返回的时间也不小。因此我们把已经merge的pr的信息缓存下来,时间设置为永久不失效。而仍处于open状态的,将它的过期时间设置为2h(这个时间间隔是为了满足我们CI的build时间)。
if(status.equals("merged")){
redisUtil.set(pr, prInfo, -1);
}else {
redisUtil.set(pr, prInfo, 120L);
}
借此,我们很快就能够获取所有需要查询的pr状态(30天内的)并画出gantt。
redis部署也是用docker,服务只要起来就可以用,缓存的数据也不是相对重要,因此也无需考虑持久化。
网友评论