客戶端通過Redis緩存獲取知識包
當服務(wù)端啓用(yòng)集群的部署方式後,我們可(kě)以選擇将知識包放到Redis中(zhōng)緩存,客戶端需要更新(xīn)知識包時,去Redis中(zhōng)獲取而不是去服務(wù)端獲取。
服務(wù)端需要實現 ClusterPacketCacheAdapter
,在以下方法中(zhōng),操作(zuò)Redis中(zhōng)的緩存。
方法 | 說明 |
---|---|
putPacket | 第一次和重置緩存時觸發 |
remove | 删除知識包緩存時觸發 |
refreshPacket | 刷新(xīn)知識包緩存時觸發 |
removeProject | 删除項目時觸發 |
recacheAllPackets | 重置全部知識包緩存時觸發 |
實現參考
1、定義緩存操作(zuò)接口
import com.bstek.urule.runtime.KnowledgePackage;
/**
* 自定義知識包緩存接口
*/
public interface CustomKnowledgeCacheService {
public static final String BEAN_ID = "urule.ext.customKnowledgeCache";
//緩存中(zhōng)放入知識包
public void putCache(String key ,KnowledgePackage value);
//删除知識包
public void removeCache(String key);
//删除所有(yǒu)知識包
public Long removeAllCache(String prefixKey);
}
2、知識包Reids緩存實現類
import java.util.Set;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.bstek.urule.Utils;
import com.bstek.urule.console.cache.packet.PacketData;
import com.bstek.urule.runtime.KnowledgePackage;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class RedisKnowledgeCacheServiceImpl implements CustomKnowledgeCacheService {
@Resource
RedisTemplate redisTemplate;
@Value("${project.urule.packetcache.prefix:packetcache:packetcache_}")
String packetCachePrefix;
@Value("${project.urule.packetcache.timestampsuffix:_timestamp}")
String timestampSuffix;
/**
* 在Redis中(zhōng)存入知識包的同時,存入一個時間戳,用(yòng)來更新(xīn)知識包時進行比對
*/
@Override
public void putCache(String packetKey, KnowledgePackage knowledgePackage) {
String knowledgePackageTimestamp = String.valueOf(knowledgePackage.getTimestamp());
String redisKnowledgePackageTimestamp = (String) redisTemplate.opsForValue().get(packetCachePrefix + packetKey + timestampSuffix);
if (redisKnowledgePackageTimestamp == null || !knowledgePackageTimestamp.equals(redisKnowledgePackageTimestamp)) {
String knowledgePackageContent = Utils.knowledgePackageToString(knowledgePackage);
log.info("set redis id{},timestamp={},redistimestamp={}", packetCachePrefix + packetKey, knowledgePackageTimestamp,redisKnowledgePackageTimestamp);
redisTemplate.opsForValue().set(packetCachePrefix + packetKey, knowledgePackageContent);
redisTemplate.opsForValue().set(packetCachePrefix + packetKey + timestampSuffix, knowledgePackageTimestamp);
}
}
@Override
public void removeCache(String packetKey) {
redisTemplate.delete(packetCachePrefix + packetKey);
redisTemplate.delete(packetCachePrefix + packetKey + timestampSuffix);
}
@Override
public Long removeAllCache(String key) {
Set<String> keys = redisTemplate.keys(packetCachePrefix+key);
if(!CollectionUtils.isEmpty(keys)) {
return redisTemplate.delete(keys);
}
return null;
}
}
3、在 ClusterPacketCacheAdapter
實現中(zhōng)調用(yòng) customKnowledgeCacheService
/**
* 知識包緩存更新(xīn)消息通知類
*/
@Slf4j
@Component("urule.clusterPacketCacheAdapter")
public class MsgClusterPacketCacheAdapter implements ClusterPacketCacheAdapter{
@Autowired
private CustomKnowledgeCacheService customKnowledgeCacheService;
@Autowired
private CustomProducerService customProducerService;
public List<Map<String, Object>> recacheAllPackets(String groupId) {
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
log.info("recacheAllPackets(String groupId):"+groupId);
customKnowledgeCacheService.removeAllCache("*");
ObjectNode msg = JsonUtils.getObjectJsonMapper().createObjectNode();
msg.put("groupId", groupId);
msg.put("systemId", Utils.SystemId);
msg.put("messageType", MQConstant.QUEUE_CLUSTER_PACKET_REFRESHALL);
customProducerService.sendMessage(MQConstant.CLUSTER_TOPIC, msg.toString());
return result;
}
@Override
public List<Map<String, Object>> refreshPacket(String groupId, long packetId) {
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
Packet packet = PacketManager.ins.load(packetId);
String packetCode = packet.getCode();
PacketData packetData =PacketCache.ins.getPacket(packetId);
//緩存知識包
if(packetData!=null) {
KnowledgePackage knowledgePackage = packetData.getKnowledgePackageWrapper().getKnowledgePackage();
customKnowledgeCacheService.putCache(String.valueOf(packetId), knowledgePackage);
customKnowledgeCacheService.putCache(packetCode, knowledgePackage);
}
//通知服務(wù)端集群節點
log.info("refreshPacket(String groupId, long packetId):{}:{}:{}",groupId,packetId,packetCode);
ObjectNode clustermsg = JsonUtils.getObjectJsonMapper().createObjectNode();
clustermsg.put("groupId", groupId);
clustermsg.put("systemId", Utils.SystemId);
clustermsg.put("packetId", String.valueOf(packetId));
clustermsg.put("packetCode", packetCode);
clustermsg.put("messageType", MQConstant.QUEUE_CLUSTER_PACKET_REFRESH);
customProducerService.sendMessage(MQConstant.CLUSTER_TOPIC, clustermsg.toString());
ObjectNode clientmsg = JsonUtils.getObjectJsonMapper().createObjectNode();
clientmsg.put("groupId", groupId);
clientmsg.put("systemId", Utils.SystemId);
clientmsg.put("packetId", String.valueOf(packetId));
clientmsg.put("packetCode", packetCode);
clientmsg.put("messageType", MQConstant.QUEUE_CLIENT_PACKET_REFRESH);
customProducerService.sendMessage(MQConstant.CLIENT_TOPIC, clientmsg.toString());
return result;
}
@Override
public List<Map<String, Object>> removeProject(String groupId, long projectId, List<PacketConfig> list) {
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
log.info("removeProject(String paramString, long paramLong, List<PacketConfig> paramList):"+projectId);
for(PacketConfig pc:list) {
disableClientsPacket(groupId,pc.getId(),pc.getCode());
customKnowledgeCacheService.removeCache(String.valueOf(pc.getId()));
customKnowledgeCacheService.removeCache(pc.getCode());
}
ObjectNode msg = JsonUtils.getObjectJsonMapper().createObjectNode();
msg.put("groupId", groupId);
msg.put("systemId", Utils.SystemId);
msg.put("projectId", String.valueOf(projectId));
msg.put("messageType", MQConstant.QUEUE_CLUSTER_PROJECT_REMOVE);
customProducerService.sendMessage(MQConstant.CLUSTER_TOPIC, msg.toString());
return result;
}
@Override
public void putPacket(long packetId, PacketData paramPacketData) {
// TODO Auto-generated method stub
log.info("putPacket(long packetId){}", packetId);
if (paramPacketData == null) {
throw new RuleException("Put Package to Redis [id=" + packetId + "] not exist");
}
KnowledgePackage knowledgePackage = paramPacketData.getKnowledgePackageWrapper().getKnowledgePackage();
customKnowledgeCacheService.putCache(String.valueOf(packetId), knowledgePackage);
}
@Override
public void putPacket(String packetCode, PacketData paramPacketData) {
// TODO Auto-generated method stub
log.info("putPacket(String packetCode):{}", packetCode);
if (paramPacketData == null) {
throw new RuleException("Put Package to Redis [code=" + packetCode + "] not exist");
}
KnowledgePackage knowledgePackage = paramPacketData.getKnowledgePackageWrapper().getKnowledgePackage();
customKnowledgeCacheService.putCache(packetCode, knowledgePackage);
}
@Override
public void remove(long packetId) {
// TODO Auto-generated method stub
log.info("remove(String packetId):{}", packetId);
customKnowledgeCacheService.removeCache(String.valueOf(packetId));
}
@Override
public void remove(String packetCode) {
// TODO Auto-generated method stub
log.info("remove(String packetCode):{}", packetCode);
customKnowledgeCacheService.removeCache(packetCode);
}
public List<Map<String, Object>> disableClientsPacket(String groupId, long packetId,String packetCode) {
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
log.info("disableClientsPacket(String groupId:{}, long packetId):{},code:{}" ,groupId,packetId,packetCode);
ObjectNode msg = JsonUtils.getObjectJsonMapper().createObjectNode();
msg.put("groupId", groupId);
msg.put("systemId", Utils.SystemId);
msg.put("packetId", String.valueOf(packetId));
msg.put("packetCode", packetCode);
msg.put("messageType", MQConstant.QUEUE_CLIENT_PACKET_DISABLE);
customProducerService.sendMessage(MQConstant.CLIENT_TOPIC, msg.toString());
return result;
}
}
4、客戶端配置從Redis中(zhōng)獲取知識包