PHP-FPM 记分牌(scoreboard) 机制

前文中提到 fpm 的初始化分很多步骤,其中一个重要的步骤就是调用 fpm_scoreboard_init_main() 初始化进程记分牌。为什么需要这个记分牌?因为 FPM 的父进程需要管理非常多的子进程,这就需要一个打分的机制,不能让一个进程老是干活,而另一部分进程老是闲置,因为每个进程维护的内存空间是有限的,如果一个进程处理了较多的任务可能会产生更多的内存碎片。

先看看其核心代码结构:

  • fpm_scoreboard_acquire
  • fpm_scoreboard_child_use
  • fpm_scoreboard_free
  • fpm_scoreboard_get
  • fpm_scoreboard_get_tick
  • fpm_scoreboard_init_main
  • fpm_scoreboard_proc_acquire
  • fpm_scoreboard_proc_alloc
  • fpm_scoreboard_proc_free
  • fpm_scoreboard_proc_get
  • fpm_scoreboard_proc_release
  • fpm_scoreboard_release
  • fpm_scoreboard_update

结合上一节中 fpm 初始化的步骤可知,初始化首先被调用的是 fpm_scoreboard_init_main 函数。

for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
        size_t scoreboard_size, scoreboard_nprocs_size;
        void *shm_mem;

        if (wp->config->pm_max_children < 1) {
            zlog(ZLOG_ERROR, "[pool %s] Unable to create scoreboard SHM because max_client is not set", wp->config->name);
            return -1;
        }

        if (wp->scoreboard) {
            zlog(ZLOG_ERROR, "[pool %s] Unable to create scoreboard SHM because it already exists", wp->config->name);
            return -1;
        }

        scoreboard_size        = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *);
        scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
        shm_mem                = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size);

        if (!shm_mem) {
            return -1;
        }
        wp->scoreboard         = shm_mem;
        wp->scoreboard->nprocs = wp->config->pm_max_children;
        shm_mem               += scoreboard_size;

        for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) {
            wp->scoreboard->procs[i] = shm_mem;
        }

        wp->scoreboard->pm          = wp->config->pm;
        wp->scoreboard->start_epoch = time(NULL);
        strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
    }

这段代码是一个大循环,它会遍历所有的 fpm

results matching ""

    No results matching ""