ทำคณิตศาสตร์: ปรับขนาดแอปพลิเคชัน Microservices ด้วย Orchestrators
เผยแพร่แล้ว: 2022-03-11ไม่น่าแปลกใจเลยที่สถาปัตยกรรมแอปพลิเคชันไมโครเซอร์วิสยังคงบุกรุกการออกแบบซอฟต์แวร์ต่อไป จะสะดวกกว่ามากในการกระจายโหลด สร้างการปรับใช้งานที่มีความพร้อมใช้งานสูง และจัดการการอัปเกรด ในขณะที่การพัฒนาและการจัดการทีมลดลง
แต่เรื่องราวย่อมไม่เหมือนกันหากไม่มีผู้จัดเตรียมตู้คอนเทนเนอร์
เป็นเรื่องง่ายที่จะใช้คุณสมบัติหลักทั้งหมดโดยเฉพาะอย่างยิ่งการปรับขนาดอัตโนมัติ นับเป็นพระพรอย่างยิ่งที่ได้เฝ้าดูการปรับใช้คอนเทนเนอร์ที่ผันผวนตลอดทั้งวัน ปรับขนาดให้เล็กลงเพื่อรองรับภาระปัจจุบัน ทำให้เรามีเวลาทำงานอื่นๆ มากขึ้น เราพอใจกับสิ่งที่เครื่องมือตรวจสอบคอนเทนเนอร์ของเราแสดง ในขณะเดียวกัน เราเพิ่งกำหนดค่าการตั้งค่าสองสามอย่าง—ใช่ นั่นคือ (เกือบ) ทั้งหมดที่ใช้เพื่อสร้างเวทย์มนตร์!
ไม่ได้หมายความว่าไม่มีเหตุผลที่จะต้องภูมิใจในสิ่งนี้: เรามั่นใจว่าผู้ใช้ของเรามีประสบการณ์ที่ดีและเราจะไม่เสียเงินกับโครงสร้างพื้นฐานขนาดใหญ่เกินไป นี้ค่อนข้างมากแล้ว!
และแน่นอนว่าการเดินทางไปที่นั่นช่างเป็นการเดินทางที่สนุกจริงๆ! เพราะถึงแม้ในตอนท้ายจะมีการตั้งค่าไม่มากที่จำเป็นต้องกำหนดค่า แต่ก็ยากกว่าที่เราคิดก่อนที่เราจะเริ่มต้นได้มาก จำนวนแบบจำลองขั้นต่ำ/สูงสุด เกณฑ์การเพิ่มสเกล/ดาวน์สเกล ระยะเวลาการซิงค์ ความล่าช้าในการพัก—การตั้งค่าทั้งหมดนั้นเชื่อมโยงกันอย่างมาก การปรับเปลี่ยนอย่างใดอย่างหนึ่งมักจะส่งผลกระทบกับอีกรายการหนึ่ง แต่คุณยังต้องจัดเตรียมชุดค่าผสมที่สมดุลซึ่งเหมาะกับทั้งแอปพลิเคชัน/การปรับใช้งานและโครงสร้างพื้นฐานของคุณ และถึงกระนั้น คุณจะไม่พบตำราอาหารหรือสูตรวิเศษใดๆ บนอินเทอร์เน็ต เนื่องจากขึ้นอยู่กับความต้องการ ของคุณ เป็นอย่างมาก
พวกเราส่วนใหญ่ตั้งค่าเป็น "สุ่ม" หรือค่าเริ่มต้นก่อน ซึ่งเราจะปรับในภายหลังตามสิ่งที่เราพบขณะตรวจสอบ นั่นทำให้ฉันคิดว่า: จะเป็นอย่างไรถ้าเราสามารถกำหนดขั้นตอน "ทางคณิตศาสตร์" ที่จะช่วยให้เราพบชุดค่าผสมที่ชนะได้
การคำนวณพารามิเตอร์การจัดเรียงคอนเทนเนอร์
เมื่อเราคิดถึงไมโครเซอร์วิสที่ปรับขนาดอัตโนมัติสำหรับแอปพลิเคชัน เรากำลังพิจารณาการปรับปรุงในสองประเด็นหลัก:
- ตรวจสอบให้แน่ใจว่าการปรับใช้สามารถ ขยายได้อย่างรวดเร็ว ในกรณีที่โหลดเพิ่มขึ้นอย่างรวดเร็ว (เพื่อให้ผู้ใช้ไม่ต้องเผชิญการหมดเวลาหรือ HTTP 500)
- ลดต้นทุน ของโครงสร้างพื้นฐาน (เช่น ป้องกันไม่ให้อินสแตนซ์โหลดไม่เพียงพอ)
โดยพื้นฐานแล้วหมายถึงการปรับเกณฑ์ซอฟต์แวร์คอนเทนเนอร์ให้เหมาะสมสำหรับการปรับขนาดขึ้นและลง (อัลกอริทึมของ Kubernetes มีพารามิเตอร์เดียวสำหรับทั้งสอง)
ฉันจะแสดงในภายหลังว่าพารามิเตอร์ที่เกี่ยวข้องกับอินสแตนซ์ทั้งหมดเชื่อมโยงกับเกณฑ์การยกระดับ นี่เป็นวิธีคำนวณที่ยากที่สุด—เพราะฉะนั้นบทความนี้
หมายเหตุ: เกี่ยวกับพารามิเตอร์ที่ตั้งค่าทั่วทั้งคลัสเตอร์ ฉันไม่มีขั้นตอนที่ดีสำหรับพวกเขา แต่ในตอนท้ายของบทความนี้ ฉันจะแนะนำซอฟต์แวร์ (หน้าเว็บแบบสแตติก) ที่คำนึงถึงขณะคำนวณ พารามิเตอร์การปรับขนาดอัตโนมัติของอินสแตนซ์ ด้วยวิธีนี้ คุณจะสามารถเปลี่ยนค่านิยมของพวกเขาเพื่อพิจารณาผลกระทบได้
การคำนวณเกณฑ์การขยายขนาด
เพื่อให้วิธีนี้ใช้ได้ผล คุณต้องตรวจสอบให้แน่ใจว่าแอปพลิเคชันของคุณตรงตามข้อกำหนดต่อไปนี้:
- โหลดจะต้อง กระจายอย่างสม่ำเสมอในทุกอินสแตนซ์ ของแอปพลิเคชันของคุณ (ในลักษณะวนซ้ำ)
- ระยะเวลาของคำขอต้องสั้นกว่า ช่วงตรวจสอบโหลด ของคลัสเตอร์คอนเทนเนอร์ของคุณ
- คุณต้องพิจารณาดำเนินการตามขั้นตอนกับผู้ ใช้จำนวนมาก (กำหนดภายหลัง)
เหตุผลหลักสำหรับเงื่อนไขเหล่านั้นมาจากข้อเท็จจริงที่ว่าอัลกอริธึมไม่ได้คำนวณโหลดตาม ผู้ใช้ แต่เป็นการกระจาย (อธิบายในภายหลัง)
รับ Gaussian ทั้งหมด
อันดับแรก เราต้องกำหนดคำจำกัดความสำหรับ การโหลดที่เพิ่มขึ้นอย่างรวดเร็ว หรืออีกนัยหนึ่งคือ สถานการณ์ที่แย่ที่สุด สำหรับฉัน วิธีที่ดีในการแปลก็คือ การมีผู้ใช้จำนวนมากดำเนินการต่างๆ ที่สิ้นเปลืองทรัพยากรภายในระยะเวลาอันสั้น — และมีความเป็นไปได้ที่สิ่งนี้จะเกิดขึ้นได้เสมอในขณะที่ผู้ใช้หรือบริการกลุ่มอื่นกำลังทำงานอื่นอยู่ เริ่มจากคำจำกัดความนี้แล้วลองแยกคณิตศาสตร์ออกมา (เตรียมแอสไพรินของคุณให้พร้อม)
แนะนำตัวแปรบางส่วน:
- $N_{u}$ "ผู้ใช้จำนวนมาก"
- $L_{u}(t)$ โหลดที่สร้างขึ้นโดยผู้ใช้คนเดียวที่ดำเนินการ "การดำเนินการที่ใช้ทรัพยากรมาก" ($t=0$ ชี้ไปที่ช่วงเวลาที่ผู้ใช้เริ่มดำเนินการ)
- $L_{tot}(t)$ โหลดทั้งหมด (สร้างโดยผู้ใช้ทั้งหมด)
- $T_{tot}$ "ช่วงเวลาสั้นๆ"
ในโลกของคณิตศาสตร์ เมื่อพูดถึงผู้ใช้จำนวนมากที่ทำสิ่งเดียวกันในเวลาเดียวกัน การกระจายของผู้ใช้เมื่อเวลาผ่านไปจะเป็นไปตามการแจกแจงแบบเกาส์เซียน (หรือแบบปกติ) ซึ่งมีสูตรคือ:
\[G(t) = \frac{1}{\sigma \sqrt{2 \pi}} e^{\frac{-(t-\mu)^2}{2 \sigma^2}}\]ที่นี่:
- µ คือค่าที่คาดหวัง
- σ คือค่าเบี่ยงเบนมาตรฐาน
และได้กราฟดังนี้ (ด้วย $µ=0$):
อาจชวนให้นึกถึงบางชั้นเรียนที่คุณเคยเรียน—ไม่มีอะไรใหม่ อย่างไรก็ตาม เราพบปัญหาแรกของเราที่นี่: เพื่อให้ถูกต้องตามหลักคณิตศาสตร์ เราจะต้องพิจารณาช่วงเวลาตั้งแต่ $-\infty$ ถึง $+\infty$ ซึ่งไม่สามารถคำนวณได้อย่างชัดเจน
แต่เมื่อดูกราฟ เราสังเกตเห็นว่าค่าที่อยู่นอกช่วง $[-3σ, 3σ]$ นั้นใกล้เคียงกับศูนย์มากและไม่ได้แตกต่างกันมากนัก ซึ่งหมายความว่าผลของค่าเหล่านั้นจะน้อยมากและสามารถละเว้นได้ นี่เป็นเรื่องจริงมากขึ้น เนื่องจากเป้าหมายของเราคือการทดสอบการปรับขนาดแอปพลิเคชันของเรา ดังนั้นเราจึงมองหารูปแบบต่างๆ ของผู้ใช้จำนวนมาก
นอกจากนี้ เนื่องจากช่วง $[-3σ, 3σ]$ มีผู้ใช้ของเรา 99.7 เปอร์เซ็นต์ จึงใกล้จะถึงยอดรวมทั้งหมดแล้ว เราแค่ต้องคูณ $N_{u}$ ด้วย 1.003 เพื่อหา ความแตกต่าง. การเลือกช่วงเวลานี้ทำให้เราได้ $µ=3σ$ (เนื่องจากเราจะเริ่มจาก $t=0$)
เกี่ยวกับการโต้ตอบกับ $T_{tot}$ การเลือกให้เท่ากับ $6σ$ ($[-3σ, 3σ]$) จะไม่เป็นการประมาณที่ดี เนื่องจาก 95.4 เปอร์เซ็นต์ของผู้ใช้อยู่ในช่วง $[- 2σ, 2σ]$ ซึ่งกินเวลา $4σ$ ดังนั้น การเลือก $T_{tot}$ ให้เท่ากับ $6σ$ จะเพิ่มเวลาเพียงครึ่งเดียวสำหรับผู้ใช้เพียง 4.3 เปอร์เซ็นต์ ซึ่งไม่ได้เป็นตัวแทนจริงๆ ดังนั้นเราจึงเลือกที่จะหา $T_{tot}=4σ$ และเราสามารถอนุมานได้:
\(σ=\frac{T_{tot}}{4}\) และ \(µ=\frac{3}{4} * T_{tot}\)
คุณค่าเหล่านั้นเพิ่งถูกดึงออกมาจากหมวกหรือไม่? ใช่. แต่นี่คือจุดประสงค์ของพวกเขา และสิ่งนี้จะไม่ส่งผลต่อขั้นตอนทางคณิตศาสตร์ ค่าคงที่เหล่านั้นมีไว้สำหรับเรา และกำหนดแนวคิดที่เกี่ยวข้องกับสมมติฐานของเรา ซึ่งหมายความว่าขณะนี้เราได้ตั้งค่าแล้ว สถานการณ์กรณีที่เลวร้ายที่สุดของเราสามารถแปลได้ดังนี้:
โหลดที่สร้างขึ้นโดย 99.7 เปอร์เซ็นต์ของ $N{u}$ ดำเนินการที่สิ้นเปลือง $L{u}(t)$ และที่ 95.4 เปอร์เซ็นต์ของการดำเนินการนี้ดำเนินการภายในระยะเวลา $T{tot}$
(นี่คือสิ่งที่ควรค่าแก่การจดจำเมื่อใช้เว็บแอป)
การฉีดผลลัพธ์ก่อนหน้าลงในฟังก์ชันการแจกแจงผู้ใช้ (เกาส์เซียน) เราสามารถลดความซับซ้อนของสมการได้ดังนี้:
\[G(t) = \frac{4 N_{u}}{T_{tot} \sqrt{2 \pi}} e^\frac{- (4t-3T_{tot})^2}{T_{tot }^2}\]จากนี้ไป เมื่อกำหนด $σ$ และ $µ$ เราจะดำเนินการในช่วง $t \in [0, \frac{3}{2}T_{tot}]$ (คงอยู่ $6σ$)

โหลดผู้ใช้ทั้งหมดคืออะไร?
ขั้นตอนที่สองในไมโครเซอร์วิสที่ปรับขนาดอัตโนมัติคือการคำนวณ $L_{tot}(t)$
เนื่องจาก $G(t)$ เป็นการ แจกแจง ในการดึงข้อมูลจำนวนผู้ใช้ในช่วงเวลาหนึ่ง เราจึงต้องคำนวณอินทิกรัลของมัน (หรือใช้ฟังก์ชันการแจกแจงสะสม) แต่เนื่องจากผู้ใช้ทุกคนไม่ได้เริ่มต้นการทำงานพร้อมกัน จึงเป็นเรื่องยุ่งยากอย่างยิ่งที่จะแนะนำ $L_{u}(t)$ และลดสมการให้เป็นสูตรที่ใช้งานได้
เพื่อให้ง่ายขึ้น เราจะใช้ผลรวมรีมันน์ ซึ่งเป็นวิธีทางคณิตศาสตร์ในการประมาณอินทิกรัลโดยใช้ผลรวมจำกัดของรูปร่างขนาดเล็ก (เราจะใช้สี่เหลี่ยมที่นี่) ยิ่งมีรูปร่าง (ส่วนย่อย) มากเท่าใด ผลลัพธ์ก็จะยิ่งแม่นยำมากขึ้นเท่านั้น ประโยชน์อีกประการของการใช้ส่วนย่อยมาจากการที่เราสามารถพิจารณาผู้ใช้ทั้งหมดภายในแผนกย่อยให้เริ่มดำเนินการพร้อมกันได้
กลับไปที่ผลรวมของรีมันน์ มีคุณสมบัติดังต่อไปนี้เชื่อมต่อกับปริพันธ์:
\[\int_{a}^{b} f( x )dx = \lim_{n \rightarrow \infty } \sum_{k=1}^{n} ( x_{k} - x_{k-1} ) f( x_{k} )\]โดยที่ $x_k$ กำหนดไว้ดังนี้:
\[x_{ k } = a + k\frac{ b - a }{ n }, 0 \leq k \leq n\]นี่เป็นความจริงเมื่อ:
- $n$ คือจำนวนส่วนย่อย
- $a$ คือขอบเขตล่าง ที่นี่ 0
- $b$ เป็นขอบเขตที่สูงกว่า ที่นี่ $\frac{3}{2}*T_{tot}$
- $f$ เป็นฟังก์ชัน—ในที่นี้ $G$—เพื่อประมาณพื้นที่
หมายเหตุ: จำนวนผู้ใช้ที่มีอยู่ในส่วนย่อยไม่ใช่จำนวนเต็ม นี่คือเหตุผลสำหรับข้อกำหนดเบื้องต้นสองประการ: การมีผู้ใช้จำนวนมาก (ดังนั้น ส่วนทศนิยมจึงไม่ส่งผลกระทบมากเกินไป) และความจำเป็นในการกระจายโหลดอย่างสม่ำเสมอในทุกอินสแตนซ์
นอกจากนี้ โปรดทราบว่าเราสามารถเห็นรูปทรงสี่เหลี่ยมผืนผ้าของส่วนย่อยทางด้านขวามือของคำจำกัดความผลรวมของรีมันน์
ตอนนี้ เรามีสูตรผลรวมของรีมันน์แล้ว เราสามารถพูดได้ว่าค่าโหลด ณ เวลา $t$ คือผลรวมของจำนวนผู้ใช้ในแผนกย่อยทั้งหมดคูณด้วยฟังก์ชันโหลดของผู้ใช้ ณ เวลาที่สอดคล้องกัน สามารถเขียนได้ดังนี้:
\[L_{ tot }( t ) = \lim_{n \rightarrow \infty} \sum_{ k=1 }^{ n } ( x_{k} - x_{k-1} )G( x_{k} ) L_{ คุณ }( t - x_{k} )\]หลังจากแทนที่ตัวแปรและทำให้สูตรง่ายขึ้น สิ่งนี้จะกลายเป็น:
\[L_{ tot }( t ) = \frac{6 N_{u}}{\sqrt{2 \pi}} \lim_{n \rightarrow \infty} \sum_{ k=1 }^{ n } (\ frac{1}{n}) e^{-{(\frac{6k}{n} - 3)^{2}}} L_{ u }( t - k \frac{3 T_{tot}}{2n } )\]แล้ว โว้ย ! เราสร้างฟังก์ชั่นโหลดแล้ว!
การหาเกณฑ์ในการขยายสเกล
ในการทำให้เสร็จ เราเพียงแค่เรียกใช้อัลกอริทึมแบบแบ่งขั้วซึ่งแตกต่างกันไปตามเกณฑ์เพื่อค้นหาค่าสูงสุดที่โหลดต่ออินสแตนซ์จะไม่เกินขีดจำกัดสูงสุดตลอดฟังก์ชันโหลด (นี่คือสิ่งที่ทำโดยแอพ)
การลดพารามิเตอร์ Orchestration อื่นๆ
ทันทีที่คุณพบเกณฑ์การเพิ่มขนาดของคุณ ($S_{up}$) พารามิเตอร์อื่นๆ จะคำนวณได้ง่ายมาก
จาก $S_{up}$ คุณจะทราบจำนวนอินสแตนซ์สูงสุดของคุณ (คุณยังสามารถค้นหาโหลดสูงสุดในฟังก์ชันโหลดของคุณ และหารตามโหลดสูงสุดต่ออินสแตนซ์ โดยปัดเศษขึ้น)
ต้องกำหนดจำนวนขั้นต่ำ ($N_{min}$) ของอินสแตนซ์ตามโครงสร้างพื้นฐานของคุณ (ฉันขอแนะนำให้มีแบบจำลองขั้นต่ำหนึ่งแบบจำลองต่อ AZ) แต่ก็ต้องคำนึงถึงฟังก์ชันการโหลดด้วย: เนื่องจากฟังก์ชันเกาส์เซียนเพิ่มขึ้นค่อนข้างรวดเร็ว การกระจายโหลดจะรุนแรงขึ้น (ต่อแบบจำลอง) ในตอนเริ่มต้น ดังนั้นคุณ อาจต้องการเพิ่มจำนวนแบบจำลองขั้นต่ำเพื่อรองรับเอฟเฟกต์นี้ (สิ่งนี้มักจะเพิ่ม $S_{up}$ ของคุณ)
สุดท้าย เมื่อคุณกำหนดจำนวนแบบจำลองขั้นต่ำแล้ว คุณสามารถคำนวณเกณฑ์การลดขนาด ($S_{down}$) โดยพิจารณาจากสิ่งต่อไปนี้: เนื่องจากการลดขนาดแบบจำลองเดียวจะไม่มีผลกับอินสแตนซ์อื่นมากกว่าเมื่อลดขนาดจาก $N_{min}+1$ ถึง $N_{min}$ เราต้องตรวจสอบให้แน่ใจว่าเกณฑ์การขยายขนาดจะไม่ถูกทริกเกอร์ทันทีหลังจากลดขนาดลง หากอนุญาต จะมีผลโยโย่ กล่าวอีกนัยหนึ่ง:
\[( N_{ นาที } + 1) S_{ ลดลง } < N_{ นาที }S_{ ขึ้น }\]หรือ:
\[S_{ ลดลง } < \frac{N_{ min }}{N_{min}+1}S_{ up }\]นอกจากนี้ เรายังยอมรับได้ด้วยว่ายิ่งคลัสเตอร์ของคุณได้รับการกำหนดค่าให้รอนานขึ้นก่อนที่จะลดขนาดลง ก็ยิ่งปลอดภัยที่จะตั้งค่า $S_{down}$ ให้เข้าใกล้ขีดจำกัดที่สูงขึ้น คุณจะต้องหาจุดสมดุลที่เหมาะสมกับคุณอีกครั้ง
โปรดทราบว่าเมื่อใช้ระบบประสาน Mesosphere Marathon กับตัวปรับขนาดอัตโนมัติ จำนวนสูงสุดของอินสแตนซ์ที่สามารถลบได้ในครั้งเดียวจากการปรับขนาดลงจะผูกกับ AS_AUTOSCALE_MULTIPLIER
($A_{mult}$) ซึ่งหมายความว่า:
ฟังก์ชั่นโหลดของผู้ใช้เป็นอย่างไร?
ใช่ นั่นเป็นปัญหาเล็กน้อย และไม่ใช่ปัญหาที่ง่ายที่สุดในการแก้ปัญหาทางคณิตศาสตร์ ถ้ามันเป็นไปได้เลย
เพื่อแก้ไขปัญหานี้ แนวคิดคือการเรียกใช้อินสแตนซ์เดียวของแอปพลิเคชันของคุณ และเพิ่มจำนวนผู้ใช้ที่ทำงานเดียวกันซ้ำๆ จนกว่าเซิร์ฟเวอร์จะโหลดถึงค่าสูงสุดที่ได้รับมอบหมาย (แต่ไม่เกิน) จากนั้นหารด้วยจำนวนผู้ใช้และคำนวณเวลาเฉลี่ยของคำขอ ทำซ้ำขั้นตอนนี้กับทุกการกระทำที่คุณต้องการรวมเข้ากับฟังก์ชันการโหลดผู้ใช้ของคุณ เพิ่มเวลา และคุณอยู่ที่นั่น
ฉันทราบดีว่าขั้นตอนนี้แสดงถึงการพิจารณาว่าคำขอของผู้ใช้แต่ละรายมีการโหลดอย่างต่อเนื่องในการประมวลผล (ซึ่งเห็นได้ชัดว่าไม่ถูกต้อง) แต่ผู้ใช้จำนวนมากจะสร้างเอฟเฟกต์นี้เนื่องจากแต่ละรายการไม่ได้อยู่ในขั้นตอนการประมวลผลเดียวกันในเวลาเดียวกัน . ดังนั้น ฉันเดาว่านี่เป็นการประมาณที่ยอมรับได้ แต่เป็นการบอกเป็นนัยอีกครั้งว่าคุณกำลังติดต่อกับผู้ใช้จำนวนมาก
คุณยังสามารถลองใช้วิธีอื่นๆ เช่น กราฟเปลวไฟของ CPU แต่ฉันคิดว่ามันยากมากที่จะสร้างสูตรที่ถูกต้องซึ่งจะเชื่อมโยงการกระทำของผู้ใช้กับการใช้ทรัพยากร
แนะนำ app-autoscaling-calculator
และตอนนี้ สำหรับเว็บแอปขนาดเล็กที่กล่าวถึงทั้งหมด: ใช้เป็นอินพุตฟังก์ชันโหลดของคุณ การกำหนดค่าคอนเทนเนอร์ออร์เคสตรา และพารามิเตอร์ทั่วไปอื่นๆ และส่งคืนเกณฑ์การเพิ่มขนาดและตัวเลขที่เกี่ยวข้องกับอินสแตนซ์อื่นๆ
โปรเจ็กต์นี้โฮสต์บน GitHub แต่ก็มีเวอร์ชันใช้งานจริงด้วย
นี่คือผลลัพธ์ที่ได้จากเว็บแอป เทียบกับข้อมูลการทดสอบ (บน Kubernetes):
Scaling Microservices: ไม่มีการสะดุดในความมืดอีกต่อไป
เมื่อพูดถึงสถาปัตยกรรมแอปพลิเคชันไมโครเซอร์วิส การปรับใช้คอนเทนเนอร์จะกลายเป็นจุดศูนย์กลางของโครงสร้างพื้นฐานทั้งหมด และยิ่งมีการกำหนดค่า orchestrator และคอนเทนเนอร์ได้ดีเท่าใด รันไทม์ก็จะยิ่งราบรื่นขึ้นเท่านั้น
พวกเราในสายงานบริการ DevOps มักจะมองหาวิธีที่ดีกว่าในการปรับแต่งพารามิเตอร์การประสานสำหรับแอปพลิเคชันของเรา ลองใช้วิธีการทางคณิตศาสตร์มากขึ้นในการปรับขนาดอัตโนมัติของไมโครเซอร์วิส!