从内置服务器角度看 PHP VS Go

本文借一个小 demo,从内置服务器角度,探讨一下 PHP 与 Go 的区别

PHP

新建一个 index.php 文件

<?php
	$request_type=$_GET['type']??0;
	$request_name=$_GET['name']??"";
	vprintf("请求 %s, 开始时间 %d \r\n",[$request_name,time()]);
	if ($request_type == "1") {
		sleep(30);
		vprintf("请求 %s, 结束时间 %d \r\n",[$request_name,time()]);
	} else {
		vprintf("请求 %s, 结束时间 %d \r\n",[$request_name,time()]);
	}
?>

然后执行如下命令,开启内置 http 服务器

php -S 127.0.0.1:1333

然后依次快速执行如下命令,模拟并发

# PHP由于阻塞,需要开启5个终端窗口分别执行观察效果
curl "127.0.0.1:1333?name=1&type=1"
curl "127.0.0.1:1333?name=2"
curl "127.0.0.1:1333?name=3"
curl "127.0.0.1:1333?name=4"
curl "127.0.0.1:1333?name=5"

得出如下输出:

请求 1, 开始时间 1652149508
请求 1, 结束时间 1652149538
请求 2, 开始时间 1652149538
请求 2, 结束时间 1652149538
请求 3, 开始时间 1652149538
请求 3, 结束时间 1652149538
请求 4, 开始时间 1652149538
请求 4, 结束时间 1652149538
请求 5, 开始时间 1652149538
请求 5, 结束时间 1652149538

由于请求1需要30秒的睡眠时间,导致请求 2、3、4、5进来时,全部都延迟处理了

可见 PHP 的内置服务器,正如官方文档上所说,是单线程的,同一时间,只能处理一个请求

The web server runs only one single-threaded process, so PHP applications will stall if a request is blocked.

翻译一下就是,内置的 web 服务器只运行了一个单线程,如果请求阻塞,PHP 应用就挂掉了

Go

package main

import (
	"fmt"
	"net/http"
	"net/url"
	"time"
)

func main() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		u, _ := url.Parse(request.URL.String())
		values, _ := url.ParseQuery(u.RawQuery)

		request_type := values.Get("type")
		request_name := values.Get("name")

		fmt.Printf("请求 %s, 开始时间 %d \r\n", request_name, time.Now().Unix())

		if request_type == "1" {
			time.Sleep(30 * time.Second)
			fmt.Printf("请求 %s, 结束时间 %d \r\n", request_name, time.Now().Unix())
		} else {
			fmt.Printf("请求 %s, 结束时间 %d \r\n", request_name, time.Now().Unix())
		}
	})
	http.ListenAndServe(":1333", nil)
}

同样的测试流程,输出内容如下:

请求 1, 开始时间 1652147934 
请求 2, 开始时间 1652147936 
请求 2, 结束时间 1652147936 
请求 3, 开始时间 1652147937 
请求 3, 结束时间 1652147937 
请求 4, 开始时间 1652147939 
请求 4, 结束时间 1652147939 
请求 5, 开始时间 1652147940 
请求 5, 结束时间 1652147940 
请求 1, 结束时间 1652147964 

请求1在睡眠30秒的时候,完全不影响请求2、3、4、5的处理

可见,Go 的内置服务器,是原生支持多线程的

Hyperf

据 Hyperf 官网介绍,Hyperf 是一个高性能、高灵活性的渐进式 PHP 协程框架

class IndexController extends AbstractController
{
   public function index()
   {
       // Hyperf 无法通过 $_GET 获取 URL 参数
       $request_type=$this->request->input('type');
       $request_name=$this->request->input('name');
       vprintf("请求 %s, 开始时间 %d \r\n",[$request_name,time()]);
       if ($request_type == "1") {
           sleep(30);
           vprintf("请求 %s, 结束时间 %d \r\n",[$request_name,time()]);
       } else {
           vprintf("请求 %s, 结束时间 %d \r\n",[$request_name,time()]);
       }
   }
}

使用 php bin/hyperf.php start 来启动,同样的测试流程,Hyperf 输出内容如下:

请求 1, 开始时间 1652232037 
请求 2, 开始时间 1652232039 
请求 2, 结束时间 1652232039 
请求 3, 开始时间 1652232040 
请求 3, 结束时间 1652232040 
请求 4, 开始时间 1652232041 
请求 4, 结束时间 1652232041 
请求 5, 开始时间 1652232042 
请求 5, 结束时间 1652232042 
请求 1, 结束时间 1652232067 

可见 Hyperf 也是能够实现请求的并发处理的

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值