perf: 优化choice counter

pull/192/head
xiaojunnuo 2021-11-11 14:59:10 +08:00
parent f013f2c23a
commit 3fe0658d50
3 changed files with 16 additions and 10 deletions

View File

@ -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)
} }
} }

View File

@ -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) {

View File

@ -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')