很多服务都会使用 Unix Domain Socket 技术,特别是在本地进程间通信的场景中。本文来介绍一些常见的使用该技术的服务:

1. 数据库服务

PostgreSQL

  • Socket 文件: /tmp/.s.PGSQL.5432, /var/run/postgresql/.s.PGSQL.5432
  • 使用方式:
psql -h /var/run/postgresql -U postgres

Redis

  • Socket 文件: /tmp/redis.sock, /var/run/redis/redis-server.sock
  • 配置示例 (redis.conf):
unixsocket /tmp/redis.sock
unixsocketperm 755
  • 连接方式:
redis-cli -s /tmp/redis.sock

SQLite

  • 虽然 SQLite 是文件数据库,但一些封装工具可以使用 socket

2. Web 服务器和应用服务器

PHP-FPM

  • Socket 文件: /var/run/php/php8.1-fpm.sock, /tmp/php-fpm.sock
  • Nginx 配置示例:
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

uWSGI

  • Socket 文件: /tmp/uwsgi.sock
  • 配置示例:
[uwsgi]
socket = /tmp/uwsgi.sock
chmod-socket = 666
module = myapp:app

Gunicorn

  • Socket 文件: /tmp/gunicorn.sock
  • 启动命令:
gunicorn -b unix:/tmp/gunicorn.sock myapp:app

3. 容器和虚拟化

Docker

  • Socket 文件: /var/run/docker.sock
  • 用途: Docker 守护进程的 API 接口
  • 使用示例:
curl --unix-socket /var/run/docker.sock http://localhost/containers/json

Podman

  • 类似 Docker,也使用 socket 文件进行通信

4. 系统服务

systemd

  • Socket 文件: 各种 systemd 服务在 /run/systemd/ 目录下创建 socket 文件
  • 用途: 进程间通信和激活机制

D-Bus

  • Socket 文件: /var/run/dbus/system_bus_socket
  • 用途: 桌面环境和系统服务之间的消息总线

udev

  • Socket 文件: /run/udev/control
  • 用途: 设备管理通信

5. 包管理器

apt/dpkg

  • Socket 文件: 在包管理操作期间会创建临时 socket 文件进行进程间锁控制

6. 监控和日志服务

syslog-ng / rsyslog

  • 可以使用 socket 文件接收日志消息

collectd

  • 配置示例:
<Plugin unixsock>
  SocketFile "/var/run/collectd-unixsock"
  SocketGroup "collectd"
  SocketPerms "0770"
</Plugin>

7. 消息队列

ZeroMQ

  • 支持使用 Unix Socket 进行进程间通信

8. 版本控制系统

Git

  • 在某些配置下,Git 可以使用 socket 进行通信

实际应用场景示例

1. Docker 管理

# 通过 socket 与 Docker 守护进程通信
docker -H unix:///var/run/docker.sock ps

# 在容器内挂载 docker.sock 以实现 Docker-in-Docker

2. PHP-FPM + Nginx 架构

# Nginx 配置
server {
    listen 80;
    server_name example.com;
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

3. Python Web 应用部署

# 使用 uWSGI 启动应用
uwsgi --socket /tmp/myapp.sock --module myapp:app --chmod-socket=666

# Nginx 配置反向代理
location / {
    include uwsgi_params;
    uwsgi_pass unix:/tmp/myapp.sock;
}

4. Redis 本地访问优化

# 通过 socket 连接 Redis,性能更好
redis-cli -s /tmp/redis.sock

# 在应用配置中
redis_config = {
    'unix_socket_path': '/tmp/redis.sock'
}

为什么这些服务选择 Unix Socket?

  1. 性能优势: 避免网络协议栈开销
  2. 安全性: 通过文件系统权限控制访问
  3. 简单性: 配置和管理相对简单
  4. 可靠性: 仅限于本机通信,减少网络相关问题
  5. 轻量级: 资源消耗较少

检查系统中现有的 Socket 文件

# 查找所有 socket 文件
find /var/run /tmp -type s 2>/dev/null

# 使用 ss 命令查看
ss -lpx | grep unix

# 使用 netstat 查看
netstat -a | grep unix

Unix Domain Socket 是现代 Unix/Linux 系统中非常基础且重要的进程间通信机制,几乎所有的系统服务和许多应用服务都会用到它。