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

Что такое распределенная система?

3.0 Senior🔥 191 комментариев
#REST API и микросервисы

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

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

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

Что такое распределённая система?

Распределённая система — это набор независимых компьютеров (узлов) или процессов, которые работают параллельно и взаимодействуют между собой через сеть для достижения общей цели. При этом каждый узел имеет собственную память, процессор и может выполнять операции независимо от других.

Определение и характеристики

Ключевые признаки распределённой системы:

  1. Множество автономных компонентов — каждый узел может функционировать независимо
  2. Отсутствие глобальных часов — синхронизация времени между узлами сложна
  3. Сетевое взаимодействие — узлы общаются через сетевые протоколы
  4. Отказоустойчивость — выход из строя одного узла не должен повалить всю систему
  5. Масштабируемость — система должна работать при добавлении новых узлов

Архитектура распределённой системы

┌─────────────┐        ┌─────────────┐        ┌─────────────┐
│   Node 1    │<------>│   Node 2    │<------>│   Node 3    │
│ Process 1   │ Network │ Process 2   │ Network │ Process 3   │
│ Memory 1    │        │ Memory 2    │        │ Memory 3    │
└─────────────┘        └─────────────┘        └─────────────┘
       ^                     ^                       ^
       |                     |                       |
       └─────────────────────┴───────────────────────┘
              Взаимодействие через сеть

Примеры распределённых систем

// 1. Микросервисная архитектура
API Gateway ---> UserService (Node 1)
            ---> OrderService (Node 2)
            ---> PaymentService (Node 3)

// 2. Распределённая база данных (шардирование)
DB Shard 1: users 1-1000
DB Shard 2: users 1001-2000
DB Shard 3: users 2001-3000

// 3. Кластер веб-серверов
Load Balancer ---> Tomcat Server 1
              ---> Tomcat Server 2
              ---> Tomcat Server 3

Основные проблемы распределённых систем

1. Теорема CAP

Система не может одновременно гарантировать три свойства:

CA (Consistency + Availability)
└─ Все узлы имеют актуальные данные (C)
└─ Система всегда отвечает (A)
└─ Но не работает при разделении сети (нет P)

CP (Consistency + Partition tolerance)
└─ Данные согласованы (C)
└─ Система работает при разделении сети (P)
└─ Но может быть недоступна (нет A)

AP (Availability + Partition tolerance)
└─ Система доступна (A)
└─ Работает при разделении сети (P)
└─ Но может быть временная несогласованность (нет C)

Пример выбора:

  • Банки выбирают CP — согласованность важнее доступности
  • Социальные сети выбирают AP — доступность важнее идеальной согласованности

2. Отказы и сбои

// Узел может выйти из строя в любой момент
public class RemoteServiceClient {
    public String callRemoteService(String url) throws Exception {
        try {
            // Узел может быть недоступен
            return httpClient.get(url);
        } catch (ConnectException e) {
            // Сеть может быть недоступна
            // Другой узел может обработать запрос
            return fallbackToOtherNode();
        } catch (SocketTimeoutException e) {
            // Ответ может прийти с задержкой
            return retryWithBackoff();
        }
    }
}

3. Задержки в сети

Сетевая задержка может быть переменной и непредсказуемой:

// Даже "быстрые" операции имеют задержку
long startTime = System.currentTimeMillis();
String response = remoteService.getData(); // Минимум несколько миллисекунд
long latency = System.currentTimeMillis() - startTime;

// В локальной системе эта операция была бы микросекундной!

4. Синхронизация данных

// Проблема: как синхронизировать состояние между узлами?
public class DistributedCache {
    // Node 1 обновляет cache
    cache.put("user:123", user1);
    
    // Node 2 имеет старое значение
    User user = cache.get("user:123"); // Может быть устаревшим!
}

// Решение: консистентность в конечном итоге (eventual consistency)
public class EventuallyConsistentCache {
    // Node 1 публикует событие
    eventBus.publish(new UserUpdatedEvent(123, user1));
    
    // Node 2 получает событие и обновляет кэш
    @EventListener
    public void onUserUpdated(UserUpdatedEvent event) {
        cache.put("user:" + event.getUserId(), event.getUser());
    }
}

Паттерны и технологии

1. RPC (Remote Procedure Call)

// Вызов функции на удалённом узле
public interface RemoteCalculator {
    int add(int a, int b);
}

// Server
public class RemoteCalculatorImpl implements RemoteCalculator {
    public int add(int a, int b) {
        return a + b;
    }
}

// Client
RemoteCalculator calculator = RpcProxy.create(RemoteCalculator.class, "server:9999");
int result = calculator.add(5, 3); // Вызов на удалённом сервере

2. REST API

// Каждый узел предоставляет REST API
@RestController
@RequestMapping("/api")
public class OrderController {
    @GetMapping("/orders/{id}")
    public Order getOrder(@PathVariable Long id) {
        return orderService.findById(id);
    }
}

// Другой узел вызывает API
RestTemplate rest = new RestTemplate();
Order order = rest.getForObject("http://service1:8080/api/orders/123", Order.class);

3. Message Queue (очередь сообщений)

// Асинхронное взаимодействие через очередь

// Producer (Node 1)
public class OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    public void createOrder(Order order) {
        // Отправляем событие в очередь
        rabbitTemplate.convertAndSend("orders.exchange", "order.created", order);
    }
}

// Consumer (Node 2)
@Component
public class OrderEventListener {
    @RabbitListener(queues = "order.queue")
    public void handleOrderCreated(Order order) {
        // Обрабатываем событие асинхронно
        emailService.sendConfirmation(order);
    }
}

Примеры в Java

Apache Kafka (распределённая потоковая платформа)

public class KafkaProducerExample {
    public void publishEvent(String topic, String message) {
        KafkaTemplate kafkaTemplate = new KafkaTemplate(producerFactory);
        kafkaTemplate.send(topic, message);
    }
}

public class KafkaConsumerExample {
    @KafkaListener(topics = "events", groupId = "my-group")
    public void consume(String message) {
        System.out.println("Received: " + message);
    }
}

Apache ZooKeeper (координация узлов)

public class ZooKeeperCoordinator {
    private ZooKeeper zk;
    
    public void registerService(String serviceName, String serviceUrl) 
            throws KeeperException, InterruptedException {
        String path = "/services/" + serviceName;
        zk.create(path, serviceUrl.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, 
                  CreateMode.EPHEMERAL);
    }
    
    public List<String> discoverServices(String serviceName) 
            throws KeeperException, InterruptedException {
        String path = "/services/" + serviceName;
        return zk.getChildren(path, true);
    }
}

Преимущества и недостатки

Преимущества:

  • Масштабируемость горизонтальная
  • Отказоустойчивость
  • Лучшее использование ресурсов
  • Расширяемость

Недостатки:

  • Сложность разработки и отладки
  • Проблемы с консистентностью данных
  • Увеличенная задержка (latency)
  • Сложность операций и мониторинга

Распределённые системы — это основа современного масштабируемого ПО, но требуют глубокого понимания их проблем и паттернов решения.

Что такое распределенная система? | PrepBro