จาก Monolith สู่ Microservices

🤔 เวลาเขาถอดชิ้นส่วน Monolith ให้กลายเป็น Microservices เขาทำกันยังไงนะ ?

จากบทความ Microservices Tips เราจะพอเข้าใจแล้วว่าการที่จะทำ Microservices Architecture นั้น เราไม่ควรออกแบบให้มันเป็น microservices ตั้งแต่แรกเพราะมันมีปัญหาเยอะมาก แต่เราควรที่จะทำเป็น monolith ไปก่อน จนกว่ามันจะสุกงอมแล้วเราถึงจะค่อยๆถอดแต่ละชิ้นส่วนของมันให้ออกมาเป็น microservice เรื่อยๆนั่นเอง

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

🤔 ถอดชิ้นส่วนเป็น service เขาทำยังไงกันนะ ?

🔥 มองหาชิ้นส่วนที่จะถอด

หลังจากที่โปรแกรมแบบ Monolith เขาเราเริ่มมีขนาดใหญ่และเราเข้าใจในตัวขอบเขตของงานในแต่ละเรื่องแล้ว เราก็จะเริ่มมองหาว่าจะเอางานในส่วนไหนเปลี่ยนไปเป็น microservice ดี ซึ่งถ้าเจอแล้วเราจะต้องเอาชิ้นงานส่วนนั้นไปให้หมดแบบถอนรากถอนโคนมันเลย หรือที่เราเรียกว่า เอาไปให้หมดทั้ง Vertical ของมันนั่นเอง สาเหตุที่ต้องเอามันไปแบบถอนรากนั้นเพราะว่า microservice 1 ตัวมันควรจะต้องดูแลงานในเรื่องของมันทั้งหมดตั้งแต่หัวจรดเท้า ดังนั้นเวลาที่จะยกงานเรื่องนั้นๆออกไป มันเลยจะต้องยกออกไปทั้งหมดยังไงล่ะ ไม่อย่างนั้นมันจะทำให้มีงานเรื่องเดียวกันแต่อยู่ต่าง service เกิดขึ้น ซึ่งมันจะทำให้เวลาที่ต้องแก้งานเรื่องนั้นๆ มันจะต้องแก้ ต้องเทส ต้องเอางานขึ้นเซิฟเวอร์ใหม่ ทั้ง 2 services เลยทำให้มันเสียความคล่องตัวไปนั่นเอง

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

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

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

🔥 เตรียมสภาพแวดล้อมที่เหมาะสม

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

  • ถูกนำเอา Build เมื่อไหร่ก็ได้ อยาก Test มันเมื่อไหร่ก็ได้ และต้องเป็น Automation ด้วยนะ

  • สามารถเอา service ไปขึ้นเซิฟเวอร์ในแต่ละ environment ได้ ซึ่งกระบวนการนี้เราเรียกว่าการทำ Continuous Integration (CI) กับ Continuous Delivery (CD)

  • มีโครงสร้างที่สามารถทำ Reliable & Secure network ภายใน

  • มีระบบในการจัดการ Containers ต่างๆในการเอางานขึ้นลง ตรวจสอบ service ต่างๆว่ายังทำงานอยู่ดีมีสุขหรือเปล่า เช่น Container Orchestration

  • มีระบบจัดการ API เพื่อจัดการคนที่สามารถเข้ามาทำงานกับ service หรือแม้กระทั่งจัดการ API versioning ต่างๆ ซึ่งเราเรียกตัวนี้ว่า API management system

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

🔥 ค่อยๆปรับแก้ไป

หลังจากที่เลือกชิ้นส่วนได้แล้ว + ทีมมีความรู้ในการจัดการ environment ของ microservice แล้ว ถัดไปเราก็จะค่อยๆย้ายการทำงานใน monolith ตัวเดิมมาเป็น microservice นั่นเอง โดยเราจะไม่ copy งานเดิมมาวางไว้แล้วถือว่าจบนะ แต่เราจะต้องค่อยๆปรับให้มันทำงานกับโครงสร้างใหม่นี้ด้วย เพราะถ้ามันมีการเรียกใช้งานของที่อยู่นอกขอบเขตของมัน (Bounded context) นั่นหมายความว่า มันจะต้องเรียกใช้งานผ่าน API นั่นเอง และในทางกลับกัน โค้ดเก่าที่อยู่ใน monolith ถ้าจะมาเรียกใช้งานตัว service ที่เราย้ายออกมาแล้ว เราก็จะต้องมี API ให้เขาเรียกด้วยเช่นกัน ดังนั้นในจุดนี้จะต้องค่อยๆปรับไปเรื่อยๆจนกว่าจะเสร็จ และอย่าลืมทดสอบด้วยนะว่าตอนเรียกใช้ Pipeline ที่เตรียมไว้มันทำงานได้จริงๆ ซึ่งถ้าได้ครบหมดทุกอย่าง ก็เริ่มกลับไปหาชิ้นถัดไปมาถอดชิ้นส่วนได้เลยจร้า

🤔 ขอตัวอย่างหน่อยได้ป่ะ ?

ตัวอย่างนี้ขอเอามาจากบทความ How to break Monolith into Microservices นะครับ ซึ่งในบทความเขากำลังทำระบบขายของออนไลน์ โดยในบทความเขาเลือกถอดชิ้นส่วนไล่จากแบบง่ายไปถึงแบบยากตามด้านล่างนี้เลย

🔥 แยกชิ้นส่วนที่ไม่เกี่ยวข้องกับใคร

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

อธิบายรูปด้านบน เราก็จะเริ่มไปสร้าง service ตัวใหม่ที่ทำงานเรื่อง authentication โดยเฉพาะออกมา แล้วให้ระบบ monolith เติมได้ลองเปลี่ยนมาใช้เจ้า service ที่แยกออกมา โดยเรียกทำงานผ่าน API contracts นั่นเอง

🔥 แยกชิ้นส่วนของที่ผูกกัน

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

คำตอบก็คือเลือกทำระบบโปรโมชั่นก่อน เพราะถ้าเลือกระบบซื้อสินค้าก่อนมันจะทำให้ service ของเรายังต้องผูกติดกับ monolith เพราะจะซื้อสินค้ามันจะต้องดูโปรโมชั่นก่อน ซึ่งเจ้าโปรโมชั่นมันยังอยู่ใน monolith นั่นเอง

🔥 แยกของที่ผูกกันแบบเหนียวแน่น

ในบางกรณีเราก็ไม่สามารถบอกได้ว่าเจ้าสิ่งนั้นกับสิ่งนี้มันจะแยกเรื่องกันได้ยังไง ซึ่งโดยปรกติสาเหตุนั้นจะเกิดจากการที่เรายังไม่เคลียในเรื่องของ Domain concept นั่นเอง ดังนั้นวิธีการแก้ไขคือ เราจะต้องมานั่งทำความเข้าใจว่าจริงๆแล้วมันมี domain เรื่องอะไรบ้าง แล้วค่อยๆแก้ปมแต่ละเรื่องออก แล้วค่อยเอาไปทำเป็น microservice ต่อนั่นเอง

ในตัวอย่างการผูกกันแบบเหนียวแน่นของเขาเกิดจากการใช้ web session เลยทำให้การแยกของต่างๆทำได้ยากขึ้น เช่น ตอนซื้อของเราจะต้องเก็บว่าผู้ใช้คนนนี้ชอบอะไร มีรายการที่อยากได้อะไรบ้าง ข้อมูลการจ่ายเงินเป็นยังไงบ้าง ดังนั้นเขาเลยต้องเอามานั่ง define domain concept เสียใหม่ว่าจริงๆแล้วมันคือเรื่องอะไรบ้าง แล้วค่อยสร้าง service เพื่อแก้ไขมันทีละตัวนั่นเอง ตามรูปด้านล่าง

😵 พอก่อนเยอะละ

ในบทความที่ถอดรหัสมาเขามีเขียนไว้อีกเยอะเลย เดี๋ยววันหน้าเอามาลงต่อให้ละกันนะ

Last updated

Was this helpful?