ksundev 님의 블로그

[URL Checker][New] Go Routine을 장착한 빠른 URL Checker🔥 본문

[개발] Go/중급 프로젝트

[URL Checker][New] Go Routine을 장착한 빠른 URL Checker🔥

ksundev 2025. 7. 14. 15:00

 

2025.06.26 - [[개발] Go/중급 프로젝트] - [URL Checker] hitURL 그리고 느린 URL Checker (순차적)

 

[URL Checker] hitURL 그리고 느린 URL Checker (순차적)

urls := []string{ "https://www.airbnb.com/", "https://www.google.com/", "https://www.amazon.com/", "https://www.reddit.com/", "https://www.google.com/", "https://soundcloud.com/", "https://www.facebook.com/", "https://www.instagram.com/", }위의 유명한

ksundev.tistory.com

이전 URL Checker 포스트가 기억 나시나요? 코드로는 아래와 같았습니다.

package main

import (
	"errors"
	"fmt"
	"net/http"
)

var errRequestFailed = errors.New("Request Failed")

func main() {
	var results = make(map[string]string)
	urls := []string{
		"https://www.airbnb.com/",
		"https://www.google.com/",
		"https://www.amazon.com/",
		"https://www.reddit.com/",
		"https://www.google.com/",
		"https://soundcloud.com/",
		"https://www.facebook.com/",
		"https://www.instagram.com/",
	}

	for _, url := range urls {
		result := "OK"
		err := hitURL(url)
		if err != nil {
			result = "FAILED"
		}
		results[url] = result
	}
	for url, result := range results {
		fmt.Println(url, result)
	}
}

func hitURL(url string) error {
	fmt.Println("Checking", url)
	resp, err := http.Get(url)
	if err != nil || resp.StatusCode >= 400 {
		return errRequestFailed
	}
	return nil
}

순차적으로 페이지에 접속하다보니, 하나당 1초가 걸린다면 전체 코드가 실행되는 데 10초가 소요되었습니다.

하지만 우리는 이제 Go Routine이라는 무기가 있죠?
동시에 접속을 시도하여(병렬) 단 1초만에 모든 태스크를 마치는 버전을 만들어봅시다!

 

request 결과 구조체 만들기

type requestResult struct {
	url    string
	status string
}

채널 c 만들기

c := make(chan requestResult)

hitURL 함수 만들기

func hitURL(url string, c chan<- requestResult) {
	fmt.Println("Checking", url)
	resp, err := http.Get(url)
	status := "OK"
	if err != nil || resp.StatusCode >= 400 {
		status = "FAILED"
	}
	c <- requestResult{url: url, status: status}
}

요청 보내기 및 응답 출력 with Go Routines

// main() ...
for _, url := range urls {
		go hitURL(url, c)
	}

	for i := 0; i < len(urls); i++ {
		result := <-c
		fmt.Println(result)
	}
}

최종 전체 코드(main.go)

package main

import (
	"fmt"
	"net/http"
)

type requestResult struct {
	url    string
	status string
}

func main() {
	urls := []string{
		"https://www.airbnb.com/",
		"https://www.google.com/",
		"https://www.amazon.com/",
		"https://www.reddit.com/",
		"https://www.google.com/",
		"https://soundcloud.com/",
		"https://www.facebook.com/",
		"https://www.instagram.com/",
	}

	c := make(chan requestResult)
	for _, url := range urls {
		go hitURL(url, c)
	}

	for i := 0; i < len(urls); i++ {
		result := <-c
		fmt.Println(result)
	}
}

func hitURL(url string, c chan<- requestResult) {
	fmt.Println("Checking", url)
	resp, err := http.Get(url)
	status := "OK"
	if err != nil || resp.StatusCode >= 400 {
		status = "FAILED"
	}
	c <- requestResult{url: url, status: status}
}

실행 결과 (영상)

이제 Go Routine과 함께라면 실행속도가 얼마나 빨라지는지 직접 확인해볼까요?

BOOM!

정말 빠른 속도로 처리되는 것을 볼 수 있습니다.