PHP はシステム プログラミング用にローカル ソケット (Unix ドメイン ソケット) を実装します。
この記事で共有する内容は、システム プログラミングの PHP 実装におけるローカル ソケット (Unix ドメイン ソケット) に関するもので、必要な場合は参照してください。
ソケット API は元々、問題を解決するために設計されました。ネットワークの問題 通信のために設計され、その後、Unix ドメイン ソケットと呼ばれる技術が派生しました。その名前が示すように、ローカル ソケットは 2 つのローカル プロセス間の通信のみをサポートしますが、ネットワーク ソケット (インターネット ドメイン ソケット) はローカル相互接続も実現できます。ローカル ループバック アドレス (127.0.0.1) を介して通信を処理しますが、ローカル ソケットはネットワーク プロトコル スタック、パケットのアンパック、チェックサムの計算、その他の操作を通過する必要がないため、ネットワーク ソケットに比べて特定の利点があります。効率の観点から。ローカル ソケットは高性能、安定性が高く、血液に関係のないプロセス間通信をサポートしているため、最も広く使用されている IPC (プロセス間通信) メカニズムの 1 つでもあります。
ネットワークソケット (127.0.0.1:9000) を使用した場合とローカルソケットを使用した場合の Nginx と PHP-FPM のパフォーマンスの比較
一般的に、Nginx と PHP は明らかに PHP-FPM モニター 127.0.0.1:9000 を使用します。 -FPM は現時点ではネットワーク ソケットを介して通信します。実際、Nginx と PHP-FPM が同じサーバー上で実行されている場合、PHP-FPM にローカル ソケットを監視させることもできます。これら 2 つの方法のパフォーマンスを簡単に比較してみましょう。 。
ここで、私のNginxは2つのワーカープロセスを開始します
[root@localhost ~]# ps -ef | grep nginx root 1838 1 0 22:48 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 1839 1838 0 22:48 ? 00:00:00 nginx: worker process nginx 1840 1838 0 22:48 ? 00:00:00 nginx: worker process root 1851 1797 0 22:49 pts/0 00:00:00 grep nginx
ネットワークソケットを使用したNginxとPHP-FPMの構成は次のとおりです:
ストレステストtest.phpスクリプト
<?php phpinfo();
ストレステストの結果:
Nginx と PHP を見てみましょう - FPM はローカル ソケット通信を使用し、Nginx と PHP-FPM の構成が少し変更されています:
ストレステストの結果:
結果から、ローカルソケットはネットワークソケットと比較して平均的なQPSを持っていることがわかります。 100 ポイント以上高く、これは基本的に私たちの予想と一致しています。
PHPのローカルソケットプログラミング
実際、PHPのローカルソケットプログラミングは、渡されるパラメーターが異なることを除いて、基本的にネットワークソケットと同じです。
PHP は、ソケット プログラミング用に 2 つの API セットを提供します。1 つは、以前の一連の記事で説明した、socket_* シリーズのメソッドで、もう 1 つは、stream_socket_* シリーズのメソッドです。便宜上、ここでは後者をデモンストレーションに使用します。
stream_socket_* メソッドリスト:
•stream_socket_accept — 接受由 stream_socket_server 创建的套接字连接 •stream_socket_client — Open Internet or Unix domain socket connection •stream_socket_enable_crypto — Turns encryption on/off on an already connected socket •stream_socket_get_name — 获取本地或者远程的套接字名称 •stream_socket_pair — 创建一对完全一样的网络套接字连接流 •stream_socket_recvfrom — Receives data from a socket, connected or not •stream_socket_sendto — Sends a message to a socket, whether it is connected or not •stream_socket_server — Create an Internet or Unix domain server socket •stream_socket_shutdown — Shutdown a full-duplex connection
具体的なメソッドについてはPHPマニュアルを参照してください。直接のデモコードは次のとおりです:
サーバーコード:
<?php //stream_server.php $sockfile = '/dev/shm/unix.sock'; // 如果sock文件已存在,先尝试删除 if (file_exists($sockfile)) { unlink($sockfile); } $server = stream_socket_server("unix://$sockfile", $errno, $errstr); if (!$server) { die("创建unix domain socket fail: $errno - $errstr"); } while(1) { $conn = stream_socket_accept($server, 5); if ($conn) { while(1) { $msg = fread($conn, 1024); if (strlen($msg) == 0) //客户端关闭 { fclose($conn); break; } echo "read data: $msg"; fwrite($conn, "read ok!"); } } } fclose($server);
クライアントコード:
<?php //stream_client.php $client = stream_socket_client("unix:///dev/shm/unix.sock", $errno, $errstr); if (!$client) { die("connect to server fail: $errno - $errstr"); } while(1) { $msg = fread(STDIN, 1024); if ($msg == "quit\n") { break; } fwrite($client, $msg); $rt = fread($client, 1024); echo $rt . "\n"; } fclose($client);
运行
server端:
[root@localhost html]# php stream_server.php read data: hello unix domain socket read data: are you ok? read data: I'm fine! PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13 PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13 PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13 PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13 PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13 PHP Warning: stream_socket_accept(): accept failed: Connection timed out in /usr/share/nginx/html/stream_server.php on line 13
client端:
[root@localhost html]# php stream_client.php hello unix domain socket read ok! are you ok? read ok! I'm fine! read ok! ^C
以上是一个最简单的本地套接字的代码演示,细心的读者可能注意到了server端报的warning,服务器如果长时间没有客户端过来连接,超过了stream_socket_accept 方法设置的timeout,服务器端便会报这个警告,事实上,真正的服务端代码是不会是像这样写的,因为这种方式同一时间只能处理一个客户端连接,如果要实现并发,一种方式就是使用IO多路复用,如同 socket_* 系列方法中有socket_select 方法 (参考系列文章第一篇http://blog.csdn.net/zhang197093/article/details/77366407),stream_socket_* 系列方法提供了 stream_select 方法来实现多路复用,使用方法也很相似。
int stream_select ( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] )
The stream_select() function accepts arrays of streams and waits for them to change status. Its operation is equivalent to that of the socket_select() function except in that it acts on streams.
详细的方法介绍请参考PHP手册 : http://php.net/manual/zh/function.stream-select.php
优化后的代码如下:
<?php //stream_server.php $sockfile = '/dev/shm/unix.sock'; // 如果sock文件已存在,先尝试删除 if (file_exists($sockfile)) { unlink($sockfile); } $server = stream_socket_server("unix://$sockfile", $errno, $errstr); if (!$server) { die("创建unix domain socket fail: $errno - $errstr"); } $listen_reads = array($server); $listen_writes = array(); $listen_excepts = NULL; while(1) { $can_reads = $listen_reads; $can_writes = $listen_writes; $num_streams = stream_select($can_reads, $can_writes, $listen_excepts, 0); if ($num_streams) { foreach ($can_reads as &$sock) { if ($server == $sock) { $conn = stream_socket_accept($server, 5); //此时一定存在客户端连接,不会有超时的情况 if ($conn) { // 把客户端连接加入监听 $listen_reads[] = $conn; $listen_writes[] = $conn; } } else { $msg = fread($sock, 1024); //此时一定是可读的 if (strlen($msg) == 0) //读取到0个字符,说明客户端关闭 { fclose($sock); // 从sock监听中移除 $key = array_search($sock, $listen_reads); unset($listen_reads[$key]); $key = array_search($sock, $listen_writes); unset($listen_writes[$key]); echo "客户端关闭\n"; } else { echo "read data: $msg"; // 是否可写 if (in_array($sock, $can_writes)) { fwrite($conn, "read ok!"); } } } } } } fclose($server);
此时这个server就不会有前面那个Warning了,并且支持并发
[root@localhost html]# php stream_server.php read data: hello world read data: hello unix domain socket read data: harry up read data: read data: read data: I'm another client 客户端关闭 客户端关闭 read data: I'm the third client 客户端关闭
That‘s all!
相关推荐:
以上がPHP はシステム プログラミング用にローカル ソケット (Unix ドメイン ソケット) を実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

CakePHP へのログインは非常に簡単な作業です。使用する関数は 1 つだけです。 cronjob などのバックグラウンド プロセスのエラー、例外、ユーザー アクティビティ、ユーザーが実行したアクションをログに記録できます。 CakePHP でのデータのログ記録は簡単です。 log()関数が提供されています

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

CakePHP はオープンソースの MVC フレームワークです。これにより、アプリケーションの開発、展開、保守がはるかに簡単になります。 CakePHP には、最も一般的なタスクの過負荷を軽減するためのライブラリが多数あります。
