Files
shop-platform/docs/CRON_ENV_SETUP.md

310 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cron 任务环境变量配置指南
## 🎯 问题:如何为 `nohup php think cron:schedule` 指定 `.env` 文件
## ✅ 解决方案
**最重要的部分**
我们修改了项目目录下的 `think` 文件的内容,增加了读取环境变量的代码
```php
#!/usr/bin/env php
<?php
namespace think;
// 命令行入口文件
// 加载基础文件
require __DIR__ . '/vendor/autoload.php';
// 创建应用程序
$app = new App();
// 您的代码使用APP_ENV
$appEnv = getenv('APP_ENV') ?: '';
if ($appEnv) {
$envFile = __DIR__ . '/.env.' . $appEnv;
if (is_file($envFile)) {
$app->env->load($envFile);
}
}
// 应用初始化
$app->console->run();
```
### 方案一:使用环境变量(推荐)
```bash
# 1. 临时设置环境变量(当前会话有效)
export THINK_ENV=production
nohup php think cron:schedule > /dev/null 2>&1 &
# 2. 永久设置环境变量(写入 ~/.bashrc
echo 'export THINK_ENV=production' >> ~/.bashrc
source ~/.bashrc
nohup php think cron:schedule > /dev/null 2>&1 &
# 3. 直接传递环境变量
THINK_ENV=production nohup php think cron:schedule > /dev/null 2>&1 &
```
### 方案二:指定不同的 .env 文件
```bash
# 1. 复制环境配置文件
cp .env .env.production
# 编辑 .env.production 修改相应配置
# 2. 使用 APP_ENV 指定环境
APP_ENV=production nohup php think cron:schedule > /dev/null 2>&1 &
# 3. 或者在运行时指定
php think cron:schedule --env=production
```
### 方案三:自定义启动脚本(最佳实践)
创建专用启动脚本 `start_cron.sh`
```bash
#!/bin/bash
# 设置环境变量
export THINK_ENV=${1:-production}
# 设置工作目录
cd /path/to/your/project
# 日志文件路径
LOG_FILE="/var/log/cron_${THINK_ENV}.log"
# 启动 cron 任务
echo "Starting cron with environment: $THINK_ENV"
nohup php think cron:schedule > $LOG_FILE 2>&1 &
# 记录进程ID
echo $! > /var/run/cron_${THINK_ENV}.pid
echo "Cron started with PID: $(cat /var/run/cron_${THINK_ENV}.pid)"
```
使用方法:
```bash
chmod +x start_cron.sh
# 启动生产环境 cron
./start_cron.sh production
# 启动开发环境 cron
./start_cron.sh development
```
## 🔧 ThinkPHP 6.x 环境变量加载机制
### ThinkPHP 自动加载顺序:
1. **服务器环境变量**: `$_SERVER['APP_ENV']`
2. **系统环境变量**: `getenv('APP_ENV')`
3. **.env 文件**: 根据环境变量加载对应的 `.env.*` 文件
### 支持的环境变量:
| 变量名 | 作用 | 示例 |
|--------|------|-------|
| `APP_ENV` | 指定运行环境 | `production` |
| `THINK_ENV` | ThinkPHP 6.x 环境标识 | `production` |
| `ENV_PATH` | 自定义 .env 文件路径 | `/custom/path/.env` |
## 📁 环境配置文件结构
```
project/
├── .env # 默认配置
├── .env.development # 开发环境
├── .env.testing # 测试环境
├── .env.staging # 预发布环境
└── .env.production # 生产环境
```
## 🚀 实际使用示例
### Docker 环境中的使用
```dockerfile
# Dockerfile 中设置环境变量
ENV THINK_ENV=production
# 或者在 docker-compose.yml 中
environment:
- THINK_ENV=production
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
```
### Supervisor 配置
```ini
[program:cron-production]
command=/usr/bin/php /var/www/html/think cron:schedule
environment=THINK_ENV=production
directory=/var/www/html
autostart=true
autorestart=true
user=www-data
stdout_logfile=/var/log/supervisor/cron-production.log
stderr_logfile=/var/log/supervisor/cron-production-error.log
[program:cron-development]
command=/usr/bin/php /var/www/html/think cron:schedule
environment=THINK_ENV=development
directory=/var/www/html
autostart=false
autorestart=true
user=www-data
stdout_logfile=/var/log/supervisor/cron-development.log
stderr_logfile=/var/log/supervisor/cron-development-error.log
```
### 系统服务配置
```bash
# 创建 systemd 服务文件
sudo tee /etc/systemd/system/think-cron.service > /dev/null <<EOF
[Unit]
Description=ThinkPHP Cron Scheduler
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html
Environment=THINK_ENV=production
ExecStart=/usr/bin/php /var/www/html/think cron:schedule
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# 启用并启动服务
sudo systemctl enable think-cron
sudo systemctl start think-cron
```
## 🔍 验证配置
### 检查当前环境
```bash
# 1. 在 cron 任务中添加日志
php think cron:schedule --verbose
# 2. 检查环境变量
php -r "echo 'APP_ENV: ' . getenv('APP_ENV') . PHP_EOL;"
php -r "echo 'THINK_ENV: ' . getenv('THINK_ENV') . PHP_EOL;"
# 3. 检查 ThinkPHP 加载的配置
php think config:get app.env
```
### 测试不同环境
```bash
# 测试生产环境
APP_ENV=production php think cron:schedule --verbose
# 测试开发环境
APP_ENV=development php think cron:schedule --verbose
# 使用指定配置文件
THINK_ENV=staging php think cron:schedule --verbose
```
## 📝 日志和监控
### 日志配置
```bash
# 按环境分离日志
nohup php think cron:schedule > logs/cron_${APP_ENV:-default}.log 2>&1 &
# 带时间戳的日志
nohup php think cron:schedule > logs/cron_$(date +%Y%m%d).log 2>&1 &
```
### 进程监控
```bash
# 检查 cron 进程
ps aux | grep "think cron:schedule" | grep -v grep
# 使用 pgrep 查找进程ID
pgrep -f "think cron:schedule"
# 监控脚本
#!/bin/bash
while true; do
if ! pgrep -f "think cron:schedule"; then
echo "$(date): Cron process died, restarting..."
nohup php think cron:schedule > logs/cron.log 2>&1 &
fi
sleep 30
done
```
## 🎯 推荐配置
### 生产环境最佳实践
```bash
# 1. 使用环境变量指定配置
export APP_ENV=production
# 2. 设置适当的日志级别
nohup php think cron:schedule --quiet > /var/log/cron.log 2>&1 &
# 3. 定期检查进程状态
*/5 * * * * * /usr/bin/pgrep -f "think cron:schedule" || /usr/bin/nohup /usr/bin/php /var/www/html/think cron:schedule > /var/log/cron.log 2>&1 &
```
### 开发环境配置
```bash
# 1. 使用开发环境配置
export APP_ENV=development
# 2. 显示详细输出用于调试
nohup php think cron:schedule > /dev/null 2>&1 &
# 3. 实时查看日志
tail -f logs/cron_dev.log
```
---
### 本地开发环境配置
```bash
# 1. 使用开发环境配置
export APP_ENV=local
# 2. 显示详细输出用于调试
nohup php think cron:schedule > /dev/null 2>&1 &
# 3. 实时查看日志
tail -f logs/cron_dev.log
```
## ✅ 总结
**答案:是的,可以为 `nohup php think cron:schedule` 指定 `.env` 文件!**
**推荐方法:**
1. 使用 `APP_ENV=production` 环境变量
2. 创建对应的 `.env.production` 文件
3. 使用自定义启动脚本管理不同环境
这样可以让同一套代码在不同环境中使用不同的数据库配置、缓存配置等。