搜索凑单页大促显示延迟方案设计

本文来自网易云社区html


考拉凑单页为整单类活动凑单页面,从大促的表现来看,承载在考拉全站差很少5%左右的请求量,尤为在大促整单类活动比较多的状况,对于凑单商品的实时性就有更高的要求,要否则用户没有入口作凑单,已考拉目前的凑单页地址如https://www.kaola.com/activity/goods/1197184.html,效果以下ajax


考拉目前的搜索凑单页基于杭研的ndir去构建doc,可是考拉在大促的时候零点那一个时刻,按照3月8大促的量,存在几十万商品更新索引信息,由于全部商品的促销信息都须要更新到ndir里面,随着考拉业务的不断发展,商品的数量级仍然会不断增长,可是对于ndir来讲,更新索引是比较耗时,基于lucene全文检索实现,更新通常分为删除和插入操做doc,以前考拉的方案因为商品很少,因此在变动活动信息基于mq消息通知搜索,搜索触发更新索引操做会调用促销接口更新ndir,促销会给出当前的实时促销信息,活动结束的时候也会触发mq消息通知,这样保证活动开始和活动结束这个搜索能够即便的构建活动。
数据库

可是随着考拉商品sku数量不断扩大,ndir的更新瓶颈显得尤其明显,尤为在大促时候,瞬间有几十万商品参加活动,这样mq消息就显得特别的庞大,按照以前数据量所有更新一次索引差很少两个小时,可是大促开始那个时刻是下单量最大的,这段时间的凑单页不实时直接影响转化率和用户体验。
缓存

因此整个大促的活动总体优化方案 安全

1.搜索增长一个索引字段专门为凑单页去匹配,这个字段只给凑单页使用数据库设计

2.促销对于整单类活动的时间,促销提早返回所有未开始的整单类活动,整单类活动在发动发布的时候就刷新进缓存ide

3.促销的整单类活动的开始时间以会员时间为准,若是处于提早购阶段或者未开始的时间存在提早购增长返回提早购标示,整单类还须要把非会员开始时间,整单类结束时间落库性能

4.对于中途整单类活动已经刷进ndir,运营变动活动,修改,删除等活动都须要的实时刷新到ndir去 
优化

新增一个索引字段,主要是为了不正在进行的活动和未开始的活动的区分,在考拉的主搜那边会根据goods_tag去获取正在进行的活动,用户前台能够根据是否有促销搜索商品信息,这块信息要保证明时的一致性,不然会引发很大的客诉,https://www.kaola.com/activity/goods/1197184.html凑单页的url比较固定,这样会被用户穷举,加入用户访问了一个未开始的活动,这样也会有问题。对于这个穷举问题,考拉目前的作法是页面和数据分两个请求,页面请求为同步请求,同步请求的时候会根据活动方案号去促销系统查询改方案是否有效,若是为非法的方案号,直接渲染404错误页面,不然跳转正常的凑单页,而后再根据ajax请求搜索数据
url

 整个基于mq消息通知去更新索引信息,因为活动的数据时间常常变动,所以须要在活动发布,活动开始,价格审核经过,活动暂停,活动恢复等活动变动的流程中去控制ndir里面的索引数据,目前这块业务整合在促销的消息通知里面,为了不一次消息量过大,促销发送消息时候作了一次分批处理

@Override
public void sendActivityNotifyMessage(List<Long> goodsIdList) {
      if (CollectionUtils.isEmpty(goodsIdList)) {
         return;
       }
     List<Long> notifyGoodsIdList = new ArrayList<>(new HashSet<>(goodsIdList));
     int batchSize = promotionConfig.getInteger(sendActivityNotifyBatchSize, 500);
     ListUtils.split(notifyGoodsIdList, batchSize, new PageProcess<Long>() {
     @Override
     public void process(List<Long> pageIdList) {
        logger.info("send activity notify Message to rabbitmq goodsId:{}",pageIdList);
        Map<String,List<Long>> param = Maps.newHashMap();
        param.put("goodsIdList", pageIdList);
        rabbitTemplate.convertAndSend(param); 
      } 
    });
 }

活动变动时候为了减小发送量,只会把变动商品发送给ndir那边,变动数据主要为新增,修改和删除的商品id,促销这边基于定时任务发送变动信息,定时任务每一分钟发送一次,数据表一个商品在同一个时间点存在多个活动,这时候变动记录只会有一条,因此数据库设计以商品id和时间维度,具体表设计以下

CREATE TABLE TB_ACTIVITY_NOTIFY
    (
        ID VARCHAR2(32) NOT NULL,
        GOODS_ID NUMBER(10) NOT NULL,
        UPDATE_TIME TIMESTAMP(6) DEFAULT SYSDATE NOT NULL,
        SEND_FLAG NUMBER(1) DEFAULT 0 NOT NULL,
        CONSTRAINT PK_TB_ACTIVITY_NOTIFY PRIMARY KEY (ID)
    );

该表为了保证通知性能,须要定时清除,由于大促的商品数据量很大,若是不作定时清理或者分区,会致使通知表的性能降低,因此增长一个send_flag表示通知标示,若是已经发送的成功的话,则修改成Y,这样定时清除就能够经过标示清除已发送数据


https://www.163yun.com/gift

本文来自网易云社区,经做者李世堤受权发布。


相关文章:
【推荐】 聊聊空状态设计
【推荐】 如何作好iOS应用安全?这有一把行之有效的“三板斧”

相关文章
相关标签/搜索