我正在开发用于并发配置网络设备的 SSH 客户端应用程序,但在实现并发性时遇到了问题。我的程序接受一部分主机和一部分配置命令以发送到每个主机。我正在使用 sync.WaitGroup 来等待所有主机完成配置。这适用于小批量主机,但很快我的配置 goroutines 中的功能开始随机失败。如果我在失败的主机上重新运行程序,一些会成功,一些会再次失败。我必须重复这个过程,直到只剩下有实际错误的主机。它总是在身份验证失败时说 authentication failed: auth methods tried [none password]... 或者 sysDescr 的值没有添加到某些 设备字段。就好像当有许多主机和 goroutines 运行时,他们开始提前返回或什么的。我真的不确定发生了什么。
这是我的代码示例:
package main
import (
"fmt"
"net"
"os"
"sync"
"time"
"golang.org/x/crypto/ssh"
)
func main() {
// When there are many hosts, many calls to Dial and
// sysDescr fail. If I rerun the program on the unsuccessful
// hosts, nothing fails and the expected output is produced.
var hosts []string
cfg := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{ssh.Password("pass")},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 10 * time.Second,
}
results := make(chan *result, len(hosts))
var wg sync.WaitGroup
wg.Add(len(hosts))
for _, host := range hosts {
go connect(host, cfg, results, &wg)
}
wg.Wait()
close(results)
for res := range results {
if res.err != nil {
fmt.Fprintln(os.Stderr, res.Err)
continue
}
d := res.device
fmt.Println(d.addr, d.hostname, d.vendor, d.os, d.model, d.version)
d.Client.Close()
}
}
// Device represents a network device.
type Device struct {
*ssh.Client
addr string
hostname string
vendor string
os string
model string
version string
}
// Dial establishes an ssh client connection to a remote host.
func Dial(host, port string, cfg *ssh.ClientConfig) (*Device, error) {
// get host info in background, may take a second
info := make(chan map[string]string)
go func(c *Client) {
info <- sysDescr(host)
close(info)
}(c)
// establish ssh client connection to host
client, err := ssh.Dial("tcp", net.JoinHostPort(host, addr), cfg)
if err != nil {
return nil, err
}
m := <-info
d := &Device{
Client: client,
addr: m["addr"],
hostname: m["hostname"],
vendor: m["vendor"],
os: m["os"],
model: m["model"],
version: m["version"],
}
return d, nil
}
// sysDescr attempts to gather information about a remote host.
func sysDescr(host string) map[string]string {
// get host info
}
// result is the result of connecting to a device.
type result struct {
device *Device
err error
}
// connect establishes an ssh client connection to a host.
func connect(host string, cfg *ssh.ClientConfig, results chan<- *result, wg *sync.WaitGroup) {
defer wg.Done()
device, err := Dial(host, "22", cfg)
results <- &result{device, err}
}
我做错了什么吗?我可以限制生成的 goroutine 数量而不是为每个主机生成一个 goroutine 吗?
最佳答案
是的!要回答你的第二个问题,go 中有很多模式来限制并发。其中两个最大的是:
我个人更喜欢工作池变体,因为在我看来,它更好地帮助将业务逻辑与调度分开,但两者都是完全有效的,并且在许多项目中都存在。
关于Golang 同步协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51575774/
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
类似的问题,但对于java,Keepingi18nresourcessynced如何保持i18nyamllocals的key同步?即,当将key添加到en.yml时,如何将它们添加到nb.yml或ru.yml?如果我在my_title:"atitle"旁边添加键my_label:"sometextinenglish"我想把它给我的其他本地人我指定,因为我不能做所有的翻译,它应该回到其他语言的英语例如en.ymlsomegroup:my_tile:"atitleinenglish"my_label:"sometextinenglish"othergroup:...我想发出命令,将整个键和
点击->操作系统复习的文章集目录操作系统线程线程是什么进程与线程的关系用户态/内核态操作系统资源管理内核态用户态内核态/用户态切换程序运行类型分析计算密集型IO密集型结合进程,线程来理解程序运行类型分析协程基础上下文切换协程协程为什么叫协作式线程?协程的优缺点操作系统线程典型问题:简述进程和线程的区别以下内容带您一步步了解线程是什么比进程更小的独立运行的基本单位-线程(Threads)线程的提出主要是为了提高系统内程序并发执行的程度,从而进一步提升系统的吞吐量,充分发挥多核CPU的优越性而设计的引入进程是为了操作系统更加方便地管理程序,使得多个程序能并发管理和执行而线程则是为了减少程序在并发执
目录FIFO一.自定义同步FIFO1.1代码设计1.2Testbech1.3行为仿真***学习位宽计算函数$clog2()***$clog2()系统函数使用,可以不关注***分布式资源或者BLOCKBRAM二.异步FIFO2.1在FIFO判满的时候有两种方式:2.2异步FIFO为什么要使用格雷码2.2.1介绍格雷码2.2.2格雷码在异步FIFO中的应用2.2.2格雷码判满2.4二进制与格雷码之间的转换2.4.1二进制码转换为格雷码的方法2.4.2格雷码转换为二进制码的方法2.3实现框图2.5实现及仿真代码2.6仿真图验证2.7结论FIFO 这篇更多的是记录FIFO学习,参考了众多优秀的文章,
数据同步的方式数据同步的2大方式基于SQL查询的CDC(ChangeDataCapture):离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据。也就是我们说的基于SQL查询抽取;无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;不保障实时性,基于离线调度存在天然的延迟;工具软件以Kettle(ApacheHop最新版)、DataX为代表,需要结合任务调度系统使用。基于日志的CDC:实时消费日志,流处理,例如MySQL的binlog日志完整记录了数据库中的变更,可以把binlog文件当作流的数据源;保障数据一致性,因为binlog文件包含了所有历史变更
IGH主站通信测试linuxcnc配置基础机器人控制LinuxCNC与EtherCAT介绍&&PDO&SDO,搭建环境步骤需要配置IGH主站的查看这篇文章linux系统学习笔记7——一次性安装igh-ethercat主站CSP模式DC同步方式preemrt实时补丁直接上代码,这部分是直接控制使用csp模式控制一个从站运动使能后直接运动,10s,每秒607a(目标位置)增加100.注意:急停按下ESC代码分为两部分,一个是通信线程主要负责和伺服通信,使能伺服,读取和写入寄存器值。第二个是操作线程,负责修改位置的值,和监控按键。使用此代码,首先根据手册1.修改PDO条目,要和自己的伺服一致2.修改
为什么新的JavaScript模块request同步?它应该只用于作业队列吗?有什么方法可以在ArangoDB中发出异步http(s)请求吗? 最佳答案 完全披露:我是ArangoDB开发团队的一员,主要从事Foxx和所有JavaScript方面的工作。我也是写org/arangodb/request的人模块。ArangoDB是一个不同于Node.js的环境,尽管有许多相似之处(例如使用V8JavaScript引擎)。与Node.js(或浏览器)不同,ArangoDB使用基于线程的并发模型并且没有事件循环。然而,线程并没有在Java
我有两个关于Firebasewebplatform的相关问题的synchronisationoflocally-modifieddatatotheserver:EveryclientsharingaFirebasedatabasemaintainsitsowninternalversionofanyactivedata.Whendataisupdatedorsaved,itiswrittentothislocalversionofthedatabase.TheFirebaseclientthensynchronizesthatdatawiththeFirebaseserversandw
我有需要同步工作的promise对象。例如,第二个promise不应该在第一个promise完成之前起作用。如果第一个拒绝第一个必须再次执行。我已经实现了一些示例。这个效果很好。调用getVal,等待2000ms,返回,i++,再次调用getVal.....getVal(){returnnewPromise(function(resolve,reject){setTimeout(function(){resolve(19)},2000);});}asyncpromiseController(){for(vari=0;i但我需要控制一组promise对象。我想做的是我有一个数据,我把它分
我编写了一个JavaScript函数,它使用XmlHttpRequest异步调用Web服务。我被要求让这个函数在页面呈现之前完成它的工作。我想我可以使AJAX请求同步,但我不希望这使页面挂起太久-如果未收到响应,我想在1秒后中止请求。是否可以中止同步XmlHttpRequest? 最佳答案 你不能:http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX说:“同步AJAX(真正的SJAX——同步Javascript和XML)是模态的,这意味着javascript将停止处理您的程序