Laravel - 创建站点地图太慢(Apache 和 Node.js 安装在同一台服务器上)

Laravel - Too slow sitemap creation (Apache and Node.js installed on the same server)

我正在 运行宁两个 Angular2+ 项目和一个 Laravel API服务器在一起。第一个 angular 项目是一个 public 用户网站 (启用 SSR),第二个 angular 项目是管理面板(未启用 SSR),这两个项目 运行 在 Laravel API 上。我在创建站点地图时遇到了一个奇怪的问题。

我正在使用 this 库创建站点地图,并且 Laravel API 运行 正在 Apache 服务器上运行。

问题是 站点地图创建过程花费了太多时间(4 月 70 秒) 在我的 angular 项目上 启用服务器端呈现 后出现此问题。如果我禁用 SSR,则不会出现该问题。 angular SSR 项目 运行ning 基于 Node.js,站点地图创建过程增加了 Node.js 资源使用(CPU 高达 85%),因此此过程需要 1 分钟才能完成。这很奇怪,因为 Laravel 在 Apache 服务器上 运行ning 并且管理员可以创建站点地图,因为管理面板没有启用 SSR,它不应该与 Node.js服务器。

这是我启用了 SSR 的 angular 项目(闲置时):

这是我的进程列表:

执行以下代码时获取的ss: $sitemap = SitemapGenerator::create($website->url)->getSitemap();

如您所见,节点进程正在消耗所有 CPU 资源。

我是如何理解站点地图生成性能变慢的?

站点地图生成代码在这里:

    if($posts == null || count($posts) == 0) {
        return 'Bu siteye ait link verisi bulunamadı.!';
    } else {
        $sitemap = SitemapGenerator::create($website->url)->getSitemap(); //<-- This line
            
        return;
        //code never reach here for testing purpose
        foreach ($posts as $post) {
            //do something
        }
    }

如果我评论 $sitemap = SitemapGenerator::create($website->url)->getSitemap(); 行,请求将在 2 秒内完成,否则将在 70 秒内完成。执行此代码时,Node.js cpu 使用率正在上升。

而且如果我用终端 sudo pm2 stop ssr.website 停止 SSR,我可以在 2 秒内生成我的站点地图。


那么这个请求和Node.js进程之间存在什么样的关系?

这是 Apache 的错误吗?

这是 Node.js 错误吗?或者与这个图书馆有关的东西?

我该如何解决?

我的启用 SSR 的网站的 Apache 配置文件:

    <VirtualHost *:80>
        ServerAdmin info@example.com
        DocumentRoot /var/www/html/example.com/dist/browser

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        ServerName example.com
        ServerAlias api.example.com

        <Directory /var/www/html/example.com>
            Options -Indexes +FollowSymLinks

            RewriteEngine on

            # Don't rewrite files or directories
            RewriteCond %{REQUEST_FILENAME} -f [OR]
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^ - [L]

            # Rewrite everything else to index.html to allow HTML5 state links
            RewriteRule ^ index.html [L]
        </Directory>
        ProxyPreserveHost On
        ProxyPass / http://localhost:4000/
        ProxyPassReverse / http://localhost:4000/
        ErrorDocument 403 https://example.com/403/
    </VirtualHost>

我的 Apache 配置文件 Laravel API:

    <VirtualHost *:80>
        ServerAdmin info@example.com
        DocumentRoot /var/www/html/api.example.com/public
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        ServerName api.example.com
        ServerAlias www.api.example.com

        <Directory /var/www/html/api.example.com/public>
            AllowOverride All
        </Directory>
    </VirtualHost>

我的环境;

服务器;

谢谢

据我了解,该库通过动态抓取网站来工作。我不知道你有多少页,但这可能需要一段时间,因为爬虫会导致 angular 通用呈现所有页面以检索链接。

如果禁用 SSR,我怀疑站点地图是否会按预期工作,因为爬虫将无法检索页面内容(因为没有 SSR,呈现的页面仅包含 js/css 链接)。

一个解决方案可能是自己生成站点地图:首先添加静态链接,然后使用您的 api 生成动态页面的 lsit (product/xxx, product/yyy)

制作您自己的站点地图,并通过将所有路线传递到您的视图,以任何您想要的方式(SSR 或非 SSR)简单地呈现您的站点地图。以您想要的方式过滤和排序:

为此使用 getRoutes 函数:

public function getSiteMap()
{
    $routeList = \Route::getRoutes();

    dd($routeList);

    // filter and sort code
}

https://laravel.com/api/8.x/Illuminate/Routing/RouteCollectionInterface.html#method_getRoutes

我将在此处打印我的输出作为示例:

Illuminate\Routing\RouteCollection {#29 ▼
  #routes: array:5 [▼
    "GET" => array:26 [▶]
    "HEAD" => array:26 [▶]
    "POST" => array:13 [▶]
    "PUT" => array:5 [▶]
    "DELETE" => array:7 [▶]
  ]
  #allRoutes: array:51 [▼
    "HEAD_ignition/health-check" => Illuminate\Routing\Route {#179 ▼
      +uri: "_ignition/health-check"
      +methods: array:2 [▶]
      +action: array:7 [▶]
      +isFallback: false
      +controller: null
      +defaults: []
      +wheres: []
      +parameters: null
      +parameterNames: null
      #originalParameters: null
      #lockSeconds: null
      #waitSeconds: null
      +computedMiddleware: null
      +compiled: Symfony\Component\Routing\CompiledRoute {#391 ▶}
      #router: Illuminate\Routing\Router {#26 ▶}
      #container: Illuminate\Foundation\Application {#2 ▶}
      #bindingFields: []
    }
  ...
  and more

我建议您打印它并探索那里的属性。我还建议您简单地对该数组进行过滤和排序,并呈现您自己的站点地图,而不是依赖于这种简单情况下的依赖项。