如果在一元运算中,x 为某集合中的任意数,如果满足 f(x) = f(f(x)) ,那么该 f 运算具有幂等性。
绝对值运算 abs(a) = abs(abs(a)) 就是幂等性函数
如果在二元运算中,x 为某集合中的任意数,如果满足 f(x,x) = x,前提是 f 运算的两个参数均为 x,那么我们称 f 运算也有幂等性。
求大值函数 max(x,x) = x 就是幂等性函数
生产环境经常出现过重复的数据?在排查问题的时候,数据又是正常的。这个是何解呢?怎么会出现这种情况,而且还很难排查问题。
原因 :产生重复数据或数据不一致(假定程序业务代码没问题),绝大部分就是发生了重复的请求,重复请求是指同一个请求因为某些原因被多次提交。导致这个情况会有几种场景:(本质上:多次请求)
1)微服务场景,在我们传统应用架构中调用接口,要么成功,要么失败。但是在微服务架构下,会有第三个情况【未知】,也就是超时。如果超时了,微服务框架会进行重试。 2)用户交互的时候多次点击。如:快速点击按钮多次。 3)MQ消息中间件,消息重复消费。 4)第三方平台的接口(如:支付成功回调接口),因为异常也会导致多次异步回调。 5)其他中间件/应用服务根据自身的特性,也有可能进行重试。
接口的幂等性实际上就是 接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。更准确的讲:多次调用对系统的产生的影响是一样的,即对资源的作用是一样的,但是返回值允许不同。
场景1:支付场景
1.一个订单创建接口,第一次调用超时了,然后调用方重试了一次 2.在订单创建时,我们需要去扣减库存,这时接口发生了超时,调用方重试了一次 3.当这笔订单开始支付,在支付请求发出之后,在服务端发生了扣钱操作,接口响应超时了,调用方重试了一次 4.一个订单状态更新接口,调用方连续发送了两个消息,一个是已创建,一个是已付款。但是你先接收到已付款,然后又接收到了已创建 5.在支付完成订单之后,需要发送一条短信,当一台机器接收到短信发送的消息之后,处理较慢。消息中间件又把消息投递给另外一台机器处理
场景2:一键三连
小破站有一个一键三连的功能,长按可以对up主进行激励,每个人对每个视频只有一个一键三连的机会。就算再喜欢某个视频,多次操作,也只能有一键三连一次。
场景3:统计DAU/MAU
DAU/MAU,又叫日活/月活,是用于反映网站、互联网应用或网络游戏的运营情况的统计指标。所以一个用户当天或者当月登录多次(或者达到某种活跃用户判断机制多次),也只能看作一个活跃用户,不能重复计算。
有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,查询一次和多次,对于系统来说,没有任何影响,查出的结果也是一样,而其他功能,例如:增加、更新、删除都要保证幂等性。 以user表举例
1、查询,select * from user where xxx,不会对数据产生任何变化,具备幂等性
2、新增,insert into user(userid, name) values(1, 'a')
如 userid 为唯一主键,即重复操作上面的业务,只会插入一条用户数据,具备幂等性
如 userid 不是主键,可以重复,那上面业务多次操作,数据都会新增多条,不具备幂等性
3、修改,区分直接赋值和计算赋值
直接赋值,update user set point = 20 where userid = 1,不管执行多少次,point都一样,具备幂等性
计算赋值,update user set point = point + 20 where userid = 1,每次操作 point 数据都不一样,不具备幂等性
4、删除,delete from user where userid = 1,多次操作,结果一样,具备幂等性
因此,我们可以得出,没有唯一主键约束的数据,和修改计算赋值数据的操作都不具备幂等性 。
首先,先看SpringBoot的主配置类:
@SpringBootApplication public class StartEurekaApplication { public static void main(String[] args) { SpringApplication.run(StartEurekaApplication.class, args); } }
点进@SpringBootApplication来看,发现@SpringBootApplication是一个组合注解。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { }
首先我们先来看 @SpringBootConfiguration:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }
可以看到这个注解除了元注解以外,就只有一个@Configuration,那也就是说这个注解相当于@Configuration,所以这两个注解作用是一样的,它让我们能够去注册一些额外的Bean,并且导入一些额外的配置。
关于 CDN 是什么,我想应该不用做过多的介绍,毕竟现在是一个 “云” 的时代,你至少也听说过 阿里云 或者 腾讯云 吧,当然其中就包括 CDN 业务。
CDN 的作用有很多,比如可以用来加速网站的访问,可以用来防护网站等。本篇文章讨论的就是使用 cloudflare 作为 CDN 来加速博客网站,并让博客开启 https,提升博客安全等级。
由于 GitHub Pages 在国外,而且有时候因为图片过多等原因,静态博客页面在国内访问速度可能会非常慢,我们可以用 CDN 来加速,选择 CDN,对于个人来说,主要考虑的还是访问速度以及价格,既免费又快的 CDN就最好了。经过一番寻找,发现 Cloudflare 免费版速度还可以,而且配置起来非常简单,所以在此选用 CloudFlare CDN 来加速页面访问。也就是说,借用了cloudflare免费提供的serveless服务:workers。搭建一个反向代理。
反向代理的话相当于是我们的节点代替github pages接受了客户端的请求,所以其实我们只需要做两件事:
日常工作中权限的问题时时刻刻伴随着我们,程序员新入职一家公司需要找人开通各种权限,比如网络连接的权限、编码下载提交的权限、监控平台登录的权限、运营平台查数据的权限等等。
在很多时候我们会觉得这么多繁杂的申请给工作带来不便,并且如果突然想要查一些数据,发现没有申请过权限,需要再走审批流程,时间拉得会很长。那为什么还需要这么严格的权限管理呢?
举个例子,一家支付公司有运营后台,运营后台可以查到所有的商户信息,法人代表信息,交易信息以及费率配置信息,如果我们把这些信息不加筛选都给到公司的每一个小伙伴,那么跑市场的都可以操作商家的费率信息,如果一个不小心把费率改了会造成巨大的损失。
又比如商户的信息都是非常隐秘的,有些居心不良的小伙伴把这些信息拿出来卖给商家的竞争对手,会给商家造成严重的不良后果。虽然这么做都是个别人人为的过错,但是制度上如果本身这些信息不开放出来就能在很大程度上避免违法乱纪的事情发生了。
总体来讲**权限管理是公司数据安全的重要保证,针对不同的岗位,不同的级别看到的数据是不一样的,操作数据的限制也是不一样的。**比如涉及到资金的信息只开放给财务的相关岗位,涉及到配置的信息只开放给运营的相关岗位,这样各司其职能避免很多不必要的安全问题。
如何让各个岗位的人在系统上各司其职,就是权限管理要解决的问题。