你是否曾经需要快速检查一批网站是否正常运行?今天我们用 OpenCode 写一个命令行网站健康监测工具——输入一组 URL,一键获取每个站点的 HTTP 状态码和响应时间,支持并发检测和文件批量导入。
net/http、sync、time、bufio)安装 OpenCode 后,在终端执行 opencode 即可进入交互式编程环境。
打开 OpenCode,用自然语言让它创建项目骨架:
> 我对 OpenCode 说:
>
> 帮我创建一个 Go 项目,项目名叫 urlchecker,初始化 go mod
OpenCode 随即执行:
mkdir urlchecker && cd urlchecker && go mod init urlchecker
并在工作区打开了 main.go 等待下一步指令。无需手动敲命令,全程一句话搞定。
> 我对 OpenCode 说:
>
> 在 main.go 里实现一个函数 checkURL,接收一个 URL 字符串和超时时长,使用 http.Client 发送 GET 请求,返回一个结构体包含 URL、状态码、耗时和错误信息
OpenCode 分析需求后,生成了带结构体定义和 HTTP 客户端的核心代码:
type Result struct {
URL string
StatusCode int
Duration time.Duration
Error error
}
func checkURL(url string, timeout time.Duration) Result {
client := &http.Client{Timeout: timeout}
start := time.Now()
resp, err := client.Get(url)
duration := time.Since(start)
if err != nil {
return Result{URL: url, Error: err, Duration: duration}
}
defer resp.Body.Close()
return Result{URL: url, StatusCode: resp.StatusCode, Duration: duration}
}
不需要自己查文档——OpenCode 自动补全了 http.Client 的超时设置、defer resp.Body.Close() 等最佳实践。
单线程检测太慢,我们告诉 OpenCode 加上并发和文件导入:
> 我对 OpenCode 说:
>
> 在 main 函数里实现以下功能:
> 1. 支持从命令行参数直接传入 URL 列表
> 2. 支持 -f 参数指定一个文本文件,逐行读取 URL
> 3. 用 goroutine + WaitGroup + channel 实现并发检测所有 URL
> 4. 打印汇总报告,显示每个 URL 的状态码、耗时,最后统计正常/异常数量
OpenCode 一次性生成了 main() 函数和 readURLsFromFile() 辅助函数,并发逻辑用 sync.WaitGroup 和 chan Result 配合实现,结构清晰:
var wg sync.WaitGroup
results := make(chan Result, len(urls))
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
results <- checkURL(u, 10*time.Second)
}(url)
}
go func() {
wg.Wait()
close(results)
}()
这大概是我最喜欢的 OpenCode 使用方式——你描述业务需求,它处理并发细节。
> 我对 OpenCode 说:
>
> 编译运行,用几个真实网站测试一下
$ go build -o urlchecker.exe . && ./urlchecker.exe www.baidu.com github.com google.com ========== 网站健康监测报告 ========== 检查时间: 2026-08-07 10:30:00 URL 数量: 3 ====================================== ✓ https://www.baidu.com 200 156ms ✓ https://github.com 200 312ms ❌ https://google.com 错误: context deadline exceeded ====================================== 总计: 3 | 正常: 2 | 异常: 1
工具完美运行。整个过程从零到可用的命令行工具,只花了 4 分钟。
package main
import (
"bufio"
"fmt"
"net/http"
"os"
"strings"
"sync"
"time"
)
type Result struct {
URL string
StatusCode int
Duration time.Duration
Error error
}
func checkURL(url string, timeout time.Duration) Result {
client := &http.Client{Timeout: timeout}
start := time.Now()
resp, err := client.Get(url)
duration := time.Since(start)
if err != nil {
return Result{URL: url, Error: err, Duration: duration}
}
defer resp.Body.Close()
return Result{URL: url, StatusCode: resp.StatusCode, Duration: duration}
}
func readURLsFromFile(filename string) ([]string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
var urls []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line != "" && !strings.HasPrefix(line, "#") {
if !strings.HasPrefix(line, "http") {
line = "https://" + line
}
urls = append(urls, line)
}
}
return urls, scanner.Err()
}
func main() {
if len(os.Args) < 2 {
fmt.Println("网站健康监测工具")
fmt.Println("用法: urlchecker <url> [url2 url3 ...]")
fmt.Println(" urlchecker -f urls.txt")
os.Exit(1)
}
var urls []string
if os.Args[1] == "-f" && len(os.Args) > 2 {
var err error
urls, err = readURLsFromFile(os.Args[2])
if err != nil {
fmt.Printf("读取文件失败: %v\n", err)
os.Exit(1)
}
} else {
urls = os.Args[1:]
for i, u := range urls {
if !strings.HasPrefix(u, "http") {
urls[i] = "https://" + u
}
}
}
fmt.Println("========== 网站健康监测报告 ==========")
fmt.Printf("检查时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))
fmt.Printf("URL 数量: %d\n", len(urls))
fmt.Println("======================================")
var wg sync.WaitGroup
results := make(chan Result, len(urls))
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
results <- checkURL(u, 10*time.Second)
}(url)
}
go func() {
wg.Wait()
close(results)
}()
okCount, failCount := 0, 0
for r := range results {
if r.Error != nil {
failCount++
fmt.Printf("❌ %-50s 错误: %v\n", r.URL, r.Error)
} else {
okCount++
status := "✓"
if r.StatusCode >= 400 {
status = "⚠"
}
fmt.Printf("%s %-50s %d %v\n", status, r.URL, r.StatusCode, r.Duration.Round(time.Millisecond))
}
}
fmt.Println("======================================")
fmt.Printf("总计: %d | 正常: %d | 异常: %d\n", len(urls), okCount, failCount)
}
用 OpenCode 开发这个工具,体会最深的是从想法到代码的转换速度。传统开发流程:构思 → 查文档 → 写代码 → 查文档 → 调试;而 OpenCode 的流程是:描述需求 → 审阅生成代码 → 运行验证。
4 分钟的时间里,你只需要做两件事:描述清楚需求和确认代码正确性。至于 Go 的http.Client超时怎么设、WaitGroup怎么用、bufio.Scanner怎么读文件——这些细节 OpenCode 都能帮你处理,你专注在"想要什么"上就好。