zoukankan      html  css  js  c++  java
  • 接口幂等性

    所谓的幂等性,就是在同样的条件下,一次请求和重复多次请求,对资源的影响是一样的。比如get,不论是请求多少次,都是同样的结果。比如delete,你删除了一条数据比如id=10,当你重复请求的时候,这个id=10的数据已经删除了,资源里面已经没有这条数据了,所以即便请求多次,结果跟请求一次是一样的,所以,对资源的影响是一样的。

    关于put请求,这里摘抄了restful api官网的官方解释:

    Generally – not necessarily – PUT APIs are used to update the resource state. If you invoke a PUT API N times, the very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

    对于同一条数据的修改,不论修改多少次,也只是不断的覆盖前面的相同修改,所以对于资源的影响也是不变的。

    get/delete请求方式,是天然幂等,put请求,如果重复修改同一条数据,数据库是没有变化的,所以,put也不需要做幂等性处理。需要做幂等性处理的就只有post请求方式。

    接口幂等性的解决办法:实际生产应用中

    1、提交表单时,表单内有唯一性的元素,它本身就是天然幂等,因为唯一性的元素不会被写入到数据库,数据库的字段属性本身就会拦截它,比如手机号,比如身份证。100%解决幂等性问题。

    2、如果你提交表单是用页面刷新的方式而不是用Ajax,那么,这种方式会好一些,页面刷新之后,表单数据自然清空,用户提交的时候需要手动再次输入,

    这样可以大概率避免用户自身不断输入重复的数据提交,能解决80%的幂等性问题。

    3、最简单粗暴:

      用Ajax提交表单,表单填写完成之后,获取到表单所有数据后,传入到Ajax,同时,清除表单用户填入的信息。在post请求结束后在回调函数里面跳转到get页面。

    4、上面的2、3、都是前端做操作,后端什么都没有做。这次,换成后端做拦截,每次数据插入,都去数据库查询一遍,如果有同样的数据,就拦截提交,这样就能100%解决幂等性。幂等性问题是解决了,但是会引发出来新的问题,就是执行效率的问题,频次过高,数据库会崩溃,此时,是另一个维度的问题。解决办法就是,常用的数据查询,放入到缓存里面,这样就减轻了数据库的压力。如果数据量过大,缓存会有压力,届时,再解决缓存的问题,比如集群,主从备份,分布式等等。

    5、教科书式的,token方式。如果单纯为了做token验证幂等性,然后配置上redis等这种缓存机制,就过于浪费了,在实际生产中,不会这样做。

    不过,如果你的redis有其他用途,然后顺带着用它做token验证幂等性,这倒是可以。

    token的流程:前端调用后端接口发起请求,把表单数据传给后端,后端拿到数据,设置token随机字符串,存入到缓存机制中,放到响应参数中,返回给前端,前端拿到响应数据,提取出来token值,写入到cookie中,document.cookie即可获取cookie值,在前端页面全局皆可获取cookie值。下次请求的时候,请求头会携带cookie信息,后端拿到请求头中的token信息,跟上次设置的存入到缓存中的token值进行比对,如果是同一个token,请求重复提交,做拦截,不修改数据库。

    不论采用上面何种方法,接下来,都必须要如下处理,从安全方面考虑,防止DDS攻击(写脚本在单位时间内疯狂点击页面接口调取按钮),做频次拦截。

      后端需要处理的部分,做频次拦截,防止同一个用户在单位时间内,不断对接口进行操作,需要记录每一次操作的时间,进行比对,如果频次过高,

    给前端返回提示信息,防止服务挂掉。这个记录下来的操作时间,需要存入到mongodb,redis,rabitmq这样的缓存服务里面,不能存入到python的内存里面。

    请求结束后,python内部是有垃圾回收机制的,这些python内部的list,dict等都会被清空,就无法把每次请求时间做记录进行比对。

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/2012-dream/p/14763462.html
Copyright © 2011-2022 走看看