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

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

第1集 冗余双写架构-更新短链消费者开发实战

简介: 短链服务-更新短链-消费者开发实战

具体步骤见代码

第2集 冗余双写架构-更新短链消费者链路测试

简介: 冗余双写架构-更新短链消费者链路测试

具体步骤见代码

第3集 冗余双写架构-删除短链消费者开发实战

简介: 短链服务-删除短链-消费者开发实战

具体步骤见代码

第4集 冗余双写架构-删除短链消费者链路测试和越权修复

简介: 冗余双写架构-删除短链消费者链路测试

  • 对数据库操作的时候,一定要防止越权

    • 一个是直接RPC调用
    • 一个是通过MQ调用

    具体步骤见代码

第5集 冗余双写架构-短链服务开发总结

简介: 冗余双写架构-短链服务开发总结

  • 短链服务器CRUD
  • 冗余双写架构
    • 异常队列
    • 最终一致性

第二十七章 流量包商品服务需求和库表讲解

第1集 流量包商品服务-业务需求讲解

简介: 流量包商品服务需求讲解

  • 流量包需求讲解

    • 百度短链案例 https://dwz.cn/console/price

在这里插入图片描述

  • 流量包商品模型

    • 每个套餐都是一个虚拟商品,没库存限制
    • 免费版是新用户注册即可获得
    • 不同的商品每天限制的创建的条数不一样
    • 用户可以叠加使用多个流量包
  • 业务难点

    • 流量包购买支付(P2)
    • 流量包管理
      • 免费流量包管理(P1)
      • 付费流量包管理(P1)
    • 短链业务-流量包业务联动(P1)
第2集 流量包商品服务-数据库表介绍和实体类生成

简介: 流量包商品服务-数据库表介绍

  • 数据库表介绍
CREATE TABLE `product` (
  `id` bigint NOT NULL,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '商品标题',
  `detail` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '详情',
  `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '图片',
  `level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '产品层级:FIRST青铜、SECOND黄金、THIRD钻石',
  `old_amount` decimal(16,0) DEFAULT NULL COMMENT '原价',
  `amount` decimal(16,0) DEFAULT NULL COMMENT '现价',
  `plugin_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '工具类型 short_link、qrcode',
  `day_times` int DEFAULT NULL COMMENT '日次数:短链类型',
  `total_times` int DEFAULT NULL COMMENT '总次数:活码才有',
  `valid_day` int DEFAULT NULL COMMENT '有效天数',
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
  • 数据库创建
  • 插入初始化数据
INSERT INTO `dcloud_shop`.`product` (`id`, `title`, `detail`, `img`, `level`, `old_amount`, `amount`, `plugin_type`, `day_times`, `total_times`, `valid_day`, `gmt_modified`, `gmt_create`) VALUES (1, '青铜会员-默认', '数据查看支持||日生成短链{{dayTimes}}次||限制跳转50次||默认域名', NULL, 'FIRST', 19, 0, 'SHORT_LINK', 2, NULL, 1, '2021-10-14 17:33:44', '2021-10-11 10:49:35');




INSERT INTO `dcloud_shop`.`product` (`id`, `title`, `detail`, `img`, `level`, `old_amount`, `amount`, `plugin_type`, `day_times`, `total_times`, `valid_day`, `gmt_modified`, `gmt_create`) VALUES (2, '黄金会员-月度', '数据查看支持||日生成短链{{dayTimes}}次||限制不限制||默认域名', NULL, 'SECOND', 99, 1, 'SHORT_LINK', 5, NULL, 30, '2021-10-19 14:36:28', '2021-10-11 10:57:47');




INSERT INTO `dcloud_shop`.`product` (`id`, `title`, `detail`, `img`, `level`, `old_amount`, `amount`, `plugin_type`, `day_times`, `total_times`, `valid_day`, `gmt_modified`, `gmt_create`) VALUES (3, '黑金会员-月度', '数据查看支持||日生成短链{{dayTimes}}次||限制不限制||自定义域名', NULL, 'THIRD', 199, 2, 'SHORT_LINK', 8, NULL, 30, '2021-10-19 14:36:30', '2021-10-11 11:01:13');
  • MybatisPlus实体类生成
第3集 流量包商品服务-项目基本骨架创建

简介: 流量包商品服务-项目基本骨架创建

  • 配置文件增加和默认库表配置
server.port=8005
spring.application.name=dcloud-shop


#服务注册发现
spring.cloud.nacos.discovery.server-addr=120.79.150.146:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos




spring.shardingsphere.datasource.names=ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=class.net168


spring.shardingsphere.datasource.ds0.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds0.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds0.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds0.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds0.maxPoolSize=50
spring.shardingsphere.datasource.ds0.minPoolSize=50


spring.shardingsphere.props.sql.show=true




logging.level.root=INFO
  • 启动类配置
  • controller-service-manager层建立
第4集 流量包商品服务-商品列表和详情接口链路开发

简介: 流量包商品服务-商品列表和详情接口链路开发

  • 商品列表接口开发
  • 商品详情接口开发

第二十八章 流量包订单模块需求讲解和库表介绍

第1集 流量包订单模块-业务需求讲解

简介: 流量包订单模块-业务需求讲解

  • 流量包订单需求讲解

在这里插入图片描述

  • 需求
    • 支持叠加购买
      • 效果:1个流量包支持1天创建50条,如果买了两个则支持1天创建100条
    • 支持多渠道支付
      • 支付宝、微信等
      • 开发对接微信V3最新版支付,支付宝支付的参考第一个高并发项目大课
      • V2版微信支付对接可以看
        • https://detail.tmall.com/item.htm?id=649570556856
      • PC端支付宝支付可以看
        • https://detail.tmall.com/item.htm?id=646525336722
第2集 流量包订单-数据库表介绍和实体类生成

简介: 流量包订单-数据库表介绍和实体类生成

  • 数据库表
CREATE TABLE `product_order` (
  `id` bigint NOT NULL,
  `product_id` bigint DEFAULT NULL COMMENT '订单类型',
  `product_title` varchar(64) DEFAULT NULL COMMENT '商品标题',
  `product_amount` decimal(16,2) DEFAULT NULL COMMENT '商品单价',
  `product_snapshot` varchar(2048) DEFAULT NULL COMMENT '商品快照',
  `buy_num` int DEFAULT NULL COMMENT '购买数量',
  `out_trade_no` varchar(64) DEFAULT NULL COMMENT '订单唯一标识',
  `state` varchar(11) DEFAULT NULL COMMENT 'NEW 未支付订单,PAY已经支付订单,CANCEL超时取消订单',
  `create_time` datetime DEFAULT NULL COMMENT '订单生成时间',
  `total_amount` decimal(16,2) DEFAULT NULL COMMENT '订单总金额',
  `pay_amount` decimal(16,2) DEFAULT NULL COMMENT '订单实际支付价格',
  `pay_type` varchar(64) DEFAULT NULL COMMENT '支付类型,微信-银行-支付宝',
  `nickname` varchar(64) DEFAULT NULL COMMENT '账号昵称',
  `account_no` bigint DEFAULT NULL COMMENT '用户id',
  `del` int DEFAULT '0' COMMENT '0表示未删除,1表示已经删除',
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `bill_type` varchar(32) DEFAULT NULL COMMENT '发票类型:0->不开发票;1->电子发票;2->纸质发票',
  `bill_header` varchar(200) DEFAULT NULL COMMENT '发票抬头',
  `bill_content` varchar(200) DEFAULT NULL COMMENT '发票内容',
  `bill_receiver_phone` varchar(32) DEFAULT NULL COMMENT '发票收票人电话',
  `bill_receiver_email` varchar(200) DEFAULT NULL COMMENT '发票收票人邮箱',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_query` (`out_trade_no`,`account_no`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  • 数据库实体类生成
第3集 流量包订单-数据库表分库分表讲解和配置

简介: 流量包订单-数据库表分库分表讲解和配置

  • 业务需求
    • 用户查看自己的订单列表
  • 数据存储需求(都是前期规划,上线前可以调整分库分表策略和数量)
    • 未来2年,短链平台累计5百万用户
    • 付费流􏰀包记录:
      • 一个用户10条/年,总􏰀就是5千万条/年,两年是1亿
      • 单表不超过1千万数据,需要分10张表
      • 进一步延伸,进行水平分表,比如 2张表、4张表、8张 表、16张表
    • 分表数􏰀:线上分16张表,本地分2张表即可
  • 分片key
    • account_no作为partitionKey
#----------配置默认数据库,比如短链域名,不分库分表--------------
spring.shardingsphere.sharding.default-data-source-name=ds0
#默认id生成策略
spring.shardingsphere.sharding.default-key-generator.column=id
spring.shardingsphere.sharding.default-key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.default-key-generator.props.worker.id=${workerId}




# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
#水平分表策略+行表达式分片
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{ account_no % 2 }
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=account_no


第4集 流量包订单-Manager层CRUD接口开发

简介: 流量包订单-Manager层CRUD接口开发

  • 开发Manager层CRUD接口
第5集 流量包订单-基础分表Manager层单元测试

简介: 流量包订单-基础分表Manager层单元测试

  • 单元测试

第二十九章 流量包商品服务-下单模块开发和订单防重提交

第1集 流量包商品服务-订单controller相关接口开发

简介: 商品服务-订单controller相关接口开发

  • 分页接口开发
  • 订单状态查询接口(扫码支付-订单状态检查)
  • 下单接口(controller骨架)
    • 支付宝支付返回HTML
    • 微信支付返回JSON
第2集 流量包商品服务-流量包下单模块链路流程分析讲解

简介: 商品服务-订单下单模块链路流程分析讲解

  • 不涉及到商品库存管理
    • 防重􏰀提交(重点)
    • 获取最新的流量包价格
    • 订单验价
      • 如果有优惠券或者其他抵扣
      • 验证前端显示和后台计算价格
    • 创建订单对象保存数据库
    • 发送延迟消息-用于自动关单(重点)
    • 创建支付信息-对接三方支付(重点)
    • 回调更新订单状态(重点)
    • 支付成功创建流量包(重点)

在这里插入图片描述

第3集 流量包商品服务-下单接口链路骨架开发

简介: 商品服务-流量包下单接口链路骨架开发

  • 业务流程
    • 重防􏰀提交(TODO)
    • 获取最新的流量包价格
    • 订单验价
      • 如果有优惠券或者其他抵扣
      • 验证前端显示和后台计算价格
    • 创建订单对象保存数据库
    • 发送延迟消息-用于自动关单(TODO)
    • 创建支付信息-对接三方支付(TODO)
    • 回调更新订单状态(TODO)
    • 支付成功创建流量包(TODO)
  • 代码开发
第4集 流量包商品服务-避免􏰀重复下单你能想到几种方式

简介:避免􏰀复下单常见解决方案

  • 开发的项目中可能会出现下面这些情况:

    • 前端下单按钮􏰀复点击导致订单创建多次
    • 网速等原因造成页面卡顿,用户重复刷新提交请求
    • 黑客或恶意用户使用postman等http工具重复恶意提交表单
  • 问题

    • 会导致表单重复提交,造成数据重复或者错乱
    • 核心接口的请求增加,消耗服务器负载,严重甚至会造成服务器宕机
  • 因此核心接口需要做防重提交,你能想到几种方式

    • 方式一:前端JS控制点击次数,屏蔽点击按钮无法点击

      • 前端可以被绕过,前端有限制,后端也需要有限制
    • 方式二:数据库或者其他存储增加唯一索引约束

      • 需要想出满足业务需求的唯一索引约束,比如注册的手机号唯一
    • 方式三:服务端token令牌方式

      • 下单前先获取令牌-存储redis 下单时一并把token提交并检验和删除-lua脚本
      • 分布式情况下,采用Lua脚本进行操作
      String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
      

在这里插入图片描述

  • 方式三 是大家采用的最多的,那有没更加优雅的方式呢?
    • 采用自定义注解,也有多种方式

第三十章 流量包商品服务-多场景自定义注解防重提交实战

第1集 java核心知识-教你掌握自定义注解

简介:java核心知识-自定义注解

  • Annotation(注解)
    • 从JDK 1.5开始, Java增加了对元数据(MetaData)的支持,也就是 Annotation(注解)。
    • 注解其实就是代码里的特殊标记,它用于替代配置文件
    • 常见的很多 @Override@Deprecated
  • 什么是元注解
    • 注解的注解,比如当我们需要自定义注解时
    • 会需要一些元注解(meta-annotation),如**@Target@Retention**
  • java内置4种元注解
    • @Target 表示该注解用于什么地方
      • ElementType.CONSTRUCTOR 用在构造器
      • ElementType.FIELD 用于描述域-属性上
      • ElementType.METHOD 用在方法上
      • ElementType.TYPE 用在类或接口上
      • ElementType.PACKAGE 用于描述包
    • @Retention 表示在什么级别保存该注解信息
      • RetentionPolicy.SOURCE 保留到源码上
      • RetentionPolicy.CLASS 保留到字节码上
      • RetentionPolicy.RUNTIME 保留到虚拟机运行时(最多,可通过反射获取)
    • @Documented 将此注解包含在 javadoc 中
    • @Inherited 是否允许子类继承父类中的注解
  • @interface
    • 用来声明一个注解,可以通过default来声明参数的默认值
    • 自定义注解时,自动继承了java.lang.annotation.Annotation接口
    • 通过反射可以获取自定义注解
第2集 AOP+自定义注解-接口防重提交多场景设计

简介: AOP+自定义注解接口防重提交多场景设计

  • 防重提交方式
    • token令牌方式
    • ip+类+方法方式
  • 利用AOP
    • Aspect Oriented Program 面向切面编程, 在不改变原有逻辑上增加额外的功能
    • AOP思想把功能分两个部分,分离系统中的各种关注点
    • 好处
      • 减少代码侵入,解耦
      • 可以统一处理横切逻辑
      • 方便添加和删除横切逻辑
  • 业务流程

在这里插入图片描述

  • 自定义注解
import java.lang.annotation.*;


@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmit {


    /**
     * 加锁过期时间,默认是5秒
     * @return
     */
    long lockTime() default 5;


    /**
     * 默认限制类型,是方法参数
     * @return
     */
    Type limitType() default Type.PARAM;


    /**
     * 两种类型,token 或者 param
     */
    enum  Type{ PARAM , TOKEN};
}
第3集 订单防重提交-自定义注解开发实战-Token令牌方式

简介:订单防重提交-自定义注解开发实战-Token令牌方式

  • 新增redis配置
#-------redis连接配置-------
spring.redis.client-type=jedis
spring.redis.host=120.79.150.146
spring.redis.password=class.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
  • 编写接口获取令牌


    @Autowired
    private StringRedisTemplate redisTemplate;




    @GetMapping("token")
    public JsonData getToken(){
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        String token = CommonUtil.getStringNumRandom(32);
            //"order:submit:%s:%s"
        String key = String.format(RedisKey.SUBMIT_ORDER_TOKEN_KEY, loginUser.getAccountNo(),requestToken);


        redisTemplate.opsForValue().set(key, "1", 30, TimeUnit.MINUTES);


        return JsonData.buildSuccess(token);




    }


  • 定义切面类-开发解析器
 /**
     * 定义 @Pointcut注解表达式,
     *  方式一:@annotation:当执行的方法上拥有指定的注解时生效(我们采用这)
     *  方式二:execution:一般用于指定方法的执行
     *
     * @param repeatSubmit
     */
    @Pointcut("@annotation(repeatSubmit)")
    public void pointcutNoRepeatSubmit(RepeatSubmit repeatSubmit) {


    }
    
    
    
     /**
     * 环绕通知, 围绕着方法执行
     * @Around 可以用来在调用一个具体方法前和调用后来完成一些具体的任务。
     *
     * 方式一:单用 @Around("execution(* net.class.controller.*.*(..))")可以
     * 方式二:用@Pointcut和@Around联合注解也可以(我们采用这个)
     *
     *
     * 两种方式
     * 方式一:加锁 固定时间内不能重复提交
     * <p>
     * 方式二:先请求获取token,这边再删除token,删除成功则是第一次提交
     *
     * @param joinPoint
     * @param noRepeatSubmit
     * @return
     * @throws Throwable
     */
    @Around("pointcutNoRepeatSubmit(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit noRepeatSubmit) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();


        boolean res;


        String type = noRepeatSubmit.limitType().name();


        if (type.equals(RepeatSubmit.Type.PARAM.name())) {
            //方式一方法参数            TODO


 
        } else {
            //方式二,令牌形式
            String requestToken = request.getHeader("request-token");
            if (StringUtils.isBlank(requestToken)) {
                throw new BizException(BizCodeEnum.ORDER_CONFIRM_TOKEN_EQUAL_FAIL);


            }
            LoginUser loginUser = LoginInterceptor.threadLocal.get();
            //"order:submit:%s:%s"
             String key = String.format(RedisKey.SUBMIT_ORDER_TOKEN_KEY, loginUser.getAccountNo(),requestToken);




            /**
             * 提交表单的token key
             * 方式一:不用lua脚本获取再判断,之前是因为 key组成是 order:submit:accountNo, value是对应的token,所以需要先获取值,再判断
             * 方式二:可以直接key是 order:submit:accountNo:token,然后直接删除成功则完成
             */
            res = stringRedisTemplate.delete(key);


        }


        if (!res) {
            throw new BizException(BizCodeEnum.ORDER_CONFIRM_REPEAT);
        }


        System.out.println("目标方法执行前");
        Object object = joinPoint.proceed();
        System.out.println("目标方法执行后");
        return object;
    }
第4集 Spring里面的AOP常见概念复习巩固

简介:Spring里面的AOP常见概念复习巩固

在这里插入图片描述

  • 能否解释下AOP里面常见的概念,比如 横切、通知、连接点、切入点、切面 ?

    • 横切关注点

      • 对哪些方法进行拦截,拦截后怎么处理,这些就叫横切关注点
      • 比如 权限认证、日志、事物
    • 通知 Advice

      • 在特定的切入点上执行的增强处理
      • 做啥? 比如你需要记录日志,控制事务 ,提前编写好通用的模块,需要的地方直接调用
      • 比如重复提交判断逻辑
      • 类型
        • @Before前置通知
          • 在执行目标方法之前运行
        • @After后置通知
          • 在目标方法运行结束之后
        • @AfterReturning返回通知
          • 在目标方法正常返回值后运行
        • @AfterThrowing异常通知
          • 在目标方法出现异常后运行
        • @Around环绕通知
          • 在目标方法完成前、后做增强处理 ,环绕通知是最重要的通知类型 ,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint,需要手动执行 joinPoint.procced()
    • 连接点 JointPoint

      • 要用通知的地方,业务流程在运行过程中需要插入切面的具体位置,
      • 一般是方法的调用前后,全部方法都可以是连接点
      • 只是概念,没啥特殊
    • 切入点 Pointcut

      • 不能全部方法都是连接点,通过特定的规则来筛选连接点, 就是Pointcut,选中那几个你想要的方法
      • 在程序中主要体现为书写切入点表达式(通过通配、正则表达式)过滤出特定的一组 JointPoint连接点
      • 过滤出相应的 Advice 将要发生的joinpoint地方
    • 切面 Aspect

      • 通常是一个类,里面定义 切入点+通知 , 定义在什么地方; 什么时间点、做什么事情
      • 通知 advice指明了时间和做的事情(前置、后置等)
      • 切入点 pointcut 指定在什么地方干这个事情
      • web接口设计中,web层->网关层->服务层->数据层,每一层之间也是一个切面,对象和对象,方法和方法之间都是一个个切面
    • 目标 target

      • 目标类,真正的业务逻辑,可以在目标类不知情的条件下,增加新的功能到目标类的链路上
    • 织入 Weaving

      • 把切面(某个类)应用到目标函数的过程称为织入

在这里插入图片描述

第5集 订单防重提交-自定义注解-Token方式效果验证

简介:订单防重提交-自定义注解开发-Token式效果验证

  • 下单接口增加注解
@RepeatSubmit(limitType = RepeatSubmit.Type.TOKEN)
  • 获取令牌
  • 其他bug修复
第6集 订单防重提交-自定义注解开发实战-参数式

简介:订单防重提交-自定义注解开发实战

  • 开发配置
            //方式一方法参数
            long lockTime = noRepeatSubmit.lockTime();


            String ip = CommonUtil.getIpAddr(request);
            //获取注解
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            //目标类、方法
            String className = method.getDeclaringClass().getName();
            String name = method.getName();
            String key = String.format("%s#%s#%s#%s",accountNo,ip, className, name);


            log.info("key={}", key);




            // 分布式锁 TODO, 直接设置key配置过期时间也行


  • 分布式锁几种实现
    • Redis+Lua脚本
    • Redission
  • 直接redis操作
使用原子命令:设置和配置过期时间  setnx / setex 
如: set key 1 ex 30 nx


java代码里面 
redisTemplate.opsForValue().setIfAbsent(key,1,30,TimeUnit.MILLISECONDS)
第7集 Redission分布式锁介绍和配置引入

简介:Redission分布式锁介绍和配置引入

  • Redission介绍
    • 是一个在Redis的基础上实现的Java驻内存数据网格,支持多样Redis配置支持、丰富连接方式、分布式对象、分布式集合、分布式锁、分布式服务、多种序列化方式、三方框架整合
    • Redisson底层采用的是Netty 框架
    • 官方文档:https://github.com/redisson/redisson
  • 配置加入
聚合工程锁定版本,common项目添加依赖(多个服务都会用到分布式锁)


<!--分布式锁-->
<dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson</artifactId>
      <version>3.10.1</version>
</dependency>
  • 代码配置


    @Value("${spring.redis.host}")
    private String redisHost;


    @Value("${spring.redis.port}")
    private String redisPort;




    @Value("${spring.redis.password}")
    private String redisPwd;






    /**
     * 配置分布式锁的redisson
     * @return
     */
    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();


        //单机方式
        config.useSingleServer().setPassword(redisPwd).setAddress("redis://"+redisHost+":"+redisPort);


        //集群
        //config.useClusterServers().addNodeAddress("redis://192.31.21.1:6379","redis://192.31.21.2:6379")


        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }


    /**
     * 集群模式
     * 备注:可以用"rediss://"来启用SSL连接
     */
    /*@Bean
    public RedissonClient redissonClusterClient() {
        Config config = new Config();
        config.useClusterServers().setScanInterval(2000) // 集群状态扫描间隔时间,单位是毫秒
              .addNodeAddress("redis://127.0.0.1:7000")
              .addNodeAddress("redis://127.0.0.1:7002");
        RedissonClient redisson = Redisson.create(config);
        return redisson;
    }*/


  • 加锁调用
          // 分布式锁
            RLock lock = redissonClient.getLock(key);
            // 尝试加锁,最多等待2秒,上锁以后5秒自动解锁 [lockTime默认为5s, 可以自定义]
            res = lock.tryLock(2, lockTime, TimeUnit.SECONDS);


第8集 订单防重提交-自定义注解开发-参数式效果验证

简介:订单防重提交-自定义注解开发-参数式效果验证

  • 效果验证

  • 两种防重提交,应用场景不一样,也可以更多方式进行防重

  • 个人接入微信支付V3版参数示例

    • 公众号:appid: wx5beac15ca207c40c
    • 商户平台
      • 商户号:1601644442
      • APIv3密钥:peYcTwRF581UOdaUqoPOeHzJ8FgHgsnJ
      • 证书序列号:7064ADC5FE84CA2A3DDE71A692E39602DEB96E61
      • 证书文件:本章本集的资料里面(不可用,最新的群公告获取)
        Config config = new Config();
        config.useClusterServers().setScanInterval(2000) // 集群状态扫描间隔时间,单位是毫秒
        .addNodeAddress(“redis://127.0.0.1:7000”)
        .addNodeAddress(“redis://127.0.0.1:7002”);
        RedissonClient redisson = Redisson.create(config);
        return redisson;
        }*/

 

- 加锁调用

```java
          // 分布式锁
            RLock lock = redissonClient.getLock(key);
            // 尝试加锁,最多等待2秒,上锁以后5秒自动解锁 [lockTime默认为5s, 可以自定义]
            res = lock.tryLock(2, lockTime, TimeUnit.SECONDS);


第8集 订单防重提交-自定义注解开发-参数式效果验证

简介:订单防重提交-自定义注解开发-参数式效果验证

  • 效果验证

  • 两种防重提交,应用场景不一样,也可以更多方式进行防重

  • 个人接入微信支付V3版参数示例

    • 公众号:appid:
    • 商户平台
      • 商户号:
      • APIv3密钥:
      • 证书序列号:
      • 证书文件:本章本集的资料里面(不可用,最新的群公告获取)
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从零开始学习人工智能

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

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

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

打赏作者

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

抵扣说明:

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

余额充值