# Windows 上的 Go：一个二进制、一个服务、一个反代

> 把 Go HTTP 服务做成 Windows 服务，用环境变量传配置，优雅关闭，并安全反代。

**测试环境**

- 版本号: 26100.33650
- 版本: Standard / Datacenter
- 架构: x64
- 证据: E1
- 核验日期: 2026-10-29

## 一句话结论

Go 服务就是一个 `.exe`，服务器不用装 runtime：

```powershell
go build -trimpath -ldflags="-s -w" -o C:\apps\api\api.exe .\cmd\api
```

用 WinSW/NSSM 做成 Windows 服务，让 IIS/Nginx 占 443。

## 为目标平台构建

```powershell
$env:GOOS='windows'; $env:GOARCH='amd64'
go build -trimpath -ldflags="-s -w" -o C:\build\api.exe .\cmd\api
```

按目标架构构建；不要发错 OS/arch 的二进制。`-trimpath` 去本地路径，`-s -w` 去符号（需要栈追踪就留 debug 构建）。

## 服务包装

WinSW：

```xml
<service>
  <id>api</id>
  <executable>C:\apps\api\api.exe</executable>
  <workingdirectory>C:\apps\api</workingdirectory>
  <env name="APP_ENV" value="production"/>
  <env name="LISTEN_ADDR" value="127.0.0.1:8080"/>
  <logpath>C:\logs\api</logpath>
  <onfailure action="restart" delay="10 sec"/>
</service>
```

应用从环境变量或 exe 旁边配置文件读 `LISTEN_ADDR`/配置。不要把生产密钥硬编码进二进制。

## 优雅关闭

处理 `SIGTERM`/控制台关闭，调用带超时的 `server.Shutdown(ctx)`。Windows 服务停止会发控制事件；忽略它的 Go 应用在服务超时后被强杀，可能丢在途请求。

## 反向代理

```nginx
location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}
```

Go 应用只信任来自代理的转发头。绑 localhost，不暴露 8080。

## 验证

```powershell
sc.exe qc api
Get-CimInstance Win32_Process -Filter "Name='api.exe'" |
  Select-Object ProcessId, ExecutablePath, CommandLine
curl.exe -I http://127.0.0.1:8080/healthz
Get-Content C:\logs\api\api.err.log -Tail 50
```

查二进制路径、健康端点、日志。代理 502 通常是没有监听。

> **警告: 单二进制不等于不用运维**
>
> 还是需要服务监管、日志、配置/密钥、健康检查、补丁和回滚二进制。Go 省掉 runtime，不省运维。

## 实验室边界

E1。实验室没有构建/运行 Go 服务；命令是 Server 2025 上待验证的部署模式。

## 来源

- [Go — 下载安装](https://go.dev/doc/install)
- [WinSW](https://github.com/winsw/winsw)
- [Go — net/http Server](https://pkg.go.dev/net/http#Server)

---

来源页面: https://winbook.fyi/zh/server/runtimes/go-service/
