程序员@老李 - PHP https://blog.mostion.com/category/php/ CentOS yum 安装lnmp相关配置 https://blog.mostion.com/archives/36/ 2023-11-09T13:18:21+08:00 查看系统版本cat /etc/os-release cat /etc/redhat-release rpm -q centos-release查看内核uname -a安装epelyum -y install epel-release rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7安装remi#remi源需要手动启用 rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi yum install -y yum-utils yum-config-manager --enable remi > /dev/null安装php71#!/bin/bash yum -y install \ openssl \ openssl-devel \ libmcrypt \ libmcrypt-devel \ php71 \ php71-php \ php71-php-gd \ php71-php-mysqlnd \ php71-php-mcrypt \ php71-php-imap \ php71-php-ldap \ php71-php-mbstring \ php71-php-pear \ php71-php-xml \ php71-php-xmlrpc \ php71-php-soap \ php71-php-bcmath \ php71-php-mcrypt \ php71-php-fpm \ php71-php-pecl-http \ php71-php-pecl-redis \ php71-php-opcache \ php71-php-pecl-zip //phpexcel 必须#!/bin/bash yum -y install \ openssl \ openssl-devel \ libmcrypt \ libmcrypt-devel \ php74 \ php74-php \ php74-php-gd \ php74-php-mysqlnd \ php74-php-mcrypt \ php74-php-imap \ php74-php-ldap \ php74-php-mbstring \ php74-php-pear \ php74-php-xml \ php74-php-xmlrpc \ php74-php-soap \ php74-php-bcmath \ php74-php-mcrypt \ php74-php-fpm \ php74-php-pecl-http \ php74-php-pecl-redis \ php74-php-opcache \ php74-php-pecl-zip //phpexcel 必须 yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php71 php71-php php71-php-gd php71-php-mysqlnd php71-php-mcrypt php71-php-imap php71-php-ldap php71-php-mbstring php71-php-pear php71-php-xml php71-php-xmlrpc php71-php-soap php71-php-bcmath php71-php-mcrypt php71-php-fpm php71-php-pecl-http php71-php-pecl-redis php71-php-opcache php71-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php72 php72-php php72-php-gd php72-php-mysqlnd php72-php-mcrypt php72-php-imap php72-php-ldap php72-php-mbstring php72-php-pear php72-php-xml php72-php-xmlrpc php72-php-soap php72-php-bcmath php72-php-mcrypt php72-php-fpm php72-php-pecl-http php72-php-pecl-redis php72-php-opcache php72-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php73 php73-php php73-php-gd php73-php-mysqlnd php73-php-mcrypt php73-php-imap php73-php-ldap php73-php-mbstring php73-php-pear php73-php-xml php73-php-xmlrpc php73-php-soap php73-php-bcmath php73-php-mcrypt php73-php-fpm php73-php-pecl-http php73-php-pecl-redis php73-php-opcache php73-php-pecl-zip php73-php-pecl-redis4 php73-php-phalcon4yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php80 php80-php php80-php-gd php80-php-mysqlnd php80-php-mcrypt php80-php-imap php80-php-ldap php80-php-mbstring php80-php-pear php80-php-xml php80-php-xmlrpc php80-php-soap php80-php-bcmath php80-php-mcrypt php80-php-fpm php80-php-pecl-http php80-php-opcache php80-php-pecl-zip php80-php-pecl-redis5 php80-php-phalcon4#修改yum设置,让rpm包缓存到本地 vi /etc/yum.conf #修改keepcache为1 keepcache=1 #清空yum缓存 yum clean all #安装你要离线安装的rpm包 yum install xxx.rpm -y #rpm包缓存到了/var/cache/yum下面 cd /var/cache/yum find ./ -name *.rpm #找到你的rpm包,并拷走就可以离线安装了安装php56#!/bin/bash yum -y install \ libmcrypt \ libmcrypt-devel \ # libjpeg* \ php56 \ php56-php \ php56-php-gd \ php56-php-mysqlnd \ php56-php-mcrypt \ php56-php-imap \ php56-php-ldap \ php56-php-mbstring \ php56-php-pear \ php56-php-xml \ php56-php-xmlrpc \ php56-php-soap \ php56-php-bcmath \ php56-php-mcrypt \ php56-php-fpm \ php56-php-pecl-http \ php56-php-pecl-redis \ php56-php-opcache# 查看某个包的信息 yum --enablerepo=epel info htop # 列出epel信息 yum --disablerepo="*" --enablerepo="epel" list available | less安装MySQL访问地址 下载对应的rpm包http://dev.mysql.com/downloads/repo/yum/安装源wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm yum localinstall mysql80-community-release-el7-1.noarch.rpm手动启用想要的版本yum -y install mysql-community-server yum -y install mysql-community-client启动服务# 启动服务 systemctl start mysqld # 初始化 mysql_secure_installation初始密码cat /var/log/mysqld.logMySQL 2059错误alter user root@localhost identified by 'password' password expire never; alter user root@localhost identified with mysql_native_password by 'password'; flush privileges;安装开发工具包yum groupinstall "Development Tools" "Development Libraries" yum install gcc gcc-c++ gcc-g77 flex bison \ autoconf automake bzip2-devel zlib-devel \ ncurses-devel libjpeg-devel libpng-devel \ libtiff-devel freetype-devel pam-devel \ openssl-devel libxml2-devel gettext-devel \ pcre-devel系统服务目录/usr/lib/systemd/system/ #RPM包安装时分发的unit文件 /run/systemd/system/ #systemd运行时创建的文件 /etc/systemd/system/ #systemctl enable创建的unit文件Linux Headersredhat系列sudo yum -y install kernel-headers //安装kernel-headers sudo yum -y install kernel-devel //安装kernel-develdebian系列sudo apt-get install build-essential //install build-essential(optional) sudo apt-get update //install linux-headers sudo apt-get install linux-headers-$(uname -r) sudo apt-get update && sudo apt-get install build-essential linux-headers-$(uname -r)#discuz 安全 location ~ /(template|attachment|upload)/.*\.(php|php5|PHP|PHP5)?$ { deny all; } Laravel实现适用于API的分页查询 https://blog.mostion.com/archives/34/ 2023-11-06T08:36:00+08:00 Laravel 实现适用于 API 的分页查询Laravel自带分页查询方法里有一些多余的数据,并不完美适用于我们用来做API的查询。本文旨在通过重写 paginate 解决分页查询针对API接口的的灵活性和适用性。新建BaseModel.php文件,代码如下:<?php namespace App\Http\Model; use Illuminate\Database\Eloquent\Model; use Illuminate\Pagination\Paginator; class BaseModel extends Model{ public $timestamps = false; //重写分页方法,使其更加匹配API的规范 //考虑到性能问题,通常$columns我们不以*号为值。可传入需要查询的字段替代。这里只做演示。无此要求 public function paginate($perPage = null, $columns = ['*'], $page = null, $pageName = 'page'){ $page = $page ?: Paginator::resolveCurrentPage($pageName); $perPage = $perPage ?: $this->model->getPerPage(); $results = ($total = $this->toBase()->getCountForPagination()) ? $this->forPage($page, $perPage)->get($columns) : $this->model->newCollection(); $pages = ceil($total / $perPage); $result = ['total'=>$total,'current_page'=>$page,'page_size'=>$perPage,'pages'=>$pages,'list'=>$results]; return $result; } } 然后在业务模型继承此类即可,范例如下:<?php namespace App\Http\Model; class MsgBoard extends BaseModel{ protected $table = 'msg_board'; public function getMsgPageList($page,$pageSize){ return $this->paginate($pageSize, ['*'], $page, 'page'); } } 然后在控制器当中调用即可。范例如下:$page = $request->input('page',1); $pageSize = $request->input('pageSize',12); $msgList = $mMsgBoard->getMsgPageList($page,$pageSize);THE END; php-fpm 调优和配置 https://blog.mostion.com/archives/33/ 2023-11-05T09:08:20+08:00 知识点一般 php-fpm 进程占用20~30m左右的内存就按30m算。如果单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,由于大家一般Nginx、MySQL都在一台机器上,于是预留一半给它们,即php-fpm进程数(max_children)为$Mem/2/30。max_requests:指一个php-fpm的工作进程在处理多少个请求后就终止掉。这个用来处理因为PHP解析器或引用的第三方库时,造成的内存泄露问题。一般原则是:动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗常用命令查看当前php-fpm总进程数,命令:ps -ylC php-fpm --sort:rss 。其中RSS就是占用的内存情况查看当前php-fpm进程的内存占用情况及启动时间,命令如下:ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5查看当前php-fpm进程平均占用内存情况:ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'配置详解:pid = /usr/local/var/run/php-fpm.pid #pid设置,一定要开启,上面是Mac平台的。默认在php安装目录中的var/run/php-fpm.pid。比如centos的在: /usr/local/php/var/run/php-fpm.pid error_log = /usr/local/var/log/php-fpm.log #错误日志,上面是Mac平台的,默认在php安装目录中的var/log/php-fpm.log,比如centos的在: /usr/local/php/var/log/php-fpm.log log_level = notice #错误级别. 上面的php-fpm.log纪录的登记。可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice. emergency_restart_threshold = 60 emergency_restart_interval = 60s #表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。0 表示 '关闭该功能'. 默认值: 0 (关闭). process_control_timeout = 0 #设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0. daemonize = yes #后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。 listen = 127.0.0.1:9000 #fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置。如果nginx和php在不同的机器上,分布式处理,就设置ip这里就可以了。 listen.backlog = -1 #backlog数,设置 listen 的半连接队列长度,-1表示无限制,由操作系统决定,此行注释掉就行。backlog含义参考:http://www.3gyou.cc/?p=41 listen.allowed_clients = 127.0.0.1 #允许访问FastCGI进程的IP白名单,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接。 listen.owner = www listen.group = www listen.mode = 0666 #unix socket设置选项,如果使用tcp方式访问,这里注释即可。 user = www group = www #启动进程的用户和用户组,FPM 进程运行的Unix用户, 必须要设置。用户组,如果没有设置,则默认用户的组被使用。 pm = dynamic #php-fpm进程启动模式,pm可以设置为static和dynamic和ondemand #如果选择static,则进程数就数固定的,由pm.max_children指定固定的子进程数。 #如果选择dynamic,则进程数是动态变化的,由以下参数决定: pm.max_children = 50 #子进程最大数 pm.start_servers = 2 #启动时的进程数,默认值为: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.min_spare_servers = 1 #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程 pm.max_spare_servers = 3 #,保证空闲进程数最大值,如果空闲进程大于此值,此进行清理 pm.max_requests = 500 #设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0. pm.status_path = /status #FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. munin监控会使用到 ping.path = /ping #FPM监控页面的ping网址. 如果没有设置, 则无法访问ping页面. 该页面用于外部检测FPM是否存活并且可以响应请求. 请注意必须以斜线开头 (/)。 ping.response = pong #用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong. access.log = log/$pool.access.log #每一个请求的访问日志,默认是关闭的。 access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" #设定访问日志的格式。 slowlog = log/$pool.log.slow #慢请求的记录日志,配合request_slowlog_timeout使用,默认关闭 request_slowlog_timeout = 10s #当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off' request_terminate_timeout = 0 #设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。 rlimit_files = 1024 #设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 rlimit_core = 0 #设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值. chroot = #启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用. chdir = #设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时) catch_workers_output = yes #重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 默认值: 空.