在文章开始前,先介绍一个背景。著名的异步框架 async 中有一个 waterfall 方法(官方示例),该方法用于控制异步的流程非常直观而且方便,就像下面这样: async.waterfall([ function Task1(callback) { callback(null, 'a'); }, function Task2(last, callback) { // last now equals 'a' callback(null, 'b'); }, function Task3(last, callback) { // last now…

代理 ip 因为配置简单而且廉价,经常用来作为反反爬虫的手段,但是稳定性一直是其诟病。筛选出优质的代理 ip 并不简单,即使付费购买的代理 ip 源,卖家也不敢保证 100% 可用;另外代理 ip 的生命周期也无法预知,可能上一秒能用,下一秒就扑街了。基于这些原因,会给使用代理 ip 的爬虫程序带来很多不稳定的因素。要排除代理 ip 的影响,通常的做法是建一个代理 ip 池,每次请求前来池子取一个 ip,用完之后归还,保证池子里的 ip 都是可用的。…

好像在我们团队建立的初期,那还是两年多前,就有了打枪的传统。噢,这里要解释一下,这个打枪是指在手机上的FPS(第一人称射击)游戏,不是那个意思啦。那时还是玩BIA2(兄弟连),这个游戏太老了,以至于后面IOS升级后没法玩,官方也出了BIA3,但是联机不是这个游戏的特长,所以有很长的一段时间,打枪文化逐渐消退了。直到最近两个月,发现CFM(穿越火线手游版)可以联机实时PK,我们的这个文化又浮出了水面。每天中午吃完饭休息的时候都要来个三局两胜。你以为这篇是要介绍CFM,那就真的错了,下面我要给大家介绍一下我们打枪背后的那些事,其实就是我们的打枪计分系统。 计分系统1.0 这个计分系统的发起人是Johnny,Johnny喜欢数据,什么都喜欢搞个报表,他一开始的想法是搞个Excel,把我们每局的比分记下来,然后可以看到每个人的发挥趋势和排名;…

当Web请求发起时,会先查看本地是否有该资源已缓存的副本,如果有,就直接从本地读取,而不需要从原始服务器中获取该资源。这样一来可以非常有效地减少冗余的数据传输,也可以减轻原始服务器的请求压力。下图就是一个请求的神奇之旅: 左边虚线框都是在缓存层完成,大部分情况下是指浏览器内部的缓存机制,也可以指一些缓存代理服务,如CDN等(本文不讨论);右边虚线框都是在服务器端完成的。 下面就按照这个流程图,客户端使用Chrome浏览器打开Google(但愿你看到的不是404 not found)来演示不同场景下的请求。 缓存未命中 这是最简单的场景,所有资源都是从服务器返回,就好像没有缓存这一层一样。通常是资源从来没有请求过,或者在请求头部指明不使用缓存。Chrome开发者工具有个很方便的功能,就是可以设置当打开开发者工具时禁用缓存: 它的原理很简单,就是在每个请求前加上不使用缓存的头部cache-control: no-cache和pragma: no-cache: 在给静态文件打版本号还没流行的时候,这个办法也常用来更新静态文件的缓存,即用Ajax设置cache-control:…