php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法

本文实例讲述了php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法。分享给大家供大家参考,具体如下:

微信支付api.mch.weixin.qq.com域名解析慢了,导致付款时非常的慢,那么要如何来解决微信支付慢的问题呢,这里就来一起分析一下。

有朋友在阿里云主机实现微信支付逻辑时,发现api.mch.weixin.qq.com的解析实在是太慢了。

因此出现了手动修改/etc/hosts的情况,当然了,哪天微信支付要是换个机房肯定要挂。

我们的机房也有相似的同题,专门记录一下。

代码里用curl来请求微信,经常超时,这时使用wget试验:

[root@01 tmp]# wget api.mch.weixin.qq.com
--2016-06-18 14:51:03-- http://api.mch.weixin.qq.com/
Resolving api.mch.weixin.qq.com...

域名解析很久不出来

测试确认是ipv6问题

给wget加上-4,强制使用ipv4,如果很快,那基本上确定是ipv6惹的祸了。

[root@01 tmp]# wget -4 api.mch.weixin.qq.com
--2016-06-18 17:03:52-- http://api.mch.weixin.qq.com/
Resolving api.mch.weixin.qq.com... 123.151.71.149, 123.151.79.109
Connecting to api.mch.weixin.qq.com|123.151.71.149|:80... connected.

代码分析

专门写个代码来测试ipv6的解析,用到系统函数getaddrinfo:

#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <iostream>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
using namespace std;
int main() {
  struct addrinfo hints,*answer,*curr,*p;
  int error;
  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_INET6;//AF_UNSPEC; // use AF_INET6 to force IPv6
  hints.ai_socktype = SOCK_STREAM;//SOCK_DGRAM; // SOCK_STREAM
  if ((error = getaddrinfo("api.mch.weixin.qq.com", NULL, &hints, &answer)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
    return 1;
  } else cout <<"Success with a URL\n";
  char ipstr[16];
  for (curr = answer; curr != NULL; curr = curr->ai_next) {
    inet_ntop(AF_INET,&(((struct sockaddr_in *)(curr->ai_addr))->sin_addr),ipstr, 16);
    printf("%s\n", ipstr);
  }
  freeaddrinfo(answer);
  return 0;
}

包含头文件

netdb.h

函数原型:

int getaddrinfo( const char hostname, const char service, const struct addrinfo *hints, struct addrinfo **result );

参数说明:

hints:可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息。而是否ipv6则由ai_family决定。
result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针。

返回值:0——成功,非0——出错

测试结果:

ai_family为ipv6时,只会寻找ipv6的解析结果,一般域名也没设置。ai_family为AF_UNSPEC时,会先ipv6再ipv4的,而api.mch.weixin.qq.com这个域名的ipv6解析出奇的慢(qq.com却不慢,原因见后)。

解决办法:

如果是curl,c可以强制指定ipv4,使用curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

其他语言的也参考此法。

深层原因分析

nslookup -query=AAAA api.mch.weixin.qq.com -debug 是找不到解析的(指定的AAAA就是ipv6),然后会发现一个SOA声明和他的上级weixin.qq.com有一个ipv6的CNAME,到了minorshort.weixin.qq.com,而这域名又是没有ipv6的解析的。

目测ipv6找解析时是在这个SOA和CNAME的地方打圈了,微信的同学们是不是考虑让大伙好过一点,把这些个域名的ipv6设置去掉。

dig @ns-tel1.qq.com weixin.qq.com AAAA
weixin.qq.com.    43200  IN  SOA ns-tel1.qq.com. webmaster.qq.com. 1293502040 300 600 86400 300

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP微信开发技巧汇总》、《PHP编码与转码操作技巧汇总》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

时间: 2016-10-09

PHP随机获取未被微信屏蔽的域名(微信域名检测)

用户名和KEY请到www.weixin139.com获取 <?php $url = "https://api.weixin139.com/weixin/domain/auto_check_list?user=xxx&key=xxx&type=1"; $con = get_msg($url); $data = json_decode($con,true); $count = count($data)-1; $rand = rand(0,$count); echo $

Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解

前言: 前段时间有一个关于通过获取用户当前经纬度坐标,计算出该用户距离某指定地点之间的距离.因为做这个项目需要能够获取到比较精确的经纬度坐标,刚开始使用的是百度地图结果发现百度地图地位不太准确(有时候相差的比较的大,后来了解到了百度获取用户经纬度与用户当前使用的网络有很大的关系),后来换成了高德地图结果还是一样.最后我想刚好做的是个微信网站项目,为什么不使用微信自带接口呢?所以最后使用了微信JS-SDK来获取用户当前地理位置的接口. 微信JS-SDK的使用步骤,配置信息的生成获取讲解: 关于JS

四种数据库随机获取10条数据的方法

四种数据库随机获取10条数据的方法 SQL Server: 复制代码 代码如下: SELECT TOP 10 * FROM T_USER ORDER BY NEWID() ORACLE: 复制代码 代码如下: SELECT * FROM (SELECT * FROM T_USER ORDER BY DBMS_RANDOM.RANDOM()) WHERE RONUM <= 10 MySQL: 复制代码 代码如下: SELECT * FROM T_USER  ORDER BY  RAND() LIM

mongodb中随机获取1条记录的实现方法

实现原理如下 1.先查询表中的记录总数 2.随机获取偏移量为0~总记录数-1 3.查询时skip偏移量,再获取1条记录 因本人测试环境php已升级到7.0以上,mongodb扩展使用支持php7.0以上的扩展,很多方法与php5.6不同.因此代码必须在php7.0以上运行.如果是php5.6环境,需要修改代码才能运行. 代码如下: function.php <?php // 连接mongodb function conn($host, $user, $passwd){ $server = 'mo

php随机获取金山词霸每日一句的方法

本文实例讲述了php随机获取金山词霸每日一句的方法.分享给大家供大家参考.具体实现方法如下: header('Content-Type:text/html; charset=utf-8'); $nowyear=date("Y"); $nowmouth = date('m'); $nowday = date('d'); $date = mt_rand("2012",$nowyear)."-".mt_rand("1",$nowmo

PHP实现在数据库百万条数据中随机获取20条记录的方法

本文实例讲述了PHP实现在数据库百万条数据中随机获取20条记录的方法.分享给大家供大家参考,具体如下: 额,为什么要写这个? 在去某个公司面试时,让写个算法出来,当时就蒙了,我开发过程中用到算法的吗?又不是大数据开发,分析. 今天偶然想起来一个坑爹数据,如:PHP取百万条数据中随机20条记录,当时就用的算法. 1.先统计统计数据库多少条记录(这个做个数据缓存,如1小时重新统计一次), 2.根据总条数,随机1次,1次性取出20条记录(当然这个就相当于分页了,要求不高的话,这个最快,我用的就是这个)

mongodb 随机获取一条记录的方法

原理: 1.先查询表中的记录总数 2.随机获取偏移量为0~总记录数-1 3.查询时skip偏移量,再获取1条记录 因本人测试环境PHP已升级到7.0以上,mongodb扩展使用支持php7.0以上的扩展,很多方法与php5.6不同.因此代码必须在php7.0以上运行.如果是php5.6环境,需要修改代码才能运行. 代码如下: function.php <?php // 连接mongodb function conn($host, $user, $passwd){ $server = 'mongo

Android实现获取未接来电和未读短信数量的方法

本文实例展示了Android实现获取未接来电和未读短信数量的方法,在Android程序开发中非常常见,是非常实用的功能,现分享给大家供大家参考.具体如下: 一.未读短信   首先注册Observer,当有新短信或彩信来的时候会调用 onChange方法,我们可以在onChange方法中去获取未读短信和彩信,然后做一些UI上的处理! 具体功能代码如下: private ContentObserver newMmsContentObserver = new ContentObserver(new H

Android 获取未安装的APK图标、版本号、包名等信息方法

一.获取APK图标 public static Drawable getApkIcon(Context context, String apkPath) { PackageManager pm = context.getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo a

wordpress自定义标签云与随机获取标签的方法详解

wp_tag_cloud() 函数的作用是用来标签云的,可以根据每个标签所关联的文章次数来定义字体大小.标签排序等属性.从 2.8 版本开始,添加了 分类法(taxonomy)参数,这就意味着,除了 标签(tags)以外,还可以将 分类(Categories) 或其他 自定义分类法(Custom Taxonomies)作为"云"显示. 用法 <?php wp_tag_cloud( $args ); ?> 默认用法 <?php $args = array( 'small