← Назад к вопросам

Будет ли один процесс знать что делает другой процесс?

1.8 Middle🔥 71 комментариев
#Node.js и JavaScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Коммуникация между процессами (IPC)

Это фундаментальный вопрос об изоляции процессов и inter-process communication (IPC). Краткий ответ: по умолчанию нет, но есть механизмы для коммуникации.

Основной принцип: Изоляция процессов

Операционная система намеренно изолирует процессы друг от друга:

# Запуск двух независимых Node.js приложений
node app1.js &  # Процесс 1 (PID: 1234)
node app2.js &  # Процесс 2 (PID: 1235)

# Процесс 1 НЕ знает о существовании процесса 2
# Процесс 2 НЕ знает о существовании процесса 1

Почему это нужно:

  • Безопасность — один процесс не может повредить другой
  • Стабильность — крах одного не влияет на другой
  • Ресурсы — каждый имеет свою память и файловые дескрипторы

Когда процессы могут общаться

Если нам нужна коммуникация между процессами, мы должны явно установить механизм обмена данными.

Способ 1: Environment Variables и File System

// process1.ts
import fs from 'fs';

const data = { status: 'processing', timestamp: Date.now() };
fs.writeFileSync('/tmp/process1_state.json', JSON.stringify(data));
console.log('Process 1 wrote state to file');
// process2.ts
import fs from 'fs';

setInterval(() => {
  try {
    const data = fs.readFileSync('/tmp/process1_state.json', 'utf-8');
    const state = JSON.parse(data);
    console.log('Process 2 sees Process 1 state:', state);
  } catch (e) {
    console.log('Process 1 file not found yet');
  }
}, 1000);

Проблемы этого подхода:

  • Медленно (чтение с диска)
  • Race conditions при одновременной записи
  • Не масштабируется

Способ 2: Message Passing (TCP/HTTP)

// process1.ts (сервер на порту 3001)
import express from 'express';

const app = express();
let state = { count: 0, status: 'running' };

app.get('/api/state', (req, res) => {
  res.json(state);
});

app.post('/api/state', express.json(), (req, res) => {
  state = { ...state, ...req.body };
  res.json({ success: true });
});

app.listen(3001, () => {
  console.log('Process 1: listening on port 3001');
});

setInterval(() => {
  state.count++;
}, 1000);
// process2.ts (клиент)
import axios from 'axios';

const BASE_URL = 'http://localhost:3001/api/state';

setInterval(async () => {
  const response = await axios.get(BASE_URL);
  console.log('Process 2 sees state:', response.data);
  
  // Может изменить состояние
  await axios.post(BASE_URL, { status: 'paused' });
}, 2000);

Преимущества: ✅ Простая и понятная коммуникация ✅ Хорошо работает для distributed систем ✅ HTTP/REST стандартизирован

Недостатки: ⚠️ Сетевая latency ⚠️ Сложнее при высокой частоте обмена

Способ 3: Message Queue (Redis, RabbitMQ)

Это правильный способ для production систем.

// process1.ts (producer)
import redis from 'redis';

const client = redis.createClient({ url: 'redis://localhost:6379' });
await client.connect();

setInterval(async () => {
  const message = {
    from: 'process1',
    timestamp: Date.now(),
    data: { temperature: 25 },
  };
  
  // Отправляем сообщение в очередь
  await client.publish('system_channel', JSON.stringify(message));
  console.log('Process 1: published message');
}, 2000);
// process2.ts (consumer)
import redis from 'redis';

const client = redis.createClient({ url: 'redis://localhost:6379' });
await client.connect();

// Подписываемся на сообщения
await client.subscribe('system_channel', (message) => {
  const data = JSON.parse(message);
  console.log('Process 2 received:', data);
  
  // Можем обработать и ответить
  // Отправляем результат другому процессу
});

Преимущества: ✅ Масштабируется ✅ Асинхронная коммуникация ✅ Гарантия доставки ✅ Несколько подписчиков одновременно

Способ 4: Shared Memory (сложный, не рекомендуется)

# Linux поддерживает shared memory через /dev/shm
# Но это ОЧЕНЬ редко используется в Node.js

# Более современный способ — это native модули через N-API
# Но это слишком сложно для обычных задач

Способ 5: Child Process (в одном приложении)

Когда нам нужны несколько процессов в одном Node.js приложении:

// master.ts
import { fork } from 'child_process';

const worker1 = fork('./worker.js', { stdio: 'inherit' });
const worker2 = fork('./worker.js', { stdio: 'inherit' });

setInterval(() => {
  // Master знает о workers и может общаться с ними
  worker1.send({ command: 'update_count', value: 10 });
  worker2.send({ command: 'get_status' });
}, 2000);

// Слушаем ответы от workers
worker1.on('message', (msg) => {
  console.log('Worker 1 says:', msg);
});
// worker.ts
process.on('message', (msg) => {
  console.log('Worker received:', msg);
  
  if (msg.command === 'update_count') {
    console.log('Updating count to', msg.value);
  }
  
  if (msg.command === 'get_status') {
    // Отправляем ответ обратно
    process.send({ status: 'working', processed: 100 });
  }
});

Реальный пример: микросервисная архитектура

# Типичная setup
Service A (PID: 1001)  ->  API Gateway (localhost:3000)
                           ├── Service B (PID: 1002) на порту 3001
                           └── Service C (PID: 1003) на порту 3002
                           
                    Redis (localhost:6379) для pub/sub
// service-a.ts
const serviceB = axios.create({ baseURL: 'http://localhost:3001' });
const serviceC = axios.create({ baseURL: 'http://localhost:3002' });

app.post('/api/process', async (req, res) => {
  // Service A знает о Service B и C через HTTP
  const resultB = await serviceB.post('/process', { data: req.body });
  const resultC = await serviceC.post('/process', { data: resultB.data });
  
  res.json(resultC.data);
});

// Асинхронная коммуникация через Redis
await redisClient.publish('events', JSON.stringify({
  type: 'order_created',
  orderId: 123
}));

Таблица сравнения методов коммуникации

МетодLatencyМасштабируемостьСложностьКогда использовать
ФайлыНизкаяНетНизкаяРедко, для простых случаев
HTTP/RESTСредняяДаСредняяМикросервисы, API
Redis Pub/SubВысокаяДаСредняяAsync events, notifications
Redis QueueВысокаяДаСредняяTask queues, background jobs
Child ProcessОчень высокаяНетСредняяВнутри одного приложения
gRPCОчень высокаяДаВысокаяHigh-performance микросервисы

Best Practice в Node.js

// ❌ Плохо — два независимых процесса без коммуникации
node app1.js &
node app2.js &
# Они вообще не знают друг о друге

// ✅ Хорошо — явная коммуникация через API Gateway
node api-gateway.js &      # На порту 3000
node service-a.js &        # На порту 3001
node service-b.js &        # На порту 3002
# Gateway маршрутизирует запросы между сервисами

// ✅ Хорошо — асинхронная коммуникация через очередь
node worker-a.js &    # Слушает очередь в Redis
node worker-b.js &    # Слушает очередь в Redis
redis-server          # Центральная очередь
# Workers берут задачи из Redis и обрабатывают

Итоги

Нет, процессы по умолчанию не знают друг о друге. Но есть много механизмов для коммуникации:

HTTP/REST — для синхронной коммуникации между микросервисами ✓ Redis Pub/Sub — для асинхронных событий ✓ Message Queues — для надёжной доставки задач ✓ Child Process — для процессов внутри одного Node.js приложения ✓ gRPC — для высокопроизводительной RPC

Выбор метода зависит от требований: частота обмена, latency, надёжность, масштабируемость.

Будет ли один процесс знать что делает другой процесс? | PrepBro