幂等相关(二)
上文参考了网上的一些资料,本文将针对一些场景说说自己的理解。
一般请求或者MQ读取消息时,可以对业务数据的类型,状态等进行有效性校验,更新的时候利用状态机更新。
也可以利用利用唯一流水号和防重表【直接insert + 主键/唯一索引冲突】的方法,直接防重。当然为了防止防重表过大,可以定时的删除一定时间前的数据。(MQ的时候,唯一流水号可以在生产端生成,随着业务数据一起推送)
对于注册这种业务,可以明确确定唯一索引字段,比如手机号或者手机号+租户号,可以直接做到插入的数据防重。
对于下单这种业务,不能确定 同一个用户+相同的下单商品 就是唯一数据,这种情况防重的话,除了前端做二重提交的处理外,后端接口我能想到的有一下几种思路:
前端在订单提交页生成唯一流水号,和业务数据一起作为参数传给生成订单接口,接口利用防重表,插入成功的情况下,继续处理。因唯一索引插入失败的情况下,则视为重复提交数据,直接返回,不做后续处理。
和1一样,在订单提交页生成唯一流水号作为参数传给生成订单接口,接口利用唯一流水号作为分布式锁对象,能够获取到锁,继续处理,获取不到锁,则视为重复提交数据,直接返回 ...
幂等相关(一)
日常开发中,有很多例子需要考虑幂等
比如提交form表单时,如果快速点击提交按钮,可能产生了两条一样的数据(前端重复提交,下单,用户注册等)
MQ(消息中间件)消费者读取消息时,有可能会读取到重复消息。(重复消费)
幂等意味着一条请求的唯一性。不管是你哪个方案去设计幂等,都需要一个全局唯一的ID,去标记这个请求是独一无二的。
如果你是利用唯一索引控制幂等,那唯一索引是唯一的
如果你是利用数据库主键控制幂等,那主键是唯一的
如果你是悲观锁的方式,底层标记还是全局唯一的ID
幂等设计的基本流程幂等处理的过程,说到底其实就是过滤一下已经收到的请求,当然,请求一定要有一个全局唯一的ID标记哈。然后,怎么判断请求是否之前收到过呢?把请求储存起来,收到请求时,先查下存储记录,记录存在就返回上次的结果,不存在就处理请求。
实现幂等的8种方案1. select+insert+主键/唯一索引冲突
日常开发中,为了实现交易接口幂等,我是这样实现的:
交易请求过来,我会先根据请求的唯一流水号 bizSeq字段,先select一下数据库的流水表
如果数据已经存在,就拦截是重复请求,直接返回成功 ...
几个系统性能指标
QPS
QPS Queries Per Second 是每秒查询率 ,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准, 即每秒的响应请求数,也即是最大吞吐能力。
TPS
TPS Transactions Per Second 也就是事务数/秒。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数,
QPS和TPS区别
个人理解如下:
1、Tps即每秒处理事务数,包括了
1)用户请求服务器 2)服务器自己的内部处理 3)服务器返回给用户
这三个过程,每秒能够完成N个这三个过程,Tps也就是N;
2、Qps基本类似于Tps,但是不同的是,对于一个页面的一次访问,形成一个Tps;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入“QPS”之中。
例子
例如:访问一个页面会请求服务器3次,一次放,产生一个“T”,产生3个“Q”
例如:一个大胃王一秒能吃10个包子,一个女孩子0.1秒能吃1个包子,那么他们是不 ...
全民付支付对接
前段时间对接了全民付的支付宝小程序和微信小程序支付,支付宝是可以直接唤起全民付主体的小程序,微信则必须申请自己主体的小程序,进而两者流程上有一定的不同,
项目整体框架包括:原生壳子,页面为jsp(SpringMVC框架)。
支付宝小程序支付对接流程:1.支付确认页js请求自己的支付接口2.自己的支付接口内拼装好参数调用全民付支付接口3.全民付支付接口将支付结果返回(appPayRequest:APP支付用的请求报文,带有签名信息)给自己的支付接口4.自己的支付接口将支付结果的APP支付用的请求报文(appPayRequest)返回给js5.js拿到将APP支付用的请求报文(appPayRequest)作为参数,调用原生方法6.原生加载APP支付用的请求报文(appPayRequest),唤起全民付支付宝小程序,7.用户通过唤起的支付宝小程序进行支付操作,支付结果通过回调url(支付请求参数中传入)返回给系统。8.支付确认页通过调用接口一直监听支付结果,拿到结果后跳转到支付结果页
微信小程序支付对接流程:1.支付确认页js将支付请求参数拼接好作为参数调用原生方法2.原生唤起自己主体的微信 ...
RocketMQ消费模式
消费者同组时,有两种消息模式:
1.集群模式,多个消费者通过负载均衡一起消费信息。
2.广播模式,一个消息会复制成多份分发给每一个消费者。
消费者不同组时:
一个消息会复制多份发给不同的消费者组。
springboot集成sftp
1.引入相关依赖12345<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version></dependency>
2.定义相关配置12345678excel.domain=http://192.168.102.1/excel/pic.domain=http://192.168.102.1/uploadImg/sftp.host=192.168.102.1sftp.port=22sftp.user=rootsftp.password=12341234sftp.file.path=/home/nginx/html/excelsftp.image.path=/home/nginx/html/uploadImg
3.实现工具类12345678910111213141516171819202122232425262728293031323 ...
mongo聚合的理解
理解mongo聚合类似关系型数据库的分组操作,
mongo聚合操作是一种管道操作,每一步的结果都是下一步的操作的输入。
实例1234567891011121314151617181920212223242526272829303132333435363738394041424344// Criteria作为检索条件Criteria criteria = Criteria.where("orgId").is(formReplyModel.getOrgId());criteria.and("formId").in(formReplyModel.getFormId());criteria.and("formName").regex("^.*" + formReplyModel.getFormName() + ".*$");// 创建一个聚合操作的list,后续执行聚合的时候按list的0,1,2...的顺序执行List<AggregationOperation> operation ...
oracle转mysql
1.seqence 主键mysql没有序列但是有auto_increment字段,将字段修改为自增,插入时: nextval —-》 null
ALTER TABLE T_BLOGROLL_INFO MODIFY id INT AUTO_INCREMENT;
新建了函数currval,nextval
2.分页 和 rownum的修改 =>limit
3.存储过程4.日期等函数修改获取当前时间函数: sysdate =========> now()字符串转时间的函数: to_date(#{createEndTime},’yyyy/mm/dd’) ===>str_to_date(#{createBeginTime},’%Y/%m/%d’)
时间转字符串的函数: to_char(OPERATE_TIME,’yyyy-MM-dd hh24:mi:ss’)=== ...
