首先让我说我是 Go 的新手,欢迎任何指点/更正。
我正在尝试编写一个小型 Go 应用程序,它将创建多个 DNS 查询并在各自的 Go 例程中发送它们。我从包含 1000 个 URL 的文件中获取 URL 并创建一个 slice ,对于 slice 中的每个 URL,我查询 A 记录,如果成功,则将 URL 和耗时推送到结果 channel ,如果 a 出现错误各自的错误 channel 。然后我会选择收听。
我正在努力解决的问题是,在使用 TCP 时我会收到(看似随机的)一些查询的 EOF 错误,而在使用 UDP 时会收到 i/o 超时错误。我想使用 TCP 并确保响应,我不知道为什么会收到 EOF 错误。如果我对同一个 URL 和 1000 个不同的 URL 进行 1000 次查询,也会发生这种情况
在 OSX 和 Go 1.6 版上工作
这是我目前所拥有的:
package main
import (
"bufio"
"fmt"
"github.com/miekg/dns"
"os"
"time"
)
// CHECK AND PRINT ERRORS
func checkErr(e error) {
if e != nil {
fmt.Println("Error: %s", e)
}
}
// MAKES A SLICE OF URLS FROM TXT FILE
func urlSlice() []string {
result := []string{}
file, err := os.Open("topsites.txt")
checkErr(err)
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
result = append(result, scanner.Text())
}
return result
}
func makeQuery(target string) (string, error) {
server := "8.8.8.8"
// WILL RECIEVE EOF ERROR IF TCP - I/O TIMEOUT IF UDP
c := dns.Client{Net: "tcp", Timeout: time.Duration(100 * time.Second)}
m := dns.Msg{}
m.SetQuestion(dns.Fqdn(target+"."), dns.TypeA)
_, t, err := c.Exchange(&m, server+":53")
if err != nil {
return "", err
}
return "Url: " + target + " - - Took: " + t.String(), nil
}
func main() {
start := time.Now()
targets := urlSlice()
resch, errch := make(chan string), make(chan error)
for _, url := range targets {
go func(url string) {
res, err := makeQuery(url)
if err != nil {
errch <- err
return
}
resch <- res
}(url)
}
for i := 0; i < len(targets); i++ {
select {
case res := <-resch:
fmt.Println(res)
case err := <-errch:
fmt.Println(err)
}
}
elapsed := time.Since(start)
fmt.Println("\ntotal time elapsed: ", elapsed)
}
输出:
Url: facebook.com - - Took: 548.582107ms
Url: wordpress.com - - Took: 548.805505ms
Url: google.com.br - - Took: 541.491363ms
Url: onclickads.net - - Took: 548.16544ms
Url: bongacams.com - - Took: 543.28688ms
Url: tianya.cn - - Took: 543.41525ms
Url: blogger.com - - Took: 544.461005ms
Url: alibaba.com - - Took: 543.53541ms
Url: gmw.cn - - Took: 543.56093ms
Url: pornhub.com - - Took: 664.297282ms
Url: outbrain.com - - Took: 664.423217ms
Url: ask.com - - Took: 671.557037ms
EOF
EOF
EOF
EOF
EOF
EOF
EOF
Url: t.co - - Took: 1.166130918s
Url: youth.cn - - Took: 1.946658912s
Url: apple.com - - Took: 2.763568935s
...continued...
total time elapsed: 23.703546858s
所有的想法、建议和帮助都值得赞赏。谢谢!
最佳答案
这可能是有趣的:https://idea.popcount.org/2013-11-28-how-to-resolve-a-million-domains/
根据这篇文章,天真的方法受限于可以同时打开多少 UDP 套接字 - 大约 1000。我假设 TCP 套接字也是如此 - 你将用完文件描述符或一些其他资源。
作者在文章末尾提供了一个指向他的并行 DNS 解析器的链接:https://github.com/majek/goplayground/blob/master/resolve/resolve.go
他使用可配置数量的 go-routines,所有这些都通过同一个 UDP 端口进行通信。我猜如果你想使用 TCP,你必须为每个 go-routine 使用 1 个 tcp 连接(go-routines 的数量远低于 1000)
关于go - 在 Go 中发送多个请求时出现零星的 EOF 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727448/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test