การทำ Microservice ด้วย Nestjs
Microservice คือรูปแบบสถาปัตยกรรมรูปแบบหนึ่งที่ทำการแยกส่วนต่าง ๆ ออกมาเป็นเซอร์วิสย่อย ๆ ซึ่งเซอร์วิสใดที่มีการใช้งานมาก ๆ ก็จะสามารถทำระบบขยายเพื่อให้รองรับกับความต้องการ และสามารถที่จะทำการแยกส่วนของการ Deploy ได้ด้วย เมื่อทำการแยกส่วนออกมาแล้วจากหนึ่งทีมดูแลระบบเดียว ก็จะกลายเป็นแต่ละทีมสามารถที่จะดูแลเซอร์วิสต่าง ๆ แยกออกจากกันได้ และในแต่ละเซอร์วิสก็สามารถที่จะแยกใช้เทคโนโลยีหรือเครื่องมือได้อย่างอิสระ ซึ่งเซอร์วิสต้องทำงานได้ถึงแม้เซอร์วิสอื่น ๆ ที่ทำงานอยู่ร่วมกันจะพังก็ตาม
ข้อดีสำหรับการทำ Microservice
-
ความสามารถในการขยาย คือ Microservice อนุญาตให้แต่ละเซอร์วิสนั้นทำงานแยกออกจากกันทำให้เซอร์วิสที่รองรับการใช้งานเยอะ สามารถขยายเครื่องเฉพาะเซอร์วิสนั้น ซึ่งจะช่วยลดค่าใช้จ่ายและการปรับปรุงประสิทธิภาพ
-
มีความยืดหยุ่นและความคล่องตัว คือ Microservice มีจุดเด่นเรื่องความยืดหยุ่นและคล่องตัวในการพัฒนา นั่นคือแต่ละเซอร์วิสจะสามารถเลือกใช้เทคโนโลยี วิธีการ Deploy หรือการอัปเดตที่แตกต่างกันได้
-
การแบ่งแยกเซอร์วิสในการใช้งานจะแบ่งออกเป็นหลายเซอร์วิส ทำให้หากมีเซอร์วิสใดเกิดพังขึ้นมา เซอร์วิสที่เหลือก็ยังสามารถคงทำงานต่อไปได้ โดยไม่ได้รับผลกระทบจากเซอร์วิสที่พังไป การแยกกันของเซอร์วิสจะช่วยให้ทำการระบุปัญหาที่เกิดได้ง่ายขึ้น
-
ใช้เทคโนโลยีและเครื่องมือได้หลากหลาย คือ Microservice นั้นอนุญาตให้ใช้เทคโนโลยีหรือเครื่องมือที่แตกต่างกันในการพัฒนาสำหรับแต่ละเซอร์วิส
-
ง่ายต่อการบำรุงรักษาและอัปเดตข้อมูล คือ Microservice สามารถที่จะอัปเดตข้อมูลแยกออกจากกันโดยไม่มีผลกระทบต่อเซอร์วิสอื่น ทำให้ง่ายต่อการอัปเดตเซอร์วิส การแก้ไขบัค หรือการเพิ่มฟีเจอร์ใหม่เข้าไป
-
ใช้ทีมที่มีประสบการณ์ต่างกันได้ ในการพัฒนานั้นไม่จำเป็นต้องใช้เครื่องมือหรือภาษาเดียวกัน ทำให้ทีมต่าง ๆ สามารถเข้าไปพัฒนาหรือดูแลในส่วนเซอร์วิสที่ถนัด
-
มีความยืดหยุ่นและอดทนต่อความผิดพลาด ถ้าหากเซอร์วิสใดพังหรือทำงานไม่ได้ ส่วนที่เหลือก็ยังคงสามารถทำงานต่อไปได้
ข้อเสียสำหรับการทำ Microservice
-
ความซับซ้อน คือ Microservice มีการออกแบบที่ซับซ้อนกว่า Monolithic ดังนั้นการจัดการเซอร์วิส จำนวนมากอาจจะเกิดความท้าทายขึ้นได้ ทั้งในด้านการออกแบบ การวางระบบ และการบำรุงรักษา
-
การจัดการด้านข้อมูล โดยปกติจะมีฐานข้อมูลเป็นของตัวเอง จึงทำให้เกิดความซับซ้อนในการจัดการข้อมูลให้ข้อมูลเท่ากัน ระหว่างเซอร์วิสต่าง ๆ ซึ่งการพัฒนาระบบที่รองรับการทำธุรกรรมที่หลากหลายจะมีความยากและซับซ้อน บางครั้งอาจเกิดปัญหาเรื่องประสิทธิภาพอีกด้วย
-
ต้องเทสความถูกต้องหลายครั้ง การเทส Microservice จะมีความซับซ้อนมากกว่า Monolithic เพราะต้องทำให้มั่นใจว่าเซอร์วิสที่มีอยู่จะทำงานร่วมกัน ต้องมีการทดสอบแต่ละเซอร์วิสก่อนที่จะไปทดสอบการเชื่อมต่อระหว่างเซอร์วิสอีกครั้ง
-
การจัดการงานที่เยอะขึ้น การจัดการและตรวจสอบระบบของ Microservice จำนวนมากนั้นมีความยากมากขึ้น เช่น การทำ Load Balance เชื่อมต่อเซอร์วิส การค้นหาปัญหาของแต่ละเซอร์วิส
-
การสื่อสารที่มากเกินไป การติดต่อสื่อสารกันระหว่างเซอร์วิสอาจจะนำไปสู่การเพิ่มขึ้นของปริมาณการใช้ Internet ซึ่งอาจจะทำให้ได้ผลลัพธ์ช้า อาจจะทำให้เกิดผลกระทบต่อภาพรวมของระบบ
Nestjs นั้นมีรูปแบบที่เอาไว้สื่อสารกันระหว่างเซอร์วิสเรียกว่า Pattern โดยจะมี 2 แบบ คือ
-
การสื่อสารทางเดียว (Event Pattern)
-
การสื่อสารไปและกลับ (Message Pattern)
ยกตัวอย่างสถานการณ์ เช่น ผู้ชายกับผู้หญิงกำลังหารือกันว่าจะไปกินบุฟเฟ่ต์ร้านใด ฝ่ายชายอยากจะกินชาบู แต่ฝ่ายหญิงอยากกินปิ้งย่าง ทำให้ทะเลาะกัน หลายวันผ่านไปผู้ชายได้คุยเรื่องนี้กับเพื่อนคนหนึ่งถึงปัญหา เพื่อนของผู้ชายได้รับฟังจึงเสนอจะทำแอปพลิเคชันสำหรับสุ่มร้านบุฟเฟต์ขึ้นมา
จากเรื่องราวข้างต้น เราจะมาพัฒนาระบบให้อยู่ในรูปแบบ Microservice กันครับ โดยจะมีด้วยกัน 3 Microservice
-
nestjs-Microservice-backend เป็นตัวกลางที่ใช้สื่อสารกับ Microservice ตัวอื่น ๆ
-
nestjs-add-buffet เป็นเซอร์วิสที่ใช้สำหรับเพิ่มร้านบุฟเฟ่ต์
-
nestjs-random-buffet เป็นเซอร์วิสที่ใช้สำหรับสุ่มร้านบุฟเฟ่ต์
Source code : https://github.com/nattaphonBuNat/nestjs-Microservice-buffet-random
สำหรับคนที่ยังไม่ได้ติดตั้ง ให้ทำตาม Document
สร้าง Project nest ขึ้นมาด้วยคำสั่งดังต่อไปนี้
nest new nestjs-Microservice-backend
nest new nestjs-add-buffet
nest new nestjs-random-buffet
หากสร้างเสร็จแล้วจะได้มา 3 nestjs project ครับ
จากนั้นแต่ละ Project ต้องติดตั้ง Dependency ด้วยนั้นคือ nestjs/Microservice
yarn add @nestjs/Microservices
เริ่มด้วยการไประบุช่องทางเชื่อมต่อให้กับเซอร์วิสเพิ่มเมนูกันครับ โดยให้เข้าไปยัง Folder nestjs-add-buffet จะเจอไฟล์ main.ts
จากรูปเราจะประกาศช่องทางสื่อสารโดยใช้เป็น TCP ที่ port 3001 สำหรับให้ nestjs-Microservice-backend สื่อสารกัน
จากนั้นไปยัง app.controller.ts เราจะมาทำการสร้าง eventPattern โดยจะถูกทำงานก็ต่อเมื่อมีเซอร์วิสใดก็ตามเรียกใช้ buffet_menu_created
จากนั้นไปแก้ไข app.service.ts โดยจะมีหน้าที่แค่รับข้อมูลและแสดงออกมา
ทำการสร้าง create-buffet-menu-event.ts เป็นโครงสร้างสำหรับรับ-ส่งข้อมูล
ถัดมาจะกลับไปที่ nestjs-Microservice-backend โดยจะทำการ import ช่องทางที่ใช้ในการสื่อสารกันระหว่างเซอร์วิส โดยระบุ name เป็น ADD_BUFFET (จะเป็นชื่ออะไรก็ได้ครับ) ส่วนช่องทางสื่อสารตอนนี้ใช้เป็น TCP แต่หากเป็น redis หรือช่องทางอื่นก็จะมีวิธีตั้งค่าอีกแบบนึง
จากนั้นมายัง app.controller.ts จะทำการสร้างAPI ที่ใช้ในการเพิ่มเมนู buffet กันซึ่งจะใช้ Method Post ครับ
ไปต่อที่ app.service.ts ประกาศ Inject ตัวเซอร์วิสที่ทำการ import ไว้ที่ app.module.ts โดยเราจะประกาศเซอร์วิสซึ่งอยู่ภายใต้ class ClinetProxy โดยการทำงานของฟังก์ชันนี้จะทำการเพิ่มเมนู Buffet ไปยัง buffetList และจะทำการเรียกใช้ EventPattern ไปหา buffet_menu_created
ทำการสร้าง create-buffet-menu-event.ts เป็นโครงสร้างสำหรับรับ-ส่งข้อมูล
ทำการรัน service ทั้ง 2 ด้วย
yarn start:dev
ทำการลองยิง API
ใน Terminal ของ nestjs-add-buffet ก็จะแสดงข้อมูลตามที่ได้เขียนไว้
ต่อจากนี้จะเป็น Random Buffet ทำหน้าที่รับจำนวนทั้งหมดของร้าน Buffet จากนั้นจะทำการสุ่มเลขออกไป 1 ค่า เพื่อคำนวณว่าจะได้ Buffet ร้านไหน
ไปยัง folder nestjs-random-buffet ไปยังไฟล์ main.ts เพื่อทำการตั้งค่าช่องทางการสื่อสาร
ไปยัง app.controller.ts จะทำการเพิ่ม MessagePattern ชื่อว่า random-buffet หากมีเซอร์วิสที่เรียกด้วยคำนี้ เซอร์วิสก็จะทำงาน
ไปยัง app.service.ts ทำการสร้างฟังก์ชันสำหรับสุ่มค่าตัวเลข โดยจะรับจำนวนร้าน Buffet เข้ามาและทำการส่งผลลัพธ์เป็นตัวเลขออกไป
กลับมายัง folder nestjs-Microservice-backend โดยไปยังไฟล์ app.module.ts ให้ตั้งค่าช่องทางการสื่อสารระหว่าง Random เซอร์วิส
ไปยัง app.controller.ts จากนั้นเพิ่มเส้น randomBuffet ขึ้นมาโดยสามารถเรียกใช้งานผ่าน Method Get
ไปยัง app.service.ts เพิ่มฟังก์ชัน randomBuffet ที่จะทำการเรียกใช้ random-buffet ที่ได้ทำการสร้างเอาไว้
ทำการรันเซอร์วิส nestjs-random-buffet ด้วยคำสั่ง yarn start:dev
และได้ทำการเพิ่ม buffet list เข้ามา 7 รายการ มาดูกันว่าจะได้ไปกินร้านไหนกัน
และแล้วผลสุ่มออกมาก็ได้เป็น BAR B Q PLAZA นั่นเองครับ
สรุป Microservice มีทั้งข้อดีและข้อเสียขึ้นอยู่กับว่าการพัฒนาของทีมนั้นต้องการให้ไปในทิศทางไหน การใช้สถาปัตยกรรมแบบ Monolithic นั้นก็ไม่มีผิดเหมือนกันขึ้นอยู่กับวัตถุประสงค์และความต้องการของระบบ และการทำให้ซอฟต์แวร์สามารถทำงานได้ตรงตามความต้องการคือจุดสำคัญสำหรับการเลือกสถาปัตยกรรม