On production, there are a few important things to think about:
Use Supervisor to keep your worker(s) running
You’ll want one or more “workers” running at all times. To do that, use a process control system like Supervisor.
Don’t Let Workers Run Forever
Some services (like Doctrine’s EntityManager) will consume more memory over time. So, instead of allowing your worker to run forever, use a flag like messenger:consume --limit=10 to tell your worker to only handle 10 messages before exiting (then Supervisor will create a new process). There are also other options like --memory-limit=128M and --time-limit=3600.
Restart Workers on Deploy
Each time you deploy, you’ll need to restart all your worker processes so that they see the newly deployed code. To do this, run messenger:stop-workers on deployment. This will signal to each worker that it should finish the message it’s currently handling and should shut down gracefully. Then, Supervisor will create new worker processes. The command uses the app cache internally - so make sure this is configured to use an adapter you like.
Use the Same Cache Between Deploys
If your deploy strategy involves the creation of new target directories, you should set a value for the cache.prefix.seed configuration option in order to use the same cache namespace between deployments. Otherwise, the cache.app pool will use the value of the kernel.project_dir parameter as base for the namespace, which will lead to different namespaces each time a new deployment is made.
# this command needs anyway executed via cron or similar task scheduler
# it fills the message queue with the necessary tasks, which are then processed by messenger:consume
*/5 * * * * /your/project/bin/console pimcore:maintenance --async
# it's recommended to run the following command using a process control system like Supervisor
# please follow the Symfony Messenger guide for a best practice production setup:
# https://symfony.com/doc/current/messenger.html#deploying-to-production
*/5 * * * * /your/project/bin/console messenger:consume pimcore_core pimcore_maintenance --time-limit=300
<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/
namespace App\Sitemaps;
use Pimcore\Localization\LocaleServiceInterface;
use Pimcore\Model\DataObject\News;
use Pimcore\Model\Document;
use Pimcore\Sitemap\Element\AbstractElementGenerator;
use Pimcore\Sitemap\Element\GeneratorContext;
use Presta\SitemapBundle\Service\UrlContainerInterface;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class NewsGenerator extends AbstractElementGenerator
{
public function __construct(protected LocaleServiceInterface $localeService, array $filters = [], array $processors = [])
{
parent::__construct($filters, $processors);
}
public function populate(UrlContainerInterface $urlContainer, string $section = null)
{
if (null !== $section && $section !== 'news') {
// do not add entries if section doesn't match
return;
}
$section = 'news';
$list = new News\Listing();
$list->setOrderKey('date');
$list->setOrder('DESC');
// the context contains metadata for filters/processors
// it contains at least the url container, but you can add additional data
// with the params parameter
$context = new GeneratorContext($urlContainer, $section, ['foo' => 'bar']);
//change locale as per multilingual setup
$this->localeService->setLocale('en');
/** @var News $newsArticle */
foreach ($list as $newsArticle) {
// only add element if it is not filtered
if (!$this->canBeAdded($newsArticle, $context)) {
continue;
}
// use a link generator to generate an URL to the article
// you need to make sure the link generator generates an absolute url
$link = $newsArticle->getClass()->getLinkGenerator()->generate($newsArticle, [
'referenceType' => UrlGeneratorInterface::ABSOLUTE_URL,
'document' => Document::getByPath('/en/info/News')
]);
// create an entry for the sitemap
$url = new UrlConcrete($link);
// run url through processors
$url = $this->process($url, $newsArticle, $context);
// processors can return null to exclude the url
if (null === $url) {
continue;
}
// add the url to the container
$urlContainer->addUrl($url, $section);
}
}
}
ブログ記事のサイトマップジェネレータ作成
src/Sitemaps/BlogGenerator.php
<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/
namespace App\Sitemaps;
use Pimcore\Localization\LocaleServiceInterface;
use Pimcore\Model\DataObject\Blog;
use Pimcore\Model\Document;
use Pimcore\Sitemap\Element\AbstractElementGenerator;
use Pimcore\Sitemap\Element\GeneratorContext;
use Presta\SitemapBundle\Service\UrlContainerInterface;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class BlogGenerator extends AbstractElementGenerator
{
public function __construct(protected LocaleServiceInterface $localeService, array $filters = [], array $processors = [])
{
parent::__construct($filters, $processors);
}
public function populate(UrlContainerInterface $urlContainer, string $section = null)
{
if (null !== $section && $section !== 'blog') {
// do not add entries if section doesn't match
return;
}
$section = 'blog';
$list = new Blog\Listing();
$list->setOrderKey('date');
$list->setOrder('DESC');
// the context contains metadata for filters/processors
// it contains at least the url container, but you can add additional data
// with the params parameter
$context = new GeneratorContext($urlContainer, $section, ['foo' => 'bar']);
//change locale as per multilingual setup
$this->localeService->setLocale('en');
/** @var Blog $blogArticle */
foreach ($list as $blogArticle) {
// only add element if it is not filtered
if (!$this->canBeAdded($blogArticle, $context)) {
continue;
}
// use a link generator to generate an URL to the article
// you need to make sure the link generator generates an absolute url
$link = $blogArticle->getClass()->getLinkGenerator()->generate($blogArticle, [
'referenceType' => UrlGeneratorInterface::ABSOLUTE_URL,
'document' => Document::getByPath('/en/Blog')
]);
// create an entry for the sitemap
$url = new UrlConcrete($link);
// run url through processors
$url = $this->process($url, $blogArticle, $context);
// processors can return null to exclude the url
if (null === $url) {
continue;
}
// add the url to the container
$urlContainer->addUrl($url, $section);
}
}
}
絶対パスによるサイトマップ作成のための Processor を作成
src/Sitemaps/Processors/AbsoluteUrlProcessor.php
<?php
declare(strict_types=1);
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/
namespace App\Sitemaps\Processors;
use Pimcore\Model\Element\ElementInterface;
use Pimcore\Sitemap\Element\GeneratorContextInterface;
use Pimcore\Sitemap\Element\ProcessorInterface;
use Pimcore\Sitemap\UrlGeneratorInterface;
use Presta\SitemapBundle\Sitemap\Url\Url;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
class AbsoluteUrlProcessor implements ProcessorInterface
{
/**
* @var UrlGeneratorInterface
*/
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function process(Url $url, ElementInterface $element, GeneratorContextInterface $context)
{
$path = $this->urlGenerator->generateUrl($url->getLoc());
$url = new UrlConcrete($path);
return $url;
}
}
# bin/console presta:sitemaps:dump
Dumping sitemaps section blog into project_folder/public directory
Created/Updated the following sitemap files:
sitemap.default.xml
sitemap.news.xml
sitemap.blog.xml
sitemap.xml
ニュースまたはブログの各サイトマップジェネレータで指定したセクションを指定して出力
# bin/console presta:sitemaps:dump --section=news
or
# bin/console presta:sitemaps:dump --section=blog