记一次某国企内外网数据同步的网络排查过程

某国企最近提了一个需求,在内网网站发布新闻的时候,需要同步到外网网站一份。这本来是一个很简单的需求,但考虑到新闻中包含的诸多图片,以及内网发布新闻时图片上传与发布操作并非同步进行,因此采用了转码的方式。即不管用户上传多少张图片,只在用户点击发布时获取到所有图片的绝对路径,并转为base64格式。在服务器端接收到内网发布的数据时,对图片资源可进行转码保存或直接使用。

但是问题发生在代码本地测试没问题,传到内网服务器后,发现内网发布新闻时,外网返回数据为空。以下是排查步骤。

1、鉴于内网服务器POST外网操作采用的是PHP的CURL方式,首先检查了PHP的扩展安装及开启情况。

2、考虑是否是CURL方法有误。这种情况多发生在header头与发送数据body不一致的时候,会导致接收端接收不到发送的数据。在排查的过程中除了我们自己写的curl请求方法之外,也可以多尝试一下其他网友的方法。有时候一个参数之差可能就需要排查老半天时间。非常耽误时间。

附赠:CURL发送网络请求方法一个,支持GET、POST及debug

  1. /**
  2.  * CURL请求
  3.  * @param $url 请求url地址
  4.  * @param $method 请求方法 get post
  5.  * @param null $postfields post数据数组
  6.  * @param array $headers 请求header信息
  7.  * @param bool|false $debug  调试开启 默认false
  8.  * @return mixed
  9.  */
  10. function httpRequest($url$method$postfields = null, $headers = array(), $debug = false) {
  11.     $method = strtoupper($method);
  12.     $ci = curl_init();
  13.     /* Curl settings */
  14.     curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  15.     curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
  16.     curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
  17.     curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
  18.     curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
  19.     switch ($method) {
  20.         case "POST":
  21.             curl_setopt($ci, CURLOPT_POST, true);
  22.             if (!emptyempty($postfields)) {
  23.                 $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
  24.                 curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
  25.             }
  26.             break;
  27.         default:
  28.             curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
  29.             break;
  30.     }
  31.     $ssl = preg_match('/^https:\/\//i',$url) ? TRUE : FALSE;
  32.     curl_setopt($ci, CURLOPT_URL, $url);
  33.     if($ssl){
  34.         curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
  35.         curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
  36.     }
  37.     //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
  38.     curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
  39.     curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
  40.     curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
  41.     curl_setopt($ci, CURLINFO_HEADER_OUT, true);
  42.     /*curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
  43.     $response = curl_exec($ci);
  44.     $requestinfo = curl_getinfo($ci);
  45.     $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
  46.     if ($debug) {
  47.         echo "=====post data======\r\n";
  48.         var_dump($postfields);
  49.         echo "=====info===== \r\n";
  50.         print_r($requestinfo);
  51.         echo "=====response=====\r\n";
  52.         print_r($response);
  53.     }
  54.     curl_close($ci);
  55.     return $response;
  56.     //return array($http_code, $response,$requestinfo);
  57. }

3、在外网服务器上写一个简单的接口,判断GET请求或POST请求后,返回请求类型(很简单的字符串能自己识别即可)。然后用POSTman或CURL请求方法进行发送数据测试。

我在测试过程中发现一个问题就是发送空数据的时候,外网接口返回了正常的返回结果。而发送模拟真实的数据时,外网又返回空白。任何提示都没有。

最后利用上述CURL封装的请求方法,开启debug后输出了一串乱码。经过解码找到了最终的原因:外网服务器的安全软件拦截了含有"Base64"字符串的请求。关掉安全软件后,数据正常录入外网数据库。

到此整个网络问题排查结束。

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!