上一句我们从源代码分析了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