加入收藏 | 设为首页 | 会员中心 | 我要投稿 济宁站长网 (https://www.0537zz.cn/)- 行业智能、边缘计算、专有云、AI硬件、5G!
当前位置: 首页 > 站长资讯 > 传媒 > 正文

优雅的使用迭代器模式以及案例复盘

发布时间:2021-01-30 10:06:23 所属栏目:传媒 来源:互联网
导读:由于企业如果考虑在项目中使用 Redis,因为大部分会拿它作为缓存来使用,那么一般都会是集群的方式出现,至少肯定也会部署两台Redis服务器。所以我们使用Redis来实现接口的幂等性是最适合不过的了。 状态机 # 对于很多业务是有一个业务流转状态的,每个状态

由于企业如果考虑在项目中使用 Redis,因为大部分会拿它作为缓存来使用,那么一般都会是集群的方式出现,至少肯定也会部署两台Redis服务器。所以我们使用Redis来实现接口的幂等性是最适合不过的了。

状态机 #

对于很多业务是有一个业务流转状态的,每个状态都有前置状态和后置状态,以及最后的结束状态。例如流程的待审批,审批中,驳回,重新发起,审批通过,审批拒绝。订单的待提交,待支付,已支付,取消。

以订单为例,已支付的状态的前置状态只能是待支付,而取消状态的前置状态只能是待支付,通过这种状态机的流转我们就可以控制请求的幂等。
 

当然这个接口的方法具体在项目中合理的使用就看项目要求了,可以通过 @Autowire 注解注入到需要使用的地方,但是缺点就是每个地方都需要调用。我个人推荐的是自定义一个注解,在需要幂等性保证的接口上加上该注解,然后通过拦截器方法拦截使用。这样简单便不会造成代码侵入和污染。

另外,使用数据库防重表的方式它有个严重的缺点,那就是系统容错性不高,如果幂等表所在的数据库连接异常或所在的服务器异常,则会导致整个系统幂等性校验出问题。如果做数据库备份来防止这种情况,又需要额外忙碌一通了啊。

Redis实现 #

上面介绍过防重表的设计方式和伪代码,也说过它的一个很明显的缺点。所以我们另外介绍一个Redis的实现方式。

Redis实现的方式就是将唯一序列号作为Key,唯一序列号的生成方式和上面介绍的防重表的一样,value可以是你想填的任何信息。唯一序列号也可以是一个字段,例如订单的订单号,也可以是多字段的唯一性组合。当然这里需要设置一个 key 的过期时间,否则 Redis 中会存在过多的 key。具体校验流程如下图所示,实现代码也很简单这里就不写了。
 

我们又重新改成每500个连接,sleep 1秒。嗯好,终于没有卡的了(或者也可以加大连接队列长度)。结论是本机50000次TCP连接在客户端统计总耗时102399 ms,减去sleep的100秒后,平均每个TCP连接消耗0.048ms。比ping延迟略高一些。这是因为当RTT变的足够小的时候,内核CPU耗时开销就会显现出来了,另外TCP连接要比ping的icmp协议更复杂一些,所以比ping延迟略高0.02ms左右比较正常。

四、结论

TCP连接建立异常情况下,可能需要好几秒,一个坏处就是会影响用户体验,甚至导致当前用户访问超时都有可能。另外一个坏处是可能会诱发雪崩。所以当你的服务器使用短连接的方式访问数据的时候,一定要学会要监控你的服务器的连接建立是否有异常状态发生。如果有,学会优化掉它。当然你也可以采用本机内存缓存,或者使用连接池来保持长连接,通过这两种方式直接避免掉TCP握手挥手的各种开销也可以。

再说正常情况下,TCP建立的延时大约就是两台机器之间的一个RTT耗时,这是避免不了的。但是你可以控制两台机器之间的物理距离来降低这个RTT,比如把你要访问的redis尽可能地部署的离后端接口机器近一点,这样RTT也能从几十ms削减到最低可能零点几ms。

最后我们再思考一下,如果我们把服务器部署在北京,给纽约的用户访问可行吗? 前面的我们同机房也好,跨机房也好,电信号传输的耗时基本可以忽略(因为物理距离很近),网络延迟基本上是转发设备占用的耗时。但是如果是跨越了半个地球的话,电信号的传输耗时我们可得算一算了。 北京到纽约的球面距离大概是15000公里,那么抛开设备转发延迟,仅仅光速传播一个来回(RTT是Rround trip time,要跑两次),需要时间 = 15,000,000 *2 / 光速 = 100ms。实际的延迟可能比这个还要大一些,一般都得200ms以上。建立在这个延迟上,要想提供用户能访问的秒级服务就很困难了。所以对于海外用户,最好都要在当地建机房或者购买海外的服务器。

(编辑:济宁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读