✕

การปฏิบัติการ การบริหารจัดการ และความต่อเนื่อง

Infrastructure

ธุรกิจยังเป็นของท่านเช่นเดิม กลไกที่อยู่ภายใต้ธุรกิจนั้นเป็นหน้าที่ของเราที่จะเดินเครื่อง

Systems สร้างพื้นฐานและทำให้มั่นคงปลอดภัย Infrastructure เข้ารับการควบคุม: เราเป็นผู้ติดตั้ง เราดูแลให้เดินเครื่องต่อเนื่องทุกวัน และเราคือผู้ที่ตื่นเฝ้าอยู่เมื่อมีสิ่งใดขยับ ห้องค้าของสถาบันการเงิน บริษัท หรือบุคคลเดียวที่มีร้านค้าออนไลน์ — มือชุดเดียวกันและการเฝ้าระวังชุดเดียวกัน

ท่านกำลังอ่านบ้านที่เราบริหารด้วยตนเอง ระบบเฝ้าระวังทำงานอยู่แล้วก่อนที่ท่านจะมาถึง — ·

ภาระที่ท่านวางลงได้

หกสิ่งที่พ้นมือท่านไปตั้งแต่วันแรกและไม่หวนกลับมาอีก

เครื่องจักร

ระบบทำงานอยู่ที่ไหน ขนาดเท่าใด และควรมีต้นทุนเท่าไร เราเป็นผู้เลือก เป็นผู้ติดตั้ง และปรับขนาดเมื่อปริมาณทราฟฟิกของท่านเปลี่ยนไป — ก่อนที่มันจะกลายเป็นปัญหาที่ท่านมองเห็น

ที่อยู่

Domain, certificate และอีเมลที่ส่งถึงปลายทางจริง ไม่ใช่ตกลงไปในโฟลเดอร์ spam ต่ออายุให้เรียบร้อยก่อนที่ท่านจะนึกได้ว่ามีสิ่งนี้อยู่ เพราะชื่อที่หมดอายุคือธุรกิจที่ปิดประตู

ร้านค้า

ขั้นตอนชำระเงิน วิธีการจ่ายเงินแยกตามแต่ละประเทศ และคำสั่งซื้อที่ต้องไม่สูญหายเป็นอันขาด สร้างครั้งเดียว แล้วรักษาให้ทำงานต่อไป — รวมถึงในวันที่ผู้จัดส่งของท่านเปลี่ยนอะไรบางอย่าง

สำเนาข้อมูล

ระบบ backup ที่ท่านไม่ต้องนึกถึงเลย และการกู้คืนที่เราได้ลงมือทำจริงมาแล้ว สำเนาที่ไม่มีใครเคยกู้กลับมาได้นั้นไม่ใช่สำเนา — มันคือความหวัง

ความเร็ว

หน้าเว็บที่เปิดได้เร็วไม่ว่าผู้เข้าชมจะยืนอยู่ที่ใด ความช้าคือเงินที่เดินออกไป ดังนั้นความเร็วจึงเป็นส่วนหนึ่งของการบริหารบ้าน ไม่ใช่รายการเสริมที่ต้องซื้อเพิ่ม

การปิดช่องโหว่

การอัปเดต certificate ที่ใกล้หมดอายุ และส่วนประกอบที่มีช่องโหว่ เราเป็นผู้ปิดให้ ตามปฏิทินของเรา — ไม่ใช่ความกังวลของท่าน และไม่ใช่ตอนตีสามของท่าน

ใครเฝ้าระวัง และเฝ้าเมื่อใด

สิ่งที่เกิดขึ้นจริงระหว่างวินาทีที่บางอย่างพังลง จนถึงวินาทีที่มันกลับมายืนได้อีกครั้ง

ในวินาทีที่เกิดเหตุ

ระบบรับรู้เอง

ทุกคำขอ ทุกประตู และทุกกุญแจถูกบันทึกไว้ที่ edge ในขณะที่เกิดขึ้น ไม่มีสิ่งใดต้องรอให้งานกลางคืนมาค้นพบในเช้าวันรุ่งขึ้น

ในลมหายใจเดียวกัน

โทรศัพท์ดังขึ้นที่ซูริก

ไม่ใช่กล่องจดหมาย ไม่ใช่ dashboard ที่อาจมีใครเปิดดูในวันรุ่งขึ้น การแจ้งเตือนไปถึงที่ซึ่งไม่อาจถูกเพิกเฉยอย่างเงียบ ๆ ได้

ก่อนที่ท่านจะถาม

ท่านได้ยินจากเราเป็นคนแรก

เกิดอะไรขึ้น กระทบส่วนใด และเราได้ดำเนินการอะไรไปแล้ว ท่านไม่ต้องรู้ว่าบ้านของท่านล่มจากปากลูกค้าของท่านเอง

จนกว่าจะกลับมายืนได้

ซ่อมให้เสร็จ ไม่ใช่ส่งต่อ

มือชุดเดียวกับที่ติดตั้งระบบคือมือที่เข้าไปซ่อม ไม่มีลำดับชั้นใดเหนือเราที่จะส่งเรื่องต่อ จึงไม่มีใครที่เราต้องรอ

ณ สิ้นเดือน

บันทึกเป็นลายลักษณ์อักษร

อะไรล้มเหลว เพราะเหตุใด และเราเปลี่ยนอะไรเพื่อให้มันไม่ล้มเหลวด้วยวิธีเดิมเป็นครั้งที่สอง ความผิดพลาดที่ไม่ได้ถูกบันทึกไว้จะหวนกลับมา

สิ่งที่ส่งถึงท่านเป็นลายลักษณ์อักษรทุกเดือน

หนึ่งแผ่น อ่านเข้าใจได้โดยผู้ที่ไม่ใช่วิศวกร เพราะนั่นคือผู้ที่เราเขียนให้

ชั่วโมงที่ระบบยืนอยู่
จำนวนชั่วโมงที่ระบบทำงานอยู่ และจำนวนนาทีที่ไม่ทำงาน — วัดจากภายนอกบ้านของท่าน ตัวเลขนี้จึงไม่ใช่สิ่งที่เราจะแต่งให้ดูดีได้
สิ่งที่เราเปลี่ยน
ทุกการเปลี่ยนแปลงที่เราทำ ด้วยภาษาที่ตรงไปตรงมา ท่านอ่านจบในหนึ่งนาที และยังทราบแน่ชัดว่าสิ่งใดขยับไป
สิ่งที่พังลง
อะไรล้มเหลว กระทบส่วนใด และเราทำอะไร — รวมถึงความผิดพลาดที่ท่านไม่เคยสังเกตเห็น ซึ่งเป็นส่วนใหญ่ของทั้งหมด
สิ่งที่จะเกิดขึ้นต่อไป
สิ่งที่เราตั้งใจจะทำในเดือนถัดไป เขียนไว้ก่อนที่เราจะลงมือ ไม่มีสิ่งใดเกิดขึ้นกับบ้านของท่านโดยไม่ได้บอกล่วงหน้า
ค่าใช้จ่าย
ตัวเลขเดียวกับเดือนก่อน เว้นแต่ท่านขอสิ่งใหม่ ไม่มีรายการใดปรากฏขึ้นบนแผ่นนี้ด้วยตัวมันเอง

อินเทอร์เฟซ

สิ่งที่เราส่งมอบให้ท่านคือครึ่งที่ทำงานอยู่ในบ้านของท่าน: การซ้อมที่ทดสอบสำเนาข้อมูลของท่านเองทุกคืน และคำสั่งเรียกเดียวที่นำบ้านหนึ่งหลังเข้าสู่การบริหารจัดการ ห้องปฏิบัติการของเรายังคงปิด — ส่วนที่ทำงานอยู่ฝั่งท่านเป็นของท่านที่จะอ่านตรวจก่อนจะวางใจ

"""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
คนที่ตอบท่าน
ไม่มีลำดับชั้น ไม่มี ticket และไม่มีใครมายืนจดบันทึกขวางหน้าเขา

สิ่งที่ลอกเลียนไม่ได้

ไม่ใช่การเปรียบเทียบราคา แต่เป็นการเปรียบเทียบว่าบ้านสองหลังถูกสร้างขึ้นอย่างไร

รูปแบบที่พบโดยทั่วไป
ที่นี่
ใครเป็นผู้ตอบ
ตารางเวรของคนที่ท่านไม่เคยพบ ใครที่รับสายต้องถูกอธิบายเสียก่อนว่าระบบของท่านคืออะไร จึงจะช่วยอะไรได้
บุคคลผู้ติดตั้งระบบนั้นเอง เขารู้จักระบบของท่านด้วยมือของตัวเองอยู่แล้ว จึงไม่มีอะไรต้องอธิบายก่อน
เวลาทำการ
ความผิดพลาดเวลา 23:40 กลายเป็น ticket ที่ถูกอ่านเวลา 09:00 ค่ำคืนนั้นเป็นของท่านเพียงลำพัง
การเฝ้าระวังไม่มีเวลาทำการ การแจ้งเตือนไปที่โทรศัพท์ และโทรศัพท์เครื่องนั้นไม่เคยปิด
ในแต่ละปี
เพิ่มอีกหนึ่งที่นั่ง อีกหนึ่งโมดูล อีกหนึ่งลำดับชั้น รูปแบบนั้นมีแต่จะหนักขึ้นเรื่อยไป
เราถอดสิ่งที่ท่านเลิกต้องการออก การปฏิบัติการเบาลง — และค่าใช้จ่ายของท่านก็เบาลงตาม
เมื่อระบบพัง
พวกเขาแจ้งท่านว่ามันพัง การซ่อมถูกเสนอราคาแยก และโดยคนอื่น
เราสร้างเครื่องยนต์นั้นเองด้วย เราจึงเข้าไปซ่อมเอง บ้านหลังเดียวรับผิดชอบทั้งสองซีก
วันที่ท่านจากไป
คอนโซลของพวกเขา รูปแบบข้อมูลของพวกเขา ค่าธรรมเนียมการออกของพวกเขา การเดินจากไปมีราคาเท่าโครงการหนึ่งโครงการ
บัญชีของท่าน domain ของท่าน ข้อมูลของท่าน เราถือกุญแจเท่าที่ได้รับมอบมา และคืนกุญแจนั้นในวันที่ท่านขอ

ทั้งหมดนี้ไม่ใช่รายการคุณสมบัติ และนั่นคือเหตุผลที่มันไม่อาจถูกเสนอราคาแข่งเอาชนะได้ บริษัทที่ทำงานด้วยตารางเวรไม่สามารถมอบบุคคลผู้สร้างระบบของท่านให้ท่านได้ บริษัทที่ใบแจ้งหนี้ต้องโตขึ้นทุกปีไม่สามารถตัดรายการใดออกได้ บริษัทที่ทำหน้าที่เฝ้าระวังเพียงอย่างเดียวไม่สามารถซ่อมได้ พวกเขาไม่ได้ตามหลังเรา — พวกเขาถูกสร้างขึ้นด้วยโครงสร้างที่ต่างออกไป และไม่อาจข้ามมาฝั่งนี้ได้โดยไม่เลิกเป็นตัวของตัวเอง

และนั่นคือเหตุผลที่หน้านี้ไม่มีรายการราคา เราพิจารณาว่าสิ่งใดต้องไม่หยุด เราวัดขอบเขตของการปฏิบัติการ แล้วจึงเสนอราคาตามที่วัดได้ แต่ละรายจ่ายตามขนาดของตน — ร้านค้าที่ดำเนินการโดยคนเดียวย่อมไม่ถูกเรียกเก็บเสมือนว่าเป็นห้องค้าของสถาบันการเงิน

บอกเราว่าท่านอยากส่งมอบสิ่งใด

สองบรรทัดก็เพียงพอ เราอ่านด้วยตนเองและตอบด้วยตนเอง — ไม่มีคิวใดยืนรออยู่หลังหน้าต่างบานนี้

ข้อความไปถึงคนเพียงคนเดียว และคนนั้นเป็นผู้ตอบ ไม่มีสิ่งใดในนี้ถูกแบ่งปัน ขาย หรือส่งต่อ

Mr. MatchTop · matchtopalgorithm.ai