บทที่ 1: โครงสร้างของการลองอีกครั้งใน Go
1.1 เข้าใจความจำเป็นของกลไกการลองอีกครั้ง
ในสถานการณ์การคำนวณหลายรายการ โดยเฉพาะเมื่อมีปัญหาในระบบที่แบ่งเบาะแบ่งหรือการสื่อสารผ่านเครือข่าย การดำเนินการอาจล้มเหลวเนื่องจากข้อผิดพลาดชั่วคราว ข้อผิดพลาดเหล่านี้มักเป็นปัญหาชั่วคราว เช่น ความไม่เสถียรของเครือข่าย การให้บริการที่ไม่พร้อมใช้งานชั่วคราว หรือการหมดเวลา แทนที่จะล้มเหลวทันที ระบบควรถูกออกแบบให้ลองดำเนินการเมื่อเจอข้อผิดพลาดชั่วคราวเหล่านั้น การใช้วิธีนี้ช่วยปรับปรุงความเชื่อถือได้อย่างมีนัยสำคัญและความคงทนของระบบ
กลไกการลองอีกครั้งอาจเป็นสิ่งขาดไม่ได้ในแอปพลิเคชันที่ต้องการความสอดคล้องและความสมบูรณ์ของการดำเนินการ นอกจากนี้ มันยังช่วยลดอัตราข้อผิดพลาดที่ผู้ใช้สุดท้ายพบเจอ อย่างไรก็ตาม การนำกลไกการลองอีกครั้งมาใช้นั้นมาพร้อมกับความท้าทาย เช่น การตัดสินใจว่าต้องลองอีกครั้งเท่าไหร่และนานเท่าไหร่ก่อนที่จะยอมแพ้ นั่นคือจุดที่กลไกสูญเสียมีบทบัญชาอย่างมีนัยสำคัญ
1.2 ภาพรวมของไลบรารี go-retry
ใน Go
ไลบรารี go-retry
ใน Go มอบความยืดหยุ่นในการเพิ่มตัวตนการลองอีกครั้งลงในแอปพลิเคชันของคุณด้วยกลไกการลองอีกครั้งที่หลากหลาย. คุณสมบัติหลักประกอบด้วย:
- ความยืดหยุ่นในการเพิ่มตัวตน: เหมือนกับแพ็คเกจ
http
ใน Go,go-retry
ถูกออกแบบมาเพื่อที่จะสามารถขยายตัวด้วยมิดเด็ด คุณสามารถเขียนฟังก์ชันใหม่หรือใช้ฟิลเตอร์ที่มีประโยชน์ได้ - อิสระ: ไลบรารีนี้ใช้เพียงแค่ไลบรารีมาตรฐานของ Go และหลีกเลี่ยงการพึ่งพาจากแหล่งข้อมูลภายนอก เพื่อให้โปรเจคของคุณมีน้ำหนักระบาย
- การทำงานแบบพร้อมสวน: มันปลอดภัยในการใช้งานแบบพร้อมสวนและสามารถทำงานร่วมกับกอรูทีนโดยไม่ต้องรบกวนเพิ่มเติม
- รอบคำขอใบ้สึก: มันสนับสนุนคอนเท็กซ์ของ Go สำหรับการหมดเวลาและการยกเลิก ผสานอย่างสวยงามกับโมเดลความพร้อมสวนของ Go
บทที่ 2: การนำเข้าไลบรารี
ก่อนที่คุณจะใช้ไลบรารี go-retry
คุณต้องนำเข้าไลบรารีนี้เข้าสู่โปรเจคของคุณ นี้สามารถทำได้โดยใช้ go get
ซึ่งคือคำสั่ง Go เพื่อเพิ่มขึ้นอยู่กับโมดูลของคุณ แค่เปิดโปรแกรมคอมพิวเตอร์และใช้คำสั่งต่อไปนี้:
go get github.com/sethvargo/go-retry
คำสั่งนี้จะดึงไลบรารี go-retry
และเพิ่มไปยังขึ้นอยู่กับโปรเจคของคุณ หลังจากนั้นคุณสามารถนำเข้ามันเข้าไปในโค้ดของคุณได้เหมือนกับแพ็คเกจ Go อื่น ๆ
บทที่ 3: การดำเนินการลองอีกครั้งพื้นฐาน
3.1 ลองอีกครั้งอย่างง่ายด้วยการหดครั้งเสมอ
รูปแบบที่ง่ายที่สุดของโลจิกการลองอีกครั้งเกี่ยวข้องกับการรอเวลาคงที่ระหว่างลองอีกครั้ง. คุณสามารถใช้ go-retry
เพื่อทำการลองอีกครั้งด้วยการหดครั้งเสมอ
นี่คือตัวอย่างที่เป็นของวิธีที่จะใช้การหดครั้งเสมอกับ go-retry
:
package main
import (
"context"
"time"
"github.com/sethvargo/go-retry"
)
func main() {
ctx := context.Background()
// สร้างการหดครั้งเสมอใหม่
backoff := retry.NewConstant(1 * time.Second)
// ห่อหุ้มโลจิกการลองอีกครั้งของคุณไว้ในฟังก์ชันซึ่งจะถูกส่งให้กับ retry.Do
operation := func(ctx context.Context) error {
// โค้ดของคุณที่นี่ คืนการลองอีกครั้ง.เรอเรียบต่อ รหัส:
// err := someOperation()
// if err != nil {
// return retry.RetryableError(err)
// }
// return nil
return nil
}
// ใช้ retry.Do พร้อมทัศนคติที่ต้องการ กลยุทธ์การหดรอและการดำเนินการ
if err := retry.Do(ctx, backoff, operation); err != nil {
// จัดการความผิดพลาด
}
}
ในตัวอย่างนี้ ฟังก์ชัน retry.Do
จะพยายานที่จะพยายานฟังก์ชัน operation
ทุก 1 วินาทีจนกว่ามันจะประสบความสำเร็จ หรือประสบภาวะหมดเวลาหรือยกเลิก
3.2 การดำเนินการกับการหดอายุแบบเพิ่ม
การหดอายุแบบเพิ่มจะทำให้รอเวลาระหว่างการลองอีกครั้งเพิ่มขึ้นอย่างเรขาคณิต กลยุทธ์นี้ช่วยลดภาระของระบบและมีประโยชน์โดยเฉพาะเมื่อมีปัญหาในระบบขนาดใหญ่หรือบริการคลาวด์
วิธีการใช้การหดอายุแบบเพิ่มกับ go-retry
ได้ดังนี้:
package main
import (
"context"
"time"
"github.com/sethvargo/go-retry"
)
func main() {
ctx := context.Background()
// สร้างการหดอายุแบบเพิ่มใหม่
backoff := retry.NewExponential(1 * time.Second)
// ระบุการดำเนินการที่สามารถทำการลองอีกได้
operation := func(ctx context.Context) error {
// ปฎิบัติการตามที่แสดงไว้ก่อนหน้านี้
return nil
}
// ใช้ retry.Do เพื่อดำเนินการการทำงานพร้อมกับการหดอายุแบบเพิ่ม
if err := retry.Do(ctx, backoff, operation); err != nil {
// จัดการความผิดพลาด
}
}
ในกรณีของการหดอายุแบบเพิ่ม หากการหดแรกถูกตั้งไว้เป็น 1 วินาที การลองอีกครั้งจะเกิดขึ้นหลังจาก 1 วินาที, 2 วินาที, 4 วินาที และอื่น ๆ โดยที่ระยะทางรอระหว่างการลองอีกครั้งเพิ่มขึ้นเป็นเรขาคณิต
3.3 กลยุทธ์การลดทอน Fibonacci
กลยุทธ์การลดทอน Fibonacci ใช้ลำดับ Fibonacci เพื่อกำหนดเวลารอระหว่างการลองใหม่ ซึ่งสามารถเป็นกลยุทธ์ที่ดีสำหรับปัญหาที่เกี่ยวกับเครือข่ายที่การเพิ่มเวลาทำให้เป็นประโยชน์
การนำกลยุทธ์การลดทอน Fibonacci มาใช้กับ go-retry
ได้ไดemonstrate ดังต่อไปนี้:
package main
import (
"context"
"time"
"github.com/sethvargo/go-retry"
)
func main() {
ctx := context.Background()
// สร้าง Fibonacci backoff ใหม่
backoff := retry.NewFibonacci(1 * time.Second)
// กำหนดการทำงานที่ต้องการทำลองใหม่
operation := func(ctx context.Context) error {
// ที่นี่คือโลจิกที่ใช้ทำการที่อาจล้มเหลวและต้องทำการลองใหม่
return nil
}
// ดำเนินการทำงานพร้อมกับ Fibonacci backoff โดยใช้ retry.Do
if err := retry.Do(ctx, backoff, operation); err != nil {
// จัดการข้อผิดพลาด
}
}
ด้วย Fibonacci backoff ที่มีค่าเริ่มต้นเป็น 1 วินาที, การทำลองใหม่จะเกิดขึ้นหลังจาก 1 วินาที, 1 วินาที, 2 วินาที, 3 วินาที, 5 วินาที, เป็นต้นไปตามลำดับ Fibonacci
บทที่ 4: เทคนิคการทำลองใหม่และมิดเดิลแวร์ขั้นสูง
4.1 การใช้ Jitter ในการทำลองใหม่
ในการนำเข้าตรรกะการทำลองใหม่, สำคัญที่จะพิจารณาผลกระทบของการทำลองใหม่พร้อมกันบนระบบที่อาจเป็นปัญหาของอุปสรรคแท่จะใช้การเพิ่มจิตเตอร์สุ่มไปยังช่วงเวลาการลดทอน วิธีการนี้ช่วยในการสลักการทำลองใหม่, ลดความน่าจะเป็นของการทำลองซ้ำๆพร้อมกันของลูกค้าหลายๆคน
ตัวอย่างการเพิ่มจิตเตอร์:
b := retry.NewFibonacci(1 * time.Second)
// คืนค่าค่าถัดไป, +/- 500ms (มิลลิวินาที)
b = retry.WithJitter(500 * time.Millisecond, b)
// คืนค่าค่าถัดไป, +/- 5% ของผลลัพธ์
b = retry.WithJitterPercent(5, b)
4.2 การกำหนดจำนวนการทำลองใหม่สูงสุด
ในบางกรณี, จำเป็นจะต้องจำกัดจำนวนการทำลองใหม่เพื่อป้องกันการทำลองใหม่ที่ยาวนานและไม่เป็นประโยชน์ โดยการระบุจำนวนการทำลองใหม่สูงสุด, เราสามารถควบคุมจำนวนการพยายามก่อนยอมและยุติการดำเนินการ
ตัวอย่างการกำหนดจำนวนการทำลองใหม่สูงสุด:
b := retry.NewFibonacci(1 * time.Second)
// หยุดหลังจาก 4 ครั้งการทำซ้ำ, เมื่อการพยายามครั้งที่ 5 ล้มเหลว
b = retry.WithMaxRetries(4, b)
4.3 การจำกัดระยะเวลาการลดทอนแต่ละครั้ง
เพื่อให้แน่ใจว่าระยะเวลาการลดทอนแต่ละครั้งไม่เกินขีดจำกัดที่ระบุไว้, เราสามารถใช้มิดเดิลแวร์ CappedDuration
นี้ ซึ่งจะป้องกันช่วงเวลาการลดทอนที่ยาวเกินไป ทำให้การทำลองใหม่ทำให้เป็นเอื้องง่าย
ตัวอย่างการจำกัดระยะเวลาการลดทอนแต่ละครั้ง:
b := retry.NewFibonacci(1 * time.Second)
// ให้แน่ใจว่าค่าสูงสุดคือ 2 วินาที
b = retry.WithCappedDuration(2 * time.Second, b)
4.4 การควบคุมระยะเวลาการทำลองใหม่ทั้งหมด
ในบางกรณีที่จำเป็นต้องมีขีดจำกัดในระยะเวลาที่รวมของกระบวนการทำลองใหม่, มิดเดิลแวร์ WithMaxDuration
สามารถใช้เพื่อระบุเวลาทั้งหมดที่สูงสุดที่อยู่ในกระบวนการทำลองใหม่ ซึ่งจะทำให้แน่ใจว่ากระบวนการทำลองใหม่ไม่ต้องการเรื่อยไปอย่างไม่มีสิ้นสุด, หากปริมาณเวลาที่ประมวลผลทำให้การทำลองใหม่ยืดนานเกินไป
ตัวอย่างการควบคุมระยะเวลาการทำลองใหม่ทั้งหมด:
b := retry.NewFibonacci(1 * time.Second)
// ให้แน่ใจว่าเวลาทำลองใหม่ทั้งหมดสูงสุดคือ 5 วินาที
b = retry.WithMaxDuration(5 * time.Second, b)