สรุปคลาส Microservices day 1/4

สรุปคลาส Microservices day 1/4

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

ต่อไปนี้คือเนื้อหาและสิ่งที่ผมได้จากการร่วมเรียนในชั้นเรียนนี้น่ะครับ

Cloud-Native

ก่อนที่เราจะกระโดดไปคุยกันเรื่อง Microservices นั้น มาดูกันในส่วนของ Cloud native กันก่อน

Cloud-native คือแนวทางในการพัฒนาหรือรัน App ให้เกิดประโยชน์สูงสุดจากการใช้ Cloud ซึ่งเป็นที่นิยมในปัจจุบันในการสร้างเครื่องเซิฟเวอร์

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

ซึ่งนั้นก็คือ Continuous Delivery (CD) นั่นเอง จากนั้นจะทำยังไงให้เราสามารถปล่อยของออกมาได้ทีละเล็ก โดยไม่เกิดความเสี่ยงจากผลกระทบกับผู้ใช้ ก็จะเข้ามาสู่ โลกของ Microservices ที่จะทำให้เราสามารถปล่อยของได้ทีละเล็ก ๆ ไม่กระทบกับระบบใหญ่แบบเดิม ซึ่งเป็นสิ่งที่จะทำให้เกิดสองข้อแรกได้อย่างชัดเจนมากยิ่งขึ้น สุดท้ายคือการนำเอาเทคโนโลยีของ Container มาใช้เพราะสิ่งที่ตามมาคือเราแยก Service ออกมาเป็นย่อย ๆ ทำให้ภาษาหรือเทคโนโลยีที่ใช้ในแต่และ Service เป็นอิสระต่อกัน ทำให้ความบรรลัยเกิดคือเราต้องเตรียมเครื่อง VM ที่ลงภาษาและเตรียม Environment คนละแบบกัน เทคโนโลยี Container นี้คือพระเอกที่จะมาช่วยเราปลดล๊อคปัญหาเหล่านี้

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

Evolution of Architecture

แน่นอนว่าก่อนจะเป็น Microservices มันต้องมีรูปแบบเดิมของ Architecture ในอดีตซึ่งค่อย ๆ พัฒนาขึ้นมาจากปัญหาที่เจอดังรูปนี้

เราเริ่มกันที่แบบเดิม ชื่อเล่นคือ monolith เรารวมทุกอย่างไว้ด้วยกัน ปัญหาที่เจอคือการเปลี่ยนแต่ละที่อาจจะส่งผลกระทบตามมาในหลายจุด ทำให้บางครั้งทีมพัฒนาไม่กล้าแก้มันส่งผลเสียอย่างมากกับทางฝั่งธุรกิจที่ไม่สามารถเพิ่มความสามารถใหม่ ๆ ออกมาได้ หลังจากที่เราได้พบปัญหานี้ จึงมีการออกแบบในรูปแบบ Traditional SOA เริ่มมีการแบ่งก้อนที่ชัดเจนแต่ยังไม่อิสระต่อกันทุกคนยังอยู่ในพิซซ่าถาดเดียวกัน แค่ถูกหั่นออกมา ส่งผลให้เกิดปัญหาของการนำงานมาร่วมกันเกิดขึ้น เราเริ่มแก้ไขโดยการต้องมีคนกลางมาทำหน้าที่เป็น Contact point เริ่มมีการทวงงานกัน หรือ ร้ายที่สุดคือโยนกันไปกันมาเพื่อหาคนแก้ไขปัญหาตรงจุดที่เชื่อมกัน สุดท้ายเราจึงมาสู่ในโลกของ Microservices ทีไม่เพียงแต่เราต้องสนใจแค่ของที่ตัวเองสร้าง แต่เรายังต้องสนใจทีมรอบด้านที่เรียกใช้งาน service ของเราอีกด้วย สิ่งที่เกิดขึ้นคือการแก้ไขภายในแทบไม่ส่งผลกระทบกับผู้ใช้งาน ถ้ายังสามารถเรียกใช้งานได้ผ่านช่องทางเดิมตามที่ตกลงกันไว้ ทีมมีอิสระต่อกัน ไม่จำเป็นต้องตัดสินใจร่วมกันในการเลือกเทคโนโลยี หรือ ภาษาที่จะใช้

Conway’s law

ถ้าเราแบ่งทีมเป็น Silo (แต่ละทีมทำตามหน้าที่หลักของตนเอง) ผลที่ตามมาก็จะเกิด Architecture สะท้อนออกมาตามภาพ เพราะ แต่ละ Layer คือเส้นแบ่งขอบเขตของตนเอง และ มักจะเป็นเส้นที่เกิดปัญหาตอนนำมารวมกัน สมมติว่าถ้าเราอยู่ในทีม DBA เราจะสนใจที่การสร้างและเตรียมข้อมูลเพียงอย่างเดียว เมื่อทำเสร็จแล้วงานเราคือเสร็จ แต่ความจริงไม่เป็นเช่นนั้น เพราะทีม API ต้องการปรับรูปแบบข้อมูล มันจะเกิดปัญหาลักษณะ Ping pong ค่อนข้างสูง ส่งผลทำให้เกิดความล่าช้าและปัญหาจากการสื่อสารที่ตกหล่นตามมาได้ ทำให้เราจะพบว่าหากมีการพัฒนาในรูปแบบ Microservices สิ่งที่ตามมาคือรูปแบบของทีมและผังองค์กรที่ต้องเปลี่ยนไปเพื่อให้เอื้อกับการพัฒนาในรูปแบบนี้

Microservices’s checklist

  • Small / Do one thing — เล็ก หลายครั้งเราเถียงกันว่าเล็กแค่ไหน บางคนบอกว่าคือ จำนวนบรรทัดต้องเท่านั้นเท่านี้ แต่สิ่งนึงที่บอกได้มันต้องทำแค่หน้าที่เดียวในแต่ละ service
  • Modular — สามารถดึงเข้าถอดออกได้
  • Easy for deployment — เมื่อเล็กแล้วมันต้องทำให้สามารถ deploy ได้ง่าย
  • Scale independently — ถ้าอยากสเกลมันต้องสามารถสเกลได้เพียงตัวเดียว ไม่กระทบกับใคร

Before we are going to Microservices

  • Architecture — ของเราต้องไม่มีคำว่า Final มันต้องสามารถปรับเปลี่ยนได้ตามข้อมูลที่เรามี นั้นคือการที่เราต้องสามารถทดสอบได้ว่าความถูกต้องคืออะไร ถ้าแก้จุดนี้แล้วจะต้องไม่กระทบกับจุดอื่น ๆ
  • Service communication — เราต้องเลือกใช้ให้ได้ว่าการสื่อสารกันระหว่าง Service นั้น จะใช้รูปแบบไหน http protocol? รูปแบบของข้อมูลคือ REST?
  • People communication — การทำงานต้องเกิดความร่วมมือกันหลายฝ่ายทั้งภายในทีมและนอกทีม เช่น การออกแบบ Service ต้องมีข้อมูลจากฝั่ง Bussiness มาประกอบในการออกแบบ หรือ การที่ทีมพัฒนาต้องทำงานร่วมกันกับ IT Operation อย่างใกล้ชิด
  • Continuous Delivery — ทีมสามารถ deploy ได้ทีละเล็กเพื่อทำให้เกิดการเรียนรู้ได้อย่างรวดเร็ว
  • Infrastructure — เมื่อ Service แยกออกจากกันทำให้ต้องเตรียมการเรื่องการสร้างเครื่อง โดยใช้เทคโนโลยีของ container เข้ามาช่วยแก้ไข
  • Monitoring — เราจะทราบได้อย่างไรว่าที่ทำขึ้นไปเกิดปัญหา หรือ มีจุดไหนที่สามารถพัฒนาให้ดีขึ้นได้ไหม สิ่งที่ตามมาคือการเตรียมการในเรื่อง Monitoring เพื่อเก็บข้อมูลและแจ้งสิ่งที่เป็นประโยชน์แกทีมพัฒนา

Benefits of Microservices

  1. Technology heterogeneity

เราสามารถเลือกใช้เทคโนโลยีได้ตามที่แต่ละ Service ควรเป็นได้อย่างอิสระ … The right tool for each job

2. Resilience

Service นั้นสามารถตายได้ แต่สิ่งที่ต้องทำได้คือไม่เกิดผลกระทบกับผู้ใช้ เช่น การที่ Load balance สามารถทำการ Health check แต่ละ Service ได้ ถ้าหากมีปัญหาก็กระจายไปยัง Instance ตัวอื่น ๆ ที่ได้ทำการ scale ไว้ก่อนหน้านี้

3. Scaling

ทำให้มีความสามารถ Scale ออกมาได้หลาย Instance ตามความเหมาะสมและความต้องการในขณะนั้น

4. Ease of deployment เกิดความง่ายในการ deploy เพราะเป็นอิสระกับตัวอื่นๆ ทำให้สามารถทำได้เร็วขึ้น และ หากเกิดปัญหาก็สามารถหาจุดที่เกิดปัญหาได้อย่างรวดเร็ว

  1. Organization alignment

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

  1. Composability and replaceability สามารถดึงเข้า ถอดออกได้อย่างอิสระ เมื่อ Service ใหญ่เกินเกิดความซับซ้อนเราสามารถดึงออกมาเป็น Service ใหม่ขึ้นมา แต่เมื่อเกิดการเรียกการใช้งานระหว่าง Service ที่ไม่เกิดประโยชน์ก็สามารถดึงเข้ามารวมกันเพื่อลด overhead process ได้

Characteristics of Microservices

  1. Responsible for a single capability — เราจะรู้ได้ยังไงว่า Service ต้องรับหน้าที่ที่เฉพาะเจาะจงไม่ทำมากเกินไป การออกแบบนั้นต้องเกิดจากข้อมูลของทั้ง 2 ด้าน นั่นก็คือฝั่ง Bussiness และ ฝั่ง Technical ว่าควรแยกออกมาอย่างไร
  2. Individually deployable — สามารถ deploy โดยไม่จำเป็นต้องเกี่ยวข้องกับตัวอื่น ๆ ได้
  3. Consists of one or more processes — Service สามารถทำงานได้ด้วยตนเองโดยไม่มีส่วนที่เกี่ยวข้องกับตัวอื่น ๆ อย่างชัดเจน นั่นคือการรันขึ้นมาเป็น Process แยกออกมาได้ ซึ่งจะใช้แค่ Resource ของตัวเองเท่านั้น ไม่มีการข้ามไปใช้ร่วมกันกับ Process อื่น ๆ
  4. Own data store — จัดเก็บข้อมูลแยกออกจากกันในแต่ละ service
  5. Small team can maintain — ขนาดของ Service ไม่ใหญ่ทำให้คนที่พัฒนาและดูแลไม่เยอะ เกิดความคล่องตัวในการพัฒนาและแก้ไขปัญหา

Challenges with Microservices

  • How to define the boundaries of each microservices?
  • How to create queries that retrieve data from several microservices?
    Data warehouse / Report data

รูปแบบการสื่อสารของ Front-end (Client app) กับ Microservices ที่นิยมกัน ซึ่งก็ล้วนมีข้อดี ข้อเสียที่แตกต่างกันตามที่เราเลือกใช้

  • How to design communication across microservices boundaries?
    Protocal : HTTP-REST / Messaging queue
    Communication : Request-Response / Observer (Pub-Sub)

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

Workshop day 1st — Planning day

  1. ลงมือวางแผนตาม Reqs ที่ได้ โดยเริ่มจาก User flow ว่าเข้ามาเจออะไร จนจบครบ Flow มีการออกแบบข้อมูลที่จะนำไปใช้ในการทำการทดสอบ ซึ่งตรงนี้คือการโฟกัสที่ฝั่ง Bussiness ก่อน
  2. จากนั้นทำการวางแผนว่าแต่ละหน้าจอที่ User interact ต้องเชื่อมต่อกับ Endpoint ไหน? Request คืออะไร? ข้อมูล Response ที่ได้หน้าตาเป็นเช่นไร?
  3. เมื่อได้ครบแล้ว ในกระดาษ A4 คือการออกแบบ Logic ของในแต่ละ Endpoint ว่ามีเงื่อนไขอะไรบ้าง ซึ่งสามารถใช้ flowchart เพื่ออธิบายได้

4. สิ่งที่เราได้คือการออกแบบ Service มาอย่างคร่าว ๆ โดยคำนึงข้อมูลจากฝั่ง Bussiness และ Technical ประกอบกัน ซึ่งจะทำให้พอเห็นภาพได้ว่าควรมี Service กี่ตัว ทำหน้าที่อย่างไรบ้างตามความสามารถที่ไปตอบโจทย์การทำงานจากผู้ใช้จริง ๆ

5. ทีมเริ่มกำหนดและวางขั้นตอนในการพัฒนาตามเทคโนโลยีที่เลือก เช่น Build, Test และ Deploy อย่างไรบ้าง เพื่อทำให้เกิด Build pipeline ของทีมออกมา โดยสนใจขั้นตอนตามปกติที่ต้องทำอยู่แล้วโดยไม่ต้องคำนึงถึงการนำเอา Continuous Integration Tool มาเกี่ยวข้อง เนื่องจากบ่อยครั้งที่เราจะพลาดขั้นตอนการทำงานของเราไป สิ่งนี้จะทำให้ทีมเข้าใจตรงกันก่อนว่ามีขั้นตอนในการพัฒนาเช่นไร

สีเขียวคือขั้นตอนของฝั่ง Front-end ส่วนสีชมพูคือขั้นตอนของฝั่ง Back-end

สำหรับช่วงท้ายของวันมีการแนะนำเรื่อง Continuous Integration (CI) เพื่อให้ทีมได้ทราบถึงแนวคิดนี้ซึ่งในวันต่อไปทีมจะได้ลงมือทำจริง