안녕하세요 고퍼스 여러분! ? 오늘은 고전적인 "고루틴이 너무 많다"는 골칫거리로부터 여러분을 구할 수 있는 방법인 GoFrame의 grpool에 대해 알아 보겠습니다. Go에서 동시성 높은 서비스를 다루어 본 적이 있다면 훈련 방법을 알고 계실 것입니다. 고루틴을 생성하고, 관리하고, 너무 많이 생성하지 않도록 기도하세요... 하지만 더 나은 방법이 있다면 어떨까요?
다음을 생각해 보세요. 업로드 처리, API에서 데이터 가져오기, WebSocket 연결 처리 등 여러 동시 작업을 처리해야 하는 서비스를 구축하고 있습니다. 첫 번째 본능은 다음과 같습니다.
for task := range tasks { go processTask(task) // Look ma, concurrency! }
청순해 보이는데요? 하지만 프로덕션 환경에서는 수천 건의 요청이 발생하여 다음과 같은 상황이 발생할 수 있습니다.
여기서 grpool이 구출하러 옵니다! ?♂️
grpool은 GoFrame 프레임워크의 일부이지만 멋진 부분이 있습니다. 독립적으로 사용할 수 있다는 것입니다! 이는 각 작업에 대해 새로운 작업자를 고용(생성)하는 대신 작업을 수행할 준비가 된 작업자 팀(고루틴)을 갖는 것과 같습니다.
먼저 패키지를 챙기세요.
go get github.com/gogf/gf/v2
가장 간단한 사용 방법은 다음과 같습니다.
import "github.com/gogf/gf/v2/os/grpool" func main() { ctx := context.Background() // Create a pool with 10 workers pool := grpool.New(10) // Add a task - it's this simple! pool.Add(ctx, func(ctx context.Context) { fmt.Println("Task executed by a worker from the pool!") }) }
여러 업로드를 동시에 처리할 수 있는 실용적인 이미지 프로세서를 만들어 보겠습니다.
package main import ( "context" "fmt" "github.com/gogf/gf/v2/os/grpool" "sync" ) func processImages() { // Create a pool with 5 workers pool := grpool.New(5) ctx := context.Background() var wg sync.WaitGroup // Simulate 20 image uploads images := make([]string, 20) for i := range images { wg.Add(1) imageURL := fmt.Sprintf("image_%d.jpg", i) pool.Add(ctx, func(ctx context.Context) { defer wg.Done() processImage(imageURL) }) } wg.Wait() } func processImage(url string) { // Simulate image processing fmt.Printf("Processing %s\n", url) // Your actual image processing logic here }
grpool과 원시 고루틴을 비교하는 몇 가지 벤치마크를 실행했습니다. 제가 찾은 내용은 다음과 같습니다.
func BenchmarkComparison(b *testing.B) { ctx := context.Background() b.Run("With grpool", func(b *testing.B) { pool := grpool.New(10) for i := 0; i < b.N; i++ { pool.Add(ctx, func(ctx context.Context) { time.Sleep(time.Millisecond) }) } }) b.Run("Without pool", func(b *testing.B) { for i := 0; i < b.N; i++ { go func() { time.Sleep(time.Millisecond) }() } }) }
내 컴퓨터의 결과:
BenchmarkComparison/With_grpool-8 5804 202395 ns/op BenchmarkComparison/Without_pool-8 3662 304738 ns/op
약 33% 성능 향상입니다! ?
// For CPU-bound tasks pool := grpool.New(runtime.NumCPU()) // For I/O-bound tasks pool := grpool.New(runtime.NumCPU() * 2)
pool.Add(ctx, func(ctx context.Context) { defer func() { if err := recover(); err != nil { log.Printf("Task panicked: %v", err) } }() // Your task code here })
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() pool.Add(ctx, func(ctx context.Context) { select { case <-ctx.Done(): fmt.Println("Task cancelled!") return default: // Your task code here } })
grpool은 다음과 같은 경우에 빛을 발합니다.
grpool은 "내가 왜 전에는 이것을 사용하지 않았지?"라고 생각하게 만드는 도구 중 하나입니다. 빠르게 시작할 수 있을 만큼 간단하지만 프로덕션 용도로 사용할 수 있을 만큼 강력합니다. 다음 프로젝트에서 시도해 보고 어떻게 진행되는지 알려주세요!
grpool이나 유사한 고루틴 풀 구현을 사용해 보셨나요? 아래 댓글로 여러분의 경험을 공유해 주세요! ?
참고: 위의 벤치마크는 내 로컬 컴퓨터에서 실행되었습니다. 결과는 하드웨어와 워크로드에 따라 다를 수 있습니다.
위 내용은 GoFrames grpool로 Go 동시 작업을 강화하세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!