背景
- 业务场景:有一个工单系统,需要通过用户姓名查询工单(用户大概在3K左右)
- 存在问题:
- 工单系统本身不维护用户信息,仅存在一个用户ID,但是功能需要通过用户姓名搜索
- 用户数据来自两个服务,也就是用户有两个数据源,两个数据源均不支持使用户姓名搜索
- 数据分页
- 数据源不支持批量获取数据
- 解决方案:
- 方案一: 工单系统维护用户数据,写入DB。
- 优点:直接支持分页、用户名搜索等。
- 缺点:
- 用户信息需要同步机制,需要通过定时服务批量获取数据来同步数据,保持数据一致
- 服务本身是工单服务,为了一个搜索功能维护DB、定时服务等会造成业务上数据冗余,并且本身数据并不多但是维护成本较高
- 方案二: 工单系统维护用户数据,创建本地缓存
- 优点:
- 缓存速度相对较快
- 设置过期时间则可以自动刷新数据
- 缺点
- 占用内存
- 模糊匹配需要循环数据
- 不支持分页等
- 优点:
- 方案一: 工单系统维护用户数据,写入DB。
最终选缓存来处理列表,因为数据少,即便以循环的方式来查询用户也不会并且数据更新很不频繁,不需要实时,
实现
使用Google Guava中的cache
添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
添加简单的一个用户Map缓存
/**
* 用户Map缓存
*
* @author hsf
* @since 2019-11-21
**/
@Component
public class UserMapCache {
private static final Logger LOGGER = LoggerFactory.getLogger(UserMapCache.class);
/**
* 缓存Key
*/
private static final String CACHE_KEY = "USER_MAP";
/**
* 缓存数据有效时间(小时)
*/
private static final Integer DURATION = 8;
@Autowired
private userBusiness userbusiness;
/**
* 缓存实例
*/
private LoadingCache<String, Map<Long, UserInfo>> userCache = CacheBuilder.newBuilder()
.refreshAfterWrite(DURATION