perf: 优化choice counter
parent
f013f2c23a
commit
3fe0658d50
|
@ -11,6 +11,7 @@ class ChoiceCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
getOrCreate (key, backups) {
|
getOrCreate (key, backups) {
|
||||||
|
log.info('get counter:', key)
|
||||||
let item = this.cache.get(key)
|
let item = this.cache.get(key)
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
item = new DynamicChoice(key)
|
item = new DynamicChoice(key)
|
||||||
|
@ -70,12 +71,16 @@ class DynamicChoice {
|
||||||
* @param count
|
* @param count
|
||||||
*/
|
*/
|
||||||
changeNext (count) {
|
changeNext (count) {
|
||||||
|
log.info('切换backup', count, this.backup)
|
||||||
count.keepErrorCount = 0 // 清空连续失败
|
count.keepErrorCount = 0 // 清空连续失败
|
||||||
if (this.backup > 0) {
|
count.total = 0
|
||||||
|
count.error = 0
|
||||||
|
if (this.backup.length > 0) {
|
||||||
this.value = this.backup.shift()
|
this.value = this.backup.shift()
|
||||||
} else {
|
} else {
|
||||||
this.value = null
|
this.value = null
|
||||||
}
|
}
|
||||||
|
log.info('切换backup完成', this.value, this.backup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,22 +91,22 @@ class DynamicChoice {
|
||||||
doCount (value, isError) {
|
doCount (value, isError) {
|
||||||
let count = this.count[value]
|
let count = this.count[value]
|
||||||
if (count == null) {
|
if (count == null) {
|
||||||
count = this.count[value] = { value: value, total: 0, error: 0, keepErrorCount: 0, successRate: 1 }
|
count = this.count[value] = { value: value, total: 5, error: 0, keepErrorCount: 0, successRate: 1 }
|
||||||
}
|
}
|
||||||
if (isError) {
|
if (isError) {
|
||||||
count.error++
|
count.error++
|
||||||
count.keepErrorCount++
|
count.keepErrorCount++
|
||||||
} else {
|
} else {
|
||||||
count.total += 10
|
count.total += 1
|
||||||
}
|
}
|
||||||
count.successRate = 1.0 - (count.error / count.total)
|
count.successRate = 1.0 - (count.error / count.total)
|
||||||
if (isError && this.value === value) {
|
if (isError && this.value === value) {
|
||||||
// 连续错误10次,切换下一个
|
// 连续错误3次,切换下一个
|
||||||
if (count.keepErrorCount >= 10) {
|
if (count.keepErrorCount >= 3) {
|
||||||
this.changeNext(count)
|
this.changeNext(count)
|
||||||
}
|
}
|
||||||
// 成功率小于50%,切换下一个
|
// 成功率小于50%,切换下一个
|
||||||
if (count.successRate < 0.51) {
|
if (count.successRate < 0.4) {
|
||||||
this.changeNext(count)
|
this.changeNext(count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ module.exports = {
|
||||||
for (const bk of interceptOpt.backup) {
|
for (const bk of interceptOpt.backup) {
|
||||||
backup.push(bk)
|
backup.push(bk)
|
||||||
}
|
}
|
||||||
const key = interceptOpt.key
|
const key = rOptions.hostname + '/' + interceptOpt.key
|
||||||
const count = RequestCounter.getOrCreate(key, backup)
|
const count = RequestCounter.getOrCreate(key, backup)
|
||||||
if (count.value == null) {
|
if (count.value == null) {
|
||||||
count.doRank()
|
count.doRank()
|
||||||
|
@ -44,6 +44,7 @@ module.exports = {
|
||||||
// eslint-disable-next-line no-template-curly-in-string
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
proxyTarget = proxyTarget.replace('${host}', rOptions.hostname)
|
proxyTarget = proxyTarget.replace('${host}', rOptions.hostname)
|
||||||
|
|
||||||
|
log.info('拦截【proxy】: original:', rOptions.hostname, ',target:', proxyTarget)
|
||||||
// const backup = interceptOpt.backup
|
// const backup = interceptOpt.backup
|
||||||
const proxy = proxyTarget.indexOf('http') === 0 ? proxyTarget : rOptions.protocol + '//' + proxyTarget
|
const proxy = proxyTarget.indexOf('http') === 0 ? proxyTarget : rOptions.protocol + '//' + proxyTarget
|
||||||
// eslint-disable-next-line node/no-deprecated-api
|
// eslint-disable-next-line node/no-deprecated-api
|
||||||
|
@ -56,9 +57,9 @@ module.exports = {
|
||||||
if (URL.port == null) {
|
if (URL.port == null) {
|
||||||
rOptions.port = rOptions.protocol === 'https:' ? 443 : 80
|
rOptions.port = rOptions.protocol === 'https:' ? 443 : 80
|
||||||
}
|
}
|
||||||
log.info('proxy:', rOptions.hostname, 'target', proxyTarget)
|
|
||||||
if (context.requestCount) {
|
if (context.requestCount) {
|
||||||
log.debug('proxy choice:', JSON.stringify(context.requestCount))
|
log.info('proxy choice:', JSON.stringify(context.requestCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interceptOpt.sni != null) {
|
if (interceptOpt.sni != null) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ class SpeedTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
async test () {
|
async test () {
|
||||||
if (this.backupList.length === 0 || this.testCount < 10 || this.testCount % 5 === 0) {
|
if (this.backupList.length === 0 || this.testCount < 15 || this.testCount % 5 === 0) {
|
||||||
const newList = await this.getIpListFromDns(this.dnsMap)
|
const newList = await this.getIpListFromDns(this.dnsMap)
|
||||||
const newBackupList = [...newList, ...this.backupList]
|
const newBackupList = [...newList, ...this.backupList]
|
||||||
this.backupList = _.unionBy(newBackupList, 'host')
|
this.backupList = _.unionBy(newBackupList, 'host')
|
||||||
|
|
Loading…
Reference in New Issue