👶 Microservices พื้นฐาน

🤔 Microservices architecture คืออะไร? ดียังไง? ควรใช้ไหม?

😢 ปัญหา

ในทุกวันนี้การทำซอฟต์แวร์ได้เปลี่ยนจากเดิมไปมากจากการเข้ามาของคลาว์ เพราะมันทำให้ของที่ทำได้ยากในสมัยก่อนสามารถทำได้ง่ายๆแล้วในสมัยนี้ และการเข้ามาของมันก็ทำให้เหล่า developer ต้องส่งมอบงานได้เร็วขึ้น ระบบต้องทำงานได้ตลอดกาลโดยไม่ล่ม ระบบต้องเพิ่มความสามารถใหม่ๆเข้าไปเรื่อยๆได้ บลาๆ โดยที่ทั้งหมดนี่ระบบจะต้องไม่มีการปิดปรับปรุงเลยอีกด้วย (เคยเห็น Google, Facebook, Twitter ปิดปรับปรุงกันไหม?) จากที่ว่ามาคลาว์ก็เป็นคำตอบนึงที่จะสามารถแก้ไขปัญหาเรื่องนี้ได้ แต่การที่เราจะให้ทีมสามารถส่งมอบงานออกมาได้เรื่อยๆโดยไม่ส่งผลกระทบต่องานส่วนอื่นๆเลย เหล่า developer จะต้องเรียนรู้หลักในการออกแบบอื่นๆเสริมเข้าไปด้วยนะ แล้วมันคืออะไรล่ะ ?

😄 วิธีแก้ปัญหา

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

🤔 Microservice เกิดขึ้นได้ยังไงนะ ?

ในการที่จะเข้าใจ Microservices Architecture ผมจะขอย้อนอดีตการพัฒนาซอฟต์แวร์ให้ฟังกันหน่อยละกัน ตามด้านล่างเลย

🔥 Monolithic application models

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

ถัดมาก็เขาเริ่มแยกหน้าที่การทำงานออกมาเป็น Layer ต่างๆ หรือที่เราเรียกว่า Multitier Architecture นั่นเอง ตามรูปด้านล่าง

อธิบายรูปด้านบน โดยปกติเราจะแบ่ง layer ออกเป็น 3 อย่างง่ายๆตามด้านล่าง ซึ่งจริงๆมันจะมีกี่ Layer ก็ได้ขึ้นกับความซับซ้อนของงาน ดังนั้นหลายๆที่ก็จะเรียกสถานะปัตยกรรมนี้ว่า N-Tier Architecture นั่นเอง

  • UI Layer - ทำหน้าที่ดูแลหน้าตาความสวยงามต่างๆ ให้ผู้ใช้กดใช้งานง่ายๆ

  • Business Logic Layer - ทำหน้าที่ดูแลว่าเมื่อผู้ใช้กดปุ่มนั้นๆแล้ว ตัวโปรแกรมจะต้องทำอะไรต่อเพื่อ เช่น กดปุ่มคำนวณภาษี ระบบจะต้องคำนวณยังไง

  • Data Layer - ทำหน้าที่ดูแลข้อมูลที่ตัวระบบเก็บไว้ เช่น พวก database ต่างๆ

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

โดยปกติสถาปัตยกรรมแบบนี้ของทุกอย่างจะอยู่รวมกันหมด เช่นตัว database ก็เก็บข้อมูลทุกอย่างที่เกี่ยวกับระบบนี้ไว้ไม่ว่าจะเป็น ข้อมูลสินค้า ข้อมูลลูกค้า บลาๆ ก็จะเก็บภายใน database ก้อนเดียวกัน หรือแม้กระทั่งตัว Business Logic เรื่อง สินค้ากับลูกค้าก็จะอยู่ภายใต้ source code เดียวกัน ดีหน่อยก็จะแยกเป็นคนละ library แต่สุดท้ายก็มารวมกันที่ project เดียวตอน deploy ซึ่งลักษณะสถาปัตยกรรมแบบนี้เราจะเรียกมันว่า Monolithic application models นั่นเองซึ่งข้อเสียของมันคือ **เวลามันล่มขึ้นมามันจะกอดคอกันตายเป็นหมู่คณะ เพราะเวลาที่ฐานข้อมูลล่ม เราจะไม่สามารถเข้าถึงข้อมูลอะไรได้เลย หรือตัว Business Logic ล่มก็เช่นกัน

🔥 Microservices architecture

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

รูปด้านล่างเป็นตัวอย่างในการแปลง Monolithic application models ให้ออกมาเป็น Microservices ต่างๆยังไง

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

หลังจากที่เราแบ่งงานออกเป็น microservice ย่อยๆแล้ว เราก็จะรวมเอา service ที่เกี่ยวข้องกันไว้ด้วยกัน โดยปกติเราจะสร้าง environment พวกนั้นไว้ใน Container แต่ละแบบไว้ ดังนั้นเวลาที่เราทำ Microservice architecture เราจะทำงานกับ Cluster นั่นเอง

Container คืออะไร สามารถอ่านได้จากลิงค์นี้เลย 👶 Docker ขั้นพื้นฐาน ซึ่งในอนาคต developer น่าจะได้ใช้ตัวนี้กันทุกคนอยู่แล้ว ดังนั้นอ่านไว้เถอะไม่เสียหายหรอก

และแต่ละ Microservice นั้นจะต้องสามารถมี Build pipeline ของมันเองได้ เช่นการทำ Continuous Integration (CI) และ Continuous Delivery (CD) เพราะ developer จะได้สามารถจัดการแต่ละ service ได้อย่างรวดเร็วและควรจะต้องมี Environments ให้ถูกต้องเหมาะสมด้วย เช่น Production environment, Staging environment, Development environment เป็นต้น

🤔 แล้วมันดียังไง ?

เพื่อให้เข้าใจมากยิ่งขึ้นเราจะทำการเปรียบเทียบระหว่าง Monolithic application model กับ Microservices architecture ดูละกันว่ามันต่างกันตรงไหนบ้าง

🔥 Monolithic application models

โดยปกติเราจะเอาทุกอย่างยัดเข้าไปอยู่ภายในแอพเดียว แล้วแบ่งกันด้วย Layers ต่างๆ

แล้วเมื่อไหร่ที่เซิฟเวอร์เราเริ่มรับโหลดไม่ไหว สิ่งที่เราทำได้คือการทำการเพิ่มจำนวนเซิฟเวอร์ออกเป็นหลายๆตัว หรือที่เราเรียกว่า Horizontally scale แล้วใช้ตัว Load-balancer เป็นตัวช่วยกระจายรับโหลดออกไปให้กับเซิฟเวอร์ต่างๆช่วยรับโหลด แต่สิ่งที่เลี่ยงไม่ได้คือเราต้องเอามันไปทั้งหมดทั้งก่อน

ก็เหมือนจะง่ายดีแต่อย่าลืมว่าถ้าเราแก้ไขงานแม้จะเล็กน้อยแค่ไหนก็ตาม ทุกอย่างจะต้อง Re-build, Re-deploy, Re-test ใหม่หมดทุกเซิฟเวอร์ด้วย

🔥 Microservices architecture

ในฝั่งของ Microservices นั้นเราจะแยกงานแต่ละเรื่องออกมาขาดกันชัดเจน โดยให้จินตนาการง่ายๆว่า งานแต่ละเรื่องหรือสิ่งที่เราเรียกว่า Component นั้นจะต้องดูแลแค่ภายใน Boundary Context ของมันเท่านั้น รวมถึงถ้ามันจะต้องดูแลข้อมูลอะไรมันก็ต้องมีฐานข้อมูลสำหรับของมันเองอีกด้วย

โดยแต่ละ Component จะใช้ภาษาและเทคโนโลยีอะไรก็ได้ เช่น Component ข้อมูลสินค้าอาจใช้ .NET และ SQL server ส่วน Component ข้อมูลลูกค้าอาจใช้ Java และ MongoDB ก็ได้ ดังนั้นเราก็จะสามารถแบ่งงานให้แต่ละทีมดูละแต่ละ Component ไปเลยก็ยังได้

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

🤔 สร้าง Microservice แล้วใช้ที่ไหน ?

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

ซึ่งคำตอบของคำถามนี้ก็คือเอาไปใช้บนคลาว์นั่นเอง เพราะทุกอย่างบนคลาว์นั้นสอดคล้องกับความต้องการของ Microservices ทุกประการ Cost efficiency, Scalability , 24x7 Availability, Reliable upgrades, Health check และ Automatic & Rollback นั่นเอง ซึ่งคลาว์ที่เราจะใช้ก็แล้วแต่เลยไม่ได้ผูกติดว่าจะต้องเป็นผู้ให้บริการรายไหน และรวมถึง private & hosted cloud ด้วยนะ

แนะนำให้อ่าน เราจะเห็นว่าในการพัฒนาซอฟต์แวร์สมัยใหม่นี้ ทุกๆอย่างจะวิ่งเข้าสู่คลาว์กันหมดแล้ว ดังนั้นในอนาคตอันใกล้การที่เรามาตั้งเซิฟเวอร์ใช้เองก็จะเริ่มลดน้อยลงเรื่อยๆ ดังนั้นใครที่สนใจอยากจะลองศึกษาใช้คลาว์ดูก็สามารถดูได้จากคอร์สนี้ครับ 👶 Microsoft Azure 101 ส่วนใครที่ยังไม่รู้เลยว่าคลาว์คืออะไรก็สามารถปูพื้นฐานความรู้ได้จากบทความนี้ครับ 👶 Cloud พื้นฐาน

🤔 ออกแบบ Microservice ยังไง ?

หลักการง่ายๆในการออกแบบ Microserive ง่ายๆ คือให้เรายึดของ 3 อย่างนี้เอาไว้

  • Single purpose - แต่ละ serivce นั้นจะต้องมีหน้าที่รับผิดชอบเพียงอย่างเดียว เพราะมันจะได้ดูแลงานเพียงงานเดียว เวลาแก้ไขก็จะไม่กระทบกับงานเรื่องอื่นๆ และตรงตามหลักการออกแบบที่ชื่อว่า Single Responsibility Principle ด้วย

  • Loose coupling - แต่ละ service ควรจะไม่รู้จักกันเลยได้ยิ่งดี แต่ให้มันติดต่อกันผ่านแค่ API contracts เท่านั้น เพราะไม่อย่างนั้นมันจะเกิดการผูกติดกันเกิดขึ้น ซึ่งจะทำให้เมื่อ service อื่นเกิดการเปลี่ยนแปลงขึ้น จะส่งผลให้ service ที่ผูกติดกับมันต้องไปไล่แก้ตามนั่นเอง

  • High cohesion - ของที่อยู่ภายใน service ควรจะต้องเป็นเรื่องที่เกี่ยวข้องกับมันเท่านั้น เพราะมันจะต้องดูแลเฉพาะงานที่มันรับผิดชอบเพียงอย่างเดียว เช่น ถ้างานของมันต้องดูละเรื่องสินค้า ของทุกอย่างใน service จะต้องเป็นเรื่องเกี่ยวกับสินค้าเท่านั้น ห้ามมี ลูกค้าเข้ามาเกี่ยวข้อง เพราะไม่อย่างนั้นเวลาแก้ไขเรื่องสินค้าอาจจะกระทบเรื่องลูกค้าก็ได้ แล้วมันจะสูญเสียความคล่องตัวของมันไปนั่นเอง

แนะนำให้อ่าน หลักในการออกแบบซอฟต์แวร์ที่ดีมีหลายตัวเลย ซึ่งผมอยากให้เพื่อนๆได้รู้จักกับ 5 ตัวพื้นฐานของมันนั่นคือสิ่งที่เรียกว่า SOLID ครับ ซึ่งสามารถอ่านได้จากบทความนี้เลย 👦 SOLID Design Principles ซึ่งภายคอร์สนั้นจะพูดถึง Single purpose, Coupling และ Cohesion ไว้อย่างละเอียดเลยว่ามันคืออะไรครับ

🤔 อยากสร้างละทำไง ?

ใจเย็นโยมเรื่องนี้ยาวเป็นหางว่าวเลย ซึ่งในบทความนี้เป็นแค่เบื้องต้นให้เขาใจเฉยๆว่า Microservice Architecture แบบคร่าวๆคืออะไรและมันต่างกับ Monolithic app ยังไง ซึ่งถ้าใครสนใจอยากลงลึกว่าจะสร้าง Microservice แล้วจะต้องทำยังไง? ต้องรู้อะไรบ้าง? สามารถดูได้จากคอร์สด้านล่างนี้เลยครับ เพราะมันยังมีเรื่องอื่นๆที่ต้องรู้กีเยอะเลยเช่น Docker Swarm and Docker Compose, Kubernetes, OpenShift, Cloud บลาๆๆ

🧭 เนื้อหาของคอร์สทั้งหมด

ตัวคอร์สนี้กำลังค่อยอัพเดทเรื่อยๆอยู่ ซึ่งถ้ามีอัพเดทใหม่จะเอามาลงไว้ในหน้านี้แหละ ส่วนถ้าเพื่อนๆไม่อยากพลาดอัพเดทให้เข้าไปกดไลค์ตัวเพจนี้ไว้นะ Saladpuk Facebook **เวลาที่มีอัพเดทใหม่มันจะได้ส่งข้อความไปหา

คิดอะไรได้เดี๋ยวเอามาใส่ตรงนี้เรื่อยๆ กว่าจะเสร็จครบหมดน่าจะวันที่ 13/10/2019 เลย ช่วงนี้ผมงานเยอะ + เดินทางครับ

🎯 บทสรุป

การทำ Microservice Architecture นั้นคือการแยกส่วนประกอบต่างๆออกเป็นเรื่องๆให้ขาดออกจากกัน โดยที่แต่ละตัวจะต้องรับผิดชอบเพียงแค่เรื่องๆเดียวเท่านั้น โดยเรียกแต่ละส่วนว่า Microservice และการทำงานร่วมกันของแต่ละ service นั้นจะทำงานผ่าน API contract ซึ่งปัจจุบันเรานิยมใช้ RESTful กัน

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

ข้อควรระวัง 1 การทำ Microservice Architecture ไม่ใช่เรื่องเท่ห์ มันไม่ใช่เรื่องว่ามันเป็นของใหม่แล้วเราควรจะเอามันไปใช้เสมอไป เพราะจากบทความ 👶 สิ่งที่คนเขียนโค้ดมักเข้าใจผิด ผมได้อธิบายไปแล้วว่าการออกแบบซอฟต์แวร์ไม่ใช่เรื่องของเทคโนโลยี แต่หัวใจสำคัญคือ Requirements ต่างหาก ส่วนเทคโยโลยีนั้นเป็นเรื่องแทบจะเป็นสิ่งสุดท้ายเลยที่เราจะเลือกครับ

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