1.缓存初始化
这一步需要将数据库中所有的有效数据写入到redis缓存
java
package org.dsk.dragon.business.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.gitee.loulan_yxq.owner.core.bean.BeanTool;
import io.gitee.loulan_yxq.owner.core.collection.ArrayTool;
import io.gitee.loulan_yxq.owner.core.collection.CollTool;
import io.gitee.loulan_yxq.owner.core.tool.ObjectTool;
import org.dsk.dragon.business.api.domain.extend.StationDetailInfo;
import org.dsk.dragon.business.api.dto.station.StationLogicalComputeDTO;
import org.dsk.dragon.business.api.entity.BsStaActTag;
import org.dsk.dragon.business.api.entity.BsStaTags;
import org.dsk.dragon.business.api.vo.StaPageQueVO;
import org.loulan.application.dragon.common.core.config.redis.RedisKey;
import org.loulan.application.dragon.common.core.domain.extend.StationInfo;
import org.loulan.application.dragon.common.core.dto.StationCacheDTO;
import org.loulan.application.dragon.common.interfaces.service.system.DgStationClientService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
/**
* 站点信息缓存类
* @ClassName StationInfoCache
* @Author yangfeng
* @Date 2025/11/4 11:36
* @Version 1.0
*/
@Component
public class StationInfoCache {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private BsStationLngService bsStationLngService;
@Resource
private DgStationClientService stationClientService;
@Async
public void cache(){
StaPageQueVO pageQueVO = new StaPageQueVO();
pageQueVO.setPageCurrent(1);
pageQueVO.setPageSize(10000);
//缓存站点详细信息 hash
Page<StationDetailInfo> stationPageList = bsStationLngService.getStationPageList(pageQueVO);
Map<String,Object> stationMap = new HashMap<>();
for (StationDetailInfo sta : stationPageList.getRecords()) {
StationCacheDTO cacheDTO = BeanTool.copy(sta, StationCacheDTO.class);
if(ArrayTool.isNotEmpty(sta.getCoord()) && sta.getCoord().length==2){
String[] coord = sta.getCoord();
cacheDTO.setLatitude(coord[0]);
cacheDTO.setLongitude(coord[1]);
}
if(ObjectTool.isNotNull(sta.getGradeTotal()) && ObjectTool.isNotNull(sta.getGradeCount())){
BigDecimal grade = sta.getGradeTotal().divide(BigDecimal.valueOf(sta.getGradeCount()), 1, RoundingMode.HALF_UP);
cacheDTO.setGrade(grade.compareTo(new BigDecimal("3.6"))<0?new BigDecimal("3.6"):grade);
}
List<BsStaTags> staTags = sta.getStaTags();
if(CollTool.isNotEmpty(staTags)){
List<Integer> tags = staTags.stream().map(BsStaTags::getTagId).toList();
if(CollTool.isNotEmpty(tags)){
cacheDTO.setServerCodes(tags);
}
}else {
cacheDTO.setServerCodes(new ArrayList<>());
}
stationMap.put(sta.getId()+"",cacheDTO);
redisTemplate.opsForHash().putAll(RedisKey.STATION_HASH,stationMap);
}
}
}
这一段代码的核心在于最后两行代码,将数据组成需要的格式后,统一使用一个设置命令将数据设置到redis缓存中

2.执行查询
java
public CustomPage<StationDetailInfo> getStationPageListV1(StaPageQueVO vo) {
Map<Object, Object> map = redisTemplate.opsForHash().entries(RedisKey.STATION_HASH);
List<StationLogicalComputeDTO> sortResultList;
List<StationLogicalComputeDTO> resultList = map.values().stream()
.map(sta -> {
StationCacheDTO stationCacheDTO = (StationCacheDTO) sta;
StationLogicalComputeDTO stationLogicalComputeDTO = BeanTool.copy(stationCacheDTO, StationLogicalComputeDTO.class);
if (StrTool.isNotBlank(stationCacheDTO.getLongitude()) && StrTool.isNotBlank(stationCacheDTO.getLatitude())) {
Integer intDistance = DistanceUtils.getIntDistanceM(vo.getCoord()[1], vo.getCoord()[0],
stationCacheDTO.getLongitude(), stationCacheDTO.getLatitude(), 2);
stationLogicalComputeDTO.setDistance(intDistance);
} else {
stationLogicalComputeDTO.setDistance(Integer.MAX_VALUE);
}
return stationLogicalComputeDTO;
})
.collect(Collectors.toList()); // 直接收集到新的 List
//距离范围和服务标签查询
if(ObjectTool.isNotNull(vo.getDistanceQuery()) && !ObjectTool.equals(StationDistanceRangeQueryEnum.NO_LIMIT.getCode(),vo.getDistanceQuery() )){
resultList = resultList.stream().filter(r -> r.getDistance()<=vo.getDistanceQuery()*1000)
.toList();
}
if(CollTool.isNotEmpty(vo.getServersQuery())){
resultList = resultList.stream()
.filter(obj -> new HashSet<>(obj.getServerCodes()).containsAll(vo.getServersQuery()))
.toList();
}
if(ObjectTool.isNotNull(vo.getSelectTypeQuery()) && !ObjectTool.equals(StationSelectTypeEnum.ALL.getCode(), vo.getSelectTypeQuery())){
resultList = resultList.stream().filter(s -> s.getSelectType().equals(vo.getSelectTypeQuery()))
.toList();
}
//名称或地址模糊查询
if(StrTool.isNotBlank(vo.getNameOrAddressQuery())){
resultList = resultList.stream()
.filter(sta-> (sta.getName() != null && sta.getName().contains(vo.getNameOrAddressQuery())) ||
(sta.getAddress() != null && sta.getAddress().contains(vo.getNameOrAddressQuery())))
.toList();
}
Comparator<StationLogicalComputeDTO> comparator = null;
if(ObjectTool.isNotNull(vo.getSortType())){
comparator = switch (vo.getSortType()) {
case 1 -> StationSortBuilder.sortByDistance(null, false);
case 2 -> StationSortBuilder.sortByGrade(null, true);
case 3 -> StationSortBuilder.sortByPrice(null, false);
case 4 -> StationSortBuilder.sortByPrice(null, true);
default -> throw new IllegalArgumentException("非法的排序类型: " + vo.getSortType());
};
}else{
comparator = StationSortBuilder.sortByDistance(null, false);
}
sortResultList = resultList.stream().sorted(comparator).toList();
sortResultList.forEach(t->{
log.info("站点Id{} 距离{} 评分{} 合力价{}",t.getId(),t.getDistance(),t.getGrade(),t.getHlPrice());
});
CustomPage<StationLogicalComputeDTO> customPage = new CustomPage<>((int) vo.getPageCurrent(), (int) vo.getPageSize(), sortResultList);
List<StationLogicalComputeDTO> records = customPage.getRecords();
if(CollTool.isNotEmpty(records)){
List<Integer> stationIds = records.stream().map(StationLogicalComputeDTO::getId).toList();
StationPageQueryVo queryVo = new StaPageQueVO();
queryVo.setPageCurrent(vo.getPageCurrent());
queryVo.setPageSize(vo.getPageSize());
queryVo.setStationIds(stationIds);
queryVo.setCoord(new String[]{vo.getCoord()[0],vo.getCoord()[1]});
List<StationInfo> stationInfos = dgStationClientService.stationList(queryVo);
List<StationDetailInfo> stationDetailInfos = BeanTool.copy(stationInfos, StationDetailInfo.class);
this.setStationDetailInfos(stationDetailInfos);
return customPage.resetRecords(stationDetailInfos);
}
return new CustomPage<>((int) vo.getPageCurrent(), (int) vo.getPageSize(), new ArrayList<>());
}
代码核心逻辑说明
- 获取hash列表转为List
java
Map<Object, Object> map = redisTemplate.opsForHash().entries(RedisKey.STATION_HASH);
List<StationLogicalComputeDTO> sortResultList;
List<StationLogicalComputeDTO> resultList = map.values().stream()
.map(sta -> {
StationCacheDTO stationCacheDTO = (StationCacheDTO) sta;
StationLogicalComputeDTO stationLogicalComputeDTO = BeanTool.copy(stationCacheDTO, StationLogicalComputeDTO.class);
if (StrTool.isNotBlank(stationCacheDTO.getLongitude()) && StrTool.isNotBlank(stationCacheDTO.getLatitude())) {
Integer intDistance = DistanceUtils.getIntDistanceM(vo.getCoord()[1], vo.getCoord()[0],
stationCacheDTO.getLongitude(), stationCacheDTO.getLatitude(), 2);
stationLogicalComputeDTO.setDistance(intDistance);
} else {
stationLogicalComputeDTO.setDistance(Integer.MAX_VALUE);
}
return stationLogicalComputeDTO;
})
.collect(Collectors.toList()); // 直接收集到新的 List
- 条件查询
java
//距离范围和服务标签查询
if(ObjectTool.isNotNull(vo.getDistanceQuery()) && !ObjectTool.equals(StationDistanceRangeQueryEnum.NO_LIMIT.getCode(),vo.getDistanceQuery() )){
resultList = resultList.stream().filter(r -> r.getDistance()<=vo.getDistanceQuery()*1000)
.toList();
}
if(CollTool.isNotEmpty(vo.getServersQuery())){
resultList = resultList.stream()
.filter(obj -> new HashSet<>(obj.getServerCodes()).containsAll(vo.getServersQuery()))
.toList();
}
if(ObjectTool.isNotNull(vo.getSelectTypeQuery()) && !ObjectTool.equals(StationSelectTypeEnum.ALL.getCode(), vo.getSelectTypeQuery())){
resultList = resultList.stream().filter(s -> s.getSelectType().equals(vo.getSelectTypeQuery()))
.toList();
}
//名称或地址模糊查询
if(StrTool.isNotBlank(vo.getNameOrAddressQuery())){
resultList = resultList.stream()
.filter(sta-> (sta.getName() != null && sta.getName().contains(vo.getNameOrAddressQuery())) ||
(sta.getAddress() != null && sta.getAddress().contains(vo.getNameOrAddressQuery())))
.toList();
}
- 排序
java
Comparator<StationLogicalComputeDTO> comparator = null;
if(ObjectTool.isNotNull(vo.getSortType())){
comparator = switch (vo.getSortType()) {
case 1 -> StationSortBuilder.sortByDistance(null, false);
case 2 -> StationSortBuilder.sortByGrade(null, true);
case 3 -> StationSortBuilder.sortByPrice(null, false);
case 4 -> StationSortBuilder.sortByPrice(null, true);
default -> throw new IllegalArgumentException("非法的排序类型: " + vo.getSortType());
};
}else{
comparator = StationSortBuilder.sortByDistance(null, false);
}
sortResultList = resultList.stream().sorted(comparator).toList();
sortResultList.forEach(t->{
log.info("站点Id{} 距离{} 评分{} 合力价{}",t.getId(),t.getDistance(),t.getGrade(),t.getHlPrice());
});
排序的工具类
java
package org.dsk.dragon.business.config;
import org.dsk.dragon.business.api.dto.station.StationLogicalComputeDTO;
import java.util.Comparator;
/**
* 站点信息排序构建器
* @ClassName StationSortBuilder
* @Author yangfeng
* @Date 2025/11/6 14:24
* @Version 1.0
*/
public class StationSortBuilder {
public static Comparator<StationLogicalComputeDTO> sortByDistance(Comparator<StationLogicalComputeDTO> comparator, boolean isDesc){
if (comparator != null) {
if(isDesc){
comparator = comparator.thenComparing(StationLogicalComputeDTO::getDistance, Comparator.reverseOrder());
}else {
comparator = comparator.thenComparing(StationLogicalComputeDTO::getDistance);
}
} else {
if(isDesc){
comparator = Comparator.comparing(StationLogicalComputeDTO::getDistance, Comparator.reverseOrder());
}else{
comparator = Comparator.comparing(StationLogicalComputeDTO::getDistance);
}
}
return comparator;
}
public static Comparator<StationLogicalComputeDTO> sortByGrade(Comparator<StationLogicalComputeDTO> comparator, boolean isDesc){
if (comparator != null) {
if(isDesc){
comparator = comparator.thenComparing(StationLogicalComputeDTO::getGrade, Comparator.reverseOrder());
}else {
comparator = comparator.thenComparing(StationLogicalComputeDTO::getGrade);
}
} else {
if(isDesc){
comparator = Comparator.comparing(StationLogicalComputeDTO::getGrade, Comparator.reverseOrder());
}else{
comparator = Comparator.comparing(StationLogicalComputeDTO::getGrade);
}
}
return comparator;
}
public static Comparator<StationLogicalComputeDTO> sortByPrice(Comparator<StationLogicalComputeDTO> comparator, boolean isDesc){
if (comparator != null) {
if(isDesc){
comparator = comparator.thenComparing(StationLogicalComputeDTO::getHlPrice, Comparator.reverseOrder());
}else {
comparator = comparator.thenComparing(StationLogicalComputeDTO::getHlPrice);
}
} else {
if(isDesc){
comparator = Comparator.comparing(StationLogicalComputeDTO::getHlPrice, Comparator.reverseOrder());
}else{
comparator = Comparator.comparing(StationLogicalComputeDTO::getHlPrice);
}
}
return comparator;
}
}
- 分页
java
CustomPage<StationLogicalComputeDTO> customPage = new CustomPage<>((int) vo.getPageCurrent(), (int) vo.getPageSize(), sortResultList);
List<StationLogicalComputeDTO> records = customPage.getRecords();
自定义分页工具类
java
package org.dsk.dragon.business.util;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.List;
/**
* @ClassName CustomPage
* @Description TODO 自定义分页构造
* @Author @yangfeng
* @Date 2022/11/9 14:11
* @Version 1.0
*/
@Data
@NoArgsConstructor
public class CustomPage<T> implements Serializable {
private Integer current;
private Integer size;
private Integer startRow;
private Integer endRow;
private Integer pages;
private List<T> records ;
private Integer total;
/**
* @Author @yangfeng
* @Description // 分页构造器返回对象
* @Date 9:44 2022/11/7
* @param current
* @param size
* @param totalList
* @return
* @return null
**/
public CustomPage(Integer current, Integer size, List<T> totalList) {
this.current = current<=1 ? 1:current;
this.size = size<=1 ? 1:size;
this.total = totalList.size();
if(CollectionUtils.isEmpty(totalList)){
return ;
}
int totalCount = totalList.size();
if(totalCount<=size){
this.pages=1;
}else{
if(totalCount%size>0){
this.pages = totalCount/size+1;
}else{
this.pages = totalCount/size;
}
}
this.startRow = (this.current - 1) * this.size;
this.endRow = this.startRow + this.size;
if(endRow>totalCount)endRow=totalCount;
this.records = totalList.subList(this.startRow,this.endRow);
}
public <R> CustomPage<R> resetRecords(List<R> newRecords) {
CustomPage<R> newPage = new CustomPage<>();
newPage.current = this.current;
newPage.size = this.size;
newPage.total = this.total;
newPage.pages = this.pages;
newPage.startRow = this.startRow;
newPage.endRow = this.endRow;
newPage.records = newRecords;
return newPage;
}
/**
* 自定义分页方法
* @Param [page, totalList]
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page
* @Date 14:00 2023/8/11
* @Author yangfeng
**/
public static Page getCustomPage(Page<?> page, List totalList){
page.setTotal(totalList.size());
if(CollectionUtils.isEmpty(totalList)){
return page;
}
Integer totalCount = totalList.size();
if(totalCount<=page.getSize()){
page.setPages(1);
}else{
if(totalCount%page.getSize()>0){
page.setPages(totalCount/page.getSize()+1) ;
}else{
page.setPages(totalCount/page.getSize()) ;
}
}
Integer current = (int)page.getCurrent();
Integer size = (int)page.getSize();
int startRow = current>0?(current-1)*size:0;
int endRow= startRow+size*(current>0?1:0);
if(endRow>totalCount){
endRow=totalCount;
}
totalList = totalList.subList(startRow,endRow);
page.setRecords(totalList);
return page;
}
}
- 从数据库查询数据(保证根据传入的id按照顺序返回数据)
java
if(CollTool.isNotEmpty(records)){
List<Integer> stationIds = records.stream().map(StationLogicalComputeDTO::getId).toList();
StationPageQueryVo queryVo = new StaPageQueVO();
queryVo.setPageCurrent(vo.getPageCurrent());
queryVo.setPageSize(vo.getPageSize());
queryVo.setStationIds(stationIds);
queryVo.setCoord(new String[]{vo.getCoord()[0],vo.getCoord()[1]});
List<StationInfo> stationInfos = dgStationClientService.stationList(queryVo);
List<StationDetailInfo> stationDetailInfos = BeanTool.copy(stationInfos, StationDetailInfo.class);
this.setStationDetailInfos(stationDetailInfos);
return customPage.resetRecords(stationDetailInfos);
}
return new CustomPage<>((int) vo.getPageCurrent(), (int) vo.getPageSize(), new ArrayList<>());
查询数据要保证按照传入的数据顺序返回,请参考如下具体实现:
xml
<select id="getStaList" resultType="org.loulan.application.dragon.common.core.domain.extend.StationInfo">
select
<include refid="Base_Column_List"/>
<if test="vo.coord != null and vo.coord.length==2">
,earth_distance(ll_to_earth (cast(#{vo.coord[0]} as numeric),cast(#{vo.coord[1]} as numeric)),
ll_to_earth(cast((regexp_split_to_array(coord, E','))[1] as numeric),cast((regexp_split_to_array(coord,
E','))[2] as numeric))) as distance
</if>
from dg_station
where del_flag=1
<if test="vo.domainName != null and vo.domainName != ''">
<bind name="domainNameLike" value="'%'+vo.domainName+'%'"/>
AND domain_name LIKE #{domainNameLike}
</if>
<if test="vo.name != null and vo.name != ''">
<bind name="nameLike" value="'%'+vo.name+'%'"/>
AND ( name LIKE #{nameLike} OR address LIKE #{nameLike})
</if>
<if test="vo.operStatus != null">
AND oper_status = #{vo.operStatus}
</if>
<if test="vo.selectType != null">
AND select_type = #{vo.selectType}
</if>
<if test="vo.status != null">
AND status = #{vo.status}
</if>
<if test="vo.type != null">
AND type = #{vo.type}
</if>
<if test="vo.stationId != null">
AND id = #{vo.stationId}
</if>
<if test="vo.stationIds != null and vo.stationIds.size() > 0">
AND id IN
<foreach item="item" index="index" collection="vo.stationIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="vo.isScore != null">
AND is_score = #{vo.isScore}
</if>
<if test="vo.scoreCheckConf != null">
AND score_check_conf = #{vo.scoreCheckConf}
</if>
<if test="vo.stationIds != null and vo.stationIds.size() > 0">
ORDER BY
<foreach item="item" index="index" collection="vo.stationIds" open="CASE" separator=" " close="END">
WHEN id = #{item} THEN ${index + 1}
</foreach>
</if>
</select>
3.缓存更新
缓存更新使用手动设置和aop方式设置更新
手动设置是针对新增的情况,因为更新缓存是基于主键id查询数据库然后更新,新增时主键还不存在,所以需手动设计
aop方式更新是针对修改和删除操作
- 手动设置示例
java
stationService.addStationCacheUpdateStrategy(new StationCacheUpdateStrategyDTO(req.getId(),true));
具体执行的操作就是将数据设置到消息队列
java
public void addStationCacheUpdateStrategy(StationCacheUpdateStrategyDTO dto) {
try {
rabbitTemplate.convertAndSend(RabbitConstant.BUSY_EXCHANGE, RabbitConstant.STATION_CACHE_INFO_UPDATE_QUEUE, dto);
} catch (AmqpException e) {
// throw new RuntimeException(e);
log.error("站点缓存信息入队异常",e);
}
}
- aop方式设置
定义注解
java
package org.loulan.application.dragon.system.annotation;
import java.lang.annotation.*;
/**
* 站点信息缓存注解
* @ClassName StationCacheAnnotation
* @Author yangfeng
* @Date 2025/11/14 11:55
* @Version 1.0
*/
@Target(ElementType.METHOD) // 注解只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时保留
@Documented
public @interface StationCacheAnnotation {
String value() default ""; // 可以定义属性,比如操作描述
boolean isUpdated() default true;// 为true表示需要更新缓存(针对新增和更新场景)false表示删除缓存(针对删除场景)
String parameterType() default "obj";//参数类型,默认为obj,表示传入的是StationCacheDTO对象;如果是id,表示传入的是站点ID
}
将需要处理的方法加上如上注解

定义切面
java
package org.loulan.application.dragon.system.config;
import io.gitee.loulan_yxq.owner.core.bean.BeanTool;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.loulan.application.dragon.common.core.dto.StationCacheUpdateStrategyDTO;
import org.loulan.application.dragon.system.annotation.StationCacheAnnotation;
import org.loulan.application.dragon.system.service.DgStationService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
@Aspect
@Component
@Slf4j
public class StationCacheAnnotationAspect {
@Resource
private DgStationService stationService;
@Pointcut("@annotation(org.loulan.application.dragon.system.annotation.StationCacheAnnotation)")
public void methodsToProcess() {}
// 定义切点:匹配所有被@StationCacheAnnotation注解的方法
@AfterReturning(
pointcut = "methodsToProcess()", // 引用上面定义的切点
returning = "result" // 指定用于接收返回值的参数名
)
public Object afterAdvice(JoinPoint joinPoint, Object result) throws Throwable {
// 获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 获取注解
StationCacheAnnotation annotation = method.getAnnotation(StationCacheAnnotation.class);
String annotationValue = annotation.value();
boolean updated = annotation.isUpdated();
String type = annotation.parameterType();
Object[] args = joinPoint.getArgs();
// 在方法执行前可以做一些处理,比如日志记录
log.info("开始执行方法: {} ,参数: {} ,注解值: {}", method.getName(),Arrays.toString(args), annotationValue);
Integer stationId = -1;
Object obj = null;
if(type.equals("obj")){
obj = args[0];
Map<String, Object> paramMap = BeanTool.beanToMap(obj);
Object o = paramMap.get("id");
if(null==o){
o = paramMap.get("stationId");
}
if(null!=o){
stationId = (Integer) o;
}
}else {
stationId = (Integer) args[0];
}
stationService.addStationCacheUpdateStrategy(new StationCacheUpdateStrategyDTO(stationId,updated));
// 在方法执行后也可以做一些处理
return result;
}
}
- 消息消费,更新缓存
java
/**
* 更新站点缓存信息
* @param t
* @param channel
* @param deliveryTag
* @Return: void
* @author: yangfeng
* @date: 2025/11/14 17:59
**/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = RabbitConstant.STATION_CACHE_INFO_UPDATE_QUEUE, durable = "true"),
exchange = @Exchange(name = RabbitConstant.BUSY_EXCHANGE, durable = "false"),
key = {RabbitConstant.STATION_CACHE_INFO_UPDATE_QUEUE}
))
public void staCacheUpdate(StationCacheUpdateStrategyDTO t, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
log.info("需要更新的站点缓存信息为 msg = {}",t);
String lockKey = RedisKey.STATION_CACHE_UPDATE_LOCK_KEY + t.getStationId();
Boolean lock = distributedRedisLock.lock(lockKey,0,10, TimeUnit.SECONDS);
if(lock){
try {
updateStaCache(t);
channel.basicAck(deliveryTag,true);
} catch (Exception e) {
//出现异常直接丢弃消息,说明代码有问题
channel.basicNack(deliveryTag, false, false);
log.error("更新的站点缓存信息错误:{},数据:{}",e.getMessage(), t);
// throw new RuntimeException(e);
} finally {
distributedRedisLock.unlock(lockKey);
}
}else{
//requeue:true为将消息重返当前消息队列,还可以重新发送给消费者;false:将消息丢弃
channel.basicNack(deliveryTag, false, false);
}
}
执行更新方法
java
//更新单个气站缓存信息
private void updateStaCache(StationCacheUpdateStrategyDTO t) {
if(t.isUpdated()){
StationDetailInfo detailInfo = bsStationLngService.getStationInfoDetailById(t.getStationId());
if(ObjectTool.isNull(detailInfo)){
log.warn("站点id={}的站点信息不存在,无法更新缓存",t.getStationId());
return;
}
StationCacheDTO cacheDTO = BeanTool.copy(detailInfo, StationCacheDTO.class);
if(ArrayTool.isNotEmpty(detailInfo.getCoord()) && detailInfo.getCoord().length==2){
String[] coord = detailInfo.getCoord();
cacheDTO.setLatitude(coord[0]);
cacheDTO.setLongitude(coord[1]);
}
if(ObjectTool.isNotNull(detailInfo.getGradeTotal()) && ObjectTool.isNotNull(detailInfo.getGradeCount())){
BigDecimal grade = detailInfo.getGradeTotal().divide(BigDecimal.valueOf(detailInfo.getGradeCount()), 1, RoundingMode.HALF_UP);
cacheDTO.setGrade(grade.compareTo(new BigDecimal("3.6"))<0?new BigDecimal("3.6"):grade);
}
List<BsStaTags> staTags = detailInfo.getStaTags();
if(CollTool.isNotEmpty(staTags)){
List<Integer> tags = staTags.stream().map(BsStaTags::getTagId).toList();
if(CollTool.isNotEmpty(tags)){
cacheDTO.setServerCodes(tags);
}
}else {
cacheDTO.setServerCodes(new ArrayList<>());
}
StationCacheDTO redisData = (StationCacheDTO) redisTemplate.opsForHash().get(org.loulan.application.dragon.common.core.config.redis.RedisKey .STATION_HASH,detailInfo.getId()+"");
if(ObjectTool.isNotNull(redisData)){
BeanTool.copy(cacheDTO, redisData);
redisTemplate.opsForHash().put(org.loulan.application.dragon.common.core.config.redis.RedisKey .STATION_HASH,detailInfo.getId()+"",redisData);
}else{
redisTemplate.opsForHash().put(org.loulan.application.dragon.common.core.config.redis.RedisKey .STATION_HASH,detailInfo.getId()+"",cacheDTO);
}
}else {
//删除站点操作,直接伤处缓存
redisTemplate.opsForHash().delete(org.loulan.application.dragon.common.core.config.redis.RedisKey .STATION_HASH,t.getStationId()+"");
}
}