Files
hyperf-admin/docs/backend/components/business/make_component.md

4.6 KiB

需求提炼

hyperf 项目启动后, 会将config 目录下的配置信息, 统一载入到 Config 对象中, 以供框架使用, 但对于部分业务性的配置依赖, 如果我们想修改, 必须修改代码->提交pr->合入主干->线上部署等一系列的工作, 如果我们能实现一个配置中心, 只要在后台修改下指定配置, 然后线上各进程中的Config对象做到自动更新, 那么就会极大的进化工作流程. 所以, 让我们来一起实现一个config-center配置中心的组件吧.

拆解如下:

  1. 底层存储可以基于 ConsulNacosRedis
    1. 考虑到低成本实现, 最终决定用Redis, 如果多语言交互的话, 建议使用 Consule/Nacos等配置中心
  2. 配置的修改, 发布后可以实时更新到线上的工作进程
  3. 提供通用管理页面, 无差别化底层的存储
  4. 额外再提供一个基于配置中心的switch_service开关服务

基本思路:

  1. 配置存放在mysql, 有 insertupdate 时, 保存聚合数据到Redis
  2. woker 启动时, 合并代码中的config 和 配置中心的配置, 加载到内存
  3. worker进程中增加timer, 当缓存数据有更新时, 加载新数据到内存, 以供业务使用

开动吧

1. 确定表结构

CREATE TABLE `config_center` (
  `id` int(12) unsigned NOT NULL AUTO_INCREMENT,
  `path` varchar(255) NOT NULL DEFAULT '' COMMENT '存储位置, . 分隔',
  `value` text COMMENT '节点值',
  `create_uid` int(12) NOT NULL COMMENT '创建者id',
  `is_locked` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '是否被锁定',
  `owner_uids` varchar(255) NOT NULL COMMENT '所有者, 逗号分隔',
  `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. 创建 Controller, Model

wlXctg

此时基础文件已经生成在lib/ 下, 作为一个composer包模式开发, 我们将其转移至 /opt/hyperf-admin/config-center目录

然后 cd /opt/hyperf-admin/config-center 执行 composer init, 初始包文件

然后, 调整依赖 hyperf-admin/admin, ConfigProvider, Insert Command 等, 此时的目录结构如下

./
├── composer.json
└── src
    ├── ConfigProvider.php
    ├── Controller
    │   └── ConfigCenterController.php
    ├── Install
    │   ├── InstallCommand.php
    │   └── install.sql
    └── Model
        └── ConfigCenter.php

接下来回来主项目, 修改 composer.json 的 repositories

"repositories": [
   {
       "type": "path",
       "url": "/opt/hyperf-admin/config-center"
   }
]

安装config-center的开发包 composer require hyperf-admin/config-center

3. 添加菜单 注册路由

uAR5lj

<?php

use HyperfAdmin\ConfigCenter\Controller\ConfigCenterController;

register_route('/config_center', ConfigCenterController::class);

ConfigProvider 中注册该文件路径到 init_routes节点

?> 若配置有不生效的情况, 执行 rm vendor/hyperf-admin/config-center && composer require hyperf-admin/config-center 重新安装即可

EFvajy

至此已经完成了, 配置的CRUD.

4. 配置变动的Redis更新

ConfigCenterService 将配置从mysql中捞出, 聚合后, 存入Redis中, 并更新相应版本号

ConfigCenterController.afterSave 钩子中, 调用 ConfigCenterService

5. 工作进程中的配置自动更新

BootProcessListener 中监听BeforeWorkerStart, BeforeProcessHandle, BeforeHandle事件, 定设置定时器, 定时同步配置.

有了配置中心我们可以做的很有想象空间了, 比如线上db信息的保密, 动态控制自定义进程的启用禁用(结合服务重启), 等等.

完整代码结构如下, 具体源码在src/config-center目录 这里

./
├── composer.json
└── src
    ├── BootProcessListener.php
    ├── ConfigProvider.php
    ├── Controller
    │   └── ConfigCenterController.php
    ├── Install
    │   ├── InstallCommand.php
    │   └── install.sql
    ├── Model
    │   └── ConfigCenter.php
    ├── Service
    │   └── ConfigCenterService.php
    └── routes.php