> For the complete documentation index, see [llms.txt](https://www.saladpuk.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.saladpuk.com/basic/microservices.md).

# Microservices พื้นฐาน

## 😢 ปัญหา

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

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

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

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

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

### 🔥 Monolithic application models

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

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

![](/files/-LuAO2BhDbELxVmXJUQ3)

**อธิบายรูปด้านบน**\
โดยปกติเราจะแบ่ง 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** นั่นเองซึ่งข้อเสียของมันคือ *\*\**&#xE40;วลามันล่มขึ้นมามันจะกอดคอกันตายเป็นหมู่คณะ เพราะเวลาที่ฐานข้อมูลล่ม เราจะไม่สามารถเข้าถึงข้อมูลอะไรได้เลย หรือตัว Business Logic ล่มก็เช่นกัน

### 🔥 Microservices architecture

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

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

![](/files/-Lu8FAoq7C07LG4ag-ls)

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

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

{% hint style="info" %}
**Container** คืออะไร สามารถอ่านได้จากลิงค์นี้เลย [👶 Docker ขั้นพื้นฐาน](https://saladpuk.gitbook.io/learn/basic/docker) ซึ่งในอนาคต developer น่าจะได้ใช้ตัวนี้กันทุกคนอยู่แล้ว ดังนั้นอ่านไว้เถอะไม่เสียหายหรอก
{% endhint %}

![](/files/-LzbuJYahtp1gMFSXM90)

และแต่ละ 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 ต่างๆ

![](/files/-LmwqERhwEjXcswRsVGE)

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

![](/files/-Lzg25K-76uqSQIVaW-w)

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

### 🔥 Microservices architecture

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

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

![](/files/-LnSFWshBJfwjoCpQrrG)

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

![](/files/-LsZZqUCbRWUtgn0L8hc)

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

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

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

![](/files/-Lq621SaBSwV_mczIihi)

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

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

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

* **Single purpose** - แต่ละ serivce นั้นจะต้องมีหน้าที่รับผิดชอบเพียงอย่างเดียว เพราะมันจะได้ดูแลงานเพียงงานเดียว เวลาแก้ไขก็จะไม่กระทบกับงานเรื่องอื่นๆ และตรงตามหลักการออกแบบที่ชื่อว่า **Single Responsibility Principle** ด้วย
* **Loose coupling** - แต่ละ service ควรจะไม่รู้จักกันเลยได้ยิ่งดี แต่ให้มันติดต่อกันผ่านแค่ API contracts เท่านั้น เพราะไม่อย่างนั้นมันจะเกิดการผูกติดกันเกิดขึ้น ซึ่งจะทำให้เมื่อ service อื่นเกิดการเปลี่ยนแปลงขึ้น จะส่งผลให้ service ที่ผูกติดกับมันต้องไปไล่แก้ตามนั่นเอง
* **High cohesion** - ของที่อยู่ภายใน service ควรจะต้องเป็นเรื่องที่เกี่ยวข้องกับมันเท่านั้น เพราะมันจะต้องดูแลเฉพาะงานที่มันรับผิดชอบเพียงอย่างเดียว เช่น ถ้างานของมันต้องดูละเรื่องสินค้า ของทุกอย่างใน service จะต้องเป็นเรื่องเกี่ยวกับสินค้าเท่านั้น ห้ามมี ลูกค้าเข้ามาเกี่ยวข้อง เพราะไม่อย่างนั้นเวลาแก้ไขเรื่องสินค้าอาจจะกระทบเรื่องลูกค้าก็ได้ แล้วมันจะสูญเสียความคล่องตัวของมันไปนั่นเอง

{% hint style="success" %}
**แนะนำให้อ่าน**\
หลักในการออกแบบซอฟต์แวร์ที่ดีมีหลายตัวเลย ซึ่งผมอยากให้เพื่อนๆได้รู้จักกับ 5 ตัวพื้นฐานของมันนั่นคือสิ่งที่เรียกว่า **SOLID** ครับ ซึ่งสามารถอ่านได้จากบทความนี้เลย [👦 SOLID Design Principles](https://saladpuk.gitbook.io/learn/basic/solid) ซึ่งภายคอร์สนั้นจะพูดถึง **Single purpose,** **Coupling** และ **Cohesion** ไว้อย่างละเอียดเลยว่ามันคืออะไรครับ
{% endhint %}

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

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

{% content-ref url="/pages/-Lq6FxsL\_v69XEsK2xno" %}
[Azure Service Fabric](/cloud/azure-service-fabric.md)
{% endcontent-ref %}

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

{% hint style="info" %}
ตัวคอร์สนี้กำลังค่อยอัพเดทเรื่อยๆอยู่ ซึ่งถ้ามีอัพเดทใหม่จะเอามาลงไว้ในหน้านี้แหละ ส่วนถ้าเพื่อนๆไม่อยากพลาดอัพเดทให้เข้าไปกดไลค์ตัวเพจนี้ไว้นะ [**Saladpuk Facebook**](https://facebook.com/mr.saladpuk) *\*\**&#xE40;วลาที่มีอัพเดทใหม่มันจะได้ส่งข้อความไปหา
{% endhint %}

{% content-ref url="/pages/-LqC-2vn7IkUvF5gMvmH" %}
[Microservices ที่ดีมีลักษณะยังไง](/basic/microservices/microservices.md)
{% endcontent-ref %}

{% content-ref url="/pages/-LqHPHCSWBzzlO-2Z2X4" %}
[Microservices Tips](/basic/microservices/tips.md)
{% endcontent-ref %}

{% content-ref url="/pages/-LqQmurs6IPG5QAPPD-v" %}
[จาก Monolith สู่ Microservices](/basic/microservices/monolith-services.md)
{% endcontent-ref %}

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

## 🎯 บทสรุป

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

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

{% hint style="danger" %}
**ข้อควรระวัง 1**\
การทำ Microservice Architecture ไม่ใช่เรื่องเท่ห์ มันไม่ใช่เรื่องว่ามันเป็นของใหม่แล้วเราควรจะเอามันไปใช้เสมอไป เพราะจากบทความ [👶 สิ่งที่คนเขียนโค้ดมักเข้าใจผิด](https://saladpuk.gitbook.io/learn/basic/mist) ผมได้อธิบายไปแล้วว่าการออกแบบซอฟต์แวร์ไม่ใช่เรื่องของเทคโนโลยี แต่**หัวใจสำคัญคือ Requirements** ต่างหาก ส่วนเทคโยโลยีนั้นเป็นเรื่องแทบจะเป็นสิ่งสุดท้ายเลยที่เราจะเลือกครับ
{% endhint %}

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