1.客服系统多用户同时排队时,会有并发问题
1)第一时间想到的方案是加同步代码块,但是通过实践证明这样的效率低下,行不通
2)最后想到的方案是通过redis来解决并发的问题,因为redis是单线程的,所以在每次分配完客服之后,判断redis中是否已存在自动分配的客服id如果已存在返回"暂无客服",否则向redis里面加一个key为自动分配客服id的值,用来阻止其他用户并发的分配到这个客服。执行完所有代码后删除redis中的值.
//自动分配客服,生成会话,存评分表信息
List<SysUser> sysUserList = sysUserMapper.getByProductId(productId,SysUser.Type.kf.ordinal(),SysUser.KFStatus.on.ordinal(),Evaluate.State.on.ordinal(),CommonConstant.msgNumLimit,SysUser.Status.on.ordinal());//查询可分配的客服列表
if(sysUserList == null || sysUserList.size() == 0 ){
return resultData.initCodeAndDesp(1003);//暂无在线客服
}
int i = new Random().nextInt(sysUserList.size());//随机的客服
SysUser sysUser = sysUserList.get(i);
//1.关键代码
if(this.redisDao.hasKey(CommonConstant.REDIS_REGISTER_KEFU + sysUser.getId())){
return resultData.initCodeAndDesp(1003);//暂无在线客服
}
this.redisDao.set(CommonConstant.REDIS_REGISTER_KEFU + sysUser.getId(), 1, 5);
//返回参数
resultMap = new HashMap<>();
resultMap.put("token", token);
resultMap.put("userId", imId);
resultMap.put("msgNum",msgNum);
resultMap.put("kfId",sysUser.getImId());
resultMap.put("kfName", sysUser.getUsername());
resultMap.put("isNewMsgNum", CommonConstant.isNewMsgNum);//标识 是否是新会话
resultData.setData(resultMap);
//2.关键代码
redisDao.del(CommonConstant.REDIS_REGISTER_KEFU + sysUser.getId());
return resultData.initCodeAndDesp();