背景
我们做的是移动端的APP, 包含安卓跟IOS;在我们的APP中一个模块是广告,广告的内容包括了开屏页、首页、轮播图,正常的情况是我们后台管理系统设置好广告信息列表后,提供HTTP接口给APP调用,完成广告信息的加载并显示。
问题
我们的广告业务场景类似电商系统,只有在大促销比如618、双11才会进行广告内容改动,平常都不会有太大的改动,广告的内容信息有大概3KB,这样在高并发的情况下,每次请求数据库/缓存会都服务器资源造成过大的资源消耗。
解决方案
使用阿里云CDN,具体的流程图如下:
在APP加载流程中,我们使用了HTTP head请求先判断ETag是否一致(ETag类似于是文件的MD5值),head是不返回请求内容的,http的head请求校验会加快,这样的话使我们的APP整个判断会加快。
后端代码示例
@Slf4j
@Order(1001)
@Aspect
@Component
//定义广告切面类
public class AdvertiseRefreshAspect {
//广告位服务
@Autowired
private IAdvertisePositionService iAdvertisePositionService;
//广告内容服务
@Autowired
private IAdvertiseContentService iAdvertiseContentService;
//阿里云OSS对象操作服务
@Autowired
private OssServer ossServer;
//AOP切入点定义
@Pointcut("execution(* com.xxx.controller.*.*.*( ..))")
public void pointcut() { }
//AOP切入点定义
@Pointcut("execution(* com.xxx.controller.*.*( ..))")
public void pointcut2() { }
//AOP切入注解定义
@Pointcut("@annotation( com.sixtec.cloud.admin.annotation.AdvertiseRefresh )")
public void authAnnotationsPointcut() { }
/**
* 延迟多长时间启用 , 单位秒
*/
protected int initialDelay = 5 ;
/**
* 间隔多长进行任务重新执行
*/
protected int period = 5;
/**
* 阻塞队列,用户多次操作,在间隔时间内,我们只做一次刷新即可
*/
private LinkedBlockingQueue< Integer > blockingQueue = new LinkedBlockingQueue( 1 );
/**
* 初始化任务调度器, 定义模板由子类实现具体的批处理任务
*/
@PostConstruct
public void startTask(){
log.info( "异步刷新广告通知任务启动==》" );
Executors.newScheduledThreadPool(1)
.scheduleAtFixedRate(()->{
try {
if( blockingQueue.poll() != null ){
//需要进行数据的刷新
refreshProcess();
log.info( "刷新广告内容CDN缓存成功====》》》" );
}
}catch (Exception e){
e.printStackTrace();
}
} , initialDelay , period , TimeUnit.SECONDS );
}
/**
* 刷新切面实现
* @param joinPoint
* @return
* @throws Throwable
*/
@Around(" (pointcut() || pointcut2()) && authAnnotationsPointcut() ")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//将刷新指令放入消息队列
blockingQueue.offer(1);
return joinPoint.proceed();
}
//刷新具体业务
private void refreshProcess(){
//查询广告位
List<AdvertisePosition> positionList = iAdvertisePositionService.list(
new QueryWrapper<AdvertisePosition>()
.select("id , position,position_code,frequency,click_cancel,carousel_period")
.eq("d_flag" , DataLogicEnum.NORMAL.getCode())
);
List<AdvertisePositionPo> advertisePositionPoList = new ArrayList<>(positionList.size());
for ( AdvertisePosition position : positionList){
//查询广告位对应的信息
List<AdvertiseContent> advertiseContents = iAdvertiseContentService.list(
new QueryWrapper<AdvertiseContent>()
.select("id , adv_name,start_time,end_time,data_url,jump_url,order_no")
.eq("d_flag" , DataLogicEnum.NORMAL.getCode())
.eq("position_id" , position.getId() )
.orderByAsc( "order_no" )
);
AdvertisePositionPo advertisePositionPo = new AdvertisePositionPo();
BeanUtils.copyProperties( position , advertisePositionPo );
advertisePositionPoList.add( advertisePositionPo );
List<AdvertiseContentPo> advertiseContentPos = new ArrayList<>(advertiseContents.size());
for (AdvertiseContent advertiseContent : advertiseContents){
AdvertiseContentPo advertiseContentPo = new AdvertiseContentPo();
advertiseContentPo.setId( advertiseContent.getId() );
advertiseContentPo.setAdvName( advertiseContent.getAdvName() );
advertiseContentPo.setStartTime( advertiseContent.getStartTime() );
advertiseContentPo.setEndTime( advertiseContent.getEndTime() );
advertiseContentPo.setDataUrl( advertiseContent.getDataUrl() );
advertiseContentPo.setJumpUrl( advertiseContent.getJumpUrl() );
advertiseContentPo.setOrderNo( advertiseContent.getOrderNo() );
advertiseContentPos.add( advertiseContentPo );
}
advertisePositionPo.setContentPos( advertiseContentPos );
}
//上传到OSSCDN中
ossServer.putFile(AdvertiseConstants.CDN_ADVERTISE_URL , JSON.toJSONString( advertisePositionPoList , true ));
}
}
结束
记录下一个后台管理广告信息,使用阿里云OSS CDN缓存广告信息给APP加载,从而减少了服务端请求,提高了APP加载速度,你们的广告信息怎么优化的呢?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至22018681@qq.com 举报,一经查实,本站将立刻删除。