最近在开发一个golang的web项目,遇到了一个很奇怪的问题,服务一直无法启动。发现错误的原因让人很无奈。

错误

报的错误很简单

1
: getaddrinfow: The specified class was not found.

问题重现

为了便于配置web项目,我写了一个conf配置文件,golang自己手动解析出参数,作为web启动的相关参数,配置文件内容如下

1
2
3
Addr=:8000
ReadTimeout=20s
WriteTimeout=20s

就是配置了服务端口,超时时间。为了方便开发,我直接从网上粘贴了一个按行读取文件的代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
f, err := os.Open(confFile)
if err != nil {
	panic(err)
}
defer f.Close()

rd := bufio.NewReader(f)
for {
	line, err := rd.ReadString('\n')
	kv := strings.Split(line, "=")
	if len(kv) != 2 {
		continue
	}
	conf[kv[0]] = kv[1]
	if err != nil {
		if err == io.EOF {
			break
		} else {
			break
		}
	}
}

看起来很正常,按照=分割配置,左作为key,右边作为value,存入map供后面调用。 获取端口代码如下

1
2
3
4
5
6
func WebAddr() (string) {
	if addr, ok := conf["Addr"]; ok {
		return addr
	}
	return ":701"
}

就是简单的读取map的内容,返回端口 配置server如下

1
2
3
4
5
6
httpServer = &http.Server{
	Addr:         util.WebAddr(),
	Handler:      router.Mux,
	ReadTimeout:  util.ReadTimeout(),
	WriteTimeout: util.WriteTimeout(),
}

没有任何问题,结果出现了开头的错误。

解决方案

百度不成去谷歌,结果看到了一个github的issue,看起来就是让bug提交的,并不是真正的解决问题。结果往下面看到了这一条回复 > I don't make sure but probably, the serverport contain spaces or \r.

我在windows下进行的开发,而且读取文件的时候并没有删除\r\n,怪不得会出错,那就直接删除了吧。

1
line = strings.Trim(line, "\r\n")

结果,部署到linux服务器上,进行修改后,文件就没有\r了! 那我就判断字符串的结尾方式吧!有什么我就删什么。可是这样处理总感觉是hack的方式。 想到java里面都有readLine的函数,golang里面应该也有。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
f, err := os.Open(confFile)
if err != nil {
	panic(err)
}
defer f.Close()

rd := bufio.NewReader(f)

for {
	line, _, err := rd.ReadLine()
	if err == io.EOF {
		break
	}
	kv := strings.Split(string(line), "=")
	if len(kv) != 2 {
		continue
	}
	conf[kv[0]] = kv[1]
}

windows还有linux可以正确运行了。