当前位置: 首页 > news >正文

海量数据处理商用短链接生成器平台 - 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=nacosspring.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.net168spring.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=50spring.shardingsphere.props.sql.show=truelogging.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
  • 编写接口获取令牌
@Autowiredprivate 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 nxjava代码里面 
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*/@Beanpublic 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连接*//*@Beanpublic 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密钥:
      • 证书序列号:
      • 证书文件:本章本集的资料里面(不可用,最新的群公告获取)
http://www.lryc.cn/news/417461.html

相关文章:

  • 从困境到突破,EasyMR 集群迁移助力大数据底座信创国产化
  • 【Mysql】第十二章 视图特性(概念+使用)
  • 【颠覆数据处理的利器】全面解读Apache Flink实时大数据处理的引擎-上篇
  • 【C++】C++11(可变参数模板、lambda表达式、包装器)
  • 矩阵获客时代,云微客让你一个人成就一支队伍
  • 浅谈基础的图算法——Tarjan求强联通分量算法(c++)
  • 【Godot4自学手册】第四十四节用着色器(shader)实现溶解效果
  • 【画流程图工具】
  • Revit二次开发选择过滤器,SelectionFilter
  • 【Linux】进程概念—环境变量
  • 第十二章 Spring MVC 框架扩展和SSM框架整合(2023版本IDEA)
  • js中的全局函数有这些
  • Android SurfaceFlinger——重绘闪烁处理(四十六)
  • 罗马数字转整数 C++
  • Day20_2--介绍同步加载和异步加载
  • sftp做成一个池子
  • 全网最全-Netty从入门到精通
  • C#知识|文件与目录操作:对象的创建、保存、读取
  • 自定义 SwiftUI 中符号图像的外观
  • 循环神经网络和自然语言处理一
  • CSS技巧专栏:一日一例 20-纯CSS实现点击会凹陷的按钮
  • 20240807 每日AI必读资讯
  • 海外社媒账号如何让防关联?账号隔离的5大要点
  • 下一代 AI 搜索引擎 MindSearch:多智能体 + 系统2,模拟人类认知过程的 AI 搜索引擎
  • 一键生成专业PPT:2024年AI技术在PPT软件中的应用
  • Godot学习笔记8——PONG游戏制作
  • 软件RAID配置实战(2个案例场景)
  • # 基于MongoDB实现商品管理系统(2)
  • 国标GB28181视频平台LntonCVS视频融合共享平台视频汇聚应用方案
  • java基础I/O