插件管理
一、插件系统概述
ThingsGateway 采用插件化架构设计,所有与外部设备的交互代码都由插件完成,主程序只负责调度执行。这种设计使得系统具有高度的扩展性和灵活性。
1.1 插件的作用
- 功能扩展:通过插件可以轻松添加新的设备驱动、 通信协议和业务功能
- 模块化设计:将不同功能封装在独立插件中,便于维护和升级
- 热插拔:支持在系统运行时动态加载和卸载插件
- 社区贡献:鼓励社区开发者贡献插件,丰富系统功能
1.2 插件类型
| 插件类型 | 描述 | 基类 | 示例 |
|---|---|---|---|
| 采集插件 | 负责从外部设备采集数据 | CollectBase/CollectFoundationBase | Modbus、OPC UA、MQTT 等 |
| 业务插件 | 实现特定的业务逻辑 | BusinessBase | 数据转发、报警处理、定时任务等 |
1.3 插件生命周期
- 加载:插件类型被系统发现并加载到内存中
- 初始化:插件执行初始化操作,准备运行环境
- 运行:插件执行其核心功能,如数据采集、业务处理等
- 停止:插件停止运行,清理资源
- 卸载:插件从内存中移除
二、插件管理界面
2.1 插件管理页面
插件管理页面是管理所有插件的中心,提供了插件的上传、重载、启用/禁用等功能。
2.2 页面功能说明
- 插件列表:显示所有已加载的插件,包括名称、版本、类型等信息
- 上传插件:支持上传新的插件文件(DLL格式)
- 重载插件:重新检测插件文件,加载新的插件或更新现有插件
三、插件上传和管理
3.1 上传插件
- 准备插件文件:确保插件已编译为DLL文件,并且符合ThingsGateway的插件规范
- 访问插件管理页面:登录系统后,进入「系统管理」→「插件管理」
- 上传插件:点击「上传插件」按钮,选择插件DLL文件进行主程序集上传,如果有附属文件,点击附属文件上传
- 等待上传完成:系统会自动处理上传的插件文件
- 重载插件:上传完成后,点击「重载」按钮,使新插件生效
3.2 手动重载插件
当插件文件发生变化时(如上传新插件、更新现有插件),需要手动重载插件:
- 访问插件管理页面
- 点击重载按钮:系统会重新检测插件目录中的所有插件文件
- 等待重载完成:系统会加载新的插件并更新现有插件的状态
提示
插件分为当前域内dll插件(默认Plugins文件夹)以及隔离插件(默认GatewayPlugins文件夹),当前进程域的dll插件不会立即发生改变。如果需要立即生效,请手动点击网关重启按钮。
3.3 插件目录结构
当前进程域内的插件文件存储在系统的 `Plugins` 目录中,目录结构如下:
Plugins/
├── xxx.dll # 插件或附属文件
隔离域内的插件文件存储在系统的 `GatewayPlugins` 目录中,目录结构如下:
GatewayPlugins/
├── XXX/ # 插件同名文件夹
├──── XXX.dll # 插件或附属文件
四、插件开发和调试
具体逻辑查看wiki源码文档:https://deepwiki.com/ThingsGateway/Plugin/8.2-creating-a-custom-database-plugin
五、插件依赖管理
5.1 插件依赖
插件可能依赖于其他库或组件,需要确保这些依赖项在运行时可用:
- 内部依赖:ThingsGateway.Gateway.Application、ThingsGateway.Foundation等核心库
- 外部依赖:第三方库,如Kafka库等
5.2 依赖冲突解决
当多个插件依赖于不同版本的同一库时,可能会出现依赖冲突:
- 隔离插件:为每个插件创建独立的依赖环境,避免版本冲突,放到GatewayPlugins文件夹内,默认为隔离方式
- 统一依赖版本:确保所有插件使用相同版本的依赖库
六、插件安全
6.1 安全考虑
- 代码安全:确保插件代码不包含恶意代码或安全漏洞
- 权限控制:限制插件的权限,避免插件访问敏感资源
- 异常处理:主程序会接管全部插件执行任务,一般情况的异常产生不会导致程序崩溃,但要注意P/Invoke等方式时出现的内核错误
6.2 安全最佳实践
- 代码审查:对第三方插件进行代码审查,确保安全性
- 沙箱运行:考虑使用沙箱技术,限制插件的运行环境
- 签名验证:对插件进行数字签名,确保插件的完整性和来源
- 权限 最小化:只授予插件必要的权限,遵循最小权限原则
七、插件性能优化
7.1 性能考虑
- 并发处理:使用异步编程模式,提高并发处理能力
- 缓存策略:合理使用缓存,减少重复计算和网络操作
- 批量操作:对外部系统的操作使用批量处理,减少通信次数
7.2 优化技巧
- 异步编程:使用async/await模式,避免阻塞主线程
- 资源管理:使用using语句和Dispose方法,及时释放资源
- 连接复用:复用网络连接、数据库连接等,避免频繁建立和关闭连接
- 延迟初始化:使用延迟初始化技术,只在需要时创建资源