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

简介: PHP 曾是Web开发领域佼佼者,随着业务壮大,异步和高并发方面不足显现。Swoole 曾经尝试填补空白,但局限性也比较的明显。Go 语言的崛起,简洁语法和并发优势吸引大厂使用,吸引了大多数程序员的转型。

大家好,我是码农先森。

写在前面

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 语言是高并发领域的一支独秀,天然支持高并发,并且能够充分的利用物理资源。

欢迎关注、分享、点赞、收藏、在看,我是微信公众号「码农先森」作者。

相关文章
|
1月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
130 3
|
1月前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
58 3
|
3月前
|
Java Maven Windows
使用Java创建集成JACOB的HTTP服务
本文介绍了如何在Java中创建一个集成JACOB的HTTP服务,使Java应用能够调用Windows的COM组件。文章详细讲解了环境配置、动态加载JACOB DLL、创建HTTP服务器、实现IP白名单及处理HTTP请求的具体步骤,帮助读者实现Java应用与Windows系统的交互。作者拥有23年编程经验,文章来源于稀土掘金。著作权归作者所有,商业转载需授权。
使用Java创建集成JACOB的HTTP服务
|
3月前
|
安全 网络协议 应用服务中间件
AJP Connector:深入解析及在Apache HTTP Server中的应用
【9月更文挑战第6天】在Java Web应用开发中,Tomcat作为广泛使用的Servlet容器,经常与Apache HTTP Server结合使用,以提供高效、稳定的Web服务。而AJP Connector(Apache JServ Protocol Connector)作为连接Tomcat和Apache HTTP Server的重要桥梁,扮演着至关重要的角色
91 2
|
22天前
|
前端开发 UED 开发者
CSS Sprites和图标字体在网页图标加载优化中的应用。CSS Sprites通过合并多图标减少HTTP请求,提升加载速度
本文探讨了CSS Sprites和图标字体在网页图标加载优化中的应用。CSS Sprites通过合并多图标减少HTTP请求,提升加载速度;图标字体则以字体形式呈现图标,便于调整样式。文章分析了两者的优缺点及应用场景,并提供了应用技巧和注意事项,旨在帮助开发者提升页面性能,改善用户体验。
23 5
|
1月前
|
缓存 安全 网络安全
HTTP/2与HTTPS在Web加速中的应用
HTTP/2与HTTPS在Web加速中的应用
|
1月前
|
Go UED
Go Web服务中如何优雅平滑重启?
在生产环境中,服务升级时如何确保不中断当前请求并应用新代码是一个挑战。本文介绍了如何使用 Go 语言的 `endless` 包实现服务的优雅重启,确保在不停止服务的情况下完成无缝升级。通过示例代码和测试步骤,详细展示了 `endless` 包的工作原理和实际应用。
47 3
|
1月前
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
51 13
|
1月前
|
JSON Go UED
Go Web服务中如何优雅关机?
在构建 Web 服务时,优雅关机是一个关键的技术点,它确保服务关闭时所有正在处理的请求都能顺利完成。本文通过一个简单的 Go 语言示例,展示了如何使用 Gin 框架实现优雅关机。通过捕获系统信号和使用 `http.Server` 的 `Shutdown` 方法,我们可以在服务关闭前等待所有请求处理完毕,从而提升用户体验,避免数据丢失或不一致。
25 1
|
1月前
|
缓存 安全 前端开发
HTTP 协议的请求方法在实际应用中有哪些注意事项?
【10月更文挑战第29天】HTTP协议的请求方法在实际应用中需要根据具体的业务场景和需求,合理选择和使用,并注意各种方法的特点和限制,以确保网络通信的安全、高效和数据的一致性。