ads:

关注以下公众号查看更多文章

 

       phpfpm起多个进程的原因是因为在请求-响应期间单个phpfpm被阻塞,为了满足及时响应其他请求的需要而增加phpfpm的数量。为了减少单次请求消耗掉的时间,减少不必要的cpu、内存消耗,我们可以安装opcache和apcu。opcache可以避免每次请求都要读取php脚本文件生成opcode的过程。而apcu可以在多次不同的请求之间共享一些信息,避免每次请求查询这些公共信息造成额外的网络请求和数据库查询。

opcache

        在原有的docker镜像中安装opcache命令为

docker-php-ext-install opcache

        需要配置一下opcahce

zend_extension=opcache
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=44
opcache.interned_strings_buffer=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=72
opcache.use_cwd=1
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.consistency_checks=0
opcache.blacklist_filename=/src/.opcacheignore

opcache各个配置的含义如下:

opcache扩展位置
zend_extension=opcache.so
启用opcache
opcache.enable=1
使用共享内存大小
opcache.memory_consumption=200
字符串缓存大小
opcache.interned_strings_buffer=8
最大缓存文件数量
opcache.max_accelerated_files=8000
出现异常,立即释放全部内存
opcache.fast_shutdown=1
最大允许占用内存百分比,超过此限制会重启进程
opcache.max_wasted_percentage=20
如果置为1,则将当前路径加入到文件key中,以避免可能产生的同文件名的文件key冲突
opcache.use_cwd=1
文件检测周期
revalidate_freq=3600
启用文件缓存时间戳
opcache.validate_timestamps=1
黑名单中的文件描述的文件不会被opcache缓存
opcache.blacklist_filename

opcache的性能调优

php opcache缺点,PHP Opcache 注意事项以及调优

可以通过 opcache_get_status(false) 这个函数监控opcache的实际消耗,控制opcache给予的资源,目前返回信息如下

array(7) {
  ["opcache_enabled"]=>
  bool(true)
  ["cache_full"]=>
  bool(false)
  ["restart_pending"]=>
  bool(false)
  ["restart_in_progress"]=>
  bool(false)
  ["memory_usage"]=>
  array(4) {
    ["used_memory"]=>
    int(43161896)
    ["free_memory"]=>
    int(359491288)
    ["wasted_memory"]=>
    int(0)
    ["current_wasted_percentage"]=>
    float(0)
  }
  ["interned_strings_usage"]=>
  array(4) {
    ["buffer_size"]=>
    int(16777216)
    ["used_memory"]=>
    int(288256)
    ["free_memory"]=>
    int(16488960)
    ["number_of_strings"]=>
    int(6567)
  }
  ["opcache_statistics"]=>
  array(13) {
    ["num_cached_scripts"]=>
    int(18)
    ["num_cached_keys"]=>
    int(20)
    ["max_cached_keys"]=>
    int(130987)
    ["hits"]=>
    int(34)
    ["start_time"]=>
    int(1663285335)
    ["last_restart_time"]=>
    int(0)
    ["oom_restarts"]=>
    int(0)
    ["hash_restarts"]=>
    int(0)
    ["manual_restarts"]=>
    int(0)
    ["misses"]=>
    int(18)
    ["blacklist_misses"]=>
    int(0)
    ["blacklist_miss_ratio"]=>
    float(0)
    ["opcache_hit_rate"]=>
    float(65.384615384615)
  }
}

实际使用内存42m,字符串使用内存0.28m,我们可以给容器内存70m,最大浪费空间不能超过50/70 = 72%

apcu

安装apcu命令如下

pecl install apcu

需要配置一下apcu

extension=apcu
apc.enabled=1
apc.shm_segments=1
apc.shm_size=5M
apc.entries_hint=0
apc.ttl=3600
apc.gc_ttl=0
apc.slam_defense=0
apc.coredump_unmap=true

由于composer是每次请求都要去处理的依赖,可以使用acpu进行优化

composer install --no-dev -o --prefer-dist --no-scripts --no-suggest --classmap-authoritative --apcu-autoloader

通过 apcu_sma_info() 这个函数查看实际acpu内存的使用情况,我的是

array(4) {
  ["num_seg"]=>
  int(1)
  ["seg_size"]=>
  float(5242752)
  ["avail_mem"]=>
  float(5226136)
  ["block_lists"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      array(2) {
        ["size"]=>
        int(5226104)
        ["offset"]=>
        int(16712)
      }
    }
  }
}

一个 5242752 字节内存,可用 5226136 字节,使用了 16616 ,约0.02m,我们给1m内存就够用了

apcu常用的一些函数如下

<?php

// 设置一个缓存,失效时间单位为秒。时间可选,默认永不失效(非重启)
var_dump(apcu_store("bool_store", FALSE, 5));
var_dump(apcu_store("string_store", "string", 10));
var_dump(apcu_store("int_store", 999, 15));
var_dump(apcu_store("float_store", 99.99, 20));
var_dump(apcu_store("array_store", [1, 2, 3, 4, 5], 25));

// 更新一个key的值
$old = 1;
$new = 2;
apcu_add("cas", $old);
var_dump(apcu_cas("cas", $old, $new));

// 自增
apcu_add("inc", 1);
$success = false;
var_dump(apcu_inc("inc", 10, $success));
apcu_fetch("inc");
var_dump($success);

// 自减,可以为负数
apcu_add("dec", 100);
$success = false;
var_dump(apcu_dec("dec", 10, $success));
apcu_fetch("dec");
var_dump($success);

// 判断key是否存在,当参数为数组时返回数组,数组key为APCu缓存的key,值为bool类型true或false
apcu_add("int", 1);
apcu_add("string", "string");
var_dump(apcu_exists("int"));
var_dump(apcu_exists(["int", "string"]));

// 以原子方式获取或生成缓存
$entry = apcu_entry("entry", function ($key) {
    return ["entry" => "this is entry"];
}, 100);
var_dump($entry);
$success = false;
var_dump(apcu_fetch("entry", $success));
var_dump($success);

// 清除全部缓存
// var_dump(apcu_clear_cache());

 相关链接

手把手教你部署nginx+php

php和nginx镜像合并 && 代码打包到镜像

nginx-php镜像安装常用软件

yaf && yar微服务/hprose微服务 镜像初始化

常用开发工具:php_codesniffer代码规范检查&修复、phpstan语法检查、phpunit单元测试

.gitlab-ci.yaml自动镜像打包&&互联网企业规范化上线流程(上)

kustomize/kubectl自动镜像部署&&互联网企业规范化上线流程(下)

apisix网关、JMeter压测  

prometheus/grafana监控数据收集与展示

k8s容器网络性能调优

supervisor进程管理

安装opcache和apcu

APM性能监测工具skywalking

链路跟踪工具zipkin

phpfpm和nginx配置

php整合apollo配置中心

php rdkafka操作kafka消息队列

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐