Микросервисы 2
В прошлой статье я начал изучать микросервисный подход, но до полноценного решения тогда не дошёл. Тогда я пробовал сам поднимать процессы на php, управлять ими, связывать между собой через очереди потому что монолит не мог справиться с асинхронными задачами. Но чего у меня реально нехватало, так это нормальной изоляции и деплоймента, межсервисного взаимодействия и стабильной работы.
Docker
Я сразу скажу что не знаю как настраивать production с докер-контейнерами, но сервисы в рабочем окружении поднимаются тривиально
- 
Ставите Docker для Мака или для Windows 
- 
Ставите dry для терминала (по желанию) 
- 
Создаёте Dockerfile 
- 
Создаёте docker-compose.yml 
- 
Запускаете docker-compose up 
Концепции
Images (образы) это изолированная среда, как правило с конкретным языком (node, php) или библиотекой. За это отвечает Dockerfile, который ссылается на существующий, скачиваемый образ на докер хабе.
Что-бы увидеть установленные образы, есть комманда docker images .
Контейнеры это запущенные образы которые изолированы от host-машины. Обычно контейнер поднимается для какого-то сервиса, поэтому у него есть своё название, явно объявлен маппинг сетевых портов на host-машину и способ монтирования файловой системы - за это отвечает docker-compose.yml
Что-бы увидеть установленные образы, есть комманда docker images .
Контейнеры это запущенные образы которые изолированы от host-машины. Обычно контейнер поднимается для какого-то сервиса, поэтому у него есть своё название, явно объявлен маппинг сетевых портов на host-машину и способ монтирования файловой системы - за это отвечает docker-compose.yml
По умолчанию порт не перебрасываются на такой же , а файлы хоста не линкуются и не будут обновляться внутри контейнера после старта.
Что-бы увидеть запущенные контейнеры, есть комманда docker ps (а лучше dry)
Что-бы запустить текущую папку есть docker-compose down && docker-compose up — это основная комманда которой вы будете пользоваться в разработке если будете делать изменения
Для автоматизации перезагрузки контейнера при изменении файлов на hostе, для node надо копать в сторону pm2-docker
Consul
Консул это сервер, который служит для связывания сервисов воедино (service discovery), поддержания их состояния здоровья (healthcheck) и для их конфигурации без перезапуска (key-value storage)
Каждый поднимающийся сервис сам должен зарегистрировать себя в консуле, указать на каком IP/порте он работает. Сам должен открыть HTTP endpoint который будет выдавать состояние здоровья
Сложности
При создании микросервисов самая сложная часть это граница и управление. Сервис должен отвечать за конкретную бизнес-функцию и доменную область. Это вертикальный срез приложения. Но при этом сервис должен выполнять весь стек работы — ui, backend, db storage, queue processor. Впихивать столько ответсвенности в один сервис технологически сложно, поэтому приходится дробить вертикальный стек ещё на несколько горизонтальных слоёв. Образно был article-manager - стал article-frontend, article-server, article-worker, над которыми нависают ещё всякие сервисы мониторинга. Это тяжело связывать вместе и деплоить разом.
Node
Поскольку нода висит постоянно в памяти, в отличие от php, который запускается при запросе, то возникает проблема перезагрузки кода при его изменении. Вот как выглядит Dockerfile с PM2:
FROM node:6-alpine
USER root
ENV PORT=3000
EXPOSE 3000
RUN npm install pm2 -g
WORKDIR /app
CMD ["pm2-docker", "start", "pm2.json", "--watch"]
Теперь в pm2.json описывается при каком случае надо перезапускать докер сервис
{
  "apps": [
    {
      "name": "article-manager",
      "script": "index.js",
      "env": {
        "PORT": 3000,
        "CONSUL_IP": "192.168.10.10",
        "CONSUL_PORT": 8500,
        "SERVICE_NAME": "article-manager"
      },
      "watch": true,
      "ignore_watch": [
        "node_modules",
        "npm-debug.log",
        ".idea",
        ".git",
        "test/coverage"
      ],
      "watch_options": {
        "followSymlinks": false
      }
    }
  ]
}
Redis
Очень быстрая in-memory база для кеширования данных
version: '2'
services:
  redis-master:
    image: 'redis:2.8'
    network_mode: bridge
    volumes:
        - ./data:/data
    ports:
        - 6379:6379
    command: redis-server --appendonly yes
Alias
Для удобства, советую добавить в ваш ~/.bashrc или ~/.zshrc алиас на быстрое поднятие контейнера:
alias doc='docker-compose down && docker-compose up'