详细Nginx和PHP-FPM的进程间通信使用

详细Nginx和PHP-FPM的进程间通信使用

工作中考虑到PHP-FPM效率,发现PHP-FPM和NGINX的进程通信不止配置端口这一种方式:bowtie:

Nginx和PHP-FPM的进程间通信有两种方式,一种是TCP,一种是UNIX Domain Socket.

其中TCP是IP加端口,可以跨服务器.而UNIX Domain Socket不经过网络,只能用于Nginx跟PHP-FPM都在同一服务器的场景.

介绍Unix Domain Socket

Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信。socket 原本是为网络通讯设计的,但后来在 socket 的框架上发展出一种 IPC 机制,就是 UNIX domain socket。虽然网络 socket 也可用于同一台主机的进程间通讯(通过 loopback 地址 127.0.0.1),但是 UNIX domain socket 用于 IPC 更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC 机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。

UNIX domain socket 是全双工的,API 接口语义丰富,相比其它 IPC 机制有明显的优越性,目前已成为使用最广泛的 IPC 机制,比如 X Window 服务器和 GUI 程序之间就是通过 UNIX domain socket 通讯的。

Unix domain socket 是 POSIX 标准中的一个组件,所以不要被名字迷惑,linux 系统也是支持它的。

用哪种取决于你的PHP-FPM配置:

方式1:
php-fpm.conf: listen = 127.0.0.1:9000
nginx.conf: fastcgi_pass 127.0.0.1:9000;

方式2:
php-fpm.conf: listen = /tmp/php-fpm.sock
nginx.conf: fastcgi_pass unix:/tmp/php-fpm.sock;

其中php-fpm.sock是一个文件,由php-fpm生成,类型是srw-rw----

创建文件:touch php-fpm.sock
创建套接字文件:nc -Ul php-fpm.sock
r = 4
w = 2
x = 1
生成权限:chmod 660 /tmp/php-fpm.sock

注意: 需要配置权限

nginx.conf

  • user www www
  • worker_processes auto

php-fpm.conf

php-fpm.conf 走 sock形式,需要开启监听

  • listen.owner = www
  • listen.group = www
  • listen.mode = 0660

文件属性

d 开头是: 目录文件。 l 开头是: 符号链接(指向另一个文件,类似于瘟下的快捷方式)。 s 开头是: 套接字文件(sock)。 b 开头是: 块设备文件,二进制文件。 c 开头是: 字符设备文件。 p 开头是: 命名管道文件。

UNIX Domain Socket可用于两个没有亲缘关系的进程,是目前广泛使用的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的.这种通信方式是发生在系统内核里而不会在网络里传播.

UNIX Domain Socket和长连接都能避免频繁创建TCP短连接而导致TIME_WAIT连接过多的问题.

对于进程间通讯的两个程序,UNIX Domain Socket的流程不会走到TCP那层,直接以文件形式,以stream socket通讯.

如果是TCP Socket,则需要走到IP层,对于非同一台服务器上,TCP Socket走的就更多了.

UNIX Domain Socket:

Nginx <=> socket <=> PHP-FPM

TCP Socket(本地回环):

Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM

TCP Socket(Nginx和PHP-FPM位于不同服务器):

Nginx <=> socket <=> TCP/IP <=> 物理层 <=> 路由器 <=> 物理层 <=> TCP/IP <=> socket <=> PHP-FPM

像mysql命令行客户端连接mysqld服务也类似有这两种方式:

# 使用Unix Socket连接(默认):
mysql -uroot -p --protocol=socket --socket=/tmp/mysql.sock

# 使用TCP连接:
mysql -uroot -p --protocol=tcp --host=127.0.0.1 --port=3306

胡梦旭博客
请先登录后发表评论
  • latest comments
  • 总共0条评论