承接 lcatlett/newrelic-guzzle-client 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

lcatlett/newrelic-guzzle-client

Composer 安装命令:

composer require lcatlett/newrelic-guzzle-client

包简介

A workaround for performance bottlenecks in Guzzle requests due to New Relic agent.

README 文档

README

This package provides a workaround to resolve performance and memory bottlenecks in Guzzle requests caused by the New Relic Agent's current implementation of metrics tracking middleware for Guzzle 6 clients.

⚠️ This library is a workaround relying on the current implementation of the New Relic extension!

Test it carefully before to use it with a new extension release.

See Overview section below for more details.

Installation

composer require lcatlett/newrelic-guzzle-client

That's all! The script is automatically imported thanks to Composer autoloader.

Without Composer

ℹ️ You can also copy the file NewRelicGuzzle.php and include directly in your project. For example, WordPress sites not using Composer can add this file by adding a require(/path/to/newrelic-guzzle-client/NewRelicGuzzle.php) at the top of wp-config.php.

Overview

The newrelic extension defines a Php function, a Guzzle middleware to report some metrics on each requests sent from Php.

The current implementation of the New Relic agent extension registers the Guzzle middleware on every new client instance and wraps the request in curl_exec rather than curl_multi_exec or a stream. This results in performance issues and memory exhaustion as middleware is re-registered on every request which are then wrapped into a single call.

Issues seen on Pantheon customer sites include increased memory usage and request times, particularly for requests intended to be asyncronous actually being blocking calls. These bottlenecks can often be seen in the Pantheon application container php-slow.log files where newrelic\Guzzle6 is invoked:

[20-Mar-2024 01:14:07]  [pool www] pid 10017
script_filename = /code/web//index.php
[0x00007f9e4ee17230] curl_exec() /code/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php:40
[0x00007f9e4ee17190] __invoke() newrelic/Guzzle6:1
[0x00007f9e4ee16ff0] newrelic\Guzzle6\{closure}() /code/vendor/guzzlehttp/guzzle/src/Middleware.php:233
[0x00007f9e4ee16f50] GuzzleHttp\{closure}() /code/vendor/guzzlehttp/guzzle/src/HandlerStack.php:71
[0x00007f9e4ee16ec0] __invoke() /code/vendor/guzzlehttp/guzzle/src/Client.php:351
[0x00007f9e4ee16db0] transfer() /code/vendor/guzzlehttp/guzzle/src/Client.php:112
[0x00007f9e4ee16d30] sendAsync() /code/vendor/guzzlehttp/guzzle/src/Client.php:129
[0x00007f9e4ee16cb0] send() /code/web/modules/contrib/search_api_pantheon/src/Services/PantheonGuzzle.php:92
[0x00007f9e4ee16c40] sendRequest() /code/vendor/solarium/solarium/src/Core/Client/Adapter/Psr18Adapter.php:66
[0x00007f9e4ee16ae0] execute() /code/vendor/solarium/solarium/src/Core/Client/Client.php:846
[0x00007f9e4ee16a30] executeRequest() /code/web/modules/contrib/search_api_pantheon/src/Services/SolariumClient.php:61
[0x00007f9e4ee169b0] executeRequest() /code/vendor/solarium/solarium/src/Core/Client/Client.php:817
[0x00007f9e4ee168e0] execute() /code/web/modules/contrib/search_api_pantheon/src/Services/SolariumClient.php:49
[0x00007f9e4ee16860] execute() /code/web/modules/contrib/search_api_solr/src/SolrConnector/SolrConnectorPluginBase.php:974
[0x00007f9e4ee167d0] execute() /code/web/modules/contrib/search_api_solr/src/SolrConnector/SolrConnectorPluginBase.php:938
[0x00007f9e4ee16730] update() /code/web/modules/contrib/search_api_solr/src/Plugin/search_api/backend/SearchApiSolrBackend.php:1129
[0x00007f9e4ee165e0] indexItems() /code/web/modules/contrib/search_api/src/Entity/Server.php:350
[0x00007f9e4ee16510] indexItems() /code/web/modules/contrib/search_api/src/Entity/Index.php:994
[0x00007f9e4ee163c0] indexSpecificItems() /code/web/modules/contrib/search_api/src/Entity/Index.php:930
[0x00007f9e4ee16290] indexItems() /code/web/modules/contrib/search_api/search_api.module:116

The above example is when the Pantheon Search API indexes content. An additional example is when the tmgmt_smartling module syncs translations:

[16-Mar-2024 02:32:50]  [pool www] pid 3593
script_filename = /code/web//index.php
[0x00007f6e9d617100] curl_exec() /code/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php:44
[0x00007f6e9d617060] __invoke() /code/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php:28
[0x00007f6e9d616fb0] GuzzleHttp\Handler\{closure}() /code/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php:48
[0x00007f6e9d616f00] GuzzleHttp\Handler\{closure}() newrelic/Guzzle6:1
[0x00007f6e9d616d60] newrelic\Guzzle6\{closure}() /code/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php:35
[0x00007f6e9d616c80] __invoke() /code/vendor/guzzlehttp/guzzle/src/Middleware.php:31
[0x00007f6e9d616bd0] GuzzleHttp\{closure}() /code/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php:71
[0x00007f6e9d616b30] __invoke() /code/vendor/guzzlehttp/guzzle/src/Middleware.php:66
[0x00007f6e9d616a90] GuzzleHttp\{closure}() /code/vendor/guzzlehttp/guzzle/src/HandlerStack.php:75
[0x00007f6e9d616a00] __invoke() /code/vendor/guzzlehttp/guzzle/src/Client.php:333
[0x00007f6e9d6168b0] transfer() /code/vendor/guzzlehttp/guzzle/src/Client.php:169
[0x00007f6e9d6167d0] requestAsync() /code/vendor/guzzlehttp/guzzle/src/Client.php:189
[0x00007f6e9d616740] request() /code/vendor/smartling/api-sdk-php/src/BaseApiAbstract.php:491
[0x00007f6e9d6165f0] sendRequest() /code/vendor/smartling/api-sdk-php/src/ProgressTracker/ProgressTrackerApi.php:61
[0x00007f6e9d616560] getToken() /code/web/modules/contrib/tmgmt_smartling/src/Smartling/ConfigManager/FirebaseConfigManager.php:69
[0x00007f6e9d616460] getAvailableConfigs() /code/web/modules/contrib/tmgmt_smartling/tmgmt_smartling.module:886
[0x00007f6e9d6163c0] tmgmt_smartling_page_attachments() /code/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php:311
[0x00007f6e9d616340] Drupal\Core\Render\MainContent\{closure}() /code/web/core/lib/Drupal/Core/Extension/ModuleHandler.php:388
[0x00007f6e9d616280] invokeAllWith() /code/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php:312
[0x00007f6e9d6161f0] invokePageAttachmentHooks() /code/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php:285

Relevant New Relic Issues

There are some longstanding issues in the https://github.com/newrelic/newrelic-php-agent issue queue which are likely related to this problem:

Note: This workaround will need to be refactored when Guzzle 7 support is added to the New Relic Agent: newrelic/newrelic-php-agent#498

统计信息

  • 总下载量: 3.12k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 2
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-03-21