?
使用php?snoopy在获取远程数据的时候,经常遇到远程站点不稳定或者是网络因素影响,造成读取数据失败或者返回时间过长的问题,本篇文章着重介绍一下大致的解决思路。
前段时间利用沈阳交通违章查询网的接口,做了一个简单的违章查询系统,并且在数据远程获取之前进行了缓存,开始设置的缓存时间为3天(因为沈阳交通违章查询网的数据每周更新一次)。这样运行了将尽3个月的时间,通过长时间的观察,发现交警队的数据源并不稳定,一周7天大约有2天网站是处于无法访问的状况,在缓存失效的情况下,经常会造成等待时间过长(大约30s),最后返回为空查询结果的问题。
?
这个问题非常影响用户体验,我也考虑了很长时间,解决思路如下:
1.对接口请求情况进行判断;
2.设置合理的超时时间。(根据远程站点响应速度,大约2-5s肯定会返回数据)
3.将最后一次成功查询结果写入数据表,接口失效的时候调用最后一次成功查询记录。
?
综合以上几点方法,基本可以解决这个问题。运行流程如下:
1.用户输入信息并提交查询请求
2.服务器端检测该查询资料是否缓存并有效,如果存在并有效则直接返回(最剩资源,不用去远程获取)
3.如果缓存不存在或者失效,则调用远程获取方法
4.远程获取方法使用php?snoopy进行获取远端数据,这里需要设置超时时间以及判断返回状态和是否超时。
$snoopy = new Snoopy; $snoopy->read_timeout=4; //读取超时时间
?
if ($snoopy->status>0&& $snoopy->status== '200' && !$snoopy->timed_out) { //这里是读取成功的处理逻辑 }else{ //这里是远程接口出问题的时候的处理逻辑 }
?首先说明一下,$snoopy->status是远程返回的状态码,成功返回的应该是200,其他情况下返回的都应该是错误的,并且有效的请求状态应该是大于0的,$snoopy->timed_out在未超时的情况下值为false,如果读取请求超时的话,返回值应该为true。
5.如果接口请求不超时,直接进行最新的数据处理,并删除该资料有关的最后一次查询结果,并将最新的查询结果写入数据库。
/** * 写入最后一次查询记录 * @param type $cache_data 传递过来的最新查询结果 */ private function write_last_info($cache_data){ $car_info=$cache_data['car_info']; $M=M('SyCar'); $info=$M->where("wz_car_no='{$car_info['wz_car_no']}'")->find(); if(empty($info)){ $car_info['wz_datetime']= get_date_full(time()); $car_info['wz_car_memo']= session('memo'); $M->add($car_info); }else{ if($info['wz_car_memo']!=session('memo')){ $info['wz_car_memo']=session('memo'); $M->save($info); } } unset($info); unset($M); $M=M('SyCarlastweizhang'); $M->where("wz_car_no='{$car_info['wz_car_no']}'")->delete(); foreach ($cache_data['weizhang_info'] as $key => $value) { $value['wz_car_no']=$car_info['wz_car_no']; $value['input_time']= get_date_full(time()); $M->add($value); } unset($M); unset($cache_data); unset($M); }
?6.在远程接口获取失败的情况下,读取最后一次查询的结果
$weizhang_info=M('SyCarlastweizhang')->where("wz_car_no='{$car_no}'")->order("wz_datetime")->select(); if(empty($weizhang_info)){ $is_cache=false; $pop_info='远程数据获取失败,请您稍后在进行查询!'; } $cache_data = array( 'pop_info' => $pop_info, 'car_info' => $car_info, //获取远端返回的汽车信息 'weizhang_info' => $weizhang_info, //获取远端返回的违章记录数组 );
?顺便说一下,如果在最后一次查询结果的表中,该查询信息也不存在的话,那么只能遗憾的返回"远程数据获取失败,请您稍后在进行查询"的错误提示了。?其实这个地方也可以输出其他的提示语句。?
?
该篇文章已经基本上解决了远程站点接口不稳定影响的用户体验问题,更完善的处理逻辑还需要继续进行完善。希望该文章思路能对您有所帮助。
FROM:http://www.9it.me/article-128.html
?
?