✕

Эксплуатация, управление и непрерывность

Infrastructure

Бизнес остаётся вашим. Механика под ним — наша забота.

Systems строит основание и защищает его. Infrastructure берёт управление: мы настраиваем, мы держим всё в работе день за днём, и это мы не спим, когда что-то происходит. Торговый зал, компания или один человек с интернет-магазином — те же руки и то же дежурство.

Вы читаете дом, которым мы управляем сами. Он уже был под дежурством, когда вы пришли — ·

Что перестаёт быть вашей ношей

Шесть вещей, которые уходят из ваших рук в первый же день и не возвращаются.

Машины

Где всё работает, какого размера и сколько это должно стоить. Мы выбираем, настраиваем и меняем размер, когда меняется ваш трафик — прежде чем это станет заметной проблемой.

Адрес

Домен, сертификаты и почта, которая доходит, а не падает в спам. Продлено прежде, чем вы вспомните, что это существует: просроченное имя — это закрытый бизнес.

Магазин

Оформление заказа, способы оплаты по каждой стране и заказ, который нельзя потерять. Собрано один раз и дальше поддерживается — в том числе в день, когда поставщик что-то меняет.

Копии

Резервные копии, о которых вам не нужно думать, и восстановление, которое мы действительно выполняли. Копия, которую никто ни разу не восстановил — не копия, а надежда.

Скорость

Страницы открываются быстро, где бы ни находился посетитель. Медленно — значит деньги уходят, поэтому скорость входит в ведение дома, а не в отдельную строку счёта.

Патчи

Обновления, сертификаты на грани истечения, компонент с дырой. Закрываем мы, по нашему календарю — не за счёт вашего беспокойства и не в три часа ночи по вашему времени.

Кто дежурит и когда

Что на самом деле происходит между моментом, когда что-то падает, и моментом, когда оно снова стоит.

В ту же секунду

Система замечает

Каждый запрос, каждая дверь и каждый ключ фиксируются на edge-узле в момент события. Ничего не ждёт ночного задания, чтобы обнаружиться к утру.

В тот же миг

В Цюрихе звонит телефон

Не почтовый ящик и не панель, которую кто-то, возможно, откроет завтра. Оповещение уходит туда, где его нельзя тихо не заметить.

Прежде чем вы спросите

Вы узнаёте от нас

Что произошло, что это затронуло и что уже сделано. Вы не узнаёте о падении своего дома от собственных клиентов.

Пока снова не встанет

Это ремонтируют, а не эскалируют

Те же руки, что всё настраивали, заходят и исправляют. Над нами нет уровня, которому можно передать задачу — значит, нам некого ждать.

В конце месяца

Это фиксируется письменно

Что отказало, почему и что мы изменили, чтобы это не отказало так же во второй раз. Сбой, который не зафиксирован письменно, возвращается.

Что приходит в письменном виде каждый месяц

Один лист. Понятный тому, кто не инженер — потому что он для него и написан.

Часы в работе
Часы, когда всё работало, и минуты, когда нет — измерено снаружи вашего дома, чтобы цифру нельзя было украсить.
Что мы изменили
Каждое наше изменение простым языком. Прочитаете за минуту и будете точно знать, что сдвинулось.
Что сломалось
Что отказало, что это затронуло и что мы сделали — включая сбои, которых вы не заметили, а их большинство.
Что дальше
Что мы намерены сделать в следующем месяце — написано до того, как сделано. С вашим домом ничего не происходит внезапно.
Сколько это стоит
Та же цифра, что и в прошлом месяце, если вы не просили ничего нового. Ни одна строка не появляется в этом листе сама собой.

Интерфейс

Вам мы передаём ту половину, что работает в вашем доме: учебное восстановление, которое каждую ночь проверяет ваши собственные копии, и единственный вызов, который ставит дом под управление. Наша операционная остаётся закрытой — то, что работает на вашей стороне, вы можете прочитать прежде, чем довериться.

"""MatchTop · restore drill — the piece that proves a copy is a copy.
Standard library only. It runs in your house, on your own copies, where you can watch it."""

import hashlib, hmac, json, os, subprocess, time
from pathlib import Path
from urllib.request import Request, urlopen

KEY    = bytes.fromhex(os.environ["MT_KEY"])    # one key per house, never on disk
EDGE   = os.environ["MT_EDGE"]                   # no address baked into the build
SHADOW = Path(os.environ["MT_SHADOW"])            # a shadow copy. never the live house.


def newest_copy(vault: Path) -> Path:
    """Drill the copy you would actually reach for, not a convenient one."""
    copies = sorted(vault.glob("*.dump"), key=lambda p: p.stat().st_mtime)
    if not copies:
        raise FileNotFoundError("the vault is empty")   # the loudest fault there is
    return copies[-1]


def fingerprint(copy: Path) -> str:
    """So that tomorrow we can prove this was the file we brought back."""
    h = hashlib.sha256()
    with copy.open("rb") as f:
        for block in iter(lambda: f.read(1 << 20), b""):
            h.update(block)
    return h.hexdigest()


def bring_it_back(copy: Path) -> dict:
    """Restore into the shadow, then ask it a question only a live house can answer."""
    SHADOW.mkdir(parents=True, exist_ok=True)
    started = time.monotonic()
    subprocess.run(["pg_restore", "--clean", "-d", "mt_shadow", str(copy)],
                   check=True, timeout=1800)
    asked = subprocess.run(["psql", "-d", "mt_shadow", "-tAc",
                            "select count(*) from orders"],
                           capture_output=True, text=True, check=True)
    return {"seconds": round(time.monotonic() - started, 1),
            "orders":  int(asked.stdout.strip())}   # a restore nobody queried is not a restore


def file_it(result: dict) -> str:
    """Signed and filed, pass or fail. The month's sheet is written from these."""
    body = json.dumps(result, separators=(",", ":"), sort_keys=True).encode()
    call = Request(EDGE, body, {
        "Content-Type": "application/json",
        "X-MT-House":   os.environ["MT_HOUSE"],
        "X-MT-Seal":    hmac.new(KEY, body, hashlib.sha256).hexdigest(),
    })
    with urlopen(call, timeout=8) as answer:        # we dial out. nothing dials in.
        return json.load(answer)["filed"]


def drill(vault: Path) -> None:
    copy   = newest_copy(vault)
    result = {"copy":        copy.name,
              "age_hours":   round((time.time() - copy.stat().st_mtime) / 3600, 1),
              "fingerprint": fingerprint(copy)[:16]}
    try:
        result |= bring_it_back(copy)
        result["verdict"] = "came back"
    except Exception as fault:
        result["verdict"] = "did not come back"      # the drill exists for this branch
        result["fault"]   = str(fault)[:200]           # and this is the night we are worth it
    file_it(result)


if __name__ == "__main__":
    drill(Path(os.environ["MT_VAULT"]))               # every night, watched or not

Измерено на нашем собственном доме

На этой странице нет клиентских цифр. Мы не приводим то, что не измерили сами, поэтому эти четыре — из домов, которые мы ведём своими руками.

2
дома под нашим управлением
этот и дом одной клиники — мы сами себе первый клиент и первая претензия
7
дверей в этом доме
по одной на язык, все под одним дежурством и одним счётом
0
консолей для изучения
вам некуда входить и нечего запоминать — вы просите, и это сделано
1
человек отвечает
без уровней, без тикетов и без посредника, который записывает за него

Что нельзя скопировать

Это сравнение не цен. Это сравнение того, как устроены два дома.

Обычная схема
Здесь
Кто отвечает
График дежурств, с которым вы никогда не познакомитесь. Тому, кто снимет трубку, сначала нужно объяснить, что у вас за система.
Тот, кто её настроил. Он знает вашу систему наизусть, поэтому объяснять ничего не нужно.
Рабочие часы
Сбой в 23:40 — это тикет, прочитанный в 09:00. Ночь принадлежит вам одному.
У дежурства нет рабочих часов. Оповещение уходит на телефон, и телефон не выключен.
Каждый год
Ещё одна лицензия, ещё один модуль, ещё один уровень. Схема может только тяжелеть.
Мы убираем то, что перестало быть нужным. Эксплуатация становится легче — и дешевле для вас.
Когда ломается
Вам сообщают, что сломалось. Ремонт считают отдельно, и делает его кто-то другой.
Мы построили и сам движок, поэтому заходим и ремонтируем. Один дом отвечает за обе половины.
В день, когда вы уходите
Их консоль, их форматы, их плата за выход. Уйти стоит целого проекта.
Ваш аккаунт, ваш домен, ваши данные. Мы храним переданные нам ключи и отдаём их в тот день, когда вы попросите.

Ничего из этого не является перечнем функций — именно поэтому это нельзя перебить ценой. Фирма с графиком дежурств не может дать вам человека, который построил вашу систему. Фирма, чей счёт обязан расти каждый год, не может убрать из него строку. Фирма, которая только наблюдает, не может ремонтировать. Они не отстают от нас — они устроены иначе и не могут перейти на эту сторону, не перестав быть собой.

Поэтому на этой странице нет и прайс-листа. Мы смотрим, что не должно остановиться, измеряем эксплуатацию и называем цену за измеренное. Каждый платит по своему размеру — магазин, которым управляет один человек, не считают как торговый зал.

Расскажите, что вы предпочли бы передать нам

Достаточно двух строк. Мы читаем их сами и отвечаем сами — за этим окном нет очереди.

Это попадает к одному человеку, и этот человек отвечает. Ничего отсюда не передаётся, не продаётся и не уходит дальше.

Mr. MatchTop · matchtopalgorithm.ai