在看公司的代码框架底层时,发现了一个问题,如下:
代码中调用接口时,使用的是curl,框架将curl资源以IP :端口的形式缓存了下来,例如:
10.10.10.10:80 curl1
10.10.10.10:8080 curl2
有点不太理解原因,所以作了两个实验,过程如下:
实验一:两个curl请求相同域名下的不同接口
实验二:一个curl请求相同域名下的不同接口
//两个curl请求相同域名的不同接口 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com/"); curl_setopt($ch, CURLOPT_HEADER, 0); $r = curl_exec($ch); $ch1 = curl_init(); curl_setopt($ch1, CURLOPT_URL, "http://www.baidu.com/img/bdlogo.gif"); curl_setopt($ch1, CURLOPT_HEADER, 0); $r1 = curl_exec($ch1);
用strace跟踪系统调用,然后过滤里面有用的信息,命令如下:
strace php cron_test.php 1 >b 2>a egrep "(fcntl|socket|sendto|connect|recvfrom)" a
结果如下:
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("61.135.169.125")}, 16) = -1 EINPROGRESS (Operation now in progress) sendto(3, "GET / HTTP/1.1\r\nHost: www.baidu."..., 52, MSG_NOSIGNAL, NULL, 0) = 52 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Fri, 15 N"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 1990 recvfrom(3, "round-image:url(http://s1.bdstat"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 2896 recvfrom(3, "www.baidu.com%2F\" target=\"_blank"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 1448 recvfrom(3, "http://baike.baidu.com\">\347\231\276\347\247\221</"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 1448 recvfrom(3, "sp;<a onmousedown=\"return ns_c({"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 2896 recvfrom(3, "1&ie=utf-8&s=s'],'tj_baike': ['w"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 1792 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 4 fcntl(4, F_GETFL) = 0x2 (flags O_RDWR) fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0 connect(4, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("61.135.169.125")}, 16) = -1 EINPROGRESS (Operation now in progress) sendto(4, "GET /img/bdlogo.gif HTTP/1.1\r\nHo"..., 66, MSG_NOSIGNAL, NULL, 0) = 66 recvfrom(4, "HTTP/1.1 200 OK\r\nDate: Fri, 15 N"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 2080
//一个curl请求相同域名下的两个接口 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com/"); curl_setopt($ch, CURLOPT_HEADER, 0); $r1 = curl_exec($ch); curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com/img/bdlogo.gif"); $r2 = curl_exec($ch);
用strace跟踪系统调用,然后过滤里面有用的信息,命令如下:
strace php cron_test.php 1 >b 2>a egrep "(fcntl|socket|sendto|connect|recvfrom)" a
结果如下:
connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("61.135.169.105")}, 16) = -1 EINPROGRESS (Operation now in progress) sendto(3, "GET / HTTP/1.1\r\nHost: www.baidu."..., 52, MSG_NOSIGNAL, NULL, 0) = 52 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Fri, 15 N"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 618 sendto(3, "GET /img/bdlogo.gif HTTP/1.1\r\nHo"..., 66, MSG_NOSIGNAL, NULL, 0) = 66 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Fri, 15 N"..., 16384, MSG_NOSIGNAL, NULL, NULL) = 2080
以上代码中,红色部分为两个实验的区别
可以看出,请求两个相同域名的接口时,用两个curl时,建立了两次连接,而用一个curl时,共用了一次连接
缓存curl可以节省一次网络连接
这就是为什么要缓存curl资源的原因。