海量数据处理商用短链接生成器平台 - 10

第二十一章 短链服务冗余双写-链路测试和异常消息处理实战

第1集 冗余双写MQ架构-消费者配置自动创建队列和集群测试

简介: 冗余双写MQ架构-MQ消费者配置自动创建队列

  • controller-service层开发
  • 配置文件配置MQ
##----------rabbit配置--------------
spring.rabbitmq.host=120.79.150.146
spring.rabbitmq.port=5672
#需要手工创建虚拟主机
spring.rabbitmq.virtual-host=dev
spring.rabbitmq.username=admin
spring.rabbitmq.password=password
#消息确认方式,manual(手动ack) 和auto(自动ack)
spring.rabbitmq.listener.simple.acknowledge-mode=auto
  • 大家遇到的问题 (不会自动创建队列)

    • 加了@bean配置交换机和queue,启动项目却没自动化创建队列
    • RabbitMQ懒加载模式, 需要配置消费者监听才会创建,
    @RabbitListener(queues = "short_link.add.link.queue")
    
  • 另外种方式(若Mq中无相应名称的队列,会自动创建Queue)

    @RabbitListener(queuesToDeclare = { @Queue("short_link.add.link.queue") })
    
  • 链路测试-多节点启动

第2集 冗余双写架构-MQ消费者异常重试处理方案链路

简介: 冗余双写架构-MQ消费者异常处理方案讲解

  • 消费者异常情况处理
    • 业务代码自己重试
    • 组件重试
  • RabbitMQ配置重试
#开启重试,消费者代码不能添加try catch捕获不往外抛异常
spring.rabbitmq.listener.simple.retry.enabled=true
#最大重试次数
spring.rabbitmq.listener.simple.retry.max-attempts=4
# 重试消息的时间间隔,5秒
spring.rabbitmq.listener.simple.retry.initial-interval=5000
  • 问题:多次重试失败怎么处理?

在这里插入图片描述

  • 解决方式:RepublishMessageRecoverer
    • 消息重试一定次数后,用特定的routingKey转发到指定的交换机中,方便后续排查和告警
第3集 冗余双写架构-MQ消费者异常重试处理方案编码实战

简介: 冗余双写架构-MQ消费者异常重试处理方案编码实战

  • 解决方式:RepublishMessageRecoverer
    • 消费消息重试一定次数后,用特定的routingKey转发到指定的交换机中,方便后续排查和告警
    • 注意
      • 消息消费确认使用自动确认方式
@Configuration
@Data
public class RabbitMQErrorConfig {


    private String shortLinkErrorExchange = "short_link.error.exchange";

    private String shortLinkErrorQueue = "short_link.error.queue";

    private String shortLinkErrorRoutingKey = "short_link.error.routing.key";

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 异常交换机
     * @return
     */
    @Bean
    public TopicExchange errorTopicExchange(){
        return new TopicExchange(shortLinkErrorExchange,true,false);
    }

    /**
     * 异常队列
     * @return
     */
    @Bean
    public Queue errorQueue(){
        return new Queue(shortLinkErrorQueue,true);
    }

    /**
     * 队列与交换机进行绑定
     * @return
     */
    @Bean
    public Binding BindingErrorQueueAndExchange(Queue errorQueue,TopicExchange errorTopicExchange){
        return BindingBuilder.bind(errorQueue).to(errorTopicExchange).with(shortLinkErrorRoutingKey);
    }


    /**
     * 配置 RepublishMessageRecoverer
     * 用途:消息重试一定次数后,用特定的routingKey转发到指定的交换机中,方便后续排查和告警
     *
     * 顶层是 MessageRecoverer接口,多个实现类
     *
     * @return
     */
    @Bean
    public MessageRecoverer messageRecoverer(){
        return new RepublishMessageRecoverer(rabbitTemplate,shortLinkErrorExchange,shortLinkErrorRoutingKey);
    }


}

第二十二章 短链服务冗余双写问题抛出-MQ消费者链路开发

第1集 冗余双写架构-高并发下短链码生成端问题抛出

简介: 冗余双写架构-短链码生成端问题抛出

  • 短链码是哪里生成?生产者端 还是消费者端
    • 生产者生成短链码,下面的情况
      • 用户A生成短链码AABBCC,查询数据库不存在,发送MQ,插入数据库成功
      • 用户B生成短链码AABBCC,查询数据库不存在,发送MQ,插入数据库失败
    • 消费者生成短链码,下面的情况
      • 用户A生成短链码AABBCC ,C端先插入,B端还没插入
      • 用户B也生成短链码AABBCC ,B端先插入,C端还没插入
      • 用户A生成短链码AABBCC ,B端插入
      • 用户B生成短链码AABBCC ,C端插入

在这里插入图片描述

第2集 冗余双写架构-商家创建短链-C端消费者开发实战

简介: 冗余双写架构-商家创建短链-C端消费者开发实战

  • C端消费者开发实战
//判断短链域名是否合法
//判断组名是否合法
//生成长链摘要
//生成短链码
//加锁
//查询短链码是否存在
//构建短链对象
//保存数据库
第3集 冗余双写架构-商家创建短链-B端消费者开发实战

简介: 冗余双写架构-商家创建短链-B端消费者开发实战

  • B端消费者开发实战
//生成长链摘要
//判断短链域名是否合法
//判断组名是否合法
//生成短链码
//加锁(加锁再查,不然查询后,加锁前有线程刚好新增)
//查询短链码是否存在
//构建短链mapping对象
//保存数据库
 public boolean handlerAddShortLink(EventMessage eventMessage) {


        Long accountNo = eventMessage.getAccountNo();
        String messageType = eventMessage.getEventMessageType();


        ShortLinkAddRequest addRequest = JsonUtil.json2Obj(eventMessage.getContent(), ShortLinkAddRequest.class);
        //短链域名校验
        DomainDO domainDO = checkDomain(addRequest.getDomainType(), addRequest.getDomainId(), accountNo);
        //校验组是否合法
        LinkGroupDO linkGroupDO = checkLinkGroup(addRequest.getGroupId(), accountNo);
        //长链摘要
        String originalUrlDigest = CommonUtil.MD5(addRequest.getOriginalUrl());


        //生成短链码
        String shortLinkCode = shortLinkComponent.createShortLinkCode(addRequest.getOriginalUrl());


        //TODO 加锁




        //先判断是否短链码被占用
        ShortLinkDO ShortLinCodeDOInDB = shortLinkManager.findByShortLinCode(shortLinkCode);




        if(ShortLinCodeDOInDB == null){


            //C端处理
            if (EventMessageType.SHORT_LINK_ADD_LINK.name().equalsIgnoreCase(messageType)) {
                ShortLinkDO shortLinkDO = ShortLinkDO.builder()
                        .accountNo(accountNo)
                        .code(shortLinkCode)
                        .title(addRequest.getTitle())
                        .originalUrl(addRequest.getOriginalUrl())
                        .domain(domainDO.getValue())
                        .groupId(linkGroupDO.getId())
                        .expired(addRequest.getExpired())
                        .sign(originalUrlDigest)
                        .state(ShortLinkStateEnum.ACTIVE.name())
                        .del(0)
                        .build();
                shortLinkManager.addShortLink(shortLinkDO);
                return true;


            } else if (EventMessageType.SHORT_LINK_ADD_MAPPING.name().equalsIgnoreCase(messageType)) {


                //B端处理
                GroupCodeMappingDO groupCodeMappingDO = GroupCodeMappingDO.builder()
                        .accountNo(accountNo)
                        .code(shortLinkCode)
                        .title(addRequest.getTitle())
                        .originalUrl(addRequest.getOriginalUrl())
                        .domain(domainDO.getValue())
                        .groupId(linkGroupDO.getId())
                        .expired(addRequest.getExpired())
                        .sign(originalUrlDigest)
                        .state(ShortLinkStateEnum.ACTIVE.name())
                        .del(0)
                        .build();


                groupCodeMappingManager.add(groupCodeMappingDO);
                return true;


            }
        }




        return false;


    }
第4集 同个URL生成短链码随机库表位问题和解决方案讲解

简介: 同个URL生成短链码随机库表位问题和解决方案讲解

  • 需求

    • App的下载链接,需要进行投放广告,并验证不同渠道的效果质量
    • 渠道:抖音、百度、新浪微博、知乎、B站、头条等
    • 最终下载地址一样,但是需要区分不通渠道效果质量
  • 问题抛出

    • MurmurHash对同个url产生后的值是一样的,但是随机拼接了库表位,最终生成的短链码就导致可能不一致的情况,怎么解决?

    • 问题重现

    • 答案

      • MurmurHash后的短链码,拼接随机库表位需要固定
      • 采用hashCode取模生成对应的库表位
第5集 MurmurHash短链码改进之生成固定库表位编码实战

简介: MurmurHash短链码改进之生成固定库表位编码实战

  • 编码实战
    /**
     * 获取随机的后缀
     * @return
     */
    public static String getRandomTableSuffix(String code){
        int hashCode = code.hashCode();
        int num = Math.abs(hashCode) % tableSuffixList.size();
        return tableSuffixList.get(num);
    }




   /**
     * 获取随机的前缀
     * @return
     */
    public static String getRandomDBPrefix(String code){


        int hashCode = code.hashCode();
        int num = Math.abs(hashCode) % dbPrefixList.size();
        return dbPrefixList.get(num);
    }
第6集 同个URL生成不唯一短链码问题和解决方案讲解

简介: 同个URL生产唯一短链码问题和解决方案讲解

  • 需求

    • App的下载链接,需要进行投放广告,并验证不同渠道的效果质量
    • 渠道:抖音、百度、新浪微博、知乎、B站、头条等
    • 最终下载地址一样,但是需要区分不通渠道效果质量
  • 问题抛出:

    • 解决了随机库表问题后,一个URL怎么生成多个不一样的短链码

    • URL重复生成短链问题

      • 如果原始URL不做处理,则重复概率很高
      • 方案:原始url 拼接随机串,访问前去除
    • 问题重现

    • 答案

      • 生产者发送消息携带一个时间戳 或 随机id
      • 原始URL开头拼接特殊字段
        • 原生 https://baidu.com
        • 拼接后 1469558440337604610||https://baidu.com
        • 如果冲突,则编号递增1
      • 访问前截取去除
第7集 同个URL生成不唯一短链码问题和解决方案编码实战

简介: 同个URL生成不唯一短链码问题和解决方案编码实战

  • 工具类编写
    /**
     * URL增加前缀
     * @param url
     * @return
     */
    public static String addUrlPrefix(String url){
        return IDUtil.geneSnowFlakeID()+"&"+url;
    }


    /**
     * URL移除前缀
     * @param url
     * @return
     */
    public static String removeUrlPrefix(String url){
        String originalUrl = url.substring(url.indexOf("&")+1);
        return originalUrl;
    }


    /**
     * 如果短链码重复,则调用这个方法
     * url前缀编号递增1,如果还是用雪花算法,则容易C和B端不一致,所以采用原先的id递增1
     * @param url
     * @return
     */
    public static String addUrlPrefixVersion(String url){
        String result = url.substring(0,url.indexOf("&"));
        //原始地址
        String originalUrl = url.substring(url.indexOf("&")+1);
        //新id编号
        Long newIdValue = Long.parseLong(result)+1;
        return newIdValue+"&"+originalUrl;
    }


  • 编码实战
//发送MQ消息
 @Override
    public JsonData createShortLink(ShortLinkAddRequest request) {


        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();


        String originalUrl = CommonUtil.addUrlPrefix(request.getOriginalUrl());
        request.setOriginalUrl(originalUrl);


        EventMessage eventMessage = EventMessage.builder().accountNo(accountNo)
                .content(JsonUtil.obj2Json(request))
                .messageId(IDUtil.geneSnowFlakeID().toString())
                .eventMessageType(EventMessageType.SHORT_LINK_ADD.name())
                .build();


        rabbitTemplate.convertAndSend(rabbitMQConfig.getShortLinkEventExchange(), rabbitMQConfig.getShortLinkAddRoutingKey(),eventMessage);


        return JsonData.buildSuccess();
    }
//短链解析,客户端请求
@GetMapping(path = "/{shortLinkCode}")
    public void dispatch(@PathVariable(name = "shortLinkCode") String shortLinkCode,
                         HttpServletRequest request, HttpServletResponse response) {


        try {
            log.info("短链码:{}", shortLinkCode);
            //判断短链码是否合规
            if (isLetterDigit(shortLinkCode)) {
                //查找短链
                ShortLinkVO shortLinkVO = shortLinkService.parseShortLinkCode(shortLinkCode);
                //判断是否过期和可用
                if (isVisitable(shortLinkVO)) {
                    String originalUrl = CommonUtil.removeUrlPrefix(shortLinkVO.getOriginalUrl());
                    response.setHeader("Location", originalUrl);


                    //302跳转
                    response.setStatus(HttpStatus.FOUND.value());




                } else {


                    response.setStatus(HttpStatus.NOT_FOUND.value());
                    return;
                }
            }
        } catch (Exception e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }


    }

第二十三章 短链码生成端选择和Lua分布式锁实战

第1集 短链码是生成端选择-生产者端-消费者端方案对比

简介: 短链码是生成端选择-生产者端-消费者端方案对比

  • 短链码是哪里生成?生产者端 还是消费者端

  • 方案一:生产者端生成短链码code

    • 加分布式锁 key=code,配置过期时间(加锁失败则重新生成)
    • 需要查询一次数据库或其他存储源,判断是否存在
    • 发送MQ
      • C端插入
      • B端插入
    • 解分布式锁(锁过期自动解锁)

在这里插入图片描述

方案二:消费者端生成短链码code

  • 生产者发送消息

  • C端生成

    • 加锁key=code
      • 查询数据库,如果存在,则ver版本递增,重新生成短链码
      • 保存数据库
    • 解分布式锁
  • B端生成,

    • 加锁key=code
      • 查询数据库,如果存在,则ver版本递增,重新生成短链码
      • 保存数据库
    • 解分布式锁
第2集 分布式锁知识基础+进阶-可重入锁在分布式下的应用

简介:分布式锁知识基础+进阶-可重入锁在分布式下的应用

  • 不知大家是否还记得,消费者生成短链码,高并发的情况

    • 1)用户A生成短链码AABBCC ,C端先插入,B端还没插入
    • 2)用户B也生成短链码AABBCC ,B端先插入,C端还没插入
    • 3)用户A生成短链码AABBCC ,B端插入
    • 4)用户B生成短链码AABBCC ,C端插入
  • 需要的结果是

    • 1、3可以成功, 2、4可以成功
  • 避免短链码高并发下重复

    • 加锁
      • 本地锁:synchronize、lock等,锁在当前进程内,集群部署下依旧存在问题
      • 分布式锁:redis、zookeeper等实现,虽然还是锁,但是多个进程共用的锁标记,可以用Redis、Zookeeper、Mysql等都可以
        在这里插入图片描述
  • 设计分布式锁应该考虑的东西

    • 排他性
      • 在分布式应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行
    • 容错性
      • 分布式锁一定能得到释放,比如客户端奔溃或者网络中断
    • 满足可重入、高性能、高可用
    • 注意分布式锁的开销、锁粒度
  • 方案就是加锁

    • 单节点可重入锁

      • 可重入锁: JDK指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的,synchronized 和 ReentrantLock 都是可重入锁
    • 分布式下的可重入锁

      • 进程单位,当一个线程获取对象锁之后,其他节点的同个业务线程可以再次获取本对象上的锁
第3集 短链码基于Redis实现分布式锁的坑你是否踩过《上》

简介:基于Redis实现分布式锁的几种坑

  • 实现分布式锁 可以用 Redis、Zookeeper、Mysql数据库这几种 , 性能最好的是Redis且是最容易理解

    • 分布式锁离不开 key - value 设置
    key 是锁的唯一标识,一般按业务来决定命名,比如想要给一种商品的秒杀活动加锁,key 命名为 “seckill_商品ID” 。value就可以使用固定值,比如设置成1。
    短链码可以:short_link:code:xxxx
    
  • 基于redis实现分布式锁,文档:http://www.redis.cn/commands.html#string

    • 加锁 SETNX key value
    setnx 的含义就是 SET if Not Exists,有两个参数 setnx(key, value),该方法是原子性操作
    
    
    如果 key 不存在,则设置当前 key 成功,返回 1;
    
    
    如果当前 key 已经存在,则设置当前 key 失败,返回 0
    
    • 解锁 del (key)
    得到锁的线程执行完任务,需要释放锁,以便其他线程可以进入,调用 del(key)
    
    • 配置锁超时 expire (key,30s)
    客户端奔溃或者网络中断,资源将会永远被锁住,即死锁,因此需要给key配置过期时间,以保证即使没有被显式释放,这把锁也要在一定时间后自动释放
    
    • 综合伪代码
    methodA(){
      String key = "short_link:code:abcdef"
      
      if(setnx(key,1== 1{
          expire(key,30,TimeUnit.MILLISECONDS)
          try {
              //做对应的业务逻辑
          } finally {
              del(key)
          }
      }else{
        //睡眠100毫秒,然后自旋调用本方法
        methodA()
      }
    }
    
    • 存在哪些问题,大家自行思考下
第4集 短链码基于Redis实现分布式锁的坑你是否踩过《下》

简介:短链码基于Redis实现分布式锁的坑你是否踩过

  • 存在什么问题?

    • 多个命令之间不是原子性操作,如setnxexpire之间,如果setnx成功,但是expire失败,且宕机了,则这个资源就是死锁
    使用原子命令:设置和配置过期时间  setnx / setex
    如: set key 1 ex 30 nx
    java代码里面 
    
    
    String key = "short_link:code:abcdef"
    redisTemplate.opsForValue().setIfAbsent(key,1,30,TimeUnit.MILLISECONDS)
    
    • 看业务应用情况还有更多问题,可以看Redis6课程 或者 第一个高并发大课
      • 业务超时,如何避免其他线程勿删
      • 业务执行时间过长,如何实现锁的自

之前说的方案二,消费者端生成短链码code

  • 那C端或者B端其中一个加锁成功后,另外一个怎么加锁?

  • 答案:通过value判断是否是同个账号,如果是则认为是加锁成功

  • 即下面步骤

    • C端生成

    • 加锁key=code,value=account

      • 查询数据库,如果存在,则ver版本递增,重新生成短链码
      • 保存数据库
    • 解分布式锁(锁过期自动解锁)

    • B端生成

      • 加锁key=code,value=account
      • 查询数据库,如果存在,则ver版本递增,重新生成短链码
      • 保存数据库
      • 解分布式锁(锁过期自动解锁)

在这里插入图片描述

  • 流程:加锁的方式需要保证原子性
    • 先判断是否有,如没这个key,则设置key-value,配置过期时间,加锁成功
    • 如果有这个key,判断value是否是同个账号,是同个账号则返回加锁成功
    • 如果不是同个账号则加锁失败
      • 解决方式,配置key过期时间久,比如2~5天
第5集 Lua脚本分布式重入锁+redis原生代码编写

简介:Lua脚本分布式重入锁+redis原生代码编写

  • 前面说了redis做分布式锁存在的问题

    • 核心是保证多个指令原子性,加锁使用setnx setex 可以保证原子性,那解锁使用判断和设置等怎么保证原子性
    • 文档:http://www.redis.cn/commands/set.html
    • 多个命令的原子性:采用 lua脚本+redis, 由于【判断和删除】是lua脚本执行,所以要么全成功,要么全失败
  • 流程

* 先判断是否有,如没这个key,则设置key-value,配置过期时间,加锁成功
* 如果有这个key,判断value是否是同个账号,是同个账号则返回加锁成功
* 如果不是同个账号则加锁失败
  • 代码
//key1是短链码,ARGV[1]是accountNo,ARGV[2]是过期时间
String script = "if redis.call('EXISTS',KEYS[1])==0 then redis.call('set',KEYS[1],ARGV[1]); redis.call('expire',KEYS[1],ARGV[2]); return 1;" +
                " elseif redis.call('get',KEYS[1]) == ARGV[1] then return 2;" +
                " else return 0; end;";


Long result = redisTemplate.execute(new
                DefaultRedisScript<>(script, Long.class), Arrays.asList(code), value,100);
  • 加入redis配置
#-------redis连接配置-------
spring.redis.client-type=jedis
spring.redis.host=120.79.150.146
spring.redis.password=xdclass.net
spring.redis.port=6379
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=100
spring.redis.jedis.pool.min-idle=100
spring.redis.jedis.pool.max-wait=60000
第6集 短码服务冗余双写-B端+C端分布式锁代码整合

简介:短码服务冗余双写-B端+C端分布式锁代码整合

  • 整合编码实战

第二十四章 短链服务-冗余双写B端分库分表和链路测试

第1集 GroupCodeMapping表分库分表配置实战

简介: GroupCodeMapping表分库分表配置实战

  • 数据量预估
    • 首年日活用户: 10万
    • 首年日新增短链数据:10万*50 = 500万
    • 年新增短链数:500万 * 365天 = 18.2亿
    • 往高的算就是100亿,支撑3年
  • 分库分表策略
    • 分库分表
      • 8个库, 每个库128个表,总量就是 1024个表
      • 本地开发 2库,每个库2个表
    • 分片键:
      • 分库PartitionKey:account_no
      • 分表PartitionKey:group_id
  • 接口访问量
    • C端解析,访问量大
    • B端查询,访问量少,单个表的存储数据可以多点
  • 配置


##---------- 组+短链码mapping表,策略:分库+分表--------------
# 先进行水平分库,然后再水平分表, 水平分库策略,行表达式分片
spring.shardingsphere.sharding.tables.group_code_mapping.database-strategy.inline.sharding-column=account_no
spring.shardingsphere.sharding.tables.group_code_mapping.database-strategy.inline.algorithm-expression=ds$->{account_no % 2}


# 分表策略+行表达式分片
spring.shardingsphere.sharding.tables.group_code_mapping.actual-data-nodes=ds$->{0..1}.group_code_mapping_$->{0..1}
spring.shardingsphere.sharding.tables.group_code_mapping.table-strategy.inline.sharding-column=group_id
spring.shardingsphere.sharding.tables.group_code_mapping.table-strategy.inline.algorithm-expression=group_code_mapping_$->{group_id % 2}


第2集 短链服务-冗余双写架构全链路测试实战

简介: 短链服务-冗余双写架构全链路测试实战

  • 全链路测试
    • 数据库检查
  • 创建短链
{
  "groupId":1468878230818746370,
  "title":"全链路测试测试标题",
  "originalUrl":"https://baidu.com",
  "domainId":1,
  "domainType":"OFFICIAL",
  "expired":-1
}
第3集 短链服务-B端接口-分页查找短链开发实战

简介: 短链服务-B端接口-分页查找短链开发实战

  • 分页查找某个分组下的短链数据
@Data
public class ShortLinkPageRequest {


    private int page;


    private int size;


    private long groupId;
}


    /**
     * 分页查找短链
     *
     * @return
     */
    @RequestMapping("page")
    public JsonData pageShortLinkByGroupId(@RequestBody ShortLinkPageRequest request) {


        Map<String, Object> pageResult = shortLinkService.pageShortLinkByGroupId(request);


        return JsonData.buildSuccess(pageResult);
    }
  • 注意点

    • IDEA可能有缓存,导致分库分表不生效,mvn clean清理下
  • 删除标记位增加

    • 解析
    • 查找

第二十五章 短链服务-冗余双写架构删除和更新开发实战

第1集 短链服务-冗余双写架构举一反三的能力应用

简介: 冗余双写架构举一反三的能力应用

  • 完成了短链接口的新增,采用了冗余双写的方式
  • 那其他接口呢
    • 删除
    • 更新

在这里插入图片描述

第2集 短链服务-删除和更新Controller层开发实战

简介: 短链服务-删除和更新Controller层开发实战

  • 删除接口
    • controller
    • service
      • 构建消息
@Data
public class ShortLinkDelRequest {


    /**
     * 组
     */
    private Long groupId;


    /**
     * groupCodeMapping映射id
     */
    private Long mappingId;


    /**
     * 短链码
     */
    private String code;
}
  • 更新接口
    • controller
    • service
      • 构建消息
public class ShortLinkUpdateRequest {


    /**
     * 组
     */
    private Long groupId;


    /**
     * groupCodeMapping映射id
     */
    private Long mappingId;


    /**
     * 短链码
     */
    private String code;


    /**
     * 短链标题
     */
    private String title;


    /**
     * 域名id
     */
    private Long domainId;


    /**
     * 域名类型
     */
    private String domainType;


}
  • 消息类型
public enum  EventMessageType {
    /**
     * 短链创建
     */
    SHORT_LINK_ADD,
    /**
     * 短链创建 C端
     */
    SHORT_LINK_ADD_LINK,
    /**
     * 短链创建 B端
     */
    SHORT_LINK_ADD_MAPPING,
    /**
     * 更新创建
     */
    SHORT_LINK_UPDATE,
    /**
     * 更新 C端
     */
    SHORT_LINK_UPDATE_API,
    /**
     * 更新 B端
     */
    SHORT_LINK_UPDATE_MAPPING,
    /**
     * 删除
     */
    SHORT_LINK_DEL,
    /**
     * 删除 C端
     */
    SHORT_LINK_DEL_API,
    /**
     * 删除 B端
     */
    SHORT_LINK_DEL_MAPPING,


}
第3集 冗余双写MQ实现-删除短链-交换机和队列绑定配置实战

简介: 冗余双写MQ架构实现-删除短链-交换机和队列绑定配置讲解

  • 删除短链MQ架构图
  • 更新短链MQ架构图
    在这里插入图片描述
第5集 短链服务-删除和更新模块发送MQ消息验证

简介: 短链服务-删除和更新模块发送MQ消息验证

  • 删除 发送消息

  • 更新 发送消息

  • RabbitMQ控制台查看
    private String title;

    /**

    • 域名id
      */
      private Long domainId;

    /**

    • 域名类型
      */
      private String domainType;

}


 

- 消息类型

```java
public enum  EventMessageType {
    /**
     * 短链创建
     */
    SHORT_LINK_ADD,
    /**
     * 短链创建 C端
     */
    SHORT_LINK_ADD_LINK,
    /**
     * 短链创建 B端
     */
    SHORT_LINK_ADD_MAPPING,
    /**
     * 更新创建
     */
    SHORT_LINK_UPDATE,
    /**
     * 更新 C端
     */
    SHORT_LINK_UPDATE_API,
    /**
     * 更新 B端
     */
    SHORT_LINK_UPDATE_MAPPING,
    /**
     * 删除
     */
    SHORT_LINK_DEL,
    /**
     * 删除 C端
     */
    SHORT_LINK_DEL_API,
    /**
     * 删除 B端
     */
    SHORT_LINK_DEL_MAPPING,


}
第3集 冗余双写MQ实现-删除短链-交换机和队列绑定配置实战

简介: 冗余双写MQ架构实现-删除短链-交换机和队列绑定配置讲解

  • 删除短链MQ架构图
  • 更新短链MQ架构图

[外链图片转存中…(img-1sasDsYr-1723078707796)]

第5集 短链服务-删除和更新模块发送MQ消息验证

简介: 短链服务-删除和更新模块发送MQ消息验证

  • 删除 发送消息
  • 更新 发送消息
  • RabbitMQ控制台查看
  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从零开始学习人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值