第二十一章 短链服务冗余双写-链路测试和异常消息处理实战
第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版本递增,重新生成短链码
 - 保存数据库
 
 - 解分布式锁
 
 - 加锁key=code 
    
 -  
B端生成,
- 加锁key=code 
    
- 查询数据库,如果存在,则ver版本递增,重新生成短链码
 - 保存数据库
 
 - 解分布式锁
 
 - 加锁key=code 
    
 
第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实现分布式锁的坑你是否踩过
-  
存在什么问题?
- 多个命令之间不是原子性操作,如
setnx和expire之间,如果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; 
 - 域名id
 
}
 
- 消息类型
```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控制台查看
 


















