Unix domain socket 与 TCP/IP 是两种独立机制,服务端需显式监听本地路径(如 /tmp/myapp.sock),客户端用相同路径连接;支持与否取决于启动参数而非配置文件,且路径权限、存在性及命名空间隔离(如 Docker/systemd)是连接成败关键。
Socket 连接不是“配置 TCP/IP 的替代选项”
unix domain socket(af_unix)和 tcp/ip(af_inet)是两类完全不同的底层通信机制,不存在“把 tcp 改成 socket”的配置操作。所谓“用 socket 连接服务器”,本质是服务端必须显式监听一个本地文件路径(如 /tmp/myapp.sock),客户端也必须用该路径发起连接——它不走网络协议栈,也不依赖 ip 或端口。
服务端是否支持 Unix socket,取决于启动方式而非配置文件
常见服务(如 PostgreSQL、Redis、Nginx、Gunicorn)对 Unix socket 的支持是硬编码在启动逻辑里的,不是靠改个 config.yml 就能开启。你得确认它启动时用了 --unix-socket、unix_socket_directories、bind 路径含 .sock 等明确标识。
- PostgreSQL:需在
postgresql.conf中设置unix_socket_directories = '/tmp',且listen_addresses可为''(空字符串)或不含localhost - Redis:启动时加
-s /tmp/redis.sock,或配置unixsocket /tmp/redis.sock - Gunicorn:用
--bind unix:/tmp/gunicorn.sock,不能混用--bind 127.0.0.1:8000和 socket 同一进程 - 如果你用的是自己写的 Python/Go 服务,必须调用
socket.socket(socket.AF_UNIX, ...)并bind()到文件路径,而不是AF_INET
客户端连接时路径权限和存在性比“怎么写代码”更关键
90% 的“连接失败”不是代码写错,而是:/tmp/myapp.sock 文件不存在、权限不对(比如服务以 root 启动,客户端普通用户访问被拒)、路径父目录不可执行(chmod 755 /tmp 才能进入)、或服务根本没监听这个路径。
- 检查是否存在:
ls -l /tmp/myapp.sock - 检查可访问性:
stat /tmp && stat /tmp/myapp.sock(看 uid/gid 和 mode) - Python 客户端示例(不用 requests,用原生 socket):
import socket<br>s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)<br>s.connect('/tmp/myapp.sock')<br>s.send(b'PING')<br>print(s.recv(1024)) - curl 不支持 Unix socket;
wget也不行;要用nc -U /tmp/myapp.sock或专用工具如socat
别在 Docker 或 systemd 场景下默认假设 socket 能自动透传
Docker 容器间、或 systemd 服务之间共享 Unix socket,需要显式挂载或配置,不是“同主机就能通”。容器默认无法访问宿主机的 /tmp/*.sock,除非用 -v /tmp:/tmp;systemd 服务若设了 PrivateTmp=yes(默认值),它的 /tmp 是隔离的,根本看不到其他服务建的 socket 文件。
- Docker:宿主机 socket 路径必须通过
-v映射,且注意 SELinux/AppArmor 可能拦截 - systemd:查
systemctl show myservice | grep PrivateTmp;若为yes,要么关掉,要么把 socket 放到/run下并配RuntimeDirectory= - 路径建议优先用
/run/myapp.sock(tmpfs,自动清理),而非/tmp(可能被清理或权限混乱)










