มีคนพูดคำสถาปัตยกรรมที่น่ากลัวและคุณไม่ใช่สถาปนิกใช่ไหม

กลัวเมื่อมีคนท้าทายความเข้าใจของคุณเกี่ยวกับความซับซ้อนในการคำนวณเมื่อคุณพยายามทำเพียงแค่วางวิดเจ็ตไว้บนหน้าเว็บใช่ไหม อย่ากลัวเลย มันอาจไม่ซับซ้อนหรือซับซ้อนเท่าที่คุณคิด

สถาปัตยกรรมมีชื่อเสียงในด้านที่ไม่สามารถเข้าถึงได้ มีการควบคุมประตู และเป็น "วิทยาการคอมพิวเตอร์ที่ยาก" สถาปัตยกรรมซอฟต์แวร์ส่วนใหญ่ที่คุณพบสำหรับเว็บแอประดับปานกลางถึงระดับเว็บนั้นมีความคล้ายคลึงกันอย่างน่าประหลาดใจ เราจะครอบคลุมพื้นฐาน ศัพท์เฉพาะบางส่วน และรูปแบบสถาปัตยกรรมบางอย่างที่คุณอาจพบเห็นได้ทุกที่ในไพรเมอร์สถาปัตยกรรมสั้นๆ นี้สำหรับผู้ที่ไม่ใช่สถาปนิกและโปรแกรมเมอร์เว็บ

เว็บเซิร์ฟเวอร์คืออะไร?

เอาล่ะ มาเริ่มกันที่พื้นฐานกันดีกว่า “เว็บ” หรือ “เวิลด์ไวด์เว็บ” — เพื่อใช้คำยกย่องเต็มเปี่ยมแบบโบราณอย่างสนุกสนาน เป็นเพียงคอมพิวเตอร์จำนวนหนึ่งที่เชื่อมต่อกับอินเทอร์เน็ต เว็บคือชุดของข้อตกลงที่อธิบายว่า "ทรัพยากร" (อ่าน: หน้าเว็บ) สามารถดึงข้อมูลจากคอมพิวเตอร์ที่เชื่อมต่อเหล่านี้ได้อย่างไร

เรื่องสั้นเรื่องยาว “เว็บเซิร์ฟเวอร์” ใช้ “โปรโตคอล HTTP” — ชุดคำสั่งที่คุณสามารถส่งไปยังคอมพิวเตอร์ระยะไกล — ที่ให้คุณพูดว่า “เฮ้ คอมพิวเตอร์ ส่งเอกสารนั้นมาให้ฉัน” หากฟังดูคุ้นเคย นั่นเป็นเพราะนั่นคือวิธีการทำงานของเว็บเบราว์เซอร์ของคุณ

เมื่อคุณพิมพ์ www.my-awesome-website.com ลงในเบราว์เซอร์ของคุณ รหัสที่ทำงานบนคอมพิวเตอร์ของคุณจะสร้าง “คำขอ http” และส่งไปยังเว็บเซิร์ฟเวอร์ที่เกี่ยวข้องกับ URL (อ่าน: ที่อยู่เว็บไซต์) ที่คุณพิมพ์ลงในแถบที่อยู่

ดังนั้น เว็บเซิร์ฟเวอร์ — โปรแกรมที่ทำงานบนคอมพิวเตอร์ระยะไกล เชื่อมต่อกับอินเทอร์เน็ต ซึ่งกำลังฟังคำขอและส่งคืนข้อมูลเมื่อได้รับคำขอ ความจริงที่ว่าสิ่งนี้ได้ผลนั้นถือเป็นปาฏิหาริย์เล็กๆ น้อยๆ และถูกสร้างขึ้นบน DNS (สิ่งที่เปลี่ยน my-awesome-website.com ให้เป็นที่อยู่ IP) และเครือข่าย การกำหนดเส้นทาง และการสลับจำนวนมาก คุณอาจไม่จำเป็นต้องรู้อะไรมากนักในแง่ความเป็นจริง เว้นแต่ว่าคุณจะเจาะลึกลงไป

มีเว็บเซิร์ฟเวอร์สำหรับวัตถุประสงค์ทั่วไปมากมายที่มีอยู่ แต่ในความเป็นจริงแล้ว คุณอาจเห็นส่วนผสมของ Apache, NGINX และ Microsoft IIS พร้อมด้วยเว็บเซิร์ฟเวอร์เฉพาะสำหรับสแต็กการพัฒนาบางส่วน (Node.js ทำหน้าที่ในตัวเอง เช่นเดียวกับ ASP ที่สามารถทำได้ .NET CORE สำหรับ C# และ HTTP4K สำหรับ Kotlin)

HTTP ทำงานอย่างไร? และสถาปัตยกรรมนั้นคืออะไร?

หากคุณเคยเขียนโปรแกรมเว็บมาก่อน อย่างน้อยคุณก็น่าจะคุ้นเคยกับ HTTP บ้างเล็กน้อย ย่อมาจาก “The Hyper Text Transfer Protocol” และเป็นสิ่งที่เบราว์เซอร์ของคุณพูดถึงเมื่อสื่อสารกับเว็บเซิร์ฟเวอร์ มาดู "ข้อความคำขอ" ของ HTTP แบบดิบๆ กัน:

GET http://www.davidwhitney.co.uk/ HTTP/1.1
Host: www.davidwhitney.co.uk
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64…
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8

พื้นฐานของ HTTP นั้นง่ายต่อการเข้าใจ — มี “บรรทัดคำขอ” ที่จำเป็น — นั่นคือบิตแรกที่มีกริยา (หนึ่งใน GET, POST, PUT และ HEAD ที่ใช้บ่อยที่สุด), URL (ที่อยู่เว็บ) และเวอร์ชันโปรโตคอล ( HTTP/1.1) จากนั้นจะมีฟิลด์ส่วนหัวคำขอเพิ่มเติมจำนวนมาก — นั่นคือข้อมูลอื่นๆ ทั้งหมด — คิดว่านี่เป็นข้อมูลเพิ่มเติมที่คุณมอบให้กับเว็บเซิร์ฟเวอร์เกี่ยวกับตัวคุณ หลังจากส่วนหัวของคุณ จะมีบรรทัดว่างและเนื้อหาเพิ่มเติม นั่นคือ HTTP/1.1 เราทำเสร็จแล้วที่นี่ เซิร์ฟเวอร์จะตอบสนองในรูปแบบที่คล้ายกัน

HTTP/1.1 200 OK
Cache-Control: public,max-age=1
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Server: Kestrel
X-Powered-By: ASP.NET
Date: Wed, 11 Dec 2019 21:52:23 GMT
Content-Length: 8479

<!DOCTYPE html>
<html lang="en">...

บรรทัดแรกเป็นรหัสสถานะ ตามด้วยส่วนหัวและเนื้อหาการตอบกลับ แค่นั้นแหละ. เว็บเซิร์ฟเวอร์สามารถส่งอะไรก็ได้ที่คุณชอบตามเนื้อหาของคำขอ และซอฟต์แวร์ที่ส่งคำขอจะต้องสามารถตีความการตอบสนองได้ การขอสิ่งที่ถูกต้องและการตอบสนองอย่างเหมาะสมนั้นมีความแตกต่างกันมาก แต่พื้นฐานก็เหมือนกัน

เว็บเป็นการปรับใช้รูปแบบการออกแบบ REST ซึ่งย่อมาจาก “Representational State Transfer” คุณจะได้ยินผู้คนพูดถึง REST บ่อยครั้ง เดิมที REST กำหนดไว้โดย Roy Fielding ในวิทยานิพนธ์ระดับปริญญาเอกของเขา แต่ที่สำคัญกว่านั้นคือคำอธิบายวิธีการทำงานของ HTTP/1.0 ในขณะนั้น และได้รับการบันทึกไว้ในเวลาเดียวกันกับที่ Fielding กำลังทำงานอยู่ บน HTTP/1.1

ดังนั้นเว็บจึงสงบตามค่าเริ่มต้น REST อธิบายวิธีการทำงานของ HTTP

เวอร์ชั่นสั้น? URI ที่ระบุที่อยู่ได้โดยเฉพาะ (ที่อยู่เว็บ) ที่แสดงสถานะบางอย่างที่เก็บไว้ในเครื่องที่ไหนสักแห่ง (หน้าเว็บ เอกสาร รูปภาพ และอื่นๆ) ขึ้นอยู่กับสิ่งที่ลูกค้าขอ การแสดงสถานะนั้นอาจแตกต่างกันไป

นั่นคือ HTTP และ REST และรูปแบบสถาปัตยกรรมทั้งหมดในที่เดียว

สถาปัตยกรรมของเว็บแอปพลิเคชันมีลักษณะอย่างไร

คุณสามารถเขียนซอฟต์แวร์ที่ดีโดยใช้รูปแบบสถาปัตยกรรมที่แตกต่างกันมากมาย แต่คนส่วนใหญ่ยึดติดกับรูปแบบทั่วไปเพียงไม่กี่รูปแบบ

“แอป MVC”

MVC — ตัวควบคุมมุมมองโมเดล — เป็นรูปแบบการออกแบบที่เรียบง่ายที่แยกตรรกะการประมวลผลของแอปพลิเคชันและการนำเสนอของมันออก MVC ได้รับความสนใจอย่างมากจากความสำเร็จของ Ruby on Rails (แม้ว่ารูปแบบจะเก่ากว่าสองสามทศวรรษ) และเมื่อคนส่วนใหญ่พูดว่า "MVC" พวกเขากำลังอธิบายแอป MVC "สไตล์ Rails" จริงๆ ที่โค้ดของคุณถูกจัดระเบียบ ลงในไดเร็กทอรีที่แตกต่างกันเล็กน้อย

/controllers
/models
/views

Rails นิยมใช้ "การประชุมมากกว่าการกำหนดค่า" เพื่อเชื่อมโยงสิ่งเหล่านี้เข้าด้วยกัน ควบคู่ไปกับแนวคิดเรื่อง "การกำหนดเส้นทาง" และค่าเริ่มต้นที่สมเหตุสมผล สิ่งนี้ถูกโคลนโดย ASP.NET MVC เกือบจะขายส่งและสวยมากทุกเฟรมเวิร์ก MVC อื่น ๆ ตั้งแต่นั้นมา

โดยค่าเริ่มต้น หากคุณมี URL ที่มีลักษณะดังนี้

http://www.mycoolsite.com/Home/Index

กรอบงาน MVC ที่ใช้ "เส้นทาง" ซึ่งเป็นกฎที่กำหนดตำแหน่งที่จะค้นหาสิ่งต่างๆ จะพยายามค้นหาไฟล์หรือโมดูล "HomeController" (ขึ้นอยู่กับภาษาการเขียนโปรแกรมของคุณ) ภายในไดเร็กทอรีคอนโทรลเลอร์ อาจมีฟังก์ชันที่เรียกว่า "ดัชนี" อยู่ ฟังก์ชันนั้นจะส่งคืนโมเดล — ข้อมูลบางส่วน — ที่ถูกเรนเดอร์โดย “มุมมอง” — เทมเพลต HTML จากโฟลเดอร์มุมมอง

เฟรมเวิร์กที่แตกต่างกันทั้งหมดทำสิ่งนี้แตกต่างออกไปเล็กน้อย แต่แนวคิดหลักยังคงเหมือนเดิม นั่นคือฟีเจอร์ที่จัดกลุ่มเข้าด้วยกันตามตัวควบคุม พร้อมฟังก์ชันสำหรับการส่งคืนหน้าข้อมูลและจัดการอินพุตจากเว็บ

“แอปหน้าเดียวพร้อม API

SPA เป็นเรื่องธรรมดาอย่างไม่น่าเชื่อ โดยได้รับความนิยมจากเฟรมเวิร์กฝั่งไคลเอ็นต์ เช่น Angular, React และ Vue.js ข้อแตกต่างที่แท้จริงประการเดียวที่นี่คือเราใช้แอป MVC และย้ายงานส่วนใหญ่ที่ทำไปยังฝั่งไคลเอ็นต์

มีสองรสชาติที่นี่ — มี MVC ฝั่งไคลเอ็นต์ มี MVVM (model-view-view-model) และมีการเขียนโปรแกรมเชิงโต้ตอบเชิงฟังก์ชัน (FRP) ความแตกต่างอาจดูค่อนข้างละเอียดอ่อนในตอนแรก

Angular เป็นเฟรมเวิร์ก MVC ฝั่งไคลเอ็นต์ ตามรูปแบบ "โมเดล มุมมอง และตัวควบคุม" ยกเว้นตอนนี้ที่ทำงานอยู่ในเว็บเบราว์เซอร์ของผู้ใช้

React — การใช้งานการเขียนโปรแกรมเชิงโต้ตอบเชิงฟังก์ชัน — มีความยืดหยุ่นมากกว่าเล็กน้อย แต่เกี่ยวข้องกับเหตุการณ์การเปลี่ยนแปลงสถานะในข้อมูลมากกว่า — มักใช้ที่เก็บข้อมูลเหตุการณ์บางอย่างเช่น Redux สำหรับข้อมูล

MVVM นั้นพบได้ทั่วไปเท่าเทียมกันในแอปหน้าเดียวซึ่งมีการเชื่อมโยงสองทางระหว่างสิ่งที่ให้ข้อมูล (โมเดล) และ UI (ซึ่งโมเดลมุมมองให้บริการ)

ภายใต้เฟรมเวิร์ก JavaScript จำนวนมากของไคลเอ็นต์เหล่านี้ โดยทั่วไปแล้วจะเป็น API ที่แทบจะแยกไม่ออกจาก "แอป MVC" แต่แทนที่จะส่งคืนหน้าที่แสดงผลล่วงหน้า กลับส่งคืนข้อมูลที่ไคลเอ็นต์ "ผูก" เข้ากับ UI

“ไซต์แบบคงที่ที่โฮสต์บน CDN หรือเซิร์ฟเวอร์โง่ ๆ อื่น ๆ”

บางทีอาจเป็นสิ่งที่ผิดเพี้ยนไปจากชุดนี้ — มีการฟื้นตัวของเว็บไซต์คงที่ในช่วงวัยรุ่น 20 ปี ดูสิ การปรับขนาดเว็บไซต์เพื่อให้มีการเข้าชมสูงเป็นเรื่องยากเมื่อคุณเรียกใช้โค้ดบนคอมพิวเตอร์ของคุณต่อไป

เราใช้เวลาหลายปีในการสร้างระบบการจัดการเนื้อหาที่ค่อนข้างซับซ้อนและมีประสิทธิภาพต่ำ (เช่น WordPress) ซึ่งต้องใช้เงินและฮาร์ดแวร์จำนวนมากในการปรับขนาด

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

เครื่องมือสร้างไซต์แบบคงที่จึงได้รับความนิยมเพิ่มมากขึ้น — โดยปกติแล้วจะอนุญาตให้คุณใช้สแต็กการพัฒนาเว็บส่วนหน้าตามปกติได้ แต่จากนั้นก็สร้างไฟล์ทั้งหมดโดยใช้เครื่องมือสร้างเพื่อรวมกลุ่มและแจกจ่ายไปยังเว็บเซิร์ฟเวอร์หรือ CDN ที่ไม่น่าเชื่อถือ ดูเครื่องมือเช่น — Gatsby, Hugo, Jekyll, Wyam

"อื่น ๆ อีก"

มีต้นแบบอื่นๆ ที่เว็บแอปติดตาม — มีแนวโน้มเพิ่มขึ้นอย่างช้าๆ ในเฟรมเวิร์ก transpiled (Blazor สำหรับ C# ใน WebAssembly และเป้าหมายการคอมไพล์จาวาสคริปต์ของ Kotlin) — แต่ด้วยความนิยมอย่างมากของเฟรมเวิร์กจาวาสคริปต์ที่โดดเด่นในแต่ละวัน พวกเขาทั้งหมดพยายามเล่น ไปด้วยดี

ทำไมฉันถึงเลือกอันหนึ่งมากกว่าอีกอัน?

คำถามหากิน จริงๆ แล้วมันเป็นเรื่องของรสนิยมและเป็นวิธีที่เหมาะสมที่สุดในการสร้างเว็บแอปพลิเคชัน

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

อะไรก็ตามที่ต้องใช้ UX ความเที่ยงตรงสูง ซึ่งเกือบจะเป็นค่าเริ่มต้นแล้วในตอนนี้ น่าจะเป็นแอป React, Angular หรือ Vue โมเดลการเขียนโปรแกรมทำงานได้ดีสำหรับประสบการณ์ผู้ใช้ที่ตอบสนอง และหากคุณไม่ได้ใช้โมเดลเหล่านี้ คุณจะต้องสร้างโมเดลใหม่ด้วยตัวเองเป็นส่วนใหญ่

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

HTTP API, ส่วนที่เหลือ, GraphQL, แบ็กเอนด์สำหรับส่วนหน้า

คุณจะต้องโต้ตอบกับ API อย่างแน่นอน และแม้ว่าจะมีคำศัพท์มากมายที่ถูกโยนทิ้งเพื่อทำให้สิ่งนี้ฟังดูซับซ้อน แต่แกนกลางนั้นเรียบง่าย API ส่วนใหญ่ที่คุณใช้หรือบิวด์จะเป็น “REST-ish”

คุณจะออก "คำขอ HTTP" ประเภทเดียวกับที่เบราว์เซอร์ของคุณทำ โดยส่วนใหญ่จะส่งคืนการตอบสนอง JSON (แม้ว่าบางครั้งจะเป็น XML) การอธิบาย API เหล่านี้ส่วนใหญ่เป็น JSON-RPC หรือ XML-RPC นั้นปลอดภัย

ย้อนกลับไปในช่วงเปลี่ยนผ่านของสหัสวรรษ มีการผลักดันให้มีการกำหนดมาตรฐานของ API “SOAP” (Simple Object Access Protocol) และถึงแม้ว่าจะมีสิ่งดีๆ มากมาย ผู้คนพบว่า XML อ่านได้ยาก และทำให้ความนิยมลดลง

น่าแปลกที่สิ่งต่างๆ มากมายที่ได้รับการแก้ไขใน SOAP (รูปแบบซองจดหมายข้อความที่สอดคล้องกัน ข้อควรพิจารณาด้านความปลอดภัย การตรวจสอบสคีมา) ในเวลาต่อมา จะต้อง "แก้ไขใหม่" เหนือ JSON โดยใช้มาตรฐาน open-ish ที่เกิดขึ้นใหม่ เช่น Swagger (ปัจจุบันคือ OpenAPI) และ JSON:API

เราเก่งในการคิดค้นสิ่งที่เรามีอยู่แล้วบนเว็บขึ้นมาใหม่

แล้วอะไรทำให้ REST API เป็น REST API ไม่ใช่ JSON-RPC

ฉันดีใจที่คุณไม่ถาม

REST ที่เป็นแกนหลักเป็นเรื่องเกี่ยวกับการดำเนินการสร้างโมเดลที่อาจเกิดขึ้นกับทรัพยากรผ่าน HTTP มีหนังสือดีๆ เล่มหนึ่งโดย Jim Webber ชื่อ Rest in Practice หากคุณต้องการเจาะลึกว่าทำไม REST จึงเป็นรูปแบบสถาปัตยกรรมที่ดี (และก็คือ การบอกว่า REST สมัยใหม่ส่วนใหญ่นั้นค่อนข้างไม่มีความรู้และไม่แตกต่างไปจากการรักษาที่ SOAP มี ก่อนหน้านั้น)

ผู้คนสนใจจริงๆ เกี่ยวกับสิ่งที่เป็นและไม่ใช่ REST และคุณอาจจะทำให้คนที่ใส่ใจเกี่ยวกับ REST จริงๆ ไม่พอใจด้วยการอธิบาย JSON-RPC ว่าเป็น REST JSON-RPC คือ "ระดับ 0" ของ Richardson Maturity Model ซึ่งเป็นแบบจำลองที่อธิบายคุณสมบัติของการออกแบบ REST อย่ากังวลมากเกินไปเพราะคุณสามารถสร้าง JSON-RPC ที่สงบ มีเหตุผล และเหมาะสมได้โดยทำบางสิ่ง

ขั้นแรก คุณต้องใช้ HTTP VERB อย่างถูกต้อง GET สำหรับการดึงข้อมูล (และไม่มีผลข้างเคียง) POST สำหรับ "การดำเนินการ" PUT สำหรับ "การสร้างสิ่งที่สถานะถูกควบคุมโดยไคลเอ็นต์" หลังจากนั้น ตรวจสอบให้แน่ใจว่าคุณจัดระเบียบ API ของคุณเป็น “ทรัพยากร” เชิงตรรกะ — แนวคิดโดเมนหลักของคุณ “ลูกค้า” “ผลิตภัณฑ์” “แคตตาล็อก” ฯลฯ

สุดท้าย ให้ใช้รหัสตอบกลับ HTTP ที่ถูกต้องสำหรับการโต้ตอบกับ API ของคุณ

คุณอาจไม่ได้ใช้ "ไฮเปอร์มีเดียเป็นเครื่องมือในสถานะแอปพลิเคชัน" แต่คุณอาจจะทำได้ดีพอที่จะไม่มีใครมาแย่งเลือดของคุณ

นอกจากนี้คุณยังจะได้รับประโยชน์มากมายจาก RESTful API โดยสมบูรณ์ด้วยการทำเพียงพอ — ทรัพยากรต่างๆ จะถูกนำทางผ่าน HTTP, เอกสารของคุณจะสามารถแคชได้, API ของคุณจะทำงานในเครื่องมือทั่วไปส่วนใหญ่ ใช้ไลบรารีแบบผยองหรือ OpenAPI เพื่อสร้างสคีมา และคุณก็เกือบจะทำในสิ่งที่คนส่วนใหญ่กำลังทำอยู่

แต่ฉันอ่านจากแฮกเกอร์นิวส์ว่า REST sux และ GraphQL เป็นวิธีที่จะไปใช่ไหม

ใช่แล้ว เราทุกคนก็อ่านโพสต์นั้นเหมือนกัน

GraphQL ทำให้เกิดความสับสน, ภาษาคิวรี, มาตรฐานสำหรับ HTTP API และเครื่องมือ Schema ทั้งหมดในคราวเดียว ด้วยการแพร่กระจายของแอปพลิเคชันเว็บฝั่งไคลเอ็นต์จำนวนมาก GraphQL ได้รับความนิยมโดยการผลักดันคำจำกัดความของข้อมูลที่ควรส่งคืนไปยังไคลเอ็นต์อย่างมีประสิทธิภาพลงในโค้ดไคลเอ็นต์เอง

นี่ไม่ใช่ครั้งแรกที่มีการแนะนำแนวทางสไตล์ "การสืบค้นจากส่วนหน้า" ประเภทนี้ และน่าจะไม่ใช่ครั้งสุดท้าย สิ่งที่ทำให้ GraphQL แตกต่างจากแนวทางก่อนหน้านี้เล็กน้อย (โดยเฉพาะอย่างยิ่ง OData ของ Microsoft) คือแนวคิดที่ว่า Types และ Queries จะถูกนำไปใช้กับโค้ด Resolver บนฝั่งเซิร์ฟเวอร์ แทนที่จะเพียงแค่แมปโดยตรงกับที่เก็บข้อมูล SQL บางส่วน

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

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

GraphQL เป็นเพียงวิธีที่ชาญฉลาดและมีประสิทธิภาพในการจัดทำ API ของคุณ และมอบ BFF ซึ่งเป็นแบ็คเอนด์สำหรับฟรอนต์เอนด์ ไม่ใช่เพื่อนที่ดีที่สุดตลอดไป ซึ่งเปลี่ยนแปลงได้อย่างรวดเร็ว

เพื่อนสนิท? BFF คืออะไร?

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

คุณเป็นโปรแกรมเมอร์เว็บที่พยายามทำงานให้เสร็จ และฟีเจอร์ใหม่เพิ่งเปิดตัว คุณอ่านเอกสาร

เอกสารจะอธิบายวิธีที่คุณต้องประสานการโทรระหว่าง API ต่างๆ ซึ่งทั้งหมดนี้ต้องใช้โทเค็น OAuth และการอ้างสิทธิ์ และในที่สุด คุณจะมีฟีเจอร์ใหม่ที่โดดเด่น

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

ขออภัย แบ็กเอนด์สำหรับส่วนหน้า

BFF คือ API ที่ให้บริการหนึ่งรายการ และโดยเฉพาะแอปพลิเคชันเดียวเท่านั้น แปลโดเมนภายใน (MEGACORPS BUSINESS) เป็นภาษาภายในของแอปพลิเคชันที่ให้บริการ โดยจะดูแลสิ่งต่างๆ เช่น การรับรองความถูกต้อง การจำกัดอัตรา และสิ่งที่คุณไม่ต้องการทำมากกว่าหนึ่งครั้ง ช่วยลดการไปกลับเซิร์ฟเวอร์โดยไม่จำเป็น และแปลข้อมูลให้เหมาะสมกับแอปพลิเคชันเป้าหมายมากขึ้น

ให้คิดว่ามันเป็น API สำหรับแอปของคุณเท่านั้นที่คุณควบคุม

และเครื่องมืออย่าง GraphQL และ OData นั้นยอดเยี่ยมสำหรับ BFF GraphQL gels เข้ากันได้ดีเป็นพิเศษกับส่วนหน้าที่ขับเคลื่อนด้วย JavaScript สมัยใหม่ พร้อมด้วยเครื่องมือที่ยอดเยี่ยม เช่น Apollo และ Apollo-Server ที่ช่วยเพิ่มประสิทธิภาพการโทรเหล่านี้โดยคำขอเป็นชุด

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

สิ่งอื่น ๆ ที่คุณอาจเห็นและเพราะเหตุใด

ตอนนี้เราเข้าใจเว็บเซิร์ฟเวอร์ เว็บแอป และ API ของเราแล้ว การเขียนโปรแกรมเว็บสมัยใหม่มีอะไรมากกว่านั้นอีกแน่นอน นี่คือสิ่งที่คุณอาจจะพบเจอบ่อยที่สุด

โหลดบาลานซ์

หากคุณโชคดีพอที่จะมีการเข้าชมไซต์ของคุณ แต่โชคไม่ดีที่ไม่ได้ใช้ผู้ให้บริการ Platform-as-a-Service (เพิ่มเติมในภายหลัง) คุณจะพบปัญหากับ Load Balancer ในบางจุด อย่าตื่นตกใจ. โหลดบาลานเซอร์พูดภาษาโบราณ มักดำเนินการโดย sysop ที่ไม่พอใจ หรือเพียงแค่เรียกใช้สำเนาของ NGINX

โหลดบาลานเซอร์ทั้งหมดที่ทำคือยอมรับคำขอ HTTP สำหรับแอปพลิเคชันของคุณ (หรือจากแอปพลิเคชันนั้น) เลือกเซิร์ฟเวอร์ที่ไม่ยุ่งมาก และส่งต่อคำขอ

คุณสามารถทำให้โหลดบาลานเซอร์ทำสิ่งที่บ้าบอทุกประเภทที่คุณอาจไม่ควรใช้โหลดบาลานเซอร์ทำ คนก็ยังจะพยายาม

คุณอาจเห็นโหลดบาลานเซอร์ปรับสมดุลโหลด “เส้นทางลัด” โดยเฉพาะในซอฟต์แวร์ของคุณไปยังกลุ่มฮาร์ดแวร์เฉพาะเพื่อพยายามรักษาความปลอดภัยหรือแยกออกจากความล้มเหลว คุณอาจเห็นโหลดบาลานเซอร์ที่ใช้ในการดูแลใบรับรอง SSL ให้กับคุณ ซึ่งเรียกว่าการยุติ SSL

แคชแบบกระจาย

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

การแคชแบบกระจายบุกเบิกโดย “Memcached” ซึ่งเดิมเขียนขึ้นเพื่อปรับขนาดแพลตฟอร์มบล็อก Livejournal ในปี 2003 ในขณะนั้น Memcached ช่วย Livejournal แบ่งปันสำเนาแคชของรายการล่าสุดทั้งหมดผ่านเซิร์ฟเวอร์จำนวนค่อนข้างน้อย ซึ่งช่วยลดภาระของเซิร์ฟเวอร์ฐานข้อมูลได้อย่างมาก ฮาร์ดแวร์เดียวกัน

แคชหน่วยความจำใช้เพื่อจัดเก็บผลลัพธ์ของสิ่งที่ "หนัก" ในการคำนวณ ต้องใช้เวลา หรือเพียงแค่ต้องสอดคล้องกันในคอมพิวเตอร์ทุกเครื่องที่ใช้ซอฟต์แวร์เซิร์ฟเวอร์ของคุณ เพื่อแลกกับเวลาแฝงของเครือข่ายเล็กน้อย ทำให้จำนวนหน่วยความจำทั้งหมดที่มีให้กับแอปพลิเคชันของคุณเป็นผลรวมของหน่วยความจำทั้งหมดที่มีอยู่ในเซิร์ฟเวอร์ทั้งหมดของคุณ

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

แคชแบบกระจายนั้นมีอยู่ทุกหนทุกแห่ง และผู้ให้บริการโฮสติ้งรายใหญ่ทั้งหมดมีแนวโน้มที่จะรองรับ memcached หรือ redis ที่เข้ากันได้ (อ่าน: คุณสามารถใช้ไลบรารีไคลเอนต์ memcached เพื่อเข้าถึงได้) แคชที่ได้รับการจัดการ

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

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

การแบ่งกลุ่มหน่วยความจำที่ใช้ร่วมกันขนาดใหญ่เช่นนี้เป็นเรื่องที่ชาญฉลาด เพราะมันทำให้การค้นหาสิ่งต่างๆ รวดเร็วเป็นพิเศษ ไม่มีคอมพิวเตอร์เครื่องใดที่ต้องสแกนหน่วยความจำจำนวนมากเพื่อดึงข้อมูลรายการหนึ่ง

เครือข่ายการจัดส่งเนื้อหา (CDN)

CDN เป็นเว็บเซิร์ฟเวอร์ที่ดำเนินการโดยบุคคลอื่นทั่วโลก คุณอัปโหลดข้อมูลของคุณไปยังพวกเขา และพวกเขาจะจำลองข้อมูลของคุณทั่วทั้ง “ขอบ” ของพวกเขา (คำโง่ ๆ ที่หมายถึง “ไปยังเซิร์ฟเวอร์ทั้งหมดทั่วโลกที่พวกเขาทำงาน”) ดังนั้นเมื่อมีคนร้องขอเนื้อหาของคุณ การตอบสนองของ DNS จะส่งคืนเซิร์ฟเวอร์ที่อยู่ใกล้พวกเขา และเวลาที่ใช้เพื่อดึงเนื้อหานั้นจะเร็วกว่ามาก

กลไกการทำงานของ CDN นั้นซับซ้อนกว่าการใช้ CDN มาก — แต่พวกมันก็เป็นตัวเลือกที่ดีหากคุณมีเนื้อหาคงที่ (รูปภาพ!) จำนวนมาก หรือโดยเฉพาะไฟล์ขนาดใหญ่ (วิดีโอ! ไบนารีขนาดใหญ่!) ยังมีประโยชน์อย่างยิ่งในการลดภาระโดยรวมบนเซิร์ฟเวอร์ของคุณ

การออฟโหลดไปยัง CDN เป็นหนึ่งในวิธีที่ง่ายที่สุดที่คุณจะได้รับประสิทธิภาพพิเศษโดยมีค่าใช้จ่ายเพียงเล็กน้อย

มาพูดถึงรูปแบบการออกแบบกันดีกว่า! นั่นคือสถาปัตยกรรมที่แท้จริง

“Design patterns are just bug fixes for your programming languages”

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

มาดูสิ่งที่พบบ่อยๆ กันอย่างรวดเร็ว:

  • MVC — “แยกโมเดลข้อมูล รหัส UI และตรรกะทางธุรกิจของคุณ เพื่อไม่ให้สับสน”
  • ORM — “การแมปวัตถุ-สัมพันธ์” — ใช้ไลบรารีการแมปและกฎที่กำหนดค่า เพื่อจัดการการจัดเก็บข้อมูลของออบเจ็กต์ในหน่วยความจำของคุณ ลงในการจัดเก็บข้อมูลเชิงสัมพันธ์ อย่ารวมวัตถุเข้าด้วยกันและเก็บมันไว้ด้วยกันที่ไหน”
  • บันทึกที่ใช้งานอยู่ — “ออบเจ็กต์ทั้งหมดของคุณควรสามารถช่วยตัวเองได้ เพราะสิ่งเหล่านี้เป็นเพียงแบบฟอร์มบนเว็บ ใครจะสนใจว่ามันจะเชื่อมโยงกับฐานข้อมูลหรือไม่!”
  • พื้นที่เก็บข้อมูล — “การเข้าถึงข้อมูลทั้งหมดของคุณอยู่ในคลาสนี้ — โต้ตอบกับมันเพื่อโหลดสิ่งต่างๆ”
  • มัณฑนากร — “เพิ่มหรือล้อม 'มัณฑนากร' รอบวัตถุ คลาส หรือฟังก์ชันเพื่อเพิ่มลักษณะการทำงานทั่วไป เช่น การแคช หรือการบันทึก โดยไม่เปลี่ยนแปลงการใช้งานดั้งเดิม”
  • การพึ่งพาการแทรก — “หากคลาสหรือฟังก์ชันของคุณขึ้นอยู่กับบางสิ่งบางอย่าง มันเป็นความรับผิดชอบของผู้เรียก (ซึ่งมักจะเป็นเฟรมเวิร์กที่คุณใช้) ในการจัดหาการพึ่งพานั้น”
  • โรงงาน — “ใส่โค้ดทั้งหมดที่คุณต้องการเพื่อสร้างหนึ่งในโค้ดเหล่านี้ ในที่เดียว และที่เดียวเท่านั้น”
  • อะแดปเตอร์ — “ใช้อะแดปเตอร์เพื่อเชื่อมช่องว่างระหว่างสิ่งที่ไม่สามารถทำงานร่วมกันได้ โดยการแปลการแสดงข้อมูลภายในเป็นข้อมูลภายนอก เช่นเดียวกับการแปลงการตอบกลับ Twitter ให้เป็น YourSocialMediaDataStructure”
  • คำสั่ง — “การดำเนินการหรือคำขอแยกกันแต่ละรายการถูกนำไปใช้ในที่เดียว”
  • กลยุทธ์ — “กำหนดหลายวิธีในการทำบางสิ่งที่สามารถสลับเข้าและออกได้”
  • ซิงเกิลตัน — “มีเพียงอันเดียวเท่านั้นในใบสมัครทั้งหมดของฉัน”

นั่นเป็นรายการโดยย่อของศัพท์เฉพาะรูปแบบบางส่วนที่คุณจะได้ยิน ไม่มีอะไรพิเศษเกี่ยวกับรูปแบบการออกแบบ มันเป็นเพียงเวอร์ชันปี 1990 ของคำตอบ stackoverflow ที่ได้รับการยอมรับและเป็นที่นิยม

สถาปัตยกรรมไมโครเซอร์วิส

สถาปัตยกรรมไมโครเซอร์วิสเป็นเพียง “คลื่นลูกที่สาม” ของการออกแบบเชิงบริการ

พวกเขามาจากไหน?

ในช่วงกลางทศวรรษที่ 90 “COM+” (บริการคอมโพเนนต์) และ SOAP ได้รับความนิยมเนื่องจากลดความเสี่ยงในการปรับใช้สิ่งต่าง ๆ โดยการแยกออกเป็นส่วนประกอบเล็กๆ — และมอบวิธีมาตรฐานและค่อนข้างง่ายในการพูดคุยข้ามขอบเขตกระบวนการ สิ่งนี้นำไปสู่การแพร่หลายของสถาปัตยกรรม "3-tier" และต่อมา "n-tier" สำหรับระบบแบบกระจาย

N-Tier เป็นการย่อสำหรับ “แยกชั้นข้อมูล ชั้นตรรกะทางธุรกิจ และชั้นการนำเสนอ” วิธีนี้ใช้ได้ผลสำหรับบางคน แต่ประสบปัญหาเนื่องจากการแบ่งส่วนในแนวนอนผ่านระบบมักจะต้องเปลี่ยน “ระดับ” ทุกอันจึงจะเสร็จสิ้นการเปลี่ยนแปลงทั้งหมด เอฟเฟกต์ระลอกคลื่นนี้ไม่ดีต่อความน่าเชื่อถือ

จากนั้นผู้จำหน่ายผลิตภัณฑ์ก็เข้ามามีส่วนร่วม และ SOAP ก็มีความซับซ้อนและไม่ทันสมัย ​​ซึ่งผลักดันให้ผู้คนเข้าสู่ “คลื่นลูกที่สอง” — Guerrilla SOA การออกแบบที่คล้ายกัน เพียงแต่ไม่มีพิธีการระดับสูง มีการแบ่งส่วนแนวตั้งอย่างสมบูรณ์มากขึ้น และมิดเดิลแวร์ของผู้ขายน้อยลง

สิ่งนี้นำไปสู่การขยายตัวของบริการขนาดเล็กและว่องไวมากขึ้น ในช่วงเวลาเดียวกับที่ Netflix กำลังส่งเสริม Hystrix ซึ่งเป็นแพลตฟอร์มสำหรับระบบที่มีความหน่วงแฝงและทนทานต่อข้อผิดพลาด

คลื่นลูกที่สามของ SOA ซึ่งมีตราสินค้าเป็นสถาปัตยกรรม Microservice (โดย James Lewis และ Martin Fowler) — ได้รับความนิยมอย่างมาก แต่อาจยังไม่เป็นที่เข้าใจมากนัก

ไมโครเซอร์วิสควรจะเป็นอะไร: บริการขนาดเล็ก มีประโยชน์อย่างอิสระ กำหนดเวอร์ชันได้อย่างอิสระ บริการจัดส่งได้อย่างอิสระซึ่งดำเนินการฟังก์ชันหรือการดำเนินการของโดเมนเฉพาะ

สิ่งที่ไมโครเซอร์วิสมักเป็น: บริการสายตาสั้นที่ขึ้นอยู่กับร่วมและเปราะบางซึ่งทำหน้าที่เป็นออบเจ็กต์การเข้าถึงข้อมูลผ่าน HTTP ซึ่งมักจะล้มเหลวในรูปแบบโดมิโน

การออกแบบไมโครเซอร์วิสที่ดีต้องปฏิบัติตามกฎง่ายๆ ไม่กี่ข้อ

  • ยึดตามบทบาท/การปฏิบัติงาน ไม่ใช่ศูนย์กลางข้อมูล
  • เป็นเจ้าของที่เก็บข้อมูลของคุณเสมอ
  • สื่อสารบนอินเทอร์เฟซหรือข้อความภายนอก
  • สิ่งใดที่เปลี่ยนแปลงร่วมกันและพึ่งพาอาศัยกัน แท้จริงแล้วคือสิ่งเดียวกัน
  • บริการทั้งหมดทนทานต่อข้อผิดพลาดและรอดพ้นจากการหยุดทำงานของการพึ่งพา

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

สถาปัตยกรรมหกเหลี่ยม

ตอนนี้ฟังดูเหมือน “Real Architecture TM” บางส่วน!

สถาปัตยกรรมหกเหลี่ยมหรือที่เรียกว่ารูปแบบ “พอร์ตและอะแดปเตอร์” ตามที่กำหนดโดย Alistair Cockburn เป็นหนึ่งในคำแนะนำที่ดีกว่า “สถาปัตยกรรมแอปพลิเคชันจริง”

พูดง่ายๆ ก็คือ มีตรรกะ กฎเกณฑ์ทางธุรกิจ สิ่งเฉพาะโดเมนทั้งหมดของคุณ อยู่ในรูปแบบที่ไม่เชื่อมโยงกับเฟรมเวิร์ก การขึ้นต่อกัน การจัดเก็บข้อมูล บัสข้อความ พื้นที่เก็บข้อมูล หรือ UI ของคุณ

"สิ่งภายนอก" ทั้งหมดนั้น "ถูกปรับ" ให้เข้ากับโมเดลภายในของคุณ และฉีดเข้าไปเมื่อจำเป็น

จริงๆแล้วมันมีลักษณะเป็นอย่างไร? ตรรกะทั้งหมดของคุณอยู่ในไฟล์ โมดูล หรือคลาสที่ปราศจากโค้ดเฟรมเวิร์ก กาว หรือการเข้าถึงข้อมูลภายนอก

ทำไม หมายความว่าคุณสามารถทดสอบทุกอย่างแยกกัน โดยไม่ต้องมีเฟรมเวิร์กเว็บหรือ API ที่ใช้งานไม่ได้มาขัดขวาง การรักษาตรรกะของคุณให้ชัดเจนจากข้อกังวลภายนอกทั้งหมดเหล่านี้เป็นวิธีที่ปลอดภัยในการออกแบบแอปพลิเคชัน

มีแนวทางที่สองที่ได้รับความนิยมมากซึ่งเรียกว่า "แอปสิบสองปัจจัย" ซึ่งส่วนใหญ่มีเป้าหมายการออกแบบเดียวกันนี้ โดยมีกฎที่กำหนดอีกสองสามข้ออยู่ด้านบน

การปรับขนาด

การปรับขนาดเป็นเรื่องยากหากคุณลองทำด้วยตัวเอง ดังนั้นอย่าลองทำด้วยตัวเองเด็ดขาด

ใช้ระบบคลาวด์ที่ผู้จำหน่ายจัดเตรียมไว้ให้ เช่น Google App Engine, Azure Web Apps หรือ AWS Lambda พร้อมเปิดใช้งานการรองรับการปรับขนาดอัตโนมัติ หากคุณสามารถหลีกเลี่ยงได้

ลองวาง API ของคุณบนสแต็กแบบไร้เซิร์ฟเวอร์ ยิ่งคุณได้รับสิ่งที่เป็นนามธรรมมากเท่าไร การปรับขนาดก็จะง่ายขึ้นเท่านั้น

ภูมิปัญญาดั้งเดิมกล่าวว่า “การขยายขนาดเป็นเพียงสิ่งเดียวที่คุ้มค่า” แต่บริษัทที่ประสบความสำเร็จจำนวนมากก็สามารถขยายขนาดได้ด้วยเครื่องจักรขนาดใหญ่หรือ VM จำนวนหนึ่ง การขยายขนาดให้ประโยชน์อื่นๆ แก่คุณ (ซึ่งมักจะเกี่ยวข้องกับการกระจายทางภูมิศาสตร์ หรือความยืดหยุ่นข้าม Availability Zone) แต่อย่ารู้สึกแย่หากผู้ที่เหลือเพียงคนเดียวที่คุณมีคือคนเดียวที่ติดป้ายว่า "มีพลังมากขึ้น"

รูปแบบสถาปัตยกรรมสำหรับระบบแบบกระจาย

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

มีสองสิ่งที่มีประโยชน์เสมอ

เซอร์กิตเบรกเกอร์ทุกที่

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

หลังจากนั้นครู่หนึ่ง คุณปล่อยให้คำขอเดียวไหลผ่านวงจร (สถานะ "เปิดครึ่งหนึ่ง") และหากสำเร็จ คุณจะ "ปิด" วงจรอีกครั้ง และปล่อยให้คำขอที่อยู่ในคิวทั้งหมดไหลผ่าน

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

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

Idempotency และลองใหม่

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

สิ่งนี้หมายความว่า? คุณควรออกแบบการเรียกของคุณให้ไม่ทำลายถ้าคุณส่งสองครั้ง (ค่าเดิม) และถ้าคุณมีการเรียกที่กำหนดค่าให้ลองใหม่เมื่อมีข้อผิดพลาด บางทีคุณอาจถอยออกไปเล็กน้อย (ถ้าไม่ใช่แบบทวีคูณ) เมื่อเกิดความล้มเหลวซ้ำ ๆ - อย่างน้อยที่สุดก็เพื่อให้สิ่งที่คุณเรียกว่ามีเวลาฟื้นตัว

กั้น

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

คุณสามารถปกป้องทรัพยากร ความจุ หรือฮาร์ดแวร์กายภาพที่สงวนไว้สำหรับชิ้นส่วนของซอฟต์แวร์ของคุณได้ เพื่อให้การหยุดทำงานของระบบส่วนหนึ่งไม่กระเพื่อมไปยังอีกส่วนหนึ่ง

คุณสามารถตั้งค่าขีดจำกัดการทำงานพร้อมกันสูงสุดสำหรับการโทรบางอย่างในระบบแบบมัลติเธรด ใช้การหมดเวลาอย่างรอบคอบ (ดีกว่าการหมดเวลา ดีกว่าล็อคและล้มลง) และแม้กระทั่งสำรองฮาร์ดแวร์หรือความจุสำหรับฟังก์ชันทางธุรกิจที่สำคัญ (เช่น การชำระเงิน หรือการชำระเงิน)

สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์พร้อมบันทึกการเล่นซ้ำ / ข้อความ

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

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

ฉันจำเป็นต้องมี Kubernetes เพื่อสิ่งนั้นหรือไม่?

ไม่ คุณอาจไม่มีปัญหาเรื่องการปรับขนาดแบบเดียวกับที่ Google พบ

ด้วยความนิยมของนักเทียบท่าและคอนเทนเนอร์ ทำให้มีกระแสฮือฮามากมายในสิ่งต่าง ๆ ที่นำเสนอนามธรรมที่ "เกือบจะเหมือนแพลตฟอร์ม" เหนือ Infrastructure-as-a-Service สิ่งเหล่านี้ล้วนเป็นงานหนักและมีราคาแพงมาก

หากคุณสามารถจัดการมันได้ในทางใดทางหนึ่ง ให้ใช้สิ่งที่ใกล้เคียงที่สุดกับแพลตฟอร์มที่มีการจัดการเพียงอย่างเดียวเท่าที่จะทำได้ Azure App Services, Google App Engine และ AWS Lambda จะมีประสิทธิผลมากขึ้นสำหรับคุณในฐานะโปรแกรมเมอร์ สิ่งเหล่านี้จะง่ายต่อการดำเนินการในการผลิต รวมถึงอธิบายและสนับสนุนได้มากขึ้น

Kubernetes (มักเรียกสั้น ๆ ว่า k8s อย่างน่ารำคาญ พร้อมด้วยระบบนิเวศที่ยอดเยี่ยมของการเพิ่มเติมที่มีชื่อลึกลับ เช่น helm และ flux) ต้องใช้ทีมปฏิบัติการเต็มเวลาในการดำเนินงาน และแม้แต่ใน “โหมดผู้จำหน่ายที่ได้รับการจัดการ” บน EKS/AKS/GKS เส้นโค้งการเรียนรู้ก็ยังอยู่ ชันกว่าทางเลือกอื่นมาก

เฮโรกุ? บริการแอพ? แอพเอ็นจิ้น? สิ่งเหล่านี้คือสิ่งที่คุณจะสามารถตั้งค่าสำหรับการผลิตได้ด้วยตัวเองภายในไม่กี่นาทีหรือเพียงไม่กี่ชั่วโมง

คุณจะเห็นความกดดันในการผลักดันโซลูชัน "Cloud Neutral" โดยใช้ Kubernetes ในที่ต่างๆ — แต่นั่นก็คือน้ำมันงู ความเป็นกลางบนคลาวด์หมายถึงคุณต้องจ่ายค่าใช้จ่ายในการย้ายระบบคลาวด์ (การรักษาสิ่งที่เป็นนามธรรม การแยกทางของคุณออกจากคุณสมบัติเฉพาะของผู้จำหน่ายที่เป็นประโยชน์) ตลอดไป แทนที่จะในสถานการณ์ (ไม่น่าเป็นไปได้เป็นพิเศษ) ที่คุณเปลี่ยนผู้จำหน่ายระบบคลาวด์

การใช้เทคโนโลยีอย่างรับผิดชอบรวมถึงการใช้สิ่งที่เหมาะสมที่สุดกับปัญหาและขนาดที่คุณมี

คำแนะนำที่สมเหตุสมผล

ทำสิ่งที่ง่ายที่สุดที่สามารถทำได้เสมอ สถาปัตยกรรมมีค่าใช้จ่าย เช่นเดียวกับทุกนามธรรม คุณต้องแน่ใจว่าคุณได้รับประโยชน์ก่อนที่จะดำดิ่งลงสู่รูปแบบสถาปัตยกรรมที่ซับซ้อนบางอย่าง

บ่อยครั้งที่สถาปัตยกรรมที่ดีที่สุดคือสถาปัตยกรรมที่เรียบง่ายที่สุดและคล้อยตามการเปลี่ยนแปลงได้มากที่สุด