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