Categories: Технологии

Что такое Unix Domain Socket: секретный туннель в Linux

В нашем путешествии по миру сокетов мы начали с «верхнего этажа» — WebSocket в браузере, затем спустились к фундаменту интернета — TCP/IP сокетам. Но есть еще один, особый вид сокетов, который живет глубоко в недрах вашего сервера и о котором часто забывают.

Вы наверняка видели в конфигах Nginx или MySQL странные пути, оканчивающиеся на .sock, например /var/run/php/php8.2-fpm.sock. Это не картинка, не текстовый файл и не папка. Это — Unix Domain Socket (UDS). В этой статье я расскажу, почему эти «файлы» являются секретным оружием для ускорения локальной коммуникации.

 

Аналогия: Почта против Записки

Чтобы понять разницу между TCP-сокетом и Unix-сокетом, представим офис.

  • TCP/IP Сокет (127.0.0.1:80): Вы хотите передать документ коллеге, который сидит за соседним столом. Вы кладете документ в конверт, пишете адрес офиса, клеите марку, бросаете в почтовый ящик. Почта сортирует его и приносит обратно в ваш офис вашему коллеге. Это надежно, но бессмысленно долго, если вы в одной комнате.
  • Unix Сокет (/tmp/mysql.sock): Вы просто передаете документ коллеге прямо в руки. Никаких конвертов, адресов, марок и почтальонов.

 

Как это работает технически?

Unix-сокет — это стандартный механизм межпроцессного взаимодействия (IPC) в POSIX-совместимых системах (Linux, macOS). В отличие от сетевых сокетов, использующих IP-адреса и порты, Unix-сокеты используют файловую систему как адресное пространство.

Вот почему они быстрее:

  • Нет сетевого оверхеда: Ядру ОС не нужно создавать TCP-пакеты, считать контрольные суммы, управлять порядком пакетов и подтверждением доставки (ACK).
  • Прямое копирование памяти: Данные просто копируются из буфера одной программы в буфер другой через ядро.
  • Меньше переключений контекста: Процессор выполняет меньше лишних операций.

 

Безопасность: права доступа как у файлов

Это одно из главных преимуществ. Так как Unix-сокет отображается как файл в файловой системе, к нему применяются стандартные права доступа Linux (chmod, chown).

Например, если у вас есть файл сокета базы данных /tmp/mysql.sock, вы можете настроить права так, что только пользователь www-data (ваш веб-сервер) сможет в него писать. Любой другой пользователь на сервере даже не сможет попытаться подключиться к базе. С TCP-портом (например, 3306) это сделать сложнее — он открыт для всех на localhost.

 

Практическое применение: где мы это используем?

 

1. Nginx + PHP-FPM

Это классика. В моей статье про FastCGI мы настраивали связь между веб-сервером и PHP. Вы можете сделать это двумя способами:

Метод Конфигурация Nginx Когда использовать
TCP Сокет fastcgi_pass 127.0.0.1:9000; Если Nginx и PHP-FPM на разных серверах (распределенная архитектура).
Unix Сокет fastcgi_pass unix:/var/run/php/php-fpm.sock; Если они на одном сервере. Дает прирост производительности.

 

2. Docker Daemon

Вы когда-нибудь задумывались, как Docker CLI общается с самим Docker движком? По умолчанию это происходит через Unix-сокет /var/run/docker.sock. Именно поэтому, чтобы запустить Docker без sudo, вам нужно добавить пользователя в группу, имеющую права на этот файл-сокет.

 

3. Базы данных (MySQL, PostgreSQL, Redis)

Если ваш сайт подключается к базе данных на том же сервере («localhost«), использование сокета (localhost:/tmp/mysql.sock) будет быстрее, чем подключение через TCP (127.0.0.1:3306).

 

Практика: общаемся через файл-сокет на Python

Давайте создадим сервер, который слушает не порт, а файл. Обратите внимание на использование socket.AF_UNIX вместо AF_INET.

Код сервера (unix_server.py)
import socket
import os
socket_path = "/tmp/demo_socket.sock"
# Убедимся, что файл сокета не существует
if os.path.exists(socket_path):
    os.remove(socket_path)
# Создаем Unix-сокет (AF_UNIX)
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Привязываем к файлу
server.bind(socket_path)
# Слушаем
server.listen(1)
print(f"Слушаю на {socket_path}")
while True:
    connection, client_address = server.accept()
    try:
        print("Соединение установлено!")
        data = connection.recv(1024)
        print(f"Получено: {data.decode()}")
        connection.sendall(b"Hello from Unix Socket!")
    finally:
        connection.close()

Клиент для такого сервера выглядит почти так же, только вместо IP и порта он подключается к пути файла:

client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client.connect("/tmp/demo_socket.sock")
client.sendall(b"Hello Server!")

 

Вывод: локальный герой

Unix Domain Sockets — это незаменимый инструмент для оптимизации высокопроизводительных систем. Они убирают лишних посредников в общении программ на одном компьютере.

Если ваши сервисы (веб-сервер, база данных, кэш) живут на одной машине, всегда отдавайте предпочтение Unix-сокетам перед TCP. Это бесплатный и простой способ снизить задержки (latency) и нагрузку на процессор.

 

Recent Posts

Сетевые сокеты (Network Sockets): фундамент интернета 🌐 | Глубокое погружение

В предыдущей статье мы говорили о WebSockets — технологии, позволяющей создавать интерактивные чаты в браузере.…

22 часа ago

Как ухаживать за кожей малыша летом и зимой

Кожа младенца – тонкая и нежная. Еще не справляется с защитой организма от внешних факторов.…

2 дня ago

Что такое Сокеты (WebSocket) 🔌 | подробно для начинающих

Представьте себе телефонный разговор. Вы звоните другу, он поднимает трубку, и вы можете говорить одновременно,…

3 дня ago

Мобильный воркстейшн: может ли планшет 📱 заменить ноутбук веб-разработчику?

Долгое время планшеты воспринимались исключительно как устройства для потребления контента: посмотреть YouTube, полистать ленту новостей…

4 дня ago

Как принудительно обновить кэш у пользователей 🧹 | Практические методы

Вы внесли правки в CSS, исправили критический баг в JavaScript, загрузили файлы на сервер и…

6 дней ago

HTTP-заголовки кэширования (Cache-Control) 🚀 — подробный обзор

Представьте, что вы каждое утро приходите в одно и то же кафе и спрашиваете бариста:…

7 дней ago