前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >parallel-request-testing

parallel-request-testing

作者头像
魔王卷子
发布2020-02-17 07:41:34
4530
发布2020-02-17 07:41:34
举报

并行请求测试

因为我们想要做底层服务,那么肯定会有一个对外的接口中会有好几个调用底层的接口。按照传统做法,就只能是串行请求。下面我做了一个测试。测试使用各种方法连续请求10次,看看总的统计时间,来确定使用哪种方案。

使用版本:

  • PHP: 7.3.8
  • PHP-Swoole: 4.4.8
  • PHP-cURL: 7.65.3
  • Node.js:
  • GoLang:

串行读取

首先呢,就是PHP的默认串行读取了。接下来直接看脚本吧:

代码语言:javascript
复制
$urls = [
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
];

foreach($urls as $item) {
    geturl($item);
}
	
function geturl($url){
       
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS      => 5,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL => "http://" . $url,
        ]);
        
        $output = curl_exec($ch);
        curl_close($ch);
 
        var_dump(strlen($output));
}

执行时间:

代码语言:javascript
复制
real    0m1.150s
user    0m0.045s
sys     0m0.040s

CURL并发请求

代码语言:javascript
复制
$urls = [
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
];

$rolling_window = count($urls);
 
$master   = curl_multi_init();
$curl_arr = array();
 
$std_options = array(
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_MAXREDIRS      => 5,
    CURLOPT_RETURNTRANSFER => true,
);

$options = $std_options;
 
for ($i = 0; $i < $rolling_window; $i++) {
    $ch                   = curl_init();
    $options[CURLOPT_URL] = "http://" . $urls[$i];
    curl_setopt_array($ch, $options);
    curl_multi_add_handle($master, $ch);
}

$result = [];

do {
    while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
    if ($execrun != CURLM_OK) {
        break;
    }

    while ($done = curl_multi_info_read($master)) {
        $info = curl_getinfo($done['handle']);
        $output = curl_multi_getcontent($done['handle']);
        var_dump(strlen($output));
        curl_multi_remove_handle($master, $done['handle']);
    }
} while ($running);
 
curl_multi_close($master);

执行时间:

代码语言:javascript
复制
real    0m0.246s
user    0m0.081s
sys     0m0.173s

Swoole 协程请求

代码语言:javascript
复制
Swoole\Runtime::enableCoroutine();

$urls = [
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
    "cn.bing.com",
];

$chan = new chan(count($urls));

go(function() use($chan, $urls) {
    foreach($urls as $item) {
        var_dump($chan->pop());
    }
});

foreach($urls as $url) {
    go(function() use($chan, $url) {
        $cli = new Swoole\Coroutine\Http\Client('cn.bing.com', 80);
        $ret = $cli->get('/');

        $chan->push([$url => strlen($cli->getBody())]);
    });
}

执行时间:

代码语言:javascript
复制
real    0m0.140s
user    0m0.019s
sys     0m0.031s

Golang协程

代码语言:javascript
复制
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	ch := make(chan string)

	urls := []string{
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
		"https://www.baidu.com",
	};

	for _, url := range urls {
		go fetch(url, ch) // start a goroutine
	}
	for range urls {
		<-ch
	}
}

func fetch(url string, ch chan<- string) {
	resp, err := http.Get(url)
	if err != nil {
		ch <- fmt.Sprint(err) // send to channel ch
		return
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	resp.Body.Close()
	ch <- string(len(body))
}

执行时间:0.185s

NodeJS

代码语言:javascript
复制
const axiso = require('axios');
const urls = [
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
    "https://www.baidu.com",
];

async function fetchAll() {
  const promiseAll=[];
  urls.forEach(url => {
      promiseAll.push(fetch(url));
  });
  const res = await Promise.all(promiseAll);
  res.forEach(val=>{
    //   console.log(val.data.length);
  })
}

async function fetch(url) {
  return axiso.get(url)
}

fetchAll();

运行时间 0.344s

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-292,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并行请求测试
    • 使用版本:
      • 串行读取
        • CURL并发请求
          • Swoole 协程请求
            • Golang协程
              • NodeJS
              相关产品与服务
              命令行工具
              腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档