PHP实现:点击重启按钮后2分钟自动更新SQL及防重复点击控制
Alright, let's tackle this server restart button with delayed SQL update requirement. Here's a practical PHP-based solution that covers all your needs—including preventing duplicate clicks within 2 minutes and the scheduled SQL update:
We can't rely on PHP's sleep() for the 2-minute delay (since HTTP requests are short-lived), so we'll use a database-backed task queue + cron job to handle the delayed SQL update. We'll also track the last restart attempt to block duplicate clicks.
First, create two tables (adjust names/columns to match your existing schema):
api_servers: Your existing table with server records (we’ll assume it has anidandonlinecolumn)restart_tasks: To track pending restart jobs and enforce the 2-minute cooldown
-- Create restart_tasks table CREATE TABLE restart_tasks ( id INT AUTO_INCREMENT PRIMARY KEY, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, status ENUM('pending', 'completed') NOT NULL DEFAULT 'pending' );
Create a PHP endpoint (e.g., handle_restart.php) that processes the button click request:
<?php session_start(); // Replace with your database credentials $db = new PDO('mysql:host=your_host;dbname=your_db', 'db_user', 'db_pass'); // Check if we're within the 2-minute cooldown window $lastAttempt = $db->query("SELECT created_at FROM restart_tasks WHERE status = 'pending' OR created_at >= DATE_SUB(NOW(), INTERVAL 2 MINUTE) ORDER BY created_at DESC LIMIT 1")->fetchColumn(); if ($lastAttempt && strtotime($lastAttempt) >= strtotime('-2 minutes')) { echo json_encode(['success' => false, 'message' => 'Cannot restart again within 2 minutes. Please wait.']); exit; } try { $db->beginTransaction(); // 1. Set all 3 API servers to offline $db->exec("UPDATE api_servers SET online = 0 WHERE id IN (1, 2, 3)"); // 2. Send request to restart the origin server // Use curl for better error handling (adjust the target URL as needed) $ch = curl_init('https://your-origin-server/restart-endpoint'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_exec($ch); curl_close($ch); // 3. Record the restart task as pending $db->exec("INSERT INTO restart_tasks (status) VALUES ('pending')"); $db->commit(); echo json_encode(['success' => true, 'message' => 'Restart initiated. Servers will come back online in 2 minutes.']); } catch (Exception $e) { $db->rollBack(); echo json_encode(['success' => false, 'message' => 'Error initiating restart: ' . $e->getMessage()]); } ?>
Create a script (e.g., process_pending_restarts.php) to handle the delayed online status update:
<?php // Replace with your database credentials $db = new PDO('mysql:host=your_host;dbname=your_db', 'db_user', 'db_pass'); // Find pending tasks that are older than 2 minutes $tasks = $db->query("SELECT id FROM restart_tasks WHERE status = 'pending' AND created_at <= DATE_SUB(NOW(), INTERVAL 2 MINUTE)")->fetchAll(PDO::FETCH_COLUMN); if (!empty($tasks)) { $db->beginTransaction(); // Set API servers back to online $db->exec("UPDATE api_servers SET online = 1 WHERE id IN (1, 2, 3)"); // Mark completed tasks to avoid reprocessing $taskIds = implode(',', $tasks); $db->exec("UPDATE restart_tasks SET status = 'completed' WHERE id IN ($taskIds)"); $db->commit(); } ?>
Then set up a cron job to run this script every minute (it will only act on tasks that are ready for the online update):
* * * * * /usr/bin/php /path/to/process_pending_restarts.php
(Adjust the PHP path and script path to match your server's file structure)
Add a button and AJAX logic to your webpage to interact with the PHP endpoint:
<button id="restartBtn">Restart Servers</button> <div id="statusMessage"></div> <script> document.getElementById('restartBtn').addEventListener('click', async () => { const btn = event.target; btn.disabled = true; const messageDiv = document.getElementById('statusMessage'); try { const response = await fetch('handle_restart.php', { method: 'POST' }); const result = await response.json(); messageDiv.textContent = result.message; messageDiv.style.color = result.success ? 'green' : 'red'; if (result.success) { // Re-enable button after 2 minutes (improves UX, but backend still enforces cooldown) setTimeout(() => btn.disabled = false, 120000); } else { btn.disabled = false; } } catch (err) { messageDiv.textContent = 'Failed to connect to server.'; messageDiv.style.color = 'red'; btn.disabled = false; } }); </script>
- Cooldown Reliability: We check the
restart_taskstable for recent attempts instead of just session data—this works across multiple users/sessions and server instances. - Failure Safety: Database transactions ensure that if any step fails (e.g., the origin server restart request times out), we don't leave API servers stuck in an offline state.
- Cron Job Efficiency: The script runs every minute but only acts on tasks that have passed the 2-minute window, so it won't waste resources.
内容的提问来源于stack exchange,提问作者Zac Ram

