Освоение микросервисов: популярные вопросы на собеседовании и советы экспертов

  1. Что такое микросервисы и чем они отличаются от монолитной архитектуры?
    Микросервисы — это архитектурный стиль программного обеспечения, в котором приложения состоят из небольших, независимо развертываемых сервисов, которые работают вместе для выполнения более крупных бизнес-функций. В отличие от монолитной архитектуры, микросервисы обеспечивают слабую связь, масштабируемость и независимую разработку каждого сервиса. Вот пример простого микросервиса, написанного на Node.js:
// Example microservice
const express = require('express');
const app = express();
app.get('/api/users', (req, res) => {
  // Retrieve and return users from the database
});
app.post('/api/users', (req, res) => {
  // Create a new user in the database
});
app.listen(3000, () => {
  console.log('Microservice listening on port 3000');
});
  1. Как микросервисы взаимодействуют друг с другом?
    Микросервисы взаимодействуют с помощью облегченных протоколов, таких как API-интерфейсы RESTful или очереди сообщений. API-интерфейсы RESTful обычно используются для синхронной связи, когда одна служба отправляет HTTP-запрос другой службе. С другой стороны, очереди сообщений облегчают асинхронную связь, позволяя службам отправлять и получать сообщения. Вот пример использования вызовов RESTful API для взаимодействия между службами:
// Service A making an HTTP request to Service B
const axios = require('axios');
axios.get('http://service-b/api/data')
  .then(response => {
    // Process the response from Service B
  })
  .catch(error => {
    // Handle the error
  });
  1. Как обеспечить отказоустойчивость в архитектуре микросервисов?
    Чтобы обеспечить отказоустойчивость, микросервисы используют такие методы, как избыточность, автоматические выключатели и постепенное ухудшение. Избыточность предполагает запуск нескольких экземпляров службы для обеспечения высокой доступности. Автоматические выключатели обнаруживают сбои и предотвращают каскадные сбои, временно останавливая запросы к неисправной службе. Плавное ухудшение предполагает предоставление альтернативных функций или ответов, когда служба недоступна. Вот пример использования библиотеки Hystrix для реализации автоматических выключателей на Java:
// Circuit breaker configuration
HystrixCommandProperties.Setter()
  .withCircuitBreakerEnabled(true)
  .withCircuitBreakerErrorThresholdPercentage(50)
  .withCircuitBreakerRequestVolumeThreshold(20)
  .withCircuitBreakerSleepWindowInMilliseconds(5000);
// Service call wrapped in a Hystrix command
HystrixCommand<String> command = new HystrixCommand<String>(
    HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) {
  protected String run() {
    // Make the service call
  }
  protected String getFallback() {
    // Provide a fallback response
  }
};
  1. Как можно обеспечить обнаружение сервисов в архитектуре микросервисов?
    Обнаружение сервисов имеет решающее значение для динамического обнаружения сервисов и взаимодействия с ними. Один из популярных подходов — использование реестра служб, например Netflix Eureka или HashiCorp Consul. Эти реестры позволяют службам регистрироваться самостоятельно и служат центральной точкой для обнаружения и подключения других служб. Вот пример использования Netflix Eureka с Spring Cloud в микросервисе Java:
// Service registration with Eureka
@EnableEurekaClient
@SpringBootApplication
public class UserServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(UserServiceApplication.class, args);
  }
}
  1. Как обеспечить масштабируемость в архитектуре микросервисов?
    Масштабируемость микросервисов может быть достигнута за счет горизонтального масштабирования, контейнеризации и балансировки нагрузки. Горизонтальное масштабирование предполагает добавление дополнительных экземпляров службы для обработки возросшей нагрузки. Контейнеризация с использованием таких технологий, как Docker и Kubernetes, позволяет развертывать сервисы и управлять ими согласованным и масштабируемым образом. Балансировка нагрузки распределяет входящий трафик между несколькими экземплярами службы для оптимизации производительности. Вот пример использования NGINX в качестве балансировщика нагрузки для микросервисов:
# NGINX configuration for load balancing
http {
  upstream microservices {
    server microservice1.example.com;
    server microservice2.example.com;
    server microservice3.example.com;
  }
  server {
    listen 80;
    location / {
      proxy_pass http://microservices;
    }
  }
}