上一句我们从源代码分析了go net库DNS在UNIX平台上的分析逻辑原理。这篇文章我们主要从实战角度解决go程序,但没有DNS缓存,因此解决了发生的io阻塞。
确认Cgo和go的分析性能
Go Resolver和Cgo Resolver代码funcresolverbaidu () ([] string,error) {
resolver :=net . resolver { prefergo : false }
Ctx :=con()
Return re(ctx,“www.baidu.com”)
}
func benchmarkresolverbaidu(b *){
for I :=0;I b . N;I {
_,err :=ResolverBaidu()
If err==nil {
Continue
}
}
}
用于基准测试的两个场景[root @ test-go-build-87 netresolvertest]# export go debug=net DNS=go;Go test - bench=。
GOOS : Linux
Goarch: amd64
Pkg: netResolverTest
benchmarkresolverbaidu-8 453 2725275 ns/op
帕斯
Ok netResolverTest 1.514s
[root @ test-go-build-87 netresolvertest]# export go debug=net DNS=CGO;Go test - bench=。
GOOS : Linux
Goarch: amd64
Pkg: netResolverTest
benchmarkresolverbaidu-8 458 3810726 ns/op
帕斯
Ok netResolverTest 2.030s
可以看出,没有缓存,C和go的分析基本差不多。
为Cgo提供缓存
Nscd为CGO提供了名称解析缓存#安装和启动
Yum/apt安装nscd
Service nscd start
#请重新测试一下
[root @ test-go-build-87 netresolvertest]# export go debug=net DNS=CGO;Go test - bench=。
GOOS : Linux
Goarch: amd64
Pkg: netResolverTest
benchmarkresolverbaidu-8 57067 20947 ns/op
帕斯
Ok netResolverTest 1.429s
没看错。这才是真正的结果。带缓存的CGO分析性能是GO分析性能的100倍以上。那你最好直接使用CGO来分析nscd。但是不要忘记CGO not go。事实上,有了上面的测试结果,我们就能想到。没有解决,与CGO
为Go实施分析缓存
Go解析缓存package resolverCache实现
Import(
" Context "
数学/rand '
" Net "
“反射”
“同步”
“时间”
)。
Varstore=make(地图[string] [] string)
Type resolverCache struct {
Context con
Resolver *net。Resolver
时间(小时)
洛克
}
Func New() *resolverCache {
Ctx :=con()
R :=resolverCache{
Context: CTX、
}
If r.Time==0 {
R.Time=* 30
}
Go func() {
For {
For k、v :=范围存储{
Ips,err :=r.lookup(k)
If err!=nil {
Continue
}
If re(v,ips) {
Continue
}
R.store(k、ips)
}
)。
}
}()
Return r
}
func(r * resolver cache)lookup hosts(域字符串)([] string,error) {
Return R. lookup(域)
}
func(r * resolver cache)lookuponehost(域字符串)字符串{
Ips、err:=r.lookup(域)
If err!=nil {
Return ' '
}
Rands :=rand。New()。UnixNano())
Index :=rands。Intn(len(ips))
Return IPS [索引]
}
Func (r * resolver cache) lookup(域字符串)([] string,error) {
Var(
值接口{}
Ok bool
)。
R.Lock.RLock()
值,ok=store [域];
R.Lock.RUnlock()
If!Ok {
Return R. lookuphost(域)
}
Return value。([]string),nil
}
func(r * resolver cache)lookup host(域字符串)([] string,error) {
Ips、err :=r.re、域)
If err==nil {
R.存储(域、IPS)
}
Return ips、err
}
Func (r * resolver cache) store(域字符串,IPS []字符串){
R.Lock.Lock()
Store [域]=IPS
R.Lock.Unlock()
}
启用缓存的var resolve=re()
func resolverbaidusecache(hoststring)([]string,error) {
Ips、err:=re(主机)
Return ips、err
}
func benchmarknameresolverbaidusecache(b *){
for I :=0;I b . N;I {
_,err:=resolverbaidusecache(主机)
If err==nil {
Continue
}
}
}
基准测试,每基准测试3次,每次3秒[root @ test-go-build-87 netresolvertest]# export go debug=net DNS=CGO;Gotest-bench=.-benchtime=3s-count=3
GOOS : Linux
Goarch: amd64
Pkg: netResolverTest
benchmarkresolverbaidu-8 169261 21918 ns/op
benchmarkresolverbaidu-8 162778 21683 ns/op
benchmarkresolverbaidu-8 175989 21429 ns/op
benchmarknameresolverbaidusecache-8 35489584 110 ns/op
benchmarknameresolverbaidusecache-8 31780479 116 ns/op
benchmarknameresolverbaidusecache-8 29593422 105 ns/op
帕斯
Ok netResolverTest 22.758s
由于Nscd实施的高速缓存,CGO分析性能领先于未高速缓存的GO分析,但我们可以看到,我们实施的这个高速缓存将远远落后于nscd高速缓存。(威廉莎士比亚,《北方司法》前情提要)。
最后
通过上面源码阅读分析和代码实战,你应该已经很清楚go语言在域名解析这块的机制,上面dnscache代码已经开源地址gi
1.《go分析结果怎么?终于找到答案了从net库源码窥探Go程序linux平台Dns解析原理(二)》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《go分析结果怎么?终于找到答案了从net库源码窥探Go程序linux平台Dns解析原理(二)》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/gl/3186476.html