首页 > 其他分享 >01 | Swoole与Go系列教程之HTTP服务的应用

01 | Swoole与Go系列教程之HTTP服务的应用

时间:2024-03-19 23:04:50浏览次数:30  
标签:01 http Swoole Go HTTP PHP php

首发原文链接: Swoole与Go系列教程之HTTP服务的应用

大家好,我是码农先森。

写在前面

PHP 曾是Web开发领域佼佼者,随着业务壮大,异步和高并发方面不足显现。Swoole 曾经尝试填补空白,但局限性也比较的明显。Go 语言的崛起,简洁语法和并发优势吸引大厂使用,吸引了大多数程序员的转型。疫情、战争、大环境的恶化等因素加剧了互联网行业内卷,PHP 程序员陷入了困境,因此转型 Go 语言是不二的选择。我从 PHP 转型Go,深知转型之难。因此致力于帮助其他 PHP 程序员转型,分享经验。困境时需抱团取暖,才能走过黎明前的黑暗。

HTTP 协议原理

HTTP 协议是一种用于传输超文本(如HTML)的应用层协议。它是Web通信的基础,负责在客户端和服务器之间传递请求和响应。HTTP 使用 TCP 作为传输协议,通常使用 80 端口进行通信。如下图所示 HTTP 协议在 TCP/IP 网络模型中是处于应用层,是 TCP/IP 协议的一个子集。

HTTP 协议撑起了互联网的大半江山,可以说没有 HTTP 协议就没有当下的互联网。作为一名 Web 程序的开发者,深入掌握和理解 HTTP 协议尤为重要。下面这张图是表示了 HTTP 的请求报文、响应报文格式,其实相对于其他的协议来说,HTTP 协议是比较简单了,同时也是最常用的。

原生 PHP 的实现

使用 PHP 的内置 HTTP 模块启动服务

php -S 内置服务器实际上是基于CLI(Command Line Interface)SAPI。当执行php -S命令时,PHP 会以命令行模式启动一个轻量级服务器,监听指定的IP地址和端口。但是,这种内置的服务器并不适合用于生产环境,它是为了便于开发和测试而提供的工具。如果是在生产环境上,建议部署 PHP-FPM,再通过 Nginx 做反向代理的方式实现。

1、代码文件 index.php

<?php

// 设置HTTP响应头,告知浏览器返回的是文本内容
header('Content-Type: text/plain');

// 输出 "Hello, World!" 作为响应
echo "Hello, World! For PHP Module";

2、启动

MacBook-Pro:demo$ php -S 127.0.0.1:8080
[Sat Jul 22 10:30:42 2023] PHP 8.2.5 Development Server (http://127.0.0.1:8080) started

3、访问

MacBook-Pro:demo$ curl http://127.0.0.1:8080
Hello, World! For PHP Module

使用 Socket 的方式启动 HTTP 服务

Socket 是一种用于在网络中进行通信的编程接口。它允许程序在网络上通过 IP 地址和端口号与其他计算机建立连接,从而实现数据的传输和交换。 Socket 是一种低层次的网络编程接口,支持 TCP、UDP、IPv4、IPv6 协议,不能直接支持应用层协议,例如 HTTP 协议等。因此,这里通过使用 Socket 创建一个 TCP 服务器来处理 HTTP 请求。

1、代码文件 socket.php

<?php
$host = 'localhost';  // 如果需要,可以将此处更改为你服务器的IP地址
$port = 8080;         // 服务器监听的端口

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    echo "无法创建Socket: " . socket_strerror(socket_last_error()) . PHP_EOL;
    exit(1);
}

socket_bind($socket, $host, $port) or die('无法绑定到指定地址');

socket_listen($socket);
echo "服务器监听在 $host:$port..." . PHP_EOL;

while (true) {
    $client = socket_accept($socket);
    
    // 读取客户端的请求
    $request = socket_read($client, 4096);

    // 处理请求(为简单起见,我们只处理GET请求)
    if (preg_match("/GET (.*) HTTP\/1\.1/", $request, $matches)) {
        $uri = $matches[1];
        $response = "HTTP/1.1 200 SUCCESS\r\n\r\nHello World! For PHP Socket\r\n";
    }

    // 将响应发送给客户端
    socket_write($client, $response);
    
    // 关闭客户端连接
    socket_close($client);
}

2、启动

MacBook-Pro:demo$ php socket.php 
服务器监听在 localhost:8080...

3、访问

MacBook-Pro:demo$ curl http://127.0.0.1:8080
Hello World! For PHP Socket

Swoole 扩展的实现

Swoole 使用底层 C++ 实现,充分利用了异步非阻塞的网络模型,能够处理大量并发连接,极大地提高了 HTTP 服务的性能。通过事件循环和异步处理,避免了 PHP 单进程模型的瓶颈。

每一个用户的 HTTP 请求,将由 Master 进程分配到 Worker 进程进行处理,不阻塞主进程的执行;同时,每个 Worker 进程内部会将请求协程化,避免阻塞 worker 进程,这种模式极大的提高了服务的处理能力,如下图源代码中对应使用协程来实现发送数据。

1、代码文件 swoole_http.php

<?php
// 创建HTTP服务器对象,监听在0.0.0.0:8080端口
$http = new Swoole\Http\Server("0.0.0.0", 8080);

// 设置 Worker 数量
$http->set([
    'worker_num' => 3
]);

// 在启动事件中执行初始化设置
$http->on('start', function ($server) {
    echo "Swoole HTTP服务器已启动\n";
});

// 监听HTTP请求事件
$http->on('request', function ($request, $response) {
    // 处理请求
    $response->status(200);
    $response->end("Hello World! For Swoole HTTP\r\n");
});

// 启动HTTP服务器
$http->start();

2、启动

MacBook-Pro:demo$ php swoole_http.php 
Swoole HTTP服务器已启动

3、访问

MacBook-Pro:demo$ curl http://127.0.0.1:8080
Hello World! For Swoole HTTP

Go 语言的实现

Go 语言的轻量级线程Goroutine,能够快速处理大量并发请求。Goroutine 的创建和销毁非常快速,在单个物理线程上可以同时运行成千上万个 Goroutine。并且可以高效的利用多核 CPU,充分的使用物理资源。http.ListenAndServe 启动并监听一个 HTTP 服务,客户端与服务端建立连接后,服务端会交由一个 Goroutine 处理,下面这张图是对应 Go Http 模块源代码的处理逻辑。

1、代码文件 main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    // 处理请求
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, World! For Go")
    })

    // 启动HTTP服务,监听在本地的8080端口
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println("Error starting server:", err)
    }
}

2、启动

MacBook-Pro:demo$ go run main.go

3、访问

MacBook-Pro:demo$ curl http://127.0.0.1:8080
Hello, World! For Go

总结

  1. 在 PHP 语言层面启动 HTTP 服务并不适合,通常需要结合 PHP-FPM、Nginx 等服务。
  2. Swoole 作为用 C++ 实现的扩展,弥补了 PHP 在异步通信及并发层面的不足,但是,在单进程的模式下无法高效的利用多核 CPU,不能充分的榨干物理资源。
  3. Go 语言是高并发领域的一支独秀,天然支持高并发,并且能够充分的利用物理资源。

标签:01,http,Swoole,Go,HTTP,PHP,php
From: https://blog.csdn.net/yxhbk/article/details/136764431

相关文章

  • http内网穿透CYarp[开源]
    0前言在物联网领域中,mqtt消息一直是海量设备连接到平台的标配协议,而平台向移动端开放的操作接口往往是http协议,这就要求平台为两种协议作消息一一适配。在某些情况下,这些设备是有操作系统的linux或安卓设备,如果我们换个思路,让这些设备直接提供http协议的操作接口(httpd服务器),平......
  • P3714 [BJOI2017] 树的难题
    fromxcs题意:给定一棵\(n\)个节点的树,树根为\(1\),每个点有一个编号,每条边有一个边权。定义\(dep(x)\)表示一个点到根简单路径上边权的和,\(lca(x,y)\)表示\(x,y\)节点在树上的最近公共祖先。共\(m\)组询问,每次询问给出\(l,r\),求对于所有点编号的二元组\((i,j)\)......
  • Devops-01-devops 是什么?
    拓展阅读Devops-01-devops是什么?Devops-02-Jpom简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件代码质量管理SonarQube-01-入门介绍项目管理平台-01-jira入门介绍缺陷跟踪管理系统,为针对缺陷管理、任务追踪和项目管理的商业性应用软件项目管理平台-01-Phab......
  • [SCOI2011][洛谷P3275] 糖果
    本来这是一道差分约束板子题/水题SPFA-BFS和SPFA-DFS都能过BFS#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllN=100005;#definemax(a,b)((a)>(b)?(a):(b))#definemin(a,b)((a)<(b)?(a):(b))structedge{ intto,next,w;}e[N*1000]......
  • SQLServer CLR程序集创建Http函数
    设计程序集-SQLServer|MicrosoftLearnMicrosoft.VisualBasic.dllMicrosoft.VisualC.dllmscorlib.dllSystem.dllSystem.Configuration.dllSystem.Core.dllSystem.Data.dllSystem.Data.OracleClient.dllSystem.Data.SqlXml.dllSystem.Deployment.dllSyst......
  • Windows server 2019 英文版镜像和中文版镜像Debian12.4镜像
    Windowsserver2019英文镜像​​​​​​​​​https://sl-m-ssl.xunlei.com/h5/page/download-share/index.html?entry=link&appType=PC&videobtindex=-1&storid=czvvdfq66ast&share_from=leftlist_rk_shareWindowsserver2019英文镜像https://pan.xunlei.com/s/VNtDquO1......
  • Qt+vs2019+PCL1.12.1+VTK9.1环境搭建中的相关问题
    目录1.VS中双击Ui文件无法打开2.VTK9.0以后在QtDesigner中找不到QVTKWidget组件3.无法打开源文件"QVTKOpenGLNativeWidget.h"4.无法打开源文件"QOpenGLWidget"5.QWidget:MustconstructaQApplicationbeforeaQWidget6.无法打开源文件"QtWidgets/QApplicati......
  • 为什么说HTTPS比HTTP安全? HTTPS是如何保证安全的?
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助一、安全特性在上篇文章中,我们了解到HTTP在通信过程中,存在以下问题:通信使用明文(不加密),内容可能被窃听不验证通信方的身份,因此有可能遭遇伪装而HTTPS的出现正是解决这些问题,HTTPS是建立在SSL之上,其安全性由SSL......
  • JavaScript笔记 01
    目录01js概述02js代码的基本使用03js变量的基本使用04变量的类型05数值类型06字符串类型07布尔类型08 使用typeof查看变量的类型09其他类型转换为字符串类型10其他数据类型转换为数值型11其他数据类型转换成布尔类型12小知识点01js概述前端的三......
  • 010_域名和域名系统
    目录域名解析系统DNS域名解析过程域名解析系统DNS域名解析过程......