Skip to content

Commit

Permalink
feat: 初步实现负载均衡功能
Browse files Browse the repository at this point in the history
  • Loading branch information
CaoMeiYouRen committed Oct 24, 2024
1 parent 09a42d1 commit 0ec79a2
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ LOGFILES=false

# 最大请求体大小(字节),默认 100MB
# MAX_BODY_SIZE=104857600

# RSSHub 实例 的 URL 地址,,使用英文逗号分隔。
# 官方实例 https://rsshub.app 不用列出,默认添加。
RSSHUB_NODE_URLS='https://rsshub.rssforever.com, https://hub.slarker.me, https://rsshub.pseudoyu.com, https://rsshub.ktachibana.party, https://rsshub.woodland.cafe, https://rss.owo.nz, https://yangzhi.app, https://rsshub.henry.wang, https://rss.peachyjoy.top, https://rsshub.speednet.icu'
12 changes: 6 additions & 6 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ app.use(secureHeaders())
app.onError(errorhandler)
app.notFound(notFoundHandler)

app.all('/', (c) => c.json({
message: 'Hello Hono!',
}))
// app.all('/', (c) => c.json({
// message: 'Hello Hono!',
// }))

app.all('/runtime', (c) => c.json({
runtime: getRuntimeKey(),
}))
// app.all('/runtime', (c) => c.json({
// runtime: getRuntimeKey(),
// }))

app.route('/', routes)

Expand Down
28 changes: 28 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
import { Hono } from 'hono'
import fetch from 'isomorphic-unfetch'
import { env } from 'hono/adapter'
import { StatusCode } from 'hono/utils/http-status'
import { Bindings } from '../types'
import { parseNodeUrls, randomPick } from '@/utils/helper'

const app = new Hono<{ Bindings: Bindings }>()

app.get('*', async (c) => {
const { RSSHUB_NODE_URLS } = env(c)
const allNodeUrls = parseNodeUrls(RSSHUB_NODE_URLS)
const path = c.req.path
const query = c.req.query()
// 由于 Cloudflare Workers 的限制,fetch 一次最多并发 6 个,所以最多随机选择 5 个节点。
// 添加默认节点,官方实例默认为第一个。
// 随机选择5个节点,不包括默认节点。
const nodeUrls = ['https://rsshub.app', ...randomPick(allNodeUrls, 5)].map((url) => {
const _url = new URL(url)
_url.pathname = path
_url.search = new URLSearchParams(query).toString()
return _url.toString()
})
// 并发请求,有一个成功就返回值
const res = await Promise.any(nodeUrls.map((url) => fetch(url)))
const data = await res.text()
const contentType = res.headers.get('Content-Type') || 'application/xml'
c.header('Content-Type', contentType)
c.status(res.status as StatusCode)

return c.body(data)
})

export default app
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export type Bindings = {
LOG_LEVEL: string
TIMEOUT: string
MAX_BODY_SIZE: string
RSSHUB_NODE_URLS: string
}
35 changes: 35 additions & 0 deletions src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

/**
* 将 RSSHUB_NODE_URLS 解析为数组
*
* @author CaoMeiYouRen
* @date 2024-10-24
* @export
* @param value
*/
export function parseNodeUrls(value: string) {
return [...new Set(value.split(',')
.map((url) => url.trim())),
] // 去重
.map((url) => new URL(url).toString()) // 格式化 URL
}

/**
* 从给定的数组中随机挑选五个不重复的项
* 采用洗牌算法,概率相同
*
* @author CaoMeiYouRen
* @date 2024-10-24
* @export
* @template T
* @param array
* @param count
*/
export function randomPick<T>(array: T[], count: number): T[] {
const shuffled = [...array]
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
}
return shuffled.slice(0, count)
}
7 changes: 5 additions & 2 deletions wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ compatibility_flags = ["nodejs_compat"]

[vars]
# 超时时间(ms)
TIMEOUT=60000
TIMEOUT = 60000
# 最大请求体大小(字节),默认 100MB
MAX_BODY_SIZE=104857600
MAX_BODY_SIZE = 104857600
# RSSHub 实例 的 URL 地址,,使用英文逗号分隔。
# 官方实例 https://rsshub.app 不用列出,默认添加。
RSSHUB_NODE_URLS = 'https://rsshub.rssforever.com, https://hub.slarker.me, https://rsshub.pseudoyu.com, https://rsshub.ktachibana.party, https://rsshub.woodland.cafe, https://rss.owo.nz, https://yangzhi.app, https://rsshub.henry.wang, https://rss.peachyjoy.top, https://rsshub.speednet.icu'

[env.dev]
# Development 环境配置
Expand Down

0 comments on commit 0ec79a2

Please sign in to comment.