Микросервисы и service mesh
			latest update of the page: 31-10-2024, 18:18 UTC
			
	Микросервисы (MSA)
	
		Микросервисная архитектура = метод создания распределённых приложений в виде набора независимо разрабатываемых и развёртываемых в изолированном окружении небольших служб. Является частным случаем SOA.
	
	
		Признаки микросервисной архитектуры:
		
			- Каждый сервис имеет свой домен (предметную область), сиречь занимается управлением своего собственного набора бизнес-сущностей либо своим особенным набором функций. Например, сервис формирования отчётов, сервис приёма данных в архив, сервис поиска и выдачи данных, сервис сбора метрик или логов. Поэтому такие сервисы и микро-.
 
			- Каждый сервис обычно разрабатывается отдельной командой, возможно даже в отдельном релизном цикле.
 
			- Каждый сервис имеет свой отдельный репозиторий. Команды не мешаются друг другу.
 
			- Каждый сервис имеет свой CI/CD/CDP pipeline и может быть отправлен в ПРОД независимо от других (идёт собственным дистрибутивом).
 
			- Каждый сервис может (но не обязан) включать в себя свой стек технологий. Например, один написан на Golang, другой на Java, третий на C# — на усмотрение команды разработки.
 
			- Каждый сервис имеет свою БД (и СУБД).
 
		
	
	
		Микросервисная архитектура изолирует сбои и повышает устойчивость системы. Монолитное приложение обрушается целиком, когда какой-нибудь несущественный отчёт, запускаемый раз в квартал, может стать причиной деградации всей системы массового обслуживания. Микросервисная архитектура снижает вероятность таких событий.
	
	
		Поскольку асинхронное событийное взаимодействие — практически стандарт в микросервисной архитектуре, то надо разбираться в создании событийной архитектуры (Event Driven Architecture, см. статью https://habr.com/ru/company/dataart/blog/280083/), а сами микросервисы должны соответствовать требованиям Reactive.
	
	
		
		скачать схему в формате diagrams.net (бывший draw.io)
	
	Минусы микросервисной архитектуры
	
		
			- скорее всего вы будете вынуждены перейти на асинхронное событийное взаимодействие;
 
			- рост накладных расходов — общее снижение скорости работы в сравнении с "монолитом", состоящим из модулей, взаимодействие между которыми вы вынесли вынесли на сетевой уровень, увеличение вероятности потери данных при транспортировке;
 
			- сложнее организовать транзакции.* Транзакция = способ группировки операций чтения / записи в одну логическую единицу, в рамках которой эти операции либо выполняются целиком либо не выполняются с возможностями прерывания и отката.
 
			- архитектура интерационных взаимодействий усложнится, скорее всего вам понадобится организовать трейсинг запросов для облегчения разбора различных проблем;
 
			- теперь критически важно актуальность поддерживать контрактов API (CDC);
 
			- логов теперь больше и они в разных местах — у каждого сервиса свои.
 
		
	
	Зачем в микросервисы?
	
		
			Основные плюсы здесь — с точки зрения процессов:
			
				- независимый деплой (проще тестировать и выкатывать/откатывать по кусочкам)
 
				- гарантия того, что другие команды не сунутся туда, куда им соваться не нужно, и не будет конфликтов при мержах (изоляция)
 
				- форсируется общение через чётко документированное API (нельзя взять и накостылять что-то в обход)
 
			
			Когда над монолитом работают несколько команд, постоянно что-то отваливается/не собирается, нужно разруливать какие-то конфликты при мержах, другая команда залезла в твой код и накуролесила, поменяли общий класс-зависимость и поведение немного поменялось, но сломало твои кейсы и т.д. (это даже при DDD).
			
С микросервисами вообще в этом плане лепота — присутствует какая-то стабильность, при переходе от задачи к задаче и мержах старых задач есть уверенность, что оно с вероятностью 99.99% заведется без проблем и будет работать так же, как в прошлый раз оставил.
			
© 
комментарий на habr
		 
	
	
		Что почитать на тему:
		
			- Microservices (Martin Fowler, 2014) — с этого всё началось.
 
			- Микросервисная архитектура в корпоративном ИТ-ландшафте. Вменяемая комплексная статья о микросервисах в сложном ИТ-ландшафте. Её одну можно рекомендовать взамен 10 стандартных громогласных буллщит-статей о микросервисах.
 
			- Microservices. Как правильно делать и когда применять? ("DataArt", 2016)
 
			- Микросервисная архитектура, подходы и технологии (Кирилл Ветчинкин, 2018). Плюсы, минусы, как проектировать, типовые ошибки/проблемы, способы решения. Да, в презентации есть некоторые ошибки и спорные моменты, но это одна из лучших о микросервисах на мой взгляд.
 
			- 
				Организация бизнес-процессов при микросервисном подходе:
				
			
 
			- 
				Тестирование:
				
			
 
		
	 
 
	Service mesh
	
		Что почитать на тему:
		
			- История service mesh в компании (Александр Лукьянченко, Авито, 2019). Об изначальных проблемах, о подходе к Service Mesh, о проблемах с эксплуатацией Istio, о создании собственного решения в виде sidecar-сервиса Netramesh (Golang + K8s / bare metal), о внедрении OpenTracing с инструментом Jaeger (что позволяет получать карты взаимодействия сервисов), о тестах и выделении критичных путей, о своего рода канареечных тестах с подменой роутинга для тестов.
 
			- Что такое Service Mesh? (2020) — коротко о.
 
			- Сценарии использования service mesh (2020)
 
			- Service Mesh: что нужно знать каждому Software Engineer о самой хайповой технологии (2019). Ангажировано Linkerd.
 
			- Что такое service mesh, когда внедрять, альтернативы Istio и другие ответы экспертов с АМА-сессии (2021)
 
			- Трассировка сервисов, OpenTracing и Jaeger
 
			- Как мы в Dropbox перешли с Nginx на Envoy
 
		
	 
	Кто использует service mesh
	
		Крупные корпорации, банки и прочие предприятия, имеющие сотни (микро)сервисов с очень нагруженной коммуникацией между ними, а также те, кто является владельцем целых платформ.
		
Пионерами в микросервисной архитектуре и service mesh в ИТ являются Lyft, Netflix и Twitter (ныне — X).
		
В российских реалиях внедрение происходит в топ-банках и, например, Авито.
	
	
		Ценность service mesh: предоставление функций, критически важных для работы современного серверного ПО, единообразным для всего стека и независимым от кода приложения образом.
	
	Суть
	
		Service mesh = архитектурный подход, который
		
			- в условиях наличия сотен (микро)сервисов + использования облаков с тысячами инстансов + использования контейнеризации + необходимости обработки больших объёмов межсервисных коммуникаций
 
			- за счёт добавления в инфраструктуру userspace-прокси (data plane), расположенных "рядом" с сервисами, и набора управляющих процессов (control plane)
 
			- позволяет реализовывать такие функции как service discovery + routing + balancing + tracing + authentication + authorization + encryption + circuitBreaking + autoscaling и другие
 
		
	
	
		Data plane перехватывает вызовы между сервисами, производя над ними необходимые манипуляции.
		
Control plane координирует поведение прокси и обеспечивает доступ для оператора к API, позволяя манипулировать сетью, изменяя её как единое целое.
		
	
	
		Service mesh занимается эксплуатационной логикой, а не смысловой. Занятие смысловой логикой было главным недостатком сервисной шины предприятия (ESB).
		
Сохранение этого разделения помогает service mesh избежать той же участи.
	
	Некоторые технологии и инструменты из области Service mesh
	
 
	Поясняющая схемка OS, Istio, k8s
	
		(для себя) поясняющая схемка взаимосвязи некоторых сущностей Openshift, Istio, k8s.
		
В OSE для входа используется Route, в "голом" istio / kubernetes — Ingress.
		
Разобраться с EnvoyFilter.
		
		скачать схему в формате diagrams.net (бывший draw.io)
	
	
		Пример набора сущностей для маршрутизации запросов на какой-то внешних хост через эгресс:
		
# Service. Объявлен граничный порт для сервиса граничного прокси.
kind: Service
apiVersion: v1
metadata:
  name: svc-egress
  labels:
    app: i-egressgateway
    app-group: "some-egress"
    app.kubernetes.io/part-of: istio
    app.kubernetes.io/instance: istio-controlpanel
    release: istio
    app.kubernetes. io/component: gateways
    istio: i-egressgateway
    maistra-version: 2.0.2
    app.kubernetes.io/name: gateways
    chart: gateways
    heritage: Tiller
spec:
  ports:
    - name: http-7074
      protocol: TCP
      port: 7074
      targetPort: 7074
  selector:
    app: i-egressgateway
    istio: i-egressgateway
  type: ClusterIP
status:
  loadBalancer: {}
----------------------------------------
# ServiceEntry. Описаны для целевого хоста граничный порт и порт удалённой машины
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: se-egressgateway
spec:
  exportTo:
    - .
  hosts:
    - remotehostname.com
  location: MESH_EXTERNAL
  ports:
    - name: http-7074
      number: 7074
      protocol: HTTP
    - name: https-8881
      number: 8881
      protocol: HTTPS
resolution: DNS
----------------------------------------
# VirtualService. Описана маршрутизация в направлении целевого хоста с граничного порта на целевой порт удалённой машины.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs-egressgateway
  labels:
    app-group: "some-egress"
spec:
  exportTo:
    - .
  gateways:
    - mesh
    - gw-egressgateway
  hosts:
    - remotehostname.com
  http:
    - match:
        - gateways:
            - mesh
          port: 7074
      rewrite:
        authority: remotehostname.com
      route:
        - destination:
            host: svc-egress
            port:
              number: 7074
    - match:
        - gateways:
            - gw-egressgateway
          port: 7074
      rewrite:
        authority: remotehostname.com
      route:
        - destination:
            host: remotehostname.com
            port:
              number: 8881
----------------------------------------
# Gateway. Для эгресса в направлении внешнего хоста указан граничный порт.
apiVersion: networking.istio.io/v1beta1
Kind: Gateway
metadata:
  name: gw-egressgateway
labels:
  app-group: "some-egress"
spec:
  selector:
    app: i-egressgateway
    istio: i-egressgateway
  servers:
    - hosts:
        - remotehostname.com
      port:
        name: http-7074
        number: 7074
        protocol: HTTP
----------------------------------------
# DestinationRule. В направлении внешнего хоста указан целевой порт и необходимые для MTLS сертификаты + ключ.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: dr-egressgateway
  labels:
    app-group: "some-egress"
spec:
  exportTo:
    - .
  host: remotehostname.com
  trafficpolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  portLevelSettings:
    - port:
        number: 8881
      tls:
        cacertificates: /etc/ssl/certs/caCertificates.pem
        clientCertificate: /etc/ssl/certs/tls.crt
        mode: MUTUAL
        privatekey: /etc/ssl/certs/tls.key
        sni: remotehostname.com
  outlierDetection:
    consecutive5xxErrors: 7
    interval: 5m
    baseEjectionTime: 15m