---                                                                                                                     一、先搞清楚飞腾是什么(大白话)

  ┌──────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │   概念   │                                              大白话解释                                              │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ 飞腾FT系 │ 国产ARM芯片,指令集是ARMv8/ARMv9,和手机CPU同根同源,但面向服务器                                    │
  │ 列       │                                                                                                      │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ aarch64  │ ARM 64位架构的代号,飞腾跑的就是这个                                                                 │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ NUMA     │ "非均匀内存访问",FT2500有16个NUMA节点,每个节点8个核心;进程跨节点访问内存会慢很多,就像你去隔壁城  │
  │          │ 市买早饭,太远了                                                                                     │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ JIT      │ PHP8的即时编译,把PHP代码编译成机器码直接跑;飞腾ARM64原生支持JIT(不像龙芯需要禁用)                │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ OPcache  │ PHP字节码缓存,把编译好的中间代码存内存里,省去重复解析                                              │
  ├──────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ 绑核     │ 把进程锁定在特定CPU核心上跑,防止它到处乱跳浪费时间                                                  │
  └──────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────┘

  飞腾处理器家族一览:

  ┌─────────────┬─────────┬──────────────┬───────────────────────────┐
  │    型号     │ 核心数  │     场景     │          注意点           │
  ├─────────────┼─────────┼──────────────┼───────────────────────────┤
  │ FT-2000/4   │ 4核     │ 桌面         │ 单路,NUMA简单            │
  ├─────────────┼─────────┼──────────────┼───────────────────────────┤
  │ FT-2000+/64 │ 64核    │ 服务器       │ 多NUMA节点,需绑核        │
  ├─────────────┼─────────┼──────────────┼───────────────────────────┤
  │ FT-2500     │ 64核/路 │ 高性能服务器 │ 16 NUMA节点,绑核至关重要 │
  ├─────────────┼─────────┼──────────────┼───────────────────────────┤
  │ D2000       │ 8核     │ 桌面/嵌入式  │ 兼容FT-2000/4设计         │
  └─────────────┴─────────┴──────────────┴───────────────────────────┘

  ---
  二、环境确认

  # 1. 确认架构(必须是 aarch64)
  uname -m
  # 期望输出:aarch64

  # 2. 查看飞腾CPU详情
  cat /proc/cpuinfo | grep "model name" | head -1
  # 期望类似:Phytium, FT-2000+/64

  # 3. 查看NUMA拓扑(这个对FT2500很重要!)
  numactl --hardware
  # 会显示有几个NUMA节点、每个节点多少核、各节点内存距离

  # 4. 查看操作系统(飞腾常用国产系统)
  cat /etc/os-release

  # 5. 查看GCC版本(需要9.3+才能完整支持ARMv8特性)
  gcc --version

  NUMA拓扑输出示例(FT2500双路):
  available: 16 nodes (0-15)
  node 0 cpus: 0 1 2 3 4 5 6 7
  node 0 size: 16126 MB
  node 0 free: 14200 MB
  ...
  node distances:
  node   0   1   2  ...
    0:  10  15  20  ...    # 10=本地,数字越大越远,代价越高

  ---
  三、安装编译依赖

  银河麒麟 V10 / 统信 UOS(Debian系)

  sudo apt update && sudo apt upgrade -y

  sudo apt install -y \
      build-essential \
      gcc \
      g++ \
      make \
      cmake \
      autoconf \
      bison \
      re2c \
      pkg-config \
      numactl \
      libnuma-dev \
      libxml2-dev \
      libssl-dev \
      libcurl4-openssl-dev \
      libpng-dev \
      libjpeg-dev \
      libwebp-dev \
      libfreetype-dev \
      libzip-dev \
      zlib1g-dev \
      libsqlite3-dev \
      libonig-dev \
      libreadline-dev \
      libsodium-dev \
      libgmp-dev \
      libffi-dev \
      libicu-dev \
      libbz2-dev \
      libxslt-dev

  中标麒麟 / openEuler / 华为云(Fedora/RPM系)

  sudo yum update -y

  sudo yum install -y \
      gcc \
      gcc-c++ \
      make \
      autoconf \
      bison \
      re2c \
      pkg-config \
      numactl \
      numactl-devel \
      libxml2-devel \
      openssl-devel \
      libcurl-devel \
      libpng-devel \
      libjpeg-devel \
      libwebp-devel \
      freetype-devel \
      libzip-devel \
      zlib-devel \
      sqlite-devel \
      oniguruma-devel \
      readline-devel \
      libsodium-devel \
      gmp-devel \
      libffi-devel \
      libicu-devel \
      bzip2-devel \
      libxslt-devel

  为什么要装 numactl? 飞腾NUMA架构的核心调优工具,没它PHP-FPM在跨NUMA访问时性能会差4倍。

  ---
  四、下载PHP源码并配置编译参数

  4.1 下载源码

  mkdir -p /opt/php-build
  cd /opt/php-build

  # 推荐PHP 8.3(ARM64 JIT最成熟)
  PHP_VERSION="8.3.10"
  wget "https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz"
  tar -xzf "php-${PHP_VERSION}.tar.gz"
  cd "php-${PHP_VERSION}"

  4.2 飞腾ARM64专用编译配置

  关键点: 飞腾是正宗ARM64,可以用 -march=armv8-a 开启ARM原生优化,还可以 开启JIT(龙芯不行,飞腾可以)。

  # 设置编译优化标志(飞腾ARM64专用)
  export CFLAGS="-O2 -march=armv8-a+simd -funroll-loops -fomit-frame-pointer"
  export CXXFLAGS="$CFLAGS"
  export LDFLAGS="-Wl,-O1"

  ./configure \
    --prefix=/usr/local/php \
    --with-config-file-path=/usr/local/php/etc \
    --with-config-file-scan-dir=/usr/local/php/etc/php.d \
    --with-libdir=lib64 \
    --enable-fpm \
    --with-fpm-user=www \
    --with-fpm-group=www \
    --enable-opcache \
    --enable-mysqlnd \
    --with-pdo-mysql=mysqlnd \
    --with-mysqli=mysqlnd \
    --with-pdo-sqlite \
    --with-openssl \
    --with-curl \
    --with-zlib \
    --enable-mbstring \
    --enable-bcmath \
    --enable-gd \
    --with-jpeg \
    --with-png \
    --with-webp \
    --with-freetype \
    --with-zip \
    --enable-soap \
    --enable-xml \
    --enable-json \
    --enable-ctype \
    --enable-tokenizer \
    --enable-fileinfo \
    --enable-dom \
    --enable-simplexml \
    --enable-xmlreader \
    --enable-xmlwriter \
    --enable-phar \
    --enable-filter \
    --enable-session \
    --with-readline \
    --enable-sockets \
    --enable-pcntl \
    --enable-posix \
    --with-sodium \
    --with-gmp \
    --enable-intl \
    --enable-calendar \
    --with-bz2 \
    --with-xsl \
    2>&1 | tee /opt/php-build/configure.log

  # 检查configure是否成功
  echo $?   # 输出0表示成功

  与龙芯配置的关键差异:

  ┌───────────────┬───────────────────────┬─────────────────────────────────────┐
  │     参数      │         龙芯          │                飞腾                 │
  ├───────────────┼───────────────────────┼─────────────────────────────────────┤
  │ JIT           │ --disable-opcache-jit │ 不加这个,JIT默认开启               │
  ├───────────────┼───────────────────────┼─────────────────────────────────────┤
  │ CFLAGS        │ 无特殊                │ -march=armv8-a+simd 利用ARM向量指令 │
  ├───────────────┼───────────────────────┼─────────────────────────────────────┤
  │ --with-libdir │ lib64                 │ lib64                               │
  ├───────────────┼───────────────────────┼─────────────────────────────────────┤
  │ config.guess  │ 必须更新              │ 无需,系统自带支持aarch64           │
  └───────────────┴───────────────────────┴─────────────────────────────────────┘

  ---
  五、编译和安装

  # 查看CPU核心数
  CORES=$(nproc)
  echo "使用 ${CORES} 个核心编译"

  # 开始编译
  make -j${CORES} 2>&1 | tee /opt/php-build/make.log

  # 检查编译错误(没输出说明成功)
  grep -E "^make.*Error" /opt/php-build/make.log

  # 安装
  sudo make install

  # 配置环境变量
  echo 'export PATH=/usr/local/php/bin:/usr/local/php/sbin:$PATH' | sudo tee -a /etc/profile
  source /etc/profile

  # 验证
  php -v

  ---
  六、PHP核心配置(飞腾ARM64优化版)

  6.1 复制基础配置

  cp /opt/php-build/php-8.3.10/php.ini-production /usr/local/php/etc/php.ini
  mkdir -p /usr/local/php/etc/php.d
  mkdir -p /var/log/php

  6.2 飞腾专属php.ini优化配置

  cat > /usr/local/php/etc/php.d/phytium-optimize.ini << 'EOF'
  ; ================================================
  ; 飞腾FT系列ARM64 PHP性能优化配置
  ; ================================================

  ; ===== OPcache 基础配置 =====
  ; 开启OPcache(必须)
  opcache.enable=1
  ; CLI也开启(对Swoole/WorkerMan等常驻进程有利)
  opcache.enable_cli=1
  ; 共享内存256MB(多核服务器可以给到512MB)
  opcache.memory_consumption=256
  ; 字符串缓冲区,减少重复字符串内存占用
  opcache.interned_strings_buffer=32
  ; 最多缓存文件数,含vendor目录(Laravel约8000个文件)
  opcache.max_accelerated_files=20000
  ; 生产环境关闭文件变动检查,提升性能(上线后手动清缓存)
  opcache.validate_timestamps=0
  opcache.revalidate_freq=0
  ; 保留注释(某些框架依赖注解)
  opcache.save_comments=1

  ; ===== JIT配置(飞腾ARM64原生支持!)=====
  ; JIT模式:tracing=追踪热点代码路径,比function模式更彻底
  ; 也可以用数字1255:C=1(CPU优化) R=2(全局寄存器分配) T=5(追踪JIT) O=5(最高优化级别)
  opcache.jit=tracing
  ; JIT缓冲区128MB(计算密集型业务可加到256MB)
  opcache.jit_buffer_size=128M

  ; ===== 大页(Huge Pages)优化 =====
  ; 降低TLB缺失率,飞腾多核场景效果明显
  ; 前提:系统层要先开启大页(见下方系统配置)
  opcache.huge_code_pages=1

  ; ===== 文件缓存(重启PHP后不用重新预热)=====
  opcache.file_cache=/tmp/php-opcache
  opcache.file_cache_consistency_checks=0

  ; ===== 预加载(PHP 7.4+,减少首次请求延迟)=====
  ; 指定预加载脚本(以Laravel为例,uncomment后填实际路径)
  ; opcache.preload=/var/www/html/preload.php
  ; opcache.preload_user=www

  ; ===== 基础性能配置 =====
  memory_limit=512M
  max_execution_time=60
  upload_max_filesize=128M
  post_max_size=128M
  realpath_cache_size=4096K
  realpath_cache_ttl=600

  ; ===== 错误日志(生产环境)=====
  display_errors=Off
  log_errors=On
  error_log=/var/log/php/error.log
  error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT

  ; ===== 时区 =====
  date.timezone=Asia/Shanghai
  EOF

  6.3 开启系统大页(Huge Pages)

  # 大页是什么:默认内存按4KB分页,大页按2MB分页
  # 好处:CPU的TLB(地址翻译缓存)条目变少,缺失率下降,内存访问更快
  # 飞腾多核服务器内存带宽压力大,大页效果尤其明显

  # 临时开启(重启失效)
  echo 512 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

  # 永久生效
  echo "vm.nr_hugepages=512" >> /etc/sysctl.conf
  sysctl -p

  # 验证
  cat /proc/meminfo | grep Huge
  # 输出应该包含:HugePages_Total: 512

  ---
  七、飞腾最关键的调优:NUMA绑核

  这是飞腾平台PHP调优最重要的一步,很多人忽略它,导致性能只有应有水平的1/4!

  7.1 为什么飞腾必须绑核(大白话)

  飞腾FT2500双路服务器内存结构(简化示意):

  Socket 0 (64核,8个NUMA节点,各8核)
  ├── NUMA Node 0: Core 0-7   ←→  内存A(就近访问,延迟10)
  ├── NUMA Node 1: Core 8-15  ←→  内存B(就近访问,延迟10)
  ├── NUMA Node 2: Core 16-23 ←→  内存C(就近访问,延迟10)
  ...
  Socket 1 (64核,8个NUMA节点,各8核)
  ├── NUMA Node 8: Core 64-71  ←→  内存I(就近访问)
  ...

  跨NUMA访问延迟:15~20(是本地的1.5~2倍)
  不绑核时PHP进程随机在16个节点乱跑,内存大量跨节点访问
  → IPC从正常的0.6跌到0.08,QPS只有应有水平的1/4

  7.2 查看NUMA拓扑

  # 查看NUMA节点和CPU分布
  numactl --hardware

  # 查看进程当前NUMA使用情况
  numastat -p $(pgrep php-fpm | head -1)

  # 查看NUMA节点的内存使用
  numastat

  7.3 创建NUMA感知的PHP-FPM启动脚本

  cat > /usr/local/bin/start-php-fpm-numa.sh << 'EOF'
  #!/bin/bash
  # 飞腾FT系列 NUMA感知的PHP-FPM启动脚本

  # 查询NUMA节点数量
  NUMA_NODES=$(numactl --hardware | grep "available:" | awk '{print $2}')
  echo "系统共有 ${NUMA_NODES} 个NUMA节点"

  # 飞腾FT2500双路典型部署:绑定到node0和node1(同一socket内相邻节点)
  # 根据实际NUMA拓扑调整节点编号
  NUMA_BIND_NODES="0,1"

  echo "将PHP-FPM绑定到NUMA节点: ${NUMA_BIND_NODES}"

  numactl \
      --cpunodebind=${NUMA_BIND_NODES} \
      --membind=${NUMA_BIND_NODES} \
      /usr/local/php/sbin/php-fpm \
      --nodaemonize \
      --fpm-config /usr/local/php/etc/php-fpm.conf

  EOF
  chmod +x /usr/local/bin/start-php-fpm-numa.sh

  7.4 修改systemd服务使用NUMA绑核

  cat > /etc/systemd/system/php-fpm.service << 'EOF'
  [Unit]
  Description=PHP FastCGI Process Manager (Phytium NUMA Optimized)
  After=network.target

  [Service]
  Type=forking
  PIDFile=/var/run/php-fpm.pid

  # 飞腾FT2500:绑定到NUMA node 0和1,避免跨socket内存访问
  # 根据实际numactl --hardware的输出调整
  ExecStart=/usr/bin/numactl --cpunodebind=0,1 --membind=0,1 \
      /usr/local/php/sbin/php-fpm \
      --fpm-config /usr/local/php/etc/php-fpm.conf

  ExecReload=/bin/kill -USR2 $MAINPID
  PrivateTmp=true
  LimitNOFILE=65535
  Restart=on-failure
  RestartSec=5

  [Install]
  WantedBy=multi-user.target
  EOF

  systemctl daemon-reload
  systemctl enable php-fpm

  7.5 多实例部署(高并发场景)

  对于飞腾FT2500这种超多核服务器,可以按NUMA节点部署多个PHP-FPM实例:

  # 每个NUMA节点一个PHP-FPM实例,各自使用本地内存
  # 前置:Nginx按端口或socket负载均衡到多个实例

  # 实例1:绑定NUMA node 0-1 (core 0-15),监听socket1
  cat > /etc/systemd/system/php-fpm-numa0.service << 'EOF'
  [Unit]
  Description=PHP-FPM Instance NUMA Node 0-1

  [Service]
  ExecStart=/usr/bin/numactl --cpunodebind=0,1 --membind=0,1 \
      /usr/local/php/sbin/php-fpm \
      --fpm-config /usr/local/php/etc/php-fpm-numa0.conf
  Restart=on-failure
  EOF

  # 实例2:绑定NUMA node 2-3 (core 16-31),监听socket2
  cat > /etc/systemd/system/php-fpm-numa1.service << 'EOF'
  [Unit]
  Description=PHP-FPM Instance NUMA Node 2-3

  [Service]
  ExecStart=/usr/bin/numactl --cpunodebind=2,3 --membind=2,3 \
      /usr/local/php/sbin/php-fpm \
      --fpm-config /usr/local/php/etc/php-fpm-numa1.conf
  Restart=on-failure
  EOF

  ---
  八、PHP-FPM进程池配置(飞腾多核优化)

  # 创建www用户
  groupadd www 2>/dev/null; useradd -g www -s /sbin/nologin -M www 2>/dev/null

  # 主配置
  cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

  # 进程池配置(飞腾多核优化版)
  cat > /usr/local/php/etc/php-fpm.d/www.conf << 'EOF'
  [www]
  user = www
  group = www

  ; Unix socket 比 TCP 快,推荐使用
  listen = /var/run/php-fpm/www.sock
  listen.owner = www
  listen.group = www
  listen.mode = 0660

  ; 飞腾多核服务器:dynamic模式,让系统自适应负载
  pm = dynamic

  ; 最大子进程数计算公式:
  ; 单个PHP-FPM进程内存约50-80MB
  ; 绑定2个NUMA节点,可用内存约32GB
  ; max_children = 可用内存(MB) / 单进程内存(MB) = 32768 / 64512
  ; 保守值取一半:256
  pm.max_children = 256

  ; 启动时创建进程数(建议 max_children 的 1/8)
  pm.start_servers = 32

  ; 最少保持空闲进程数
  pm.min_spare_servers = 16

  ; 最多保持空闲进程数
  pm.max_spare_servers = 64

  ; 每个进程处理1000个请求后重启(防内存泄漏)
  pm.max_requests = 1000

  ; 慢日志:请求超过2秒记录(排查慢接口)
  request_slowlog_timeout = 2s
  slowlog = /var/log/php/www-slow.log

  ; 状态页(Nginx监控用)
  pm.status_path = /fpm-status

  ; 进程空闲超时(秒)
  pm.process_idle_timeout = 60s

  ; 传递环境变量
  env[PATH] = /usr/local/php/bin:/usr/bin:/bin
  env[TMP] = /tmp
  env[TMPDIR] = /tmp
  env[TEMP] = /tmp

  ; 资源限制
  php_admin_value[memory_limit] = 512M
  php_admin_value[open_basedir] = /var/www/html:/tmp:/usr/local/php
  EOF

  # 创建日志目录
  mkdir -p /var/run/php-fpm /var/log/php
  chown www:www /var/run/php-fpm

  ---
  九、安装常用扩展

  9.1 Redis扩展

  cd /opt/php-build

  # 下载phpredis
  wget https://github.com/phpredis/phpredis/archive/refs/tags/6.0.2.tar.gz -O phpredis-6.0.2.tar.gz
  tar -xzf phpredis-6.0.2.tar.gz
  cd phpredis-6.0.2

  # phpize:准备扩展的构建环境
  /usr/local/php/bin/phpize

  # 编译
  ./configure --with-php-config=/usr/local/php/bin/php-config

  # ARM64优化编译
  CFLAGS="-O2 -march=armv8-a" make -j$(nproc)
  sudo make install

  echo "extension=redis.so" > /usr/local/php/etc/php.d/redis.ini

  # 验证
  php -m | grep -i redis

  9.2 Swoole扩展(飞腾ARM64原生支持协程)

  cd /opt/php-build

  # Swoole 5.x 已原生支持aarch64协程上下文切换(汇编实现)
  wget https://github.com/swoole/swoole-src/archive/refs/tags/v5.1.3.tar.gz -O swoole-5.1.3.tar.gz
  tar -xzf swoole-5.1.3.tar.gz
  cd swoole-src-5.1.3

  /usr/local/php/bin/phpize

  ./configure \
      --with-php-config=/usr/local/php/bin/php-config \
      --enable-swoole-curl \
      --enable-openssl \
      --with-openssl-dir=/usr \
      --enable-cares \
      --enable-swoole-pgsql

  CFLAGS="-O2 -march=armv8-a+simd" make -j$(nproc)
  sudo make install

  echo "extension=swoole.so" > /usr/local/php/etc/php.d/swoole.ini

  # 验证ARM64支持
  php --ri swoole | grep -E "arch|aarch64|context"

  Swoole在飞腾上的亮点: Swoole的协程上下文切换底层用汇编写的,5.x版本有专门的aarch64实现(context/asm/jump_aarch64_sysv
  _elf_gas.S),性能不输x86。

  9.3 ImageMagick扩展

  # 安装ImageMagick库(飞腾ARM64版本)
  sudo apt install -y libmagickwand-dev  # Debian系
  # 或
  sudo yum install -y ImageMagick-devel  # RPM系

  cd /opt/php-build
  wget https://pecl.php.net/get/imagick-3.7.0.tgz
  tar -xzf imagick-3.7.0.tgz
  cd imagick-3.7.0

  /usr/local/php/bin/phpize
  ./configure --with-php-config=/usr/local/php/bin/php-config
  make -j$(nproc)
  sudo make install

  echo "extension=imagick.so" > /usr/local/php/etc/php.d/imagick.ini

  9.4 MongoDB扩展

  /usr/local/php/bin/pecl install mongodb

  echo "extension=mongodb.so" > /usr/local/php/etc/php.d/mongodb.ini

  ---
  十、Nginx配置(配合飞腾多实例PHP-FPM)

  # 下载Nginx
  cd /opt
  wget http://nginx.org/download/nginx-1.26.2.tar.gz
  tar -xzf nginx-1.26.2.tar.gz
  cd nginx-1.26.2

  # 飞腾ARM64优化编译
  ./configure \
      --prefix=/usr/local/nginx \
      --with-http_ssl_module \
      --with-http_v2_module \
      --with-http_gzip_static_module \
      --with-http_stub_status_module \
      --with-http_realip_module \
      --with-stream \
      --with-stream_ssl_module \
      --with-cc-opt="-O2 -march=armv8-a" \
      --with-ld-opt="-Wl,-rpath,/usr/local/lib"

  make -j$(nproc)
  sudo make install

  # /usr/local/nginx/conf/nginx.conf(飞腾多核优化版)

  user www;
  # worker进程数 = CPU核心数(飞腾FT2500单路64核)
  worker_processes 64;

  # 将worker进程绑定到CPU(飞腾多核利用)
  # worker_cpu_affinity auto;  # Nginx 1.9.10+支持自动绑核
  worker_cpu_affinity auto;

  # 错误日志
  error_log /var/log/nginx/error.log warn;
  pid /var/run/nginx.pid;

  events {
      # 每个worker最大连接数
      worker_connections 4096;
      # 使用epoll(Linux最高效的IO多路复用)
      use epoll;
      # 一次接受所有新连接(飞腾高并发场景有利)
      multi_accept on;
  }

  http {
      include mime.types;
      default_type application/octet-stream;

      # 日志格式
      log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" $request_time';

      # 基础优化
      sendfile on;
      tcp_nopush on;
      tcp_nodelay on;
      keepalive_timeout 65;
      keepalive_requests 1000;

      # Gzip压缩
      gzip on;
      gzip_comp_level 4;
      gzip_types text/plain text/css application/json application/javascript;

      # 上游PHP-FPM(多NUMA实例负载均衡)
      upstream php_fpm {
          # 使用最少连接策略
          least_conn;
          # NUMA node 0-1 的 PHP-FPM 实例
          server unix:/var/run/php-fpm/www-numa0.sock weight=1;
          # NUMA node 2-3 的 PHP-FPM 实例
          server unix:/var/run/php-fpm/www-numa1.sock weight=1;
          # 单实例场景直接用:
          # server unix:/var/run/php-fpm/www.sock;
          keepalive 32;
      }

      server {
          listen 80;
          server_name _;
          root /var/www/html;
          index index.php index.html;

          access_log /var/log/nginx/access.log main;

          # PHP处理
          location ~ \.php$ {
              fastcgi_pass php_fpm;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              include fastcgi_params;

              fastcgi_connect_timeout 10;
              fastcgi_send_timeout 60;
              fastcgi_read_timeout 60;
              fastcgi_buffer_size 64k;
              fastcgi_buffers 8 64k;
          }

          # PHP-FPM状态监控(内网访问)
          location /fpm-status {
              allow 127.0.0.1;
              deny all;
              fastcgi_pass php_fpm;
              fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
              include fastcgi_params;
          }

          # 静态文件缓存
          location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
              expires 30d;
              add_header Cache-Control "public, no-transform";
          }
      }
  }

  ---
  十一、OPcache预加载(减少冷启动延迟)

  <?php
  // /var/www/html/preload.php
  // PHP-FPM启动时执行,把框架核心文件预编译进内存
  // 效果:首次请求不再需要解析这些文件,响应时间从200ms降到50ms

  declare(strict_types=1);

  $preloadDirs = [
      // Laravel框架核心
      __DIR__ . '/vendor/laravel/framework/src/Illuminate/Support',
      __DIR__ . '/vendor/laravel/framework/src/Illuminate/Http',
      __DIR__ . '/vendor/laravel/framework/src/Illuminate/Routing',
      __DIR__ . '/vendor/laravel/framework/src/Illuminate/Container',
      // ThinkPHP核心(如果用ThinkPHP)
      // __DIR__ . '/vendor/topthink/framework/src',
  ];

  $count = 0;
  foreach ($preloadDirs as $dir) {
      if (!is_dir($dir)) continue;

      $iterator = new RecursiveIteratorIterator(
          new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
      );

      foreach ($iterator as $file) {
          if ($file->getExtension() !== 'php') continue;

          $path = $file->getPathname();

          // 跳过测试文件(节省内存)
          if (strpos($path, '/test') !== false || strpos($path, '/Test') !== false) {
              continue;
          }

          if (opcache_compile_file($path)) {
              $count++;
          }
      }
  }

  // 预加载完成后输出日志
  error_log("OPcache预加载完成:共预加载 {$count} 个PHP文件");

  ; 在 phytium-optimize.ini 中添加
  opcache.preload=/var/www/html/preload.php
  opcache.preload_user=www

  ---
  十二、性能验证脚本

  #!/bin/bash
  # /usr/local/bin/phytium-php-check.sh
  # 飞腾PHP环境完整检查

  echo "=============================================="
  echo " 飞腾FT系列 PHP运行环境检查报告"
  echo "=============================================="

  # 1. 架构验证
  echo ""
  echo "【1】硬件环境"
  echo "CPU架构: $(uname -m)"
  echo "CPU型号: $(cat /proc/cpuinfo | grep 'model name' | head -1 | cut -d: -f2 | xargs)"
  echo "CPU核心: $(nproc) 个"
  echo "物理内存: $(free -g | awk '/^Mem:/{print $2}') GB"

  # 2. NUMA信息
  echo ""
  echo "【2】NUMA拓扑"
  if command -v numactl &>/dev/null; then
      NUMA_NODES=$(numactl --hardware | grep "available:" | awk '{print $2}')
      echo "NUMA节点数: ${NUMA_NODES}"
      numactl --hardware | grep "node.*size"
  else
      echo "警告:numactl未安装,无法查看NUMA信息"
  fi

  # 3. PHP信息
  echo ""
  echo "【3】PHP环境"
  PHP_BIN="/usr/local/php/bin/php"
  if [ -f "$PHP_BIN" ]; then
      echo "PHP版本: $($PHP_BIN -v | head -1)"
      echo "PHP路径: $PHP_BIN"
  else
      echo "错误:PHP未找到"
      exit 1
  fi

  # 4. OPcache和JIT
  echo ""
  echo "【4】OPcache/JIT状态"
  $PHP_BIN -r "
  \$status = opcache_get_status(false);
  if (!\$status) {
      echo 'OPcache: 未启用' . PHP_EOL;
  } else {
      echo 'OPcache: 已启用' . PHP_EOL;
      echo 'JIT状态: ' . (\$status['jit']['enabled'] ?? false ? '已启用' : '未启用(检查jit_buffer_size配置)') .
  PHP_EOL;
      if (isset(\$status['jit']['kind'])) {
          \$kinds = [0=>'禁用', 1=>'Function JIT', 2=>'Tracing JIT'];
          echo 'JIT模式: ' . (\$kinds[\$status['jit']['kind']] ?? '未知') . PHP_EOL;
      }
      echo 'OPcache内存使用: ' . round(\$status['memory_usage']['used_memory']/1024/1024, 2) . 'MB' . PHP_EOL;
      echo 'OPcache空闲内存: ' . round(\$status['memory_usage']['free_memory']/1024/1024, 2) . 'MB' . PHP_EOL;
      echo '已缓存文件数: ' . \$status['opcache_statistics']['num_cached_scripts'] . PHP_EOL;
  }
  "

  # 5. 扩展检查
  echo ""
  echo "【5】扩展状态"
  for EXT in opcache redis swoole pdo_mysql gd mbstring json curl zip; do
      STATUS=$($PHP_BIN -m | grep -w "$EXT" && echo "已安装" || echo "未安装")
      printf "  %-15s: %s\n" "$EXT" "$($PHP_BIN -m | grep -w "$EXT" > /dev/null && echo '✓ 已安装' || echo '✗ 未安装')"
  done

  # 6. PHP-FPM状态
  echo ""
  echo "【6】PHP-FPM服务"
  if systemctl is-active php-fpm &>/dev/null; then
      echo "PHP-FPM: 运行中"
      echo "进程数: $(pgrep -c php-fpm)"
  else
      echo "PHP-FPM: 未运行"
  fi

  # 7. 大页状态
  echo ""
  echo "【7】系统大页(Huge Pages)"
  HUGE_TOTAL=$(grep HugePages_Total /proc/meminfo | awk '{print $2}')
  HUGE_FREE=$(grep HugePages_Free /proc/meminfo | awk '{print $2}')
  echo "大页总数: ${HUGE_TOTAL}"
  echo "空闲大页: ${HUGE_FREE}"
  [ "$HUGE_TOTAL" -eq 0 ] && echo "警告:未开启大页,建议设置 vm.nr_hugepages=512"

  # 8. 简单性能基准
  echo ""
  echo "【8】PHP性能基准测试"
  $PHP_BIN -r "
  \$start = microtime(true);

  // 测试1:CPU计算
  \$sum = 0;
  for (\$i = 0; \$i < 1000000; \$i++) { \$sum += \$i; }
  \$t1 = round((microtime(true) - \$start) * 1000, 2);

  // 测试2:字符串操作
  \$start2 = microtime(true);
  \$str = '';
  for (\$i = 0; \$i < 10000; \$i++) { \$str .= 'PHP on Phytium FT '; }
  \$t2 = round((microtime(true) - \$start2) * 1000, 2);

  // 测试3:数组操作
  \$start3 = microtime(true);
  \$arr = range(1, 100000);
  shuffle(\$arr);
  sort(\$arr);
  \$t3 = round((microtime(true) - \$start3) * 1000, 2);

  echo '  100万次整数求和: ' . \$t1 . 'ms' . PHP_EOL;
  echo '  1万次字符串拼接: ' . \$t2 . 'ms' . PHP_EOL;
  echo '  10万元素排序:    ' . \$t3 . 'ms' . PHP_EOL;
  "

  echo ""
  echo "=============================================="
  echo " 检查完成"
  echo "=============================================="

  chmod +x /usr/local/bin/phytium-php-check.sh
  /usr/local/bin/phytium-php-check.sh

  ---
  十三、完整一键编译脚本

  #!/bin/bash
  # build_php_phytium.sh
  # 飞腾FT系列ARM64 PHP 8.3 一键编译安装脚本
  # 使用:chmod +x build_php_phytium.sh && sudo bash build_php_phytium.sh

  set -e

  PHP_VERSION="8.3.10"
  INSTALL_DIR="/usr/local/php"
  BUILD_DIR="/opt/php-build"
  PHP_USER="www"
  CORES=$(nproc)

  GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
  log_info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
  log_warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
  log_error() { echo -e "${RED}[ERRO]${NC} $1"; }

  # 验证架构
  ARCH=$(uname -m)
  if [ "$ARCH" != "aarch64" ]; then
      log_warn "当前架构为 $ARCH,本脚本针对飞腾aarch64优化,请确认"
  fi
  log_info "架构: $ARCH,CPU核心: $CORES"

  # 准备目录
  mkdir -p "$BUILD_DIR"
  cd "$BUILD_DIR"

  # 下载PHP源码
  if [ ! -f "php-${PHP_VERSION}.tar.gz" ]; then
      log_info "下载 PHP ${PHP_VERSION}..."
      wget -q "https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz"
  fi

  if [ ! -d "php-${PHP_VERSION}" ]; then
      log_info "解压源码..."
      tar -xzf "php-${PHP_VERSION}.tar.gz"
  fi

  cd "php-${PHP_VERSION}"

  # 飞腾ARM64编译优化标志
  export CFLAGS="-O2 -march=armv8-a+simd -funroll-loops -fomit-frame-pointer"
  export CXXFLAGS="$CFLAGS"
  export LDFLAGS="-Wl,-O1"

  log_info "开始configure配置..."
  ./configure \
      --prefix="$INSTALL_DIR" \
      --with-config-file-path="${INSTALL_DIR}/etc" \
      --with-config-file-scan-dir="${INSTALL_DIR}/etc/php.d" \
      --with-libdir=lib64 \
      --enable-fpm \
      --with-fpm-user="$PHP_USER" \
      --with-fpm-group="$PHP_USER" \
      --enable-opcache \
      --enable-mysqlnd \
      --with-pdo-mysql=mysqlnd \
      --with-mysqli=mysqlnd \
      --with-openssl \
      --with-curl \
      --with-zlib \
      --enable-mbstring \
      --enable-bcmath \
      --enable-gd \
      --with-jpeg \
      --with-zip \
      --enable-soap \
      --enable-xml \
      --enable-intl \
      --enable-sockets \
      --enable-pcntl \
      --enable-posix \
      --with-sodium \
      --with-gmp \
      --with-readline \
      --enable-calendar \
      2>&1 | tee "${BUILD_DIR}/configure.log"

  log_info "开始编译(${CORES}核并行)..."
  make -j"$CORES" 2>&1 | tee "${BUILD_DIR}/make.log"

  if grep -qE "^make.*Error" "${BUILD_DIR}/make.log"; then
      log_error "编译失败,请检查 ${BUILD_DIR}/make.log"
      exit 1
  fi

  log_info "安装PHP..."
  make install

  # 创建用户
  if ! id "$PHP_USER" &>/dev/null; then
      groupadd "$PHP_USER"
      useradd -g "$PHP_USER" -s /sbin/nologin -M "$PHP_USER"
  fi

  # 配置文件
  cp "${BUILD_DIR}/php-${PHP_VERSION}/php.ini-production" "${INSTALL_DIR}/etc/php.ini"
  mkdir -p "${INSTALL_DIR}/etc/php.d" /var/log/php /var/run/php-fpm
  cp "${INSTALL_DIR}/etc/php-fpm.conf.default" "${INSTALL_DIR}/etc/php-fpm.conf"
  cp "${INSTALL_DIR}/etc/php-fpm.d/www.conf.default" "${INSTALL_DIR}/etc/php-fpm.d/www.conf"

  # 写入飞腾优化配置
  cat > "${INSTALL_DIR}/etc/php.d/phytium-optimize.ini" << 'INIEOF'
  opcache.enable=1
  opcache.enable_cli=1
  opcache.memory_consumption=256
  opcache.interned_strings_buffer=32
  opcache.max_accelerated_files=20000
  opcache.validate_timestamps=0
  opcache.save_comments=1
  opcache.jit=tracing
  opcache.jit_buffer_size=128M
  opcache.huge_code_pages=1
  opcache.file_cache=/tmp/php-opcache
  memory_limit=512M
  date.timezone=Asia/Shanghai
  INIEOF

  # 创建opcache文件缓存目录
  mkdir -p /tmp/php-opcache
  chown www:www /tmp/php-opcache

  # 环境变量
  if ! grep -q "${INSTALL_DIR}/bin" /etc/profile; then
      echo "export PATH=${INSTALL_DIR}/bin:${INSTALL_DIR}/sbin:\$PATH" >> /etc/profile
  fi

  log_info "==========================================="
  log_info "飞腾FT系列 PHP ${PHP_VERSION} 安装完成!"
  log_info ""
  log_info "执行以下命令使环境变量生效:"
  log_info "  source /etc/profile"
  log_info ""
  log_info "启动NUMA优化的PHP-FPM:"
  log_info "  numactl --cpunodebind=0,1 --membind=0,1 \\"
  log_info "    ${INSTALL_DIR}/sbin/php-fpm"
  log_info ""
  log_info "验证安装:"
  log_info "  php -v && php -m | grep opcache"
  log_info "==========================================="

  ---
  十四、飞腾 vs 龙芯 配置对比速查

  ┌───────────────┬──────────────────────────────┬────────────────────────────────┐
  │    配置项     │        飞腾FT (ARM64)        │        龙芯 (LoongArch)        │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ JIT           │ 可以开启 opcache.jit=tracing │ 必须禁用 --disable-opcache-jit │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ CFLAGS        │ -march=armv8-a+simd          │ 无特殊优化标志                 │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ NUMA调优      │ 必须做,FT2500有16个NUMA节点 │ 一般不需要                     │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ config.guess  │ 系统自带支持aarch64          │ 必须手动更新                   │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ 大页          │ 支持,效果明显               │ 支持                           │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ Swoole        │ 原生支持aarch64协程(v5.x)  │ 需要v5.0.3+                    │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ PHP-FPM进程数 │ 可开到256+(多核优势)       │ 保守一些                       │
  ├───────────────┼──────────────────────────────┼────────────────────────────────┤
  │ 性能短板      │ 跨NUMA内存访问(绑核解决)   │ 单核性能偏弱                   │
  └───────────────┴──────────────────────────────┴────────────────────────────────┘

  ---
  十五、常见问题排查

  # 问题1:JIT开启后Segfault崩溃
  # 原因:内存不足或JIT buffer太大
  # 解决:
  opcache.jit_buffer_size=64M  # 先减小,逐步加大

  # 问题2:PHP-FPM进程CPU占用高但QPS低
  # 原因:跨NUMA内存访问(飞腾最常见问题)
  # 解决:
  numastat -p $(pgrep php-fpm | head -1)  # 查看NUMA命中率
  # 如果miss很高,执行绑核

  # 问题3:OPcache文件缓存报Permission Denied
  # 原因:文件缓存目录权限问题
  chown -R www:www /tmp/php-opcache

  # 问题4:编译时找不到库文件
  # 原因:aarch64库路径可能在lib64下
  export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH

  # 问题5:Swoole协程报错
  # 原因:旧版Swoole不支持aarch64汇编上下文
  # 解决:升级Swoole到5.x版本
  php --ri swoole | grep version

  ---
  总结:飞腾PHP调优核心三板斧

  第一斧:开启JIT(飞腾ARM64原生支持)
  opcache.jit=tracing
  opcache.jit_buffer_size=128M
  → CPU密集型任务提升30-100%

  第二斧:NUMA绑核(飞腾特有杀手锏)
  numactl --cpunodebind=0,1 --membind=0,1 php-fpm
  → QPS提升最高4倍,这是最大的性能杠杆

  第三斧:大页+预加载(锦上添花)
  opcache.huge_code_pages=1
  opcache.preload=/path/to/preload.php
  → 减少TLB缺失,消除冷启动延迟

更多推荐