然后会调用preload,该函数确保pool(idle)中有minIdle个空闲元素, 防止启动时大量调用factory。
最后会进行go pool.startCheckIdleTicker() 异步来goroutine中调用checkIdle定期查询pool(idle)中的元素是否超过maxIdle个元素, 如果超过则会调用factory进行释放。同时每次调用factory也会通过notifyCh来通知该goroutine执行检查操作。
pool结构初始化完成之后,resouceManager中所有对于networkResource的操作都会通过该pool进行,该pool在必要条件下再调用factory进行分配释放。
factory的具体实现是eniIPFactory, 用来调用ecs SDK进行申请释放eniIP, 并维护对应的数据结构。不同于直接使用eni设备,ENIMultiIP模式会为每个eni设备会有多个eniIP。eni设备是通过ENI结构体标识, eniIP通过ENIIP结构体标识。terway会为每个ENI创建一个goroutine, 该ENI上所有eniIP的分配释放都会在goroutine内进行,factory通过channel与该groutine通信, 每个goroutine对应一个接受channel ipBacklog,用于传递分配请求到该goroutine。 每次factory 需要创建(eniIPFactory.Create)一个eniIP时, 会一次遍历当前已经存在的ENI设备,如果该设备还有空闲的eniIP,就会通过该ipBacklog channel发送一个元素到该ENI设备的goroutine进行请求分配, 当goroutine将eniIP分配完毕之后通过factory 的resultChan通知factory, 这样factory就成功完成一次分配。 如果所有的ENI的eniIP都分配完毕,会首先创建ENI设备及其对应goroutine。因为每个ENI设备会有个主IP, 所以首次分配ENI不需要发送请求到ipBacklog, 直接将该主ip返回即可。对应的释放(Dispose)就是先释放eniIP, 等到只剩最后一个eniIP(主eniIP)时会释放整个ENI设备。对于所有ecs调用都会通过buffer channel进行流控,防止瞬间调用过大。
总结总之,terway的整个实现,逻辑比较清晰,并且扩展性也较高。后期,可以比较方便地在此基础上做一些定制和运维支持,从而很好地融入公司的基础架构设施。