怎样在PHP项目中实现SkyWalking?

wen java案例 2

在PHP项目中实现SkyWalking(现已成为Apache顶级项目)通常有两种主流方式:

怎样在PHP项目中实现SkyWalking?

使用SkyWalking PHP Agent(推荐)

安装步骤

安装C扩展
# 下载编译好的扩展(以Linux为例)
wget https://github.com/SkyAPM/SkyAPM-php-sdk/releases/download/v4.3.0/skywalking_agent-4.3.0-php7.4.so
# 放入PHP扩展目录
cp skywalking_agent-4.3.0-php7.4.so /usr/lib/php/20190902/
# 修改php.ini
extension=skywalking_agent.so
# 配置Agent
skywalking.agent.application_code=my_php_app
skywalking.agent.server_addr=127.0.0.1:11800
skywalking.agent.sample_n_per_3_secs=-1  # 全部采样
skywalking.agent.log_path=/tmp/skywalking
重启PHP服务
systemctl restart php-fpm
# 或
service php7.4-fpm restart

验证安装

// 检查扩展是否加载
php -m | grep skywalking
// 查看配置
php -i | grep skywalking

使用SkyAPM SDK手动埋点(推荐生产环境)

安装Composer依赖

composer require skyapm/skyapm

手动埋点示例

<?php
require_once 'vendor/autoload.php';
use SkyAPM\Agent;
use SkyAPM\Span;
use SkyAPM\Tracing;
// 初始化Agent
$agent = Agent::singleton();
$agent->config([
    'app_code' => 'my_php_app',
    'server_addr' => '127.0.0.1:11800',
    'sample_n_per_3_secs' => -1,
]);
// 创建入口Span(类似分布式追踪的根节点)
$entrySpan = new Span();
$entrySpan->start('web', 'POST /api/users');
$entrySpan->setOperationName('UserController@store');
try {
    // 创建子Span(数据库查询)
    $dbSpan = new Span();
    $dbSpan->start('db', 'MongoDB');
    $dbSpan->setOperationName('users.insert');
    // 执行数据库操作
    $result = $db->users->insertOne($userData);
    $dbSpan->end(); // 结束数据库Span
    // 调用外部服务
    $httpSpan = new Span();
    $httpSpan->start('http', 'curl');
    $httpSpan->setOperationName('GET /api/notify');
    $ch = curl_init('http://internal-api/notify');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    $httpSpan->end(); // 结束HTTP Span
} catch (\Exception $e) {
    $entrySpan->log(['event' => 'error', 'message' => $e->getMessage()]);
    $entrySpan->setError();
}
$entrySpan->end(); // 结束入口Span

框架集成(Laravel为例)

安装Laravel适配器

composer require skyapm/laravel-skyapm

发布配置文件

php artisan vendor:publish --provider="SkyAPM\Laravel\ServiceProvider"

配置.env

SKYWALKING_APP_CODE=laravel_app
SKYWALKING_SERVER_ADDR=127.0.0.1:11800
SKYWALKING_SAMPLE_N_PER_3_SECS=-1

自动注入中间件

app/Http/Kernel.php 中添加:

protected $middleware = [
    \SkyAPM\Laravel\Middleware::class,
    // ... 其他中间件
];

配置SkyWalking OAP后端

Docker部署OAP

# docker-compose.yml
version: '3'
services:
  skywalking-oap:
    image: apache/skywalking-oap-server:8.5.0
    ports:
      - "11800:11800"  # gRPC端口
      - "12800:12800"  # HTTP端口
    environment:
      SW_STORAGE: elasticsearch
      SW_ES_USER: elastic
      SW_ES_PASSWORD: changeme
  skywalking-ui:
    image: apache/skywalking-ui:8.5.0
    ports:
      - "8080:8080"
    depends_on:
      - skywalking-oap

配置PHP-FPM集成(关键)

Nginx配置

location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    # 传递Trace上下文(必须)
    fastcgi_param HTTP_SW8 $http_sw8;
    fastcgi_param HTTP_SW8_CORRELATION $http_sw8_correlation;
}

Apache配置

<VirtualHost *:80>
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/html/$1
    # 传递Trace header
    RequestHeader set SW8 "%{HTTP_SW8}e"
    RequestHeader set SW8-CORRELATION "%{HTTP_SW8_CORRELATION}e"
</VirtualHost>

最佳实践

上下文传播

// 跨进程传递Trace上下文
$headers = [];
$agent->inject($headers); // 注入到HTTP头
// 接收端提取
$agent->extract(getallheaders()); // 从HTTP头提取

性能采样控制

// 控制采样率(0-10000)
$agent->config([
    'sample_n_per_3_secs' => 100, // 每3秒采样100个请求
    'ignore_paths' => ['/healthz', '/metrics'], // 忽略健康检查端点
]);

日志集成(可选)

// 添加自定义日志标签
$span->addTag('user_id', $userId);
$span->addLog(['event' => 'cache_hit', 'key' => $cacheKey]);

监控验证

  1. 查看Agent日志/tmp/skywalking/skywalking_agent.log
  2. OAP Dashboardhttp://localhost:8080
  3. 命令行验证
    # 发送测试请求
    curl http://your-php-app/api/health

查看OAP日志

docker logs skywalking-oap --tail 50


## 8. 常见问题解决
### 问题1:Span未正常关闭
```php
// 确保所有Span都正确关闭
try {
    $span->start();
    // ... 业务代码
    $span->end(); // 在finally块中保证执行
} finally {
    if ($span->isRunning()) {
        $span->end();
    }
}

问题2:版本不兼容

# 检查PHP版本和扩展版本
php -v  # 需要>=7.2
skywalking_agent.so版本需要与OAP版本匹配

问题3:数据不显示

# 检查防火墙规则
telnet 127.0.0.1 11800  # 确认gRPC端口可达
# 查看OAP日志配置
vim /skywalking/config/application.yml
  • 快速接入:使用C扩展(注意PHP版本兼容性)
  • 生产环境:使用Composer包 + 手动埋点(更灵活控制)
  • 框架集成:优先使用框架适配器(如Laravel、Symfony)
  • 性能要求高:仅关键业务手动埋点,关闭全量采样

建议先在测试环境验证,确认Trace数据能够正常传输到SkyWalking OAP,再逐步接入生产环境。

抱歉,评论功能暂时关闭!