npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

koishi-plugin-auto-assign

v0.0.5

Published

自动负载均衡,参考插件bot,完善Bot不在对应channel处理

Readme

koishi-plugin-auto-assign

npm

Koishi 频道自动负载均衡插件,智能分配频道给多个机器人,确保负载均衡且支持优先级配置。

功能特性

  • 智能负载均衡:使用动态容量贪心算法,确保每个bot的负载尽可能均衡
  • 自动容错:bot下线时自动将其负责的频道转移给其他bot
  • 优先级配置:支持为特定频道配置bot优先级,实现相对固定的分配
  • 实时响应:监听bot上下线、进退群事件,自动触发重新分配
  • 平台过滤:支持指定启用的平台和排除的频道

核心数据结构

插件维护以下核心数据结构来追踪bot和频道的关系:

// 1. 频道 -> Bot映射
allChannels: Map<"platform:channelId", Set<botId>>
// 记录每个频道中有哪些bot

// 2. Bot -> 频道映射
botChannels: Map<"platform:botId", Set<channelId>>
// 记录每个bot在哪些频道中

// 3. Bot负载统计
botAssignCount: Map<"platform:botId", number>
// 记录每个bot当前分配的频道数量

// 4. 活跃Bot列表
activeBots: Map<platform, Set<botId>>
// 记录每个平台上当前在线的bot

数据维护机制

  • 初始化:通过 bot.getGuildList() 获取每个bot的群列表,构建双向索引
  • Bot上线:获取群列表,更新映射,触发负载均衡
  • Bot下线:清理映射,触发负载均衡
  • Bot进群:增量更新映射,延迟触发负载均衡
  • Bot退群:增量更新映射,如果群还有其他bot则触发负载均衡

负载均衡算法

动态容量贪心算法

算法目标:让每个bot分配到的频道数量尽可能接近,最小化负载方差。

算法步骤

  1. 初始化剩余容量

    for (每个频道) {
      for (该频道中的每个bot) {
        botRemainingCapacity[bot]++  // 统计每个bot能处理的频道数
      }
    }
  2. 动态分配

    for (每个待分配的频道) {
      validBots = 该频道中的活跃bot列表
         
      // 优先级检查
      if (频道有优先级配置) {
        按优先级列表选择第一个可用的bot
      } else {
        // 贪心策略:选择剩余容量最小的bot
        selectedBot = validBots中剩余容量最小的bot
        // 如果容量相同,选择当前负载最小的bot
      }
         
      分配频道给selectedBot
         
      // 关键:动态更新所有在该频道中的bot的剩余容量
      for (该频道中的所有bot) {
        botRemainingCapacity[bot]--
      }
    }

算法优势

  • 优先满足容量小的bot:确保"选择少"的bot优先被分配,避免后期无法分配
  • 动态更新容量:每次分配后更新所有相关bot的剩余容量,确保全局最优
  • 负载均衡:在容量约束下,尽可能让每个bot的负载接近

示例

假设有3个频道和3个bot:

  • Channel1: [BotA, BotB]
  • Channel2: [BotB, BotC]
  • Channel3: [BotA, BotC]

初始容量:BotA=2, BotB=2, BotC=2

  1. 分配Channel1 → BotA(随机选择)
    • 更新容量:BotA=1, BotB=1, BotC=2
  2. 分配Channel2 → BotB(容量最小)
    • 更新容量:BotA=1, BotB=0, BotC=1
  3. 分配Channel3 → BotA或BotC(容量都是1)
    • 最终负载:接近均衡

配置项

interface Config {
  // 负载均衡间隔(秒),最小60秒
  balanceInterval: number  // 默认: 600
  
  // 启用的平台列表,留空表示所有平台
  enabledPlatforms: string[]  // 默认: ['onebot']
  
  // 排除的频道列表,支持 "platform:channelId" 或 "channelId" 格式
  excludeChannels: string[]  // 默认: []
  
  // 频道Bot优先级配置
  channelBotPriority: Record<string, string[]>  // 默认: {}
}

优先级配置示例

channelBotPriority:
  "onebot:123456789": ["bot1", "bot2", "bot3"]  # 完整格式
  "987654321": ["bot2", "bot1"]                 # 简写格式
  • 优先级列表按顺序匹配,选择第一个可用的bot
  • 如果所有优先级bot都不可用,自动使用贪心算法
  • 如果优先级bot不在该频道,自动跳过

触发场景

插件会在以下场景自动触发负载均衡:

| 场景 | 延迟 | 说明 | |------|------|------| | 插件启动 | 立即 | 初始化分配 | | Bot状态变化 | 5秒 | 上线/下线状态变化 | | Bot上线 | 5秒 | 新bot可以分担负载 | | Bot下线 | 5秒 | 需要转移该bot负责的频道 | | Bot加入群 | 10秒 | 新群可能需要重新分配 | | Bot退群 | 5秒 | 如果群还有其他bot,需要重新分配 | | 定时器 | 600秒 | 定期检查和调整 |

日志输出

[I] auto-assign 执行负载均衡(动态容量贪心算法)...
[I] auto-assign 平台 onebot 负载均衡完成,分配了 288 个频道
[I] auto-assign 负载分布: [bot1:96, bot2:96, bot3:96],平均: 96.0,标准差: 0.00
  • 负载分布:每个bot实际分配的频道数
  • 平均值:所有bot的平均负载
  • 标准差:越小越均衡(0表示完全均衡)

使用场景

场景1:多bot负载均衡

有3个bot,希望它们平均分担所有频道的消息处理。

balanceInterval: 600
enabledPlatforms: ['onebot']

场景2:特定频道固定bot

某些重要频道希望固定由特定bot处理,但bot下线时自动切换。

channelBotPriority:
  "onebot:重要群A": ["主力bot", "备用bot1", "备用bot2"]
  "onebot:重要群B": ["主力bot"]

场景3:排除特定频道

某些频道不希望被自动分配。

excludeChannels:
  - "onebot:测试群"
  - "987654321"

注意事项

  1. channel表的作用:本插件通过修改 channel 表的 assignee 字段来实现分配,该表是应用分配结果的工具
  2. 数据源:插件通过 bot.getGuildList() 获取bot的实际群列表,不依赖channel表
  3. 延迟触发:为避免频繁重新分配,大部分事件都有延迟触发机制
  4. 容量约束:bot只能被分配到它实际加入的频道

License

MIT