# จาก Monolith สู่ Microservices

จากบทความ [Microservices Tips](https://saladpuk.gitbook.io/learn/basic/microservices/tips) เราจะพอเข้าใจแล้วว่าการที่จะทำ Microservices Architecture นั้น เราไม่ควรออกแบบให้มันเป็น microservices ตั้งแต่แรกเพราะมันมีปัญหาเยอะมาก แต่เราควรที่จะทำเป็น monolith ไปก่อน จนกว่ามันจะสุกงอมแล้วเราถึงจะค่อยๆถอดแต่ละชิ้นส่วนของมันให้ออกมาเป็น microservice เรื่อยๆนั่นเอง

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

{% hint style="success" %}
**แนะนำให้อ่าน**\
บทความนี้เป็นส่วนหนึ่งของบทความ [👶 Microservices พื้นฐาน](https://saladpuk.gitbook.io/learn/basic/microservices) หากเพื่อนๆสนใจอยากรู้ประวัติความเป็นมาและข้อมูลเบื้องต้นของ Microservices architecture ก็สามารถกดเข้าไปอ่านจากลิงค์สีฟ้าๆได้เลยนะครับ
{% endhint %}

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

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

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

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

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

{% hint style="danger" %}
**ข้อควรระวัง**\
ก่อนที่จะเริ่มต้นทำ microservice architecture อย่าลืมว่าทุกคนในทีมจะต้องเข้าใจหลักในการทำ architecture นี้ด้วยนะ ไม่อย่างนั้นเราจะได้ **service ที่เป็น monolith กระจายเต็มไปหมด** ซึ่งแย่กว่าเดิมอีก
{% endhint %}

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

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lvk8WdtGGcIgRQK7bel%2Fimage.png?generation=1583529099483863\&alt=media)

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

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

* ถูกนำเอา **Build** เมื่อไหร่ก็ได้ อยาก **Test** มันเมื่อไหร่ก็ได้ และต้องเป็น **Automation** ด้วยนะ&#x20;
* สามารถเอา 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 ](https://martinfowler.com/articles/break-monolith-into-microservices.html)นะครับ ซึ่งในบทความเขากำลังทำระบบขายของออนไลน์ โดยในบทความเขาเลือกถอดชิ้นส่วนไล่จากแบบง่ายไปถึงแบบยากตามด้านล่างนี้เลย

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

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

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LuDg5JVuRfVeKoUG_-s%2Fimage.png?generation=1583529180201224\&alt=media)

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

{% hint style="success" %}
**หลักในการแยก**\
เวลาถอดของมาทำเป็น microservice เราควรจะเลือกถอดตัวที่ เมื่อถอดแล้วมันไม่ยุ่งเกี่ยวกับ monolith ได้จะดีมาก เพราะไม่อย่างนั้นตัว service ของเราก็จะยังผูกติดกับ monolith อยู่ดีนั่นเอง ดังนั้นเวลาเลือกให้ดูด้วยว่า monolith ต่างหากที่มาผูกติดกับ microservice
{% endhint %}

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

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

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

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-M-ZSGHJJqtNzYXKBPcs%2Fimage.png?generation=1583529169350500\&alt=media)

{% hint style="success" %}
**ข้อแนะนำ**\
ถ้าเกิดเหตุการณ์ที่เลี่ยงไม่ได้ เลยทำให้ microservice ต้องไปผูกติดกับ monolith จริงๆแล้วละก็ ให้เราสร้าง API ชุดใหม่ใน monolith ออกมาให้ microservice ใช้งานเลยจะดีกว่า เพราะอย่างน้อยเรามันใจได้ว่าจะไม่มีหน้าที่การรับผิดชอบจาก monolith ไหลเข้ามาปนใน service แน่ๆ
{% endhint %}

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

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

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

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LpqfsVeVQ4yMZSqqzGz%2Fimage.png?generation=1583529114557228\&alt=media)

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

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