Maison  >  Article  >  développement back-end  >  Guide de programmation Yii2 : Comment exécuter le service Cron

Guide de programmation Yii2 : Comment exécuter le service Cron

WBOY
WBOYoriginal
2023-09-01 23:21:061019parcourir

Guide de programmation Yii2 : Comment exécuter le service Cron

Si vous demandez « Qu'est-ce que Yii ? », consultez mon tutoriel précédent : Introduction au framework Yii, qui passe en revue les avantages de Yii et décrit les nouveautés de Yii 2.0, publié en octobre 2014. Hmm>

Dans cette série Programmation avec Yii2, je guiderai les lecteurs dans l'utilisation du framework PHP Yii2. Dans le didacticiel d'aujourd'hui, je vais partager avec vous comment tirer parti des fonctionnalités de la console Yii pour exécuter des tâches cron.

Dans le passé, j'utilisais wget — une URL accessible sur le Web — dans une tâche cron pour exécuter mes tâches en arrière-plan. Cela soulève des problèmes de sécurité et entraîne des problèmes de performances. Alors que je discutais de quelques moyens d'atténuer les risques liés à notre fonctionnalité de sécurité Boot Series, j'avais espéré passer aux commandes pilotées par la console. Avec Yii2, c'est assez simple.

Pour l'exemple d'aujourd'hui, je vais faire une démonstration de la commande cron basée sur la console sur mon site Twixxr, que je décris dans cet épisode de l'API Twitter. En raison de problèmes de limitation de débit et de gestion des performances, l'API Twitter s'appuie fortement sur des tâches cron efficaces et fiables. C’est donc un excellent exemple à partager avec vous.

Avant de commencer, je tiens à réitérer : j'apprécie toujours vos idées et vos commentaires. Si vous avez des questions ou des suggestions de sujets, veuillez poster vos réflexions dans les commentaires ci-dessous. Vous pouvez également me contacter directement sur Twitter @reifman.

Qu'est-ce que Cron ?

Wikipedia décrit cron comme « un planificateur de tâches basé sur le temps dans les systèmes d'exploitation informatiques de type Unix ». C'est tout à fait exact. Fondamentalement, cron exécute toutes les tâches en arrière-plan dont nous avons besoin pour exécuter les services Web, de la gestion des journaux et des sauvegardes aux requêtes API en passant par le nettoyage de la base de données.

Pour afficher les tâches cron existantes sur un serveur, vous tapez généralement sudo crontab -l et voyez quelque chose comme ceci :

# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
*/3 * * * * wget -O /dev/null https://meetingplanner.io/daemon/frequent
*/15 * * * * wget -O /dev/null http://meetingplanner.io/daemon/quarter
0 * * * * wget -O /dev/null http://meetingplanner.io/daemon/hourly
15 1 * * * wget -O /dev/null http://meetingplanner.io/daemon/overnight
40 2 * * * /usr/sbin/automysqlbackup
15 3 * * 5 wget -O /dev/null http://meetingplanner.io/daemon/weekly
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log

Spécifiez à gauche pour activer ces tâches toutes les 3 ou 15 minutes ou tous les jours à minuit, etc., et à droite se trouve le script à exécuter. Voir aussiPlanification de tâches à l'aide de tâches Cron (Envato Tuts+).

Veuillez noter que le script Let's Encrypt est une commande de console unique. Il est exécuté depuis la ligne de commande sur notre serveur. Cependant, toutes mes tâches de planification de réunions ci-dessus sont exécutées via wget. C'est comme un robot exécutant des requêtes sur le navigateur Web à un moment précis sur notre application Web qui effectue des tâches en arrière-plan.

En plus de la surcharge requise pour les requêtes Web externes et des contraintes de délai d'attente pour les scripts sur le serveur, vous devez également sécuriser ces points d'accès. Voici un exemple de la façon dont les organisateurs de réunions peuvent procéder :

// only cron jobs and admins can run this controller's actions
    public function beforeAction($action)
    {
      // your custom code here, if you want the code to run before action filters,
      // which are triggered on the [[EVENT_BEFORE_ACTION]] event, e.g. PageCache or AccessControl
      if (!parent::beforeAction($action)) {
          return false;
      }
      // other custom code here
      if (( $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'] ) ||
          (!\Yii::$app->user->isGuest && \common\models\User::findOne(Yii::$app->user->getId())->isAdmin()))
       {
         return true;
       }
      return false; // or false to not run the action
    }

Il vérifie que l'utilisateur est connecté en tant qu'administrateur ou s'exécute localement sur le serveur avec la même adresse IP Internet.

Implémenter la commande Cron basée sur la console

Alex Makarov est l'un des principaux bénévoles dans le développement du framework Yii et il m'aide à répondre à mes questions lorsque j'écris régulièrement sur le framework Envato Tuts+. Après avoir lu mon incident de sécurité, il m'a demandé pourquoi je n'utilisais pas la fonctionnalité native de la console de Yii2 pour exécuter des tâches cron. En gros, je ne sais pas.

Tout comme j'avais un /frontend/controllers/DaemonController.php, j'ai créé un /console/controllers/DaemonController.php. Dans ce tutoriel, je ferai cela pour un service Web Twixxr plus petit et plus simple.

J'ai l'habitude d'utiliser la console pour exécuter des migrations de bases de données (comme ./yii migrate/up 7), mais c'est tout. J'aimerais essayer de l'utiliser pour effectuer des tâches en arrière-plan.

Comme je l'ai écrit dans un tutoriel précédent, mon nouveau site Web Twixxr nécessitait de nombreux processus en arrière-plan pour faire régulièrement tourner les appels d'API afin de satisfaire toutes les demandes des utilisateurs souhaitant socialiser avec des comptes Twitter d'influenceurs appartenant à des femmes.

La page d'accueil est la suivante :

Guide de programmation Yii2 : Comment exécuter le service Cron

J'ai donc pensé que Twixxr serait une bonne plate-forme de test pour exécuter des contrôleurs cron basés sur une console.

Nouveau DaemonController.php

C'est le cœur de mon nouveau DaemonController.php basé sur une console :

<?php
namespace console\controllers;

use Yii;
use yii\helpers\Url;
use yii\console\Controller;
use frontend\models\Twixxr;

/**
 * Test controller
 */
class DaemonController extends Controller {

    public function actionIndex() {
        echo "Yes, cron service is running.";
    }

    public function actionFrequent() {
      // called every two minutes
      // */2 * * * * ~/sites/www/yii2/yii test
      $time_start = microtime(true);
      $x = new \frontend\models\Twixxr();
      $x->process($time_start);
      $time_end = microtime(true);
      echo 'Processing for '.($time_end-$time_start).' seconds';
    }

    public function actionQuarter() {
        // called every fifteen minutes
        $x = new \frontend\models\Twixxr();
        $x->loadProfiles();
      }

      public function actionHourly() {
        // every hour
        $current_hour = date('G');
        if ($current_hour%4) {
          // every four hours
        }
            if ($current_hour%6) {
            // every six hours
          }
      	}

Veuillez noter que sa structure est très similaire à celle de mon contrôleur frontal, mais il n'est pas accessible en toute sécurité sur le réseau car il se trouve dans l'arborescence /console. Le site du serveur Web Apache n'est pas configuré pour parcourir cette zone.

Donc, dans l'exemple ci-dessus, actionFrequent() 将每两到三分钟调用一次。它处理另一组 Twixxr 友谊请求。另一方面,actionQuarter() est appelé toutes les 15 minutes et met à jour les informations de profil du compte de navigation. Voyons comment fonctionne la planification dans un fichier cron.

Nouveau fichier crontab

Essentiellement, dans mon fichier crontab, j'ai remplacé wget par un script Linux direct, comme indiqué ci-dessus pour le renouvellement de Let's Encrypt.

Vous tapez sudo crontab -e 进行编辑,或输入 -l pour lister son contenu. Voici mon fichier cron Twixxr :

$ sudo crontab -l
# m h  dom mon dow   command
*/3 * * * * /var/www/twixxr/yii daemon/frequent
*/15 * * * * /var/www/twixxr/yii daemon/quarter
0 * * * * /var/www/twixxr/yii daemon/hourly
15 1 * * * /var/www/twixxr/yii daemon/overnight
15 3 * * 5 /var/www/twixxr/yii daemon/weekly
#40 2 * * * /usr/sbin/automysqlbackup
30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

这非常简单。 /var/www/twixxr/yii daemon/frequent 的左侧是 yii 解释器所在的路径,右侧是控制台控制器和调用的方法。 p>

切换时一切都很顺利。我还没有切换 Meeting Planner,因为我想做更多测试。当后台任务中断时,很难知道也很难调试它们(尽管 Sentry 错误日志记录有很大帮助)。

需要考虑的问题

我遇到的一个问题是控制台命名空间与前端命名空间不同,因此,例如,我在教程中设置的 SiteHelper.php 组件(该组件描述了从单个代码库运行多个网站)失败了当我调用它时。删除它是有效的,但我需要运行测试以确保底层后台代码仍然有效。不过,大部分情况下切换都很顺利。

与任何其他代码更改一样,彻底测试和监控。

下一步是什么

展望未来,我将探索在 Yii2 框架内构建 REST API,该框架恰好依赖于创建一个不同的子树,例如控制台树,但用于外部 API。当然,这会带来复杂的身份验证和安全问题……所以与您一起探索这些将会很有趣。我将从多个角度研究 API。我对此感到非常兴奋。

请观看我的“使用 Yii2 编程”系列中即将推出的教程,我将继续深入研究该框架的不同方面。另请浏览“使用 PHP 构建您的初创公司”系列,其中记录了构建 Simple Planner 和 Meeting Planner 的过程。

如果您想知道下一个 Yii2 教程何时发布,请在 Twitter 上关注我 @reifman 或查看我的讲师页面以获取更新。

相关链接

  • Yii2 Developer Exchange,我的 Yii2 资源站点
  • 使用 Cron 作业安排任务 (Envato Tuts+)

  • 如何在 Yii2 中实现 cron(Yii 文档)
  • Twixxr,其中提到的示例网络服务

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn