Tư vấn cấu hình PHP-FPM

Discussion in 'Hỏi Đáp Kỹ Thuật' started by command, Oct 30, 2021.

  1. command

    command Bang Chúng

    Chào ae,

    Server Ubuntu mình có sử dụng hơn 400MB swap, trong khi RAM vật lý mới sử dụng 29/62 GB (khoảng 47% RAM vật lý). Tức RAM vật lý vẫn còn dư khá nhiều, mà sao có process lại chạy trên Swap, và vm.swappiness = 10. Mình hiểu khi swappiness = 10 thì mình nghĩ khi nào sử dụng hơn 90% RAM vật lý mới sử dụng tới Swap chứ.

    Sau đó, mình check thử process nào đang chạy trên Swap thì có nhiều php-fpm chạy:
    Về PHP-FPM, mình để mặc định và chỉ cấu hình lại file /etc/php/7.4/fpm/pool.d/www.conf các thông số sau:
    Vậy mình nên cấu hình PHP-FPM thế nào hoặc cấu hình server thông số nào để process này ko chạy trên Swap nữa?

    Bổ sung thêm: Nếu restart 2 dịch vụ php-fpm và nginx thì ban đầu 2 dịch vụ này ko có process nào trên Swap, nhưng tầm hơn 12h thì lại các process lại chạy trên Swap, chứng tỏ có gì đó sai sai ở đây.

    Mong nhận tư vấn của ae! Xin cám ơn,
     
    Last edited: Oct 31, 2021
  2. Phan Thị

    Phan Thị Bang Chúng

    Thế đơn giản là nếu ram thừa nhiều vậy thì tắt swap đi.
     
  3. money

    money Hương Chủ

    Em đang cấu hình giá trị nào cho pm ?
     
  4. command

    command Bang Chúng

    Mình chưa nghĩ đến giải pháp này, giải pháp này khắc phục trong ngắn hạn, còn dài hạn thì mình cần tìm ra cách khắc phục triệt để tình trạng này. Vì tại thời điểm này RAM sử dụng giả sử 47% nhưng thời điểm khác nó có thể lên hơn 90% và hơn nữa thì hãy sử dụng Swap tạm trong khi chờ giải pháp nâng cấp server để thêm RAM nếu tình trạng sử dụng hơn 90% ở 1 khoảng thời gian dài.

    pm là gì vậy a? hay giá trị pm trong PHP-FPM hở anh? Nếu thế thì pm = dynamic

    Full config của PHP-FPM thì như sau:
     
  5. money

    money Hương Chủ

    @command uh, để dynamic là ổn. Ban đầu anh nghĩ em để static thì nó luôn khởi tạo max processes nên gây memory leaks.
    Em xem lại trong cả ngày xem có lúc nào bị quá tải RAM hay không chứ cấu hình như này anh thấy không vấn đề gì với thông tin cpu và ram của em.
     
  6. command

    command Bang Chúng

    Làm sao mình check đc cả ngày CPU, RAM diễn biến thế nào và process nào chạy vào lúc đó được vậy a? A dùng phần mềm nào để giám sát thông số này? E chưa cài phần mềm giám sát bao giờ.

    Nếu restart 2 dịch vụ php-fpm và nginx thì ban đầu 2 dịch vụ này ko có process nào trên Swap, nhưng tầm hơn 12h thì lại các process lại chạy trên Swap, chứng tỏ có gì đó sai sai ở đây.
     
  7. money

    money Hương Chủ

    @command CPU, traffic thì có phần monitoring của hosting provider cung cấp (hetzner, vultr, ovh anh nhớ là có)

    À mà chỉ check usage chung chung chứ ko check dc process nào usage bao nhiêu.

    Riêng RAM anh không nhớ có hay không. Tuy nhiên, nếu không có, thì chắc là sẽ có tool (em tự search) hoặc là tự mình viết cái cronjob 1 phút ghi lại thông tin 1 lần vào file chắc cũng được.
    --- Double Post Merged, Oct 31, 2021, Original Post Date: Oct 31, 2021 ---
    Càng nghi ngờ:
    - có lúc nào đó em dùng hết RAM (nên tracking lại để theo dõi)
    - xem lại code em có quên free memory không (tạo image quên destroy, mở connection đến database mà quên đóng …)
    --- Double Post Merged, Oct 31, 2021 ---
    Anh mới xem lại cấu hình trên con AX41 của anh, có vẻ em cấu hình các chỉ số cao hơn anh

    Code:
    ; Note: This value is mandatory.
    pm = dynamic
    
    ; The number of child processes to be created when pm is set to 'static' and the
    ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
    ; This value sets the limit on the number of simultaneous requests that will be
    ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
    ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
    ; CGI. The below defaults are based on a server without much resources. Don't
    ; forget to tweak pm.* to fit your needs.
    ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
    ; Note: This value is mandatory.
    pm.max_children = 100
    
    ; The number of child processes created on startup.
    ; Note: Used only when pm is set to 'dynamic'
    ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
    pm.start_servers = 20
    
    ; The desired minimum number of idle server processes.
    ; Note: Used only when pm is set to 'dynamic'
    ; Note: Mandatory when pm is set to 'dynamic'
    pm.min_spare_servers = 5
    
    ; The desired maximum number of idle server processes.
    ; Note: Used only when pm is set to 'dynamic'
    ; Note: Mandatory when pm is set to 'dynamic'
    pm.max_spare_servers = 35
    
    ; The number of seconds after which an idle process will be killed.
    ; Note: Used only when pm is set to 'ondemand'
    ; Default Value: 10s
    ;pm.process_idle_timeout = 10s;
    Server:

    upload_2021-10-31_14-36-34.png
     
  8. command

    command Bang Chúng

    E có chủ động đóng file, image, DB sau khi dùng xong hết rồi. Có thể vấn đề nằm ở chổ khác.

    E mới giảm lại cấu hình cho PHP-FPM cho giống a, đợi thử xem phải do tạo số
    max_children, min_spare_servers nhiều hơn làm phát sinh vấn đề ko? A cho e xin tham khảo cấu hình MySQL và Nginx luôn với :)

    Ghi thông số sơ sơ mà a đoán ra dòng AX41 luôn nhé, a hay thật :)

    Server này a chịu tải được tổng bao nhiêu requests/day với Cloudflare vậy a?
     
    Last edited: Oct 31, 2021
  9. money

    money Hương Chủ

    @command server đó anh chọn ssd. Hiện có 2 sites trên đó là nhiều requests. Một số site khác nhưng không đáng kể.
    Để lát anh ngồi laptop anh share config nginx và mysql em xem.
    Hình dưới mà report 7 days của CF.
     

    Attached Files:

  10. command

    command Bang Chúng

    Ôi, server cùng cấu hình AX41-NVME mà server a chịu hơn 4M requests/day. Còn server này của e mới chịu có khoảng 1M requests/day thôi mà nhiều vấn đề rồi, và Googlebot trong GSC báo trong 1 ngày có khoảng 300/50k lỗi 4xx. Khi e truy cập url đó thì bình thường, nên tại thời điểm Googlebot vào thì server có vấn đề gì nên mới lỗi mà cay 1 cái là logs trong Nginx error thì ko có lỗi gì cả. Có lẽ do code hoặc cấu hình server bên e có vấn đề rồi nên cố gắng tìm hiểu nguyên nhân.
     
    Last edited: Oct 31, 2021
  11. money

    money Hương Chủ

    @command mysql và nginx anh không cấu hình gì đặc biệt cả. Mấy cái phần cấu hình của mysql trong đoạn ########## Andy Configurations ########## là anh đã comment out rồi, không dùng đến

    mysql:

    Code:
    # For advice on how to change settings please see
    # http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html
    
    [mysqld]
    
    ft_min_word_len=1
    ft_stopword_file=''
    
    local_infile=1
    
    #Andy: speedup restore database
    skip-log-bin
    
    #
    # Remove leading # and set to the amount of RAM for the most important data
    # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
    # innodb_buffer_pool_size = 128M
    #
    # Remove the leading "# " to disable binary logging
    # Binary logging captures changes between backups and is enabled by
    # default. It's default setting is log_bin=binlog
    # disable_log_bin
    #
    # Remove leading # to set options mainly useful for reporting servers.
    # The server defaults are faster for transactions and fast SELECTs.
    # Adjust sizes as needed, experiment to find the optimal values.
    # join_buffer_size = 128M
    # sort_buffer_size = 2M
    # read_rnd_buffer_size = 2M
    #
    # Remove leading # to revert to previous value for default_authentication_plugin,
    # this will increase compatibility with older clients. For background, see:
    # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
    # default-authentication-plugin=mysql_native_password
    
    
    ########## Andy Configurations ##########
    
    #myisam_sort_buffer_size = 1024M
    #myisam_sort_buffer_size = 1024M
    
    
    #max_connections = 1024
    
    #sort_buffer_size = 1024M
    #key_buffer_size = 1024M
    #read_buffer_size = 1024M
    #join_buffer_size = 1024M
    #read_rnd_buffer_size = 1024M
    #bulk_insert_buffer_size = 1024M
    
    #thread_concurrency = 16
    
    #tmp_table_size = 1024M
    #max_heap_table_size = 1024M
    #max_allowed_packet = 512M
    #query_cache_limit = 64M
    #query_cache_size = 1024M
    #connect_timeout = 60
    #thread_cache_size = 32
    
    ############################################
    
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock
    
    log-error=/var/log/mysqld.log
    pid-file=/var/run/mysqld/mysqld.pid
    
    [client]
    loose-local-infile=1
    nginx.conf:

    Code:
    # For more information on configuration, see:
    #   * Official English Documentation: http://nginx.org/en/docs/
    #   * Official Russian Documentation: http://nginx.org/ru/docs/
    
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    
    # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
    include /usr/share/nginx/modules/*.conf;
    
    events {
        worker_connections 1024;
    }
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 4096;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        # Load modular configuration files from the /etc/nginx/conf.d directory.
        # See http://nginx.org/en/docs/ngx_core_module.html#include
        # for more information.
        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
       
        server {
            listen       80;
            listen       [::]:80;
            server_name  _;
            root         /usr/share/nginx/html;
    
            # Load configuration files for the default server block.
            include /etc/nginx/default.d/*.conf;
    
            error_page 404 /404.html;
            location = /404.html {
            }
    
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
            }
        }
    
    # Settings for a TLS enabled server.
    #
    #    server {
    #        listen       443 ssl http2;
    #        listen       [::]:443 ssl http2;
    #        server_name  _;
    #        root         /usr/share/nginx/html;
    #
    #        ssl_certificate "/etc/pki/nginx/server.crt";
    #        ssl_certificate_key "/etc/pki/nginx/private/server.key";
    #        ssl_session_cache shared:SSL:1m;
    #        ssl_session_timeout  10m;
    #        ssl_ciphers HIGH:!aNULL:!MD5;
    #        ssl_prefer_server_ciphers on;
    #
    #        # Load configuration files for the default server block.
    #        include /etc/nginx/default.d/*.conf;
    #
    #        error_page 404 /404.html;
    #            location = /40x.html {
    #        }
    #
    #        error_page 500 502 503 504 /50x.html;
    #            location = /50x.html {
    #        }
    #    }
    
    }
    
    
    default.conf


    Code:
    server {
        listen       80;
        server_name  xxx_IP_address;
    
        root /xxx/default;
        index index.php index.html index.htm;
    
        location / {
            try_files $uri $uri/ =404;
        }
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
    
        location = /50x.html {
            root /xxx/default;
        }
    
        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            try_files $uri =404;
            include fastcgi_params;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            #fastcgi_pass   127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
     
  12. command

    command Bang Chúng

    Thanks anh @money xem qua config của các softs a, e nghĩ ko phải cấu hình softs gây ra lỗi Swap trên rồi, để e tìm cách ghi nhật lý RAM trong ngày để biết lúc quá 90% thì process nào chiếm tài nguyên nhất và lần mò dấu vết vậy.

    À, Site này e dùng MongoDB.
    --- Double Post Merged, Nov 1, 2021, Original Post Date: Oct 31, 2021 ---
    Tới giờ mới để ý php-fpm của bên a sử dụng có khoảng 12MB/process. Còn bên e thì khoảng 35MB/process, chứng tỏ do code lỡm hơn của a rồi. Hình như anh @money dùng PHP thuần mà ko sử dụng PHP framework phải ko a? Dù e chọn PHP CodeIgniter thì cũng được hàng top performance trong PHP Framework rồi.

    Ngoài ra, còn 1 vấn đề khác, e xem lại HDH CentOS 8 của 1 server cũ khác thì có vẻ khoảng sử dụng RAM hiệu năng và giải phóng RAM tốt hơn so với Ubuntu 20.04. Dù ko sử dụng chung code nên rất khó so sánh vấn đề này. Như e đã logs output của glances (pm giám sát) thì thấy vấn đề RAM vật lý vẫn còn nhưng đã sử dụng Swap rồi, chuyện này khó hiểu vì sao. Khổ cái CentOS chuẩn bị ko còn bảo trì chính hãng nên giờ khi setup server mới nên toàn dùng Ubuntu 20.04.
     
    Last edited: Nov 1, 2021
    money likes this.
  13. TheLooter

    TheLooter Khách Qua Đường

    Chạy script này để xem thằng nào ngốn nhiều ram: hxxps:// raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py
    Muốn có perform tốt và ổn định thì disable swap như bro trên đã tư vấn, và limit maximum allocated ram của các service khác, khi dùng hết allocated này các service đó sẽ tự mò đến disk -> tương tự như swap
    Ngoài ra nên "increase server limits"

    Edited:
    Có 1 số nơi tư vấn tránh leak ram, bằng emergency restart, theo kinh nghiệm mình khuyên kô nên dùng, do php fpm ko dùng quá nhiều ram, và cũng ko leak nhiều, check and comment out the followings:

    ;emergency_restart_threshold = 20
    ;emergency_restart_interval = 1m
    ;process_control_timeout = 10s

    Khi enable, sẽ có trường hợp các script đang chạy và bị kill-> kết quả trả về là trang trống, hoặc error 5xx, mà vụ này kô phải là ít, lại còn google bot đang crawl
     
    Last edited: Nov 19, 2021