导读:本期聚焦于小伙伴创作的《如何用Golang做站点可用性检测?Golang并发检测与结果上报实现方法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Golang做站点可用性检测?Golang并发检测与结果上报实现方法》有用,将其分享出去将是对创作者最好的鼓励。

站点可用性检测是很多运维系统和业务监控模块的核心功能,通过Golang的并发特性可以高效完成多站点的批量检测,同时实现检测结果的统一上报。本文会完整介绍从检测逻辑设计到并发调度再到结果上报的全流程实现。

如何用Golang做站点可用性检测?Golang并发检测与结果上报实现方法

核心需求与实现思路

站点可用性检测的核心目标是判断目标站点是否能正常响应,通常需要关注响应状态码、响应耗时、是否出现连接错误等指标。如果使用串行方式逐个检测站点,当站点数量较多时耗时会被无限拉长,因此需要使用Golang的并发能力并行处理多个检测任务。

整体实现思路分为三个部分:

  • 定义检测结果的结构体,存储站点地址、状态码、耗时、错误信息等内容
  • 使用goroutine并行发起每个站点的检测请求,通过channel收集检测结果
  • 对收集到的结果进行整理,按照需求上报到指定存储或接口

检测结果结构体定义

首先定义统一的检测结果结构体,方便后续传递和处理数据:

package main

import "time"

// CheckResult 站点检测结果结构体
type CheckResult struct {
	URL        string        // 检测的站点地址
	StatusCode int           // HTTP响应状态码,0表示请求失败
	CostTime   time.Duration // 请求耗时
	ErrMsg     string        // 错误信息,为空表示请求成功
}

单站点检测逻辑实现

单站点的检测需要实现HTTP请求发起、超时控制、状态码判断的逻辑,这里使用Golang标准库的net/http实现:

package main

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

// checkSingleSite 检测单个站点的可用性
// url:待检测的站点地址
// timeout:请求超时时间
func checkSingleSite(url string, timeout time.Duration) CheckResult {
	result := CheckResult{
		URL: url,
	}
	// 创建带超时的HTTP客户端
	client := &http.Client{
		Timeout: timeout,
	}
	// 记录请求开始时间
	startTime := time.Now()
	// 发起GET请求
	resp, err := client.Get(url)
	// 计算请求耗时
	result.CostTime = time.Since(startTime)
	if err != nil {
		result.ErrMsg = err.Error()
		result.StatusCode = 0
		return result
	}
	defer resp.Body.Close()
	// 判断状态码是否为2xx或3xx,认为是可用
	if resp.StatusCode >= 200 && resp.StatusCode < 400 {
		result.StatusCode = resp.StatusCode
	} else {
		result.StatusCode = resp.StatusCode
		result.ErrMsg = errors.New("状态码不在可用范围").Error()
	}
	return result
}

并发检测调度实现

使用goroutine和channel实现多站点的并发检测,控制并发数量避免对目标站点造成过大压力:

package main

import (
	"sync"
	"time"
)

// ConcurrentCheck 并发检测多个站点
// urls:待检测的站点地址列表
// timeout:单个请求超时时间
// maxConcurrent:最大并发数
func ConcurrentCheck(urls []string, timeout time.Duration, maxConcurrent int) []CheckResult {
	// 用于接收检测结果
	resultChan := make(chan CheckResult, len(urls))
	// 用于控制并发数的信号量
	sem := make(chan struct{}, maxConcurrent)
	var wg sync.WaitGroup

	for _, url := range urls {
		wg.Add(1)
		go func(targetURL string) {
			defer wg.Done()
			// 获取信号量,控制并发
			sem <- struct{}{}
			defer func() { <-sem }()
			// 执行单站点检测
			res := checkSingleSite(targetURL, timeout)
			resultChan <- res
		}(url)
	}

	// 等待所有检测任务完成
	go func() {
		wg.Wait()
		close(resultChan)
	}()

	// 收集所有检测结果
	var results []CheckResult
	for res := range resultChan {
		results = append(results, res)
	}
	return results
}

检测结果上报实现

检测结果上报可以根据实际需求对接不同的存储或接口,这里以两种方式为例,一种是打印到控制台,另一种是上报到自定义接口:

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

// PrintResults 将检测结果打印到控制台
func PrintResults(results []CheckResult) {
	fmt.Println("站点可用性检测结果:")
	for _, res := range results {
		if res.ErrMsg != "" {
			fmt.Printf("站点:%s,检测失败,错误信息:%s,耗时:%vn", res.URL, res.ErrMsg, res.CostTime)
		} else {
			fmt.Printf("站点:%s,检测成功,状态码:%d,耗时:%vn", res.URL, res.StatusCode, res.CostTime)
		}
	}
}

// ReportToAPI 将检测结果上报到指定接口
// reportURL:上报接口的地址
func ReportToAPI(results []CheckResult, reportURL string) error {
	// 将结果序列化为JSON
	data, err := json.Marshal(results)
	if err != nil {
		return err
	}
	// 发起POST请求上报结果
	resp, err := http.Post(reportURL, "application/json", nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("上报失败,状态码:%d", resp.StatusCode)
	}
	fmt.Println("检测结果上报成功")
	return nil
}

完整调用示例

将以上模块组合起来,实现一个完整的检测流程:

package main

func main() {
	// 待检测的站点列表
	sites := []string{
		"http://ipipp.com",
		"http://127.0.0.1:8080",
		"https://www.baidu.com",
	}
	// 单个请求超时时间设置为3秒
	timeout := 3 * time.Second
	// 最大并发数设置为5
	maxConcurrent := 5

	// 执行并发检测
	results := ConcurrentCheck(sites, timeout, maxConcurrent)
	// 打印检测结果
	PrintResults(results)
	// 上报结果到指定接口,这里替换为实际上报地址
	reportURL := "http://192.168.0.1:9000/report"
	_ = ReportToAPI(results, reportURL)
}

注意事项

在实际使用中需要注意几个问题:

  • 超时时间需要根据站点的正常响应耗时合理设置,避免误判
  • 并发数需要根据目标站点的承受能力调整,避免触发站点的限流策略
  • 如果检测的是HTTPS站点,可以自定义http.Transport配置跳过证书校验,但要明确安全风险
  • 结果上报时建议增加重试机制,避免上报失败导致数据丢失

Golang站点可用性检测并发检测结果上报goroutine修改时间:2026-06-21 17:33:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。