thinkphp框架使用command实现队列功能

背景

ThinkPHP命令行工具持久化运行的应用场景包括:队列处理,定时任务、后台服务等。本次实战是实现队列处理数据。

步骤1

application目录command.php增加

return [
    'app\admin\command\Crud',
    'app\admin\command\Menu',
    'app\admin\command\Install',
    'app\admin\command\Min',
    'app\admin\command\Addon',
    'app\admin\command\Api',
    
    'app\command\Data',//增加的代码
    
];

步骤2

application的command目录下增加Data.php文件

class Data extends Command
{

    protected function configure()
    {
        parent::configure();
        $this->setName('Data')->setDescription('Data');
    }
	
	protected function execute(Input $input, Output $output)
    {
		 
         echo 'TestTestTestTest';
		 echo "\n";
		 echo "cc";
		 echo "\n";
		 $where=array();
	     $where['status']=1;
         //$where['createtime']=array("gt","1665880701");	 		 
	     $data=Db::name('na_data')->where($where)->select();
		 foreach($data as $k => & $v){
             //处理你自己的逻辑
			 
			 echo "开始处理";
			
			  	 
			
			
			 echo "处理结束";
			 echo "\n";
			 
		 }
		 exit;
    }


}

步骤3

在项目的更目录cmd ,执行php think Data。即可

<think>我们将在ThinkPHP5.1框架实现ETL(Extract, Transform, Load)数据同步,将本地数据库的部分数据表同步到云数据库。这里我们假设本地和云端数据库都是MySQL,但方法同样适用于其他数据库(只需更改驱动和配置)。 ### 步骤概述 1. **配置数据库连接**:在ThinkPHP中配置本地数据库和云端数据库的连接。 2. **创建ETL命令行工具**:使用ThinkPHP的自定义命令功能创建ETL命令,以便可以定时或手动执行。 3. **数据抽取(Extract)**:从本地数据库指定表中读取数据。 4. **数据转换(Transform)**:根据需要对数据进行清洗、转换等操作(可选)。 5. **数据加载(Load)**:将转换后的数据写入云端数据库对应的表中。 6. **处理同步冲突**:考虑如何避免重复数据,以及更新已有数据等(如使用唯一键更新)。 ### 详细步骤 #### 1. 配置数据库连接 在`config/database.php`中配置两个数据库连接,例如: ```php return [ // 默认数据库连接(本地) 'default' => 'local_db', // 数据库连接配置 'connections' => [ // 本地数据库 'local_db' => [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'local_db', 'username' => 'root', 'password' => '123456', 'charset' => 'utf8', 'prefix' => '', 'debug' => true, ], // 云端数据库 'cloud_db' => [ 'type' => 'mysql', 'hostname' => 'cloud.mysql.com', 'database' => 'cloud_db', 'username' => 'cloud_user', 'password' => 'cloud_password', 'charset' => 'utf8', 'prefix' => '', 'debug' => true, ], ], ]; ``` #### 2. 创建ETL命令行工具 使用ThinkPHP的命令行工具创建一个新的命令,例如`SyncData`。 在项目根目录下执行: ```bash php think make:command SyncData ``` 这将在`application/command`目录下生成`SyncData.php`文件。编辑该文件: ```php <?php namespace app\command; use think\console\Command; use think\console\Input; use think\console\Output; use think\Db; class SyncData extends Command { protected function configure() { $this->setName('sync:data') ->setDescription('Sync data from local to cloud database'); } protected function execute(Input $input, Output $output) { // 这里实现ETL逻辑 $output->writeln("Starting data synchronization..."); // 示例:同步user表 $this->syncTable('user'); $output->writeln("Data synchronization completed."); } protected function syncTable($tableName) { // 1. 抽取数据 $localData = Db::connect('local_db')->table($tableName)->select(); // 2. 转换数据(这里根据需要进行转换,例如时间格式转换、字段映射等) // 假设不需要转换,直接使用 // 3. 加载数据到云端 $cloudDb = Db::connect('cloud_db'); foreach ($localData as $data) { // 假设表有唯一键id,我们使用replace避免重复(如果存在则替换) $cloudDb->table($tableName)->replace(true)->insert($data); } } } ``` 注意:上述代码使用了`replace`方法,它会尝试插入数据,如果主键或唯一索引冲突则删除原记录并插入新记录。这适用于全量覆盖同步。如果数据量很大,可以考虑批量插入。 #### 3. 注册命令 在`application/command.php`中注册该命令(如果不存在则创建): ```php return [ 'app\command\SyncData', ]; ``` #### 4. 执行同步 在命令行中运行: ```bash php think sync:data ``` ### 优化建议 1. **增量同步**:如果数据量大,全量同步效率低。可以记录每次同步的时间戳,只同步更新过的数据。例如,在表中添加`update_time`字段,并在同步时只抽取`update_time`大于上次同步时间的记录。 2. **批量插入**:使用`insertAll`方法批量插入数据,减少数据库连接次数。 3. **事务**:在加载数据时使用事务,确保数据一致性。 4. **错误处理**:添加异常捕获,记录同步失败的数据。 5. **日志**:记录同步的详细日志。 ### 增量同步示例 修改`syncTable`方法,实现增量同步(假设表有`update_time`字段记录更新时间): ```php protected function syncTable($tableName) { // 获取上次同步时间(这里简单用文件存储,实际可用数据库或缓存记录) $lastSyncFile = runtime_path() . 'last_sync_' . $tableName . '.txt'; $lastSyncTime = file_exists($lastSyncFile) ? file_get_contents($lastSyncFile) : 0; // 抽取数据:只抽取上次同步之后更新过的数据 $localData = Db::connect('local_db') ->table($tableName) ->where('update_time', '>', $lastSyncTime) ->select(); if (empty($localData)) { return; } $cloudDb = Db::connect('cloud_db'); // 使用事务 $cloudDb->startTrans(); try { foreach ($localData as $data) { // 使用replace,根据主键或唯一索引更新 $cloudDb->table($tableName)->replace(true)->insert($data); } $cloudDb->commit(); // 更新上次同步时间为当前时间 file_put_contents($lastSyncFile, time()); } catch (\Exception $e) { $cloudDb->rollback(); // 记录错误日志 Log::error('同步失败:' . $e->getMessage()); } } ``` ### 注意事项 - 确保本地和云端数据库的表结构一致,否则需要做字段映射。 - 如果数据量非常大,考虑分批次处理,避免内存溢出。 - 根据实际需求选择合适的同步策略(全量/增量)。 通过以上步骤,我们实现了在ThinkPHP5.1框架中通过命令行工具进行本地与云端数据库的数据同步。 §§相关问题§§ 1. ThinkPHP5.1中如何配置多个数据库连接? 2. 如何优化大数据量下的ETL同步性能? 3. 增量同步时如何记录和获取最后一次同步的时间戳? 4. 在ETL过程中如何处理数据转换和清洗? 5. 如何避免在数据同步过程中因网络问题导致的数据不一致?</think>在ThinkPHP5.1框架实现本地与云端数据库的ETL数据同步,可通过以下步骤实现。ETL(Extract-Transform-Load)过程包括数据抽取、转换和加载三个阶段,适用于数据迁移、备份或分析场景。 --- ### 一、基础配置 #### 1. 配置数据库连接 在`config/database.php`中定义本地和云端数据库配置: ```php return [ // 本地数据库配置 'local_db' => [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'local_db', 'username' => 'root', 'password' => 'local_pass', 'charset' => 'utf8mb4', ], // 云端数据库配置(如阿里云RDS) 'cloud_db' => [ 'type' => 'mysql', 'hostname' => 'rm-bp1xxxx.mysql.rds.aliyuncs.com', 'database' => 'cloud_db', 'username' => 'cloud_user', 'password' => 'cloud_pass', 'charset' => 'utf8mb4', ], ]; ``` #### 2. 安装ETL工具包 通过Composer安装数据处理工具: ```bash composer require league/csv # CSV处理 composer require ramsey/uuid # UUID生成 ``` --- ### 二、核心实现步骤 #### 1. 数据抽取(Extract) 从本地数据库读取数据: ```php use think\Db; public function extractData($table, $lastSyncId = 0) { // 增量同步:按ID范围分批读取 return Db::connect('local_db') ->table($table) ->where('id', '>', $lastSyncId) ->limit(1000) // 每批1000条 ->select(); } ``` #### 2. 数据转换(Transform) 对数据进行清洗和格式化: ```php public function transformData($data) { foreach ($data as &$item) { // 示例1:手机号脱敏 if (isset($item['phone'])) { $item['phone'] = substr_replace($item['phone'], '****', 3, 4); } // 示例2:时间格式转换 if (isset($item['create_time'])) { $item['create_time'] = date('Y-m-d H:i:s', $item['create_time']); } // 添加同步标记 $item['sync_uuid'] = \Ramsey\Uuid\Uuid::uuid4()->toString(); } return $data; } ``` #### 3. 数据加载(Load) 写入云端数据库: ```php public function loadData($table, $transformedData) { try { Db::connect('cloud_db') ->table($table) ->insertAll($transformedData); return true; } catch (\Exception $e) { // 记录失败日志 Log::error("同步失败: " . $e->getMessage()); return false; } } ``` --- ### 三、完整同步流程 #### 1. 创建命令行工具 ```bash php think make:command SyncData ``` 在`app/command/SyncData.php`中实现: ```php class SyncData extends Command { protected function configure(){ $this->setName('sync:data')->setDescription('ETL数据同步'); } protected function execute(Input $input, Output $output) { $tables = ['user', 'order', 'product']; // 需同步的表 foreach ($tables as $table) { $lastId = Cache::get("last_sync_id_{$table}", 0); do { $rawData = $this->extractData($table, $lastId); if (empty($rawData)) break; $transformed = $this->transformData($rawData); $this->loadData($table, $transformed); $lastId = end($rawData)['id']; // 更新最后同步ID Cache::set("last_sync_id_{$table}", $lastId); } while (count($rawData) >= 1000); } $output->writeln("同步完成"); } } ``` #### 2. 注册命令 在`app/command.php`中添加: ```php return [ 'app\command\SyncData' ]; ``` #### 3. 执行同步 ```bash php think sync:data ``` --- ### 四、高级优化方案 1. **断点续传** 使用Redis记录同步进度: ```php $lastId = Redis::get("sync:{$table}:last_id"); ``` 2. **数据冲突处理** 使用`ON DUPLICATE KEY UPDATE`: ```php Db::connect('cloud_db') ->table($table) ->duplicate(['update_time' => time()]) // 冲突时更新字段 ->insertAll($data); ``` 3. **事务回滚机制** ```php Db::connect('cloud_db')->startTrans(); try { // 数据操作... Db::connect('cloud_db')->commit(); } catch (\Exception $e) { Db::connect('cloud_db')->rollback(); } ``` 4. **性能监控** ```php // 记录同步指标 Log::info("同步统计: 表{$table} 数量".count($data)." 耗时".microtime(true)-$startTime); ``` --- ### 五、注意事项 1. **数据一致性** - 使用数据库事务保证原子性 - 添加`is_deleted`软删除字段而非物理删除 2. **安全防护** - 敏感字段加密存储(如手机号、身份证) - 使用SSL连接云端数据库: ```php 'cloud_db' => [ 'params' => [ \PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem' ] ] ``` 3. **错误恢复** 将失败数据写入死信队列: ```php // 同步失败时 Queue::push('app\job\RetrySync', $failedData); ``` --- ### 典型应用场景 1. **每日增量同步** 通过Crontab定时执行: ```bash 0 2 * * * /usr/bin/php /project_path/think sync:data ``` 2. **跨云迁移** 本地MySQL → 阿里云RDS/Amazon RDS 3. **数据分析准备** 清洗后同步到OLAP数据库(如ClickHouse) > **提示**:对于TB级数据,建议使用专业ETL工具(如Apache NiFi)或云服务(AWS DMS),框架级方案适合中小规模数据[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值