频繁调用接口的问题

  开发接口的时候,一定要对数据进行过滤,这个就不提了。

  重要的是,怎么确保对接口调用的自我保护和限流、降级机制,这个从何说起呢?

  比如,你写了一个接口,该接口并没有什么bug,但是接口没漏洞不代表系统没漏洞,如果有人调用你的接口,然后成功了,这证明你的接口没问题。

  但是,如果出现这种情况:接口调用方 高并发地 调用你的接口,其实你的接口是没问题的,但是你的服务器承受不住呀,也许对方不是故意的,但如果是对方发生状况,出现了这种情况,就比较伤心了,所以写任何接口之前或者之后,都要考虑这个问题,不要存在侥幸心理,不然真出现问题,受罪的还不知道是谁呢 

 

  注意:上面说的情况很类似于DoS攻击,请注意,只是类似于,当然也可以将DoS攻击考虑在内,因为他们是有区别的。

  之所以说不是DoS攻击,是因为,DoS攻击在TCP三次连接的过程中,只发送SYN包,但是并不会对服务器发挥的SYN ACK包进行确认,即并不会发送ACK给服务器。通过这种方式来消耗系统资源,让系统崩溃。

  而如果是一个服务异常请求的,因为他出现了bug,频繁的请求你的接口,你的服务器和请求方是完成了三次握手,每一次连接都是合法的,单从连接状态上,是判断不出什么异常的。所以对于这种情况,采用防DoS的手段来解决问题,驴头不对马嘴。

  

  你写的接口,可能涉及到数据库操作(不涉及数据库操作的接口很少吧),那么涉及数据库的连接数,数据库的最大连接数 和 服务器的最大连接数,以及数据库同一时刻能运行SQL的数量,如果是php,还涉及php-fpm,这里面的每一项,都有临界值,如果出现意外,超过临界值也是很正常的,只不过看超过了哪一项的临界值而已,临界值大的,可能坚持的时间会久一点。

  如果你的接口涉及到数据库操作,特别是查(select)操作,请尽量使用从库(或者读库)进行操作。一般情况下,都建议接口中对从库进行操作。

  如果你有很多接口,接口的使用方是不同的服务系统,可能你的一个接口提供给一个系统调用,也可能提供给多个系统调用。那么在进行限流的时候,你就得注意了,如果你是根据单位时间内接口的访问量来判断,如果超过某个阀值,就阻止对该接口的访问,那么就会出现这个问题:其中一个系统频繁调用接口,超过了阀值,于是你就拒绝了之后对该接口的请求,即使此次的请求方不是之前频繁请求的那个请求方,都会被拒绝掉,有种株连九族的意味。

  于是,你就想,当然不可能让其他的系统认为是接口挂了,你可以返回一些message,告诉用户,出现了什么问题,应该采取什么措施,同时触发一些异常处理,比如发邮件呀,IM通知,短信通知呀,其实最好的是电话通知。暂时性的拒绝用户的请求,比 等服务器崩溃之后重启,所引发的损失要小一点(这个要看实际情况)。

  聪明的你一下就想到,可以为每一个系统颁发一个token,他们每次访问接口的时候,都会想判断token是否合法,之后会记录该服务在单位时间内访问该接口的次数,如果超过某个规定的阀值(每个系统的阀值可以不同,可以针对优先级设置),就阻止下一次携带着这个token的请求。这样的话,也不会妨碍其他用户的访问,是一个不错的办法。

  如果采用上面的做法,可能会遇到这种情况:各个接口的阀值都没超,但是多个接口或者其他的服务,综合起来,总量却是超过了负载,一下服务器就崩了,各种通知呀,全都没法运行了,其实一般不会存在这个问题的,因为一般都会有个资源超过某个值就会触发报警。但是,你的系统 和 操作系统 不是等同的呀,有时候,没报警,但是你的服务就是挂了,你能咋办,干瞪眼呀。你可常见的做法,“探活”,即 每个多长时间,请求一次某个资源,如果响应5xx,就触发报警

  

posted @ 2018-05-22 15:58  寻觅beyond  阅读(7481)  评论(0编辑  收藏  举报
返回顶部