project omega
รูปแบบสถาปัตยกรรมเว็บระดับองค์กรล่าสุดที่คุณต้องการ จนกว่าจะถึงครั้งต่อไป
TL;ดร
เป้าหมายคือการเพิ่มประสิทธิภาพประสบการณ์ของนักพัฒนาซอฟต์แวร์โดยสามารถ:
- พัฒนาในท้องถิ่นราวกับว่ามันเป็นเสาหิน
- ปรับใช้เป็นไมโครเซอร์วิสที่แยกจากกัน
- จำลองสภาพแวดล้อมการผลิตภายในเครื่องโดยใช้นักเทียบท่า
สาธิต
project omega Proof of Concept - Microservices Monolith Hybrid
project omega สาธิต - Kubernetes Microserves และการปรับใช้คอนเทนเนอร์แบบสแตนด์อโลน
ทำไม
ฉันต้องการพิสูจน์ว่าเราไม่จำเป็นต้องเสียสละประสิทธิภาพของนักพัฒนาเพื่อให้ได้ความสามารถในการปรับขนาด พูดคุยเพิ่มเติมเกี่ยวกับข้อดีข้อเสียของไมโครเซอร์วิสและโมโนลิธได้ที่นี่: ไมโครเซอร์วิสและโมโนลิธ
ความประทับใจของฉันคือผู้เชี่ยวชาญในอุตสาหกรรมหลายคนอยากให้เราเชื่อว่านี่คือ 3 ตัวเลือกหลักของเรา:
- เสาหิน
- ไมโครเซอร์วิส
- "ไฮบริด" (ไม่ใช่ไฮบริดจริงๆ ทั้งแบบเสาหินและไมโครเซอร์วิสบางตัว)
ฉันต้องการแสดงให้เห็นว่าเราไม่จำเป็นต้องเลือกตัวเลือกใดๆ เหล่านี้ ด้วยความคิดสร้างสรรค์เล็กๆ น้อยๆ เราก็สามารถมี "ไฮบริด" ที่แท้จริงที่เป็นทั้งโมโนลิธและชุดไมโครเซอร์วิสได้ ด้วยกลยุทธ์ปัจจุบันของฉัน ฉันคิดว่าเราไม่สามารถกำจัดข้อเสียของโมโนลิธและไมโครเซอร์วิสได้ทั้งหมด แต่เราสามารถกำจัดปัญหาหลายๆ ข้อของทั้งสองอย่างได้
สิ่งที่มันไม่ใช่
- ฉันไม่ได้พยายามสร้างกรอบงาน (ยังไม่ใช่อย่างน้อย...) ฉันแค่รวบรวมเลโก้ทั้งหมดที่ฉันมีไว้ในรูปแบบที่แตกต่างกันเพื่อเป็นการทดลอง
- นี่ไม่ใช่โครงการเพื่อชุมชน ฉันตั้งใจที่จะทำการเปลี่ยนแปลงครั้งใหญ่บ่อยครั้งโดยไม่ต้องแจ้งให้ทราบล่วงหน้า หากแนวคิดนี้ดูน่าสนใจสำหรับคุณและคุณต้องการมีส่วนร่วม โปรดติดต่อฉันก่อน
เป้าหมายโครงการ
- สร้างรูปแบบที่จะใช้ได้กับโปรเจ็กต์ที่เป็นงานอดิเรกสำหรับนักพัฒนารายย่อยขนาดเล็ก และยังปรับขนาดเป็นนักพัฒนาหลายสิบหรือหลายร้อยรายที่ทำงานบนเว็บแอปพลิเคชันระดับองค์กรขนาดใหญ่และซับซ้อน
- สามารถพัฒนาในท้องถิ่นได้เสมือนเป็นเสาหิน:
- ที่เก็บข้อมูลแห่งหนึ่ง ด้วยเหตุผลเดียวกันทั้งหมด บริษัทต่างๆ จึงเลือกแนวทาง monorepo
- สูงสุด 3 กระบวนการที่จะรัน (ui ไคลเอนต์, เซิร์ฟเวอร์, การพึ่งพานักเทียบท่ากับฐานข้อมูล, คิวข้อความ ฯลฯ ) เราไม่ต้องการให้หน้าเอกสารการตั้งค่าเริ่มทำงาน
- สามารถปรับใช้เป็นไมโครเซอร์วิสได้
- สามารถจำลองสภาพแวดล้อมการใช้งานจริงด้วยไมโครเซอร์วิสที่ทำงานในคอนเทนเนอร์นักเทียบท่า
- เวลาติดตั้งที่รวดเร็วมาก การขึ้นต่อกันทั้งหมดนอกเหนือจาก Node และ .NET ควรรวมไว้เป็นการขึ้นต่อกันของนักเทียบท่า (ฐานข้อมูล คิวข้อความ ฯลฯ) ผู้ใช้ใหม่ควรสามารถติดตั้ง .NET, Node, โคลน repo จากนั้นดำเนินการติดตั้งและรันคำสั่ง
- โหลดซ้ำอย่างรวดเร็วมากสำหรับทั้งไคลเอนต์และเซิร์ฟเวอร์ในสภาพแวดล้อมการพัฒนา
- สามารถพัฒนาและรันแอพพลิเคชั่นบน Windows, Linux และ Mac ได้
- สามารถหมุนบริการใหม่ได้อย่างรวดเร็ว
เทคสแต็ค
Tech Stack ส่วนใหญ่ไม่เกี่ยวข้องกับแนวคิดระดับสูงที่ฉันพยายามพิสูจน์ แต่สำหรับโปรเจ็กต์นี้ ฉันจะใช้:
- .NET 5 สำหรับบริการ
- ตอบสนองส่วนหน้า (แอป create-react- พื้นฐานพร้อม typescript)
- นักเทียบท่า
แนวคิดระดับสูง
บริษัทที่มีแอปพลิเคชันขนาดใหญ่กำลังถูกผลักดันไปสู่ไมโครเซอร์วิสมากขึ้นเรื่อยๆ เพื่อให้สามารถขยายขนาดในแนวนอนได้ (ด้วยเหตุผลอื่นๆ) ดังนั้น เพื่อให้บรรลุผลสำเร็จ เรากำลังดูสิ่งต่อไปนี้:
นี่เป็นอีกเวอร์ชันหนึ่งที่แสดงวิธีหนึ่งในการปรับใช้มาตราส่วนแนวนอน:
เมื่อเราเดินไปตามเส้นทางนี้ก็จะพบกับปัญหาการพัฒนาท้องถิ่นอย่างแท้จริง มันขึ้นอยู่กับว่าผลิตภัณฑ์นั้นเป็นอย่างไร มีนักพัฒนากี่คน และใครทำงานอะไร และบ่อยแค่ไหน ดังที่กล่าวไปแล้ว บริษัทส่วนใหญ่ที่เลือกไมโครเซอร์วิสจะจบลงด้วยสถานการณ์ที่นักพัฒนาต้องตัดสินใจเลือกที่ยากลำบากเกี่ยวกับวิธีการพัฒนาในแต่ละวัน ด้วย project omega เป้าหมายคือการแสดงให้เห็นว่าเราสามารถขจัดค่าใช้จ่ายในการเรียกใช้บริการภายในเครื่องได้โดยการรวมบริการทั้งหมดไว้ในแอปพลิเคชันเดียวในขณะที่ทำงานภายในเครื่อง:
นี่คือโครงสร้างโฟลเดอร์:
และนี่คือลักษณะการใช้งานแบบไมโครเซอร์วิส:
แต่ละอินสแตนซ์จะมีสำเนาของโค้ดทั้งหมด แต่จะเรียกใช้เฉพาะการเริ่มต้น เส้นทางจุดสิ้นสุดของบริการ และกระบวนการของผู้ปฏิบัติงานสำหรับไมโครเซอร์วิสเฉพาะเท่านั้น
ด้วยเหตุนี้จึงเป็นเรื่องง่ายมากที่จะเรียกใช้แอปพลิเคชันภายในเครื่องในรูปแบบโมโนลิธ เนื่องจากเราเพียงมองหาตัวแปรสภาพแวดล้อมที่เรียกว่า SERVICE_KEY
หรือหากไม่มีอยู่ ให้เริ่มต้นบริการทั้งหมด
ตัวอย่างของการเริ่มต้นเฉพาะบริการอื่นๆ:
- การตั้งค่าการฉีดพึ่งพา
- สตริงการเชื่อมต่อฐานข้อมูล
- การย้ายฐานข้อมูล
- การเริ่มต้นคิวข้อความ
- ตั้งค่าการเชื่อมต่อแคชแบบกระจาย
- การตั้งค่าการเชื่อมต่อทรัพยากรระบบคลาวด์อื่นๆ
- การเริ่มต้น API ของบุคคลที่สาม
เมื่อเรียกใช้ Startup ระบบจะสแกนแอสเซมบลีสำหรับประเภทที่สืบทอด ProjectOmegaService
สร้างอินสแตนซ์และรันตรรกะการเริ่มต้นของบริการนั้น เมื่อรันในเครื่องมันจะรันทั้งหมด
คำแนะนำในการตั้งค่า
ติดตั้งข้อกำหนดเบื้องต้น:
- .NET5
- โหนด
- เส้นด้าย
- นักเทียบท่า
โปรดทราบว่าการใช้งาน Docker เวอร์ชันล่าสุดบน Windows อาจต้องมีขั้นตอนเพิ่มเติมหากคุณไม่ได้ดำเนินการมาระยะหนึ่งแล้ว เช่น การติดตั้ง WSL 2 และรีเฟรช WSL distro ของคุณ ทำตามคำแนะนำบนเว็บไซต์ของ Docker
ขั้นตอน:
- โคลนที่เก็บนี้
- ในเทอร์มินัลจากรูท repo ให้
yarn run installAll
- หากคุณต้องการรันเซิร์ฟเวอร์ SQL บนพอร์ตอื่นที่ไม่ใช่ 1434:
- รัน
yarn run syncEnvFiles
- เปลี่ยน
OMEGA_DEFAULT_DB_PORT
และ OMEGA_MSSQL_HOST_PORT
ใน .env.server
- เริ่มต้นการพึ่งพาโดยใช้คำสั่ง
yarn run dockerDepsUpDetached
- เรียกใช้การย้ายฐานข้อมูลในครั้งแรกที่คุณเรียกใช้ หรือเมื่อคุณได้รับการเปลี่ยนแปลงจากบุคคลอื่นด้วยการอัพเดตฐานข้อมูล:
yarn run dbMigrate
- เรียกใช้แอปในโหมดการพัฒนาในเครื่องโดยใช้หนึ่งในตัวเลือกเหล่านี้:
- ตัวเลือกที่ 1: ในเทอร์มินัลจาก repo root run
yarn run both
(ใช้พร้อมกันเพื่อรันคำสั่งจากตัวเลือก 2) - ตัวเลือกที่ 2: ใช้ 2 เทอร์มินัลแยกกัน ในเท
yarn run client
และใน yarn run server
อื่น
- เข้าถึง https://localhost:3000 (คลิกคำเตือน https ที่ผ่านมา)
ก่อนที่จะรันการทดสอบหน่วยด้วย dotnet test
ในครั้งแรกหรือหลังจากเพิ่มการทดสอบหน่วยบนสคีมา DB ใหม่:
- เริ่มต้นการพึ่งพาหากยังไม่ได้รันด้วย
yarn run dockerDepsUpDetached
- รัน
yarn run testDbMigrate
- จากนั้นทำการ
dotnet test
วิธีจำลองการผลิตและไมโครเซอร์วิสในนักเทียบท่า:
- ตรวจสอบให้แน่ใจว่าการพึ่งพานักเทียบท่ากำลังทำงานอยู่ด้วย
yarn run dockerDepsUpDetached
- ในเทอร์มินัลจากรูท repo ให้
yarn run dockerRecreateFull
- เข้าถึง https://localhost:3000 (คลิกคำเตือน https ที่ผ่านมา)
ขั้นตอนต่อไป
- การบันทึกการเปลี่ยนแปลง
- ทดลองใช้ฟอร์แมตเตอร์ Serilog json
- เพิ่มรหัสความสัมพันธ์และข้อมูลบริบทอื่นๆ ลงในรายการบันทึก
- เพิ่มเอกสารเพิ่มเติม
- ไดอะแกรมแสดงวิธีการทำงานของการจำลองนักเทียบท่า
- การพึ่งพานักเทียบท่า
- ข้อความอธิบายว่ามันคืออะไร ทำงานอย่างไร
- แผนภาพแสดงวิธีที่ docker deps เข้ากับกระบวนการพัฒนา
- เอกสารการกำหนดเส้นทาง/พร็อกซี
- การโยกย้ายฐานข้อมูล
- ทดสอบ RPC ระหว่างบริการแทนการโทรที่เหลือ http (อาจมีบางอย่างเช่นนี้: https://github.com/aspnet/AspLabs/tree/main/src/GrpcHttpApi )
- เพิ่มไปยังคลาสฐานไคลเอนต์บริการระหว่างการจัดการและการบันทึกข้อผิดพลาดเชิงนามธรรม
- การดำเนินการรับรองความถูกต้อง
- การลงทะเบียนไซต์ส่วนหน้า
- บริการเพื่อให้บริการรับรองความถูกต้อง (OAuth?)
- การสร้างเอกสารอัตโนมัติ (เอาต์พุตเอกสาร swagger และ html xml)
- การตั้งค่าคิวและบริการกระบวนการของผู้ปฏิบัติงาน
- คำจำกัดความของคิวนามธรรม (เพื่ออนุญาตให้ใช้บริการคลาวด์เป็นตัวเลือก)
- บริการประเภทกระบวนการของผู้ปฏิบัติงานขั้นพื้นฐานพร้อมลูปเหตุการณ์ที่ค้นหาข้อความ
- RabbitMQ ใน docker-compose.deps.yml
- การใช้งานพื้นฐานของ RabbitMQ เชื่อมต่อกับบริการกระบวนการของผู้ปฏิบัติงาน
- งานสาธิต Kubernetes ในพื้นที่เพิ่มเติม
- ฐานข้อมูลอาจจำเป็นต้องเรียนรู้วิธีใช้วอลุ่มถาวรของ kubernetes เว้นแต่ฉันจะรู้วิธีปรับเครือข่ายเพื่อแสดงฐานข้อมูลโฮสต์
- เพิ่ม Seq หรือทำให้ฟังก์ชัน Seq เป็นตัวเลือก และอย่าใช้เมื่อทำงานใน Kubernetes
- โครงการ Meta/สคริปต์เพื่อวิเคราะห์โซลูชัน
- วิเคราะห์บริการที่ได้รับผลกระทบตามไฟล์ที่เปลี่ยนแปลง (สำหรับรายละเอียดการปรับใช้งาน)
- โครงการนั่งร้าน:
- ความสามารถในการหมุนสำเนาใหม่ของโปรเจ็กต์โดยใช้ "คีย์" ของโปรเจ็กต์อื่นนอกเหนือจาก Omega สำหรับชื่อโปรเจ็กต์/ไดเร็กทอรีทั้งหมด
- ความสามารถในการให้โปรเจ็กต์ใหม่หมุนคอนเทนเนอร์นักเทียบท่าและทำการทดสอบการบูรณาการอย่างมีประสิทธิภาพเพื่อให้แน่ใจว่าการสร้างโปรเจ็กต์ใหม่จะประสบความสำเร็จ
เบ็ดเตล็ด
หากคุณกำลังพัฒนาบน linux คุณอาจพบข้อผิดพลาดนี้เมื่อเริ่มต้นเซิร์ฟเวอร์:
System.AggregateException: เกิดข้อผิดพลาดอย่างน้อยหนึ่งรายการ (ถึงขีดจำกัดผู้ใช้ที่กำหนดค่าไว้ (128) ในจำนวนของอินสแตนซ์ inotify หรือถึงขีดจำกัดต่อกระบวนการของจำนวนตัวอธิบายไฟล์ที่เปิดแล้ว)
อาจเกิดจากการใช้ vscode เฝ้าดูไฟล์มากเกินไป คุณสามารถเพิ่มขีดจำกัดอินสแตนซ์ inotify
ของคุณได้ (ไม่ใช่แค่จำกัดการเฝ้าดู ซึ่งอาจตั้งค่าไว้สูงมากในไฟล์ /etc/sysctl.conf
ของคุณแล้ว) ได้โดยการรันคำสั่งนี้:
echo fs.inotify.max_user_instances=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
เอกสารอื่นๆ
การวิเคราะห์ผลประโยชน์ต้นทุนรูปแบบการออกแบบ: DesignPatternCostBenefit.md
รูปแบบการออกแบบที่หลากหลาย: DesignPatternVariations.md
การตัดสินใจ: Decisions.md
ปรัชญาและการพูดจาโผงผางการพัฒนาซอฟต์แวร์: https://gist.github.com/mikey-t/3d5d6f0f5316abf9e74fb553be9fdef3