🎯 学习目标
完成本课程后,学习者将能够:
- 手把手Centos7.9 安装最新版本 CRMRB v5.6.1 单商户应用部署
- 开放防火墙端口、配置PHP扩展(fileinfo、redis)、禁用函数选项
- 数据库服务(Mysql、Redis)sql-mode 配置
- 深入理解Nginx与FastCgi通信方式(Unix Socket 方式 、TCP端口方式)
- 安装Supervisor ,管理消息队列任务
CRMRB v5.6.1 运行环境要求
这里是摘抄 CRMRB v5.6.1 官网运行环境要求,我使用的是PHP7.4 Mysql 5.7、Redis5.0 、Supervisor 4.3.0,开放防火墙端口即可,这里需要注意的是,如果是Linux环境消息队列的维护是需要再Supervisor管理的。
bash
WEB Nginx
PHP PHP 7.4
MySQL 5.7(引擎:InnoDB)
缓存 Redis 5.0
管理器 Supervisor 4.3.0
开放端口 80, 21, 8888, 888, 443, 3306, 6379(授权对象:0.0.0.0/0)
PHP 扩展 fileinfo(可选)、redis(可选)
禁用函数 proc_open, pcntl_signal, pcntl_signal_dispatch, pcntl_fork, pcntl_wait, pcntl_alarm
消息队列 运行命令:php think queue:listen --queue (使用Supervisor)
长连接 运行命令:sudo -u www php think workerman start --d (命令行执行)
定时任务 运行命令:php think timer start --d (命令行执行)
一、开放防火墙端口
开放防火墙端口,使网络可服务能够请求,如果是云服务器,设置对应的安全组添加端口,保证网络正常通信是服务的第一步,以80端口为例,CRMRB需要开放80, 21, 8888, 888, 443, 3306, 6379(授权对象:0.0.0.0/0)
bash
sudo systemctl start firewalld
sudo systemctl enable firewalld
#添加防火墙开放端口
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
#重启
sudo firewall-cmd --reload
#查看已经开放的端口
$ sudo firewall-cmd --zone=public --list-ports
2049/tcp 20048/tcp 111/tcp 111/udp 80/tcp 21/tcp 8888/tcp 888/tcp 443/tcp 3306/tcp 6379/tcp
Lnmp 一键安装
我使用的是lnmp.org lnmp2.2 一键安装集成包安装的开发环境,lnmp2.2比较快捷方便适用于小企业进行部署服务、快速验证业务逻辑的过程,安装过程有点慢,需要下载大量的安装包和扩展,需要耐心等待。
环境信息:
Centos7.9 + PHP7.4 + Mysql5.7
PHP 开启扩展 fileinfo(可选)、redis(可选)任意一种,在PHP里配置禁用函数 proc_open, pcntl_signal, pcntl_signal_dispatch, pcntl_fork, pcntl_wait, pcntl_alarm
bash
wget https://soft.lnmp.com/lnmp/lnmp2.2.tar.gz -O lnmp2.2.tar.gz
&& tar zxf lnmp2.2.tar.gz
&& cd lnmp2.2
&& ./install.sh lnmp
成功的信息如下
bash
============================== Check install ==============================
Checking ...
Nginx: OK
MySQL: OK
PHP: OK
PHP-FPM: OK
Clean Web Server src directory...
1、PHP安装扩展
查看php扩展,是否安装 fileinfo
,redis
,配置禁用函数proc_open, pcntl_signal, pcntl_signal_dispatch, pcntl_fork, pcntl_wait, pcntl_alarm
bash
php -m | grep -E "fileinfo|redis"
php.ini 中设置禁用函数,配置disable_functions
选项:
bash
# php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/php/etc
Loaded Configuration File => /usr/local/php/etc/php.ini
disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,pcntl_signal,pcntl_signal_dispatch,pcntl_fork,pcntl_wait,pcntl_alarm
2、Mysql sql-mode
Mysql 要设置 sql-mode,如果sql_mode
,不可以就使用sql-mode
,本身应该是已经配置成功了,但是在安装的时候不通过,所以两个都试试。
bash
sql_mode = NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
安装时可能遇到的问题
这里有两个可能遇到的问题需要提醒,没有遇到的跳过,一个是关于中科大EPEL失效问题,还有一个就是Nginx与php-fpm通信一致的问题。
1、中科大EPEL失效问题
错误信息http://mirrors.ustc.edu.cn/epel/7/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
,从你给出的错误信息可知,CentOS 7.9 在尝试访问中科大(USTC)的 EPEL 镜像源时,找不到 repomd.xml
文件,进而导致 yum 操作失败。
首先,如果之前设置过,更改前记得要备份EPEL 配置文件,这是一个非常良好的习惯。
bash
mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
接着,创建新的 EPEL 配置文件:
bash
cat > /etc/yum.repos.d/epel.repo << EOF
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://mirrors.aliyun.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-7
EOF
#刷新缓存
yum clean all
yum makecache
2、Nginx和php-fpm 通信的一致性
Nginx 与 PHP 通信主要有三种方式:FastCGI 模式、CGI 模式和模块模式,但现在都已经采用FastCGI 模式。
FastCGI 模式下主要有两种连接方式:TCP 端口连接 和Unix Socket 连接。两者都是通过 FastCGI 协议通信,但底层传输方式不同。
- Unix Socket ,基于文件系统的套接字,本地通信,性能更高(减少网络协议栈开销),但只支持本地传输。
- TCP 端口连接基于 TCP/IP 协议,通过端口通信,方便灵活,支持(可跨服务器部署)
php-fpm.conf
bash
[global]
pid = /usr/local/php/var/run/php-fpm.pid
error_log = /usr/local/php/var/log/php-fpm.log
log_level = notice
[www]
; 监听方式:可以是端口或
; 端口方式
listen = 127.0.0.1:9000
; Unix Socket 方式
; listen = /tmp/php-cgi.sock;
Redis安装、配置
安装redis服务和扩展、设置配置项(fileinfo、redis扩展 二选一),Redis设置密码、和访问权限。
bash
进入lnmp解压后的目录,执行:./addons.sh install redis
ps aux | grep redis
/usr/local/redis/bin/redis-server 0.0.0.0:6379
#全局搜索配置文件
sudo find / -name "redis.conf" 2>/dev/null
/usr/local/redis/etc/redis.conf
bash
# 配置绑定ip 0.0.0.0 表示允许任何人访问
bind 0.0.0.0
# 设置密码
requirepass m123456
# 关闭保护模式(允许远程访问)
protected-mode no
可以手动修改,也可以使用sed修改。
bash
sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' /usr/local/redis/etc/redis.conf
sed -i 's/# requirepass foobared/requirepass m123456/g' /usr/local/redis/etc/redis.conf
sed -i 's/protected-mode no/protected-mode yes/g' /usr/local/redis/etc/redis.conf
下载V5.6.1源码包
把源码下载到web服务器上,目录结构,需要注意文件权限,配置Nginx,web服务器root参数是 /home/wwwroot/work/crmeb/public
。
bash
[stark@bogon work]$ tree -L 1
.
├── crmeb
├── docker-compose
├── LICENSE
├── readme
├── README.md
└── template
Nginx 部署 web站点
Nginx配置,这里有一个伪静态和长连接,不要漏掉,长连接端口和官方保持一致,伪静态的配置一定要保持一致,不然请求会出错,要注意Nginx 和 PHP的所属用户和用户组权限。
bash
# 使用tee命令将Nginx配置文件写入CentOS 7.9系统
sudo cat << 'EOF' | sudo tee /usr/local/nginx/conf/vhost/work.conf > /dev/null
server {
listen 80;
server_name www.work.com;
root /home/wwwroot/work/crmeb/public;
location / {
index index.php index.html;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
autoindex off;
}
location ~ .php(.*)$ {
#fastcgi_pass 127.0.0.1:9000; #TCP端口方式
fastcgi_pass unix:/tmp/php-cgi.sock; #Unix Socket 方式
fastcgi_index index.php; #默认索引文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #设置 PHP 脚本的绝对路径(关键参数)
include fastcgi_params;
}
location /notice {
proxy_pass http://127.0.0.1:40001/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /msg {
proxy_pass http://127.0.0.1:40002/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
EOF
长连接、定时任务、消息队列
在php.ini中 配置之前请先删除以下php的禁用函数,配置项disable_functions
,也就是disable_functions
不包含他们。
bash
proc_open
pcntl_signal
pcntl_signal_dispatch
pcntl_fork
pcntl_wait
pcntl_alarm
1、设置客服长连接 启动workerman服务
启动sudo -u www php think workerman start --d
,下面的页面就是启动成功了。
bash
[stark@bogon crmeb]$ sudo -u www php think workerman start --d
string(5) "admin"
string(4) "chat"
string(7) "channel"
Workerman[think] start in DAEMON mode
-------------------------------------------- WORKERMAN ---------------------------------------------
Workerman version:3.5.19 PHP version:7.4.33
--------------------------------------------- WORKERS ----------------------------------------------
proto user worker listen processes status
tcp www none websocket://0.0.0.0:40001 1 [OK]
tcp www none websocket://0.0.0.0:40002 1 [OK]
tcp www ChannelServer frame://127.0.0.1:40003 1 [OK]
----------------------------------------------------------------------------------------------------
Input "php think stop" to stop. Start success.
2、启用定时任务
启动定时任务php think timer start --d
,得到下面的页面就是启动成功了。
bash
[stark@bogon crmeb]$ php think timer start --d
Workerman[think] start in DAEMON mode
------------------------------------- WORKERMAN --------------------------------------
Workerman version:3.5.19 PHP version:7.4.33
-------------------------------------- WORKERS ---------------------------------------
proto user worker listen processes status
tcp stark none none 1 [OK]
--------------------------------------------------------------------------------------
Input "php think stop" to stop. Start success.
3、启用消息队列
消息队列需要先安装Supervisor 来进行管理队列已经安装Supervisor的可跳过安装过程,Supervisor 是 Python 编写的工具,首先需要确保系统有 Python 和 pip:
bash
# 检查Python版本(CentOS 7通常预装Python 2.7)
python -V
# 安装pip(Python包管理工具)
yum install -y epel-release
yum install -y python-pip
# 升级pip到最新版本
pip install --upgrade pip
sudo pip install supervisor
生成 Supervisor 配置文件,添加配置
bash
sudo mkdir -p /etc/supervisor/conf.d
sudo echo_supervisord_conf > /etc/supervisor/supervisord.conf
vim /etc/supervisor/supervisord.conf
[include]
files = /etc/supervisor/conf.d/*.conf
下面是配置详解:
bash
[unix_http_server]
file=/tmp/supervisor.sock ; UNIX socket 文件
[inet_http_server] ; 启用HTTP服务器,便于通过网页管理
port=0.0.0.0:9001 ; 监听所有IP的9001端口
username=user ; 用户名(可选)
password=123 ; 密码(可选)
[supervisord]
logfile=/var/log/supervisord.log ; 日志文件
logfile_maxbytes=50MB ; 日志大小限制
logfile_backups=10 ; 日志备份数量
loglevel=info ; 日志级别
pidfile=/var/run/supervisord.pid ; PID文件
nodaemon=false ; 是否以守护进程运行
minfds=1024 ; 最小文件描述符
minprocs=200 ; 最小进程数
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; 与supervisord通信的socket
创建 Supervisor 系统服务,vim /usr/lib/systemd/system/supervisord.service
bash
[Unit]
Description=Supervisor daemon
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl shutdown
ExecReload=/usr/bin/supervisorctl reload
User=root
Restart=on-failure
[Install]
WantedBy=multi-user.target
bash
# 重新加载systemd配置
systemctl daemon-reload
# 启动Supervisor
systemctl start supervisord
# 设置开机自启
systemctl enable supervisord
# 检查运行状态
systemctl status supervisord
验证安装
bash
# 查看Supervisor版本
supervisord -v
在 Supervisor 的配置目录下创建一个专门的配置文件,创建CRMRB消息队列任务:
bash
sudo vim /etc/supervisor/conf.d/think-queue.conf
将以下内容添加到文件中(根据你的实际情况修改路径):
bash
[program:think-queue]
; 命令路径,需替换为你的项目实际路径
command=/usr/bin/php /home/wwwroot/work/crmeb/think queue:listen --queue
; 项目根目录,需替换为你的项目实际路径
directory=/home/wwwroot/work/crmeb/public
; 运行队列的用户(根据你的 Web 服务器用户设置)
user=www
; 自动启动
autostart=true
; 程序意外退出时自动重启
autorestart=true
; 启动重试次数
startretries=3
; 日志输出配置
redirect_stderr=true
stdout_logfile=/var/log/think-queue.log
; 日志文件大小限制
stdout_logfile_maxbytes=10MB
; 日志文件备份数量
stdout_logfile_backups=10
; 进程启动超时时间
startsecs=5
; 停止信号
stopsignal=INT
应用配置并重新启动:
bash
# 重新读取配置文件
sudo supervisorctl reread
# 更新配置
sudo supervisorctl update
# 启动队列进程
sudo supervisorctl start think-queue
# 查看进程状态
sudo supervisorctl status think-queue
看见这个的时候,就是已经配置成功了,去后台自己开启一下就行了。
bash
[root@bogon crmeb]# sudo supervisorctl status
think-queue RUNNING pid 32811, uptime 0:00:45
需要注意的安全机制
bash
location ~ .php(.*)$ {
fastcgi_pass unix:/tmp/php-cgi.sock; #Unix Socket 方式
fastcgi_index index.php; #默认索引文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #设置 PHP 脚本的绝对路径(关键参数)
fastcgi_split_path_info ^((?U).+.php)(/?.+)$; #用于分割 URL 中 PHP 脚本路径和额外的路径信息(PATH_INFO)
fastcgi_param PATH_INFO $fastcgi_path_info; #传递 PATH_INFO(额外路径信息)给 PHP
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; #设置 PATH_INFO 对应的文件系统路径
include fastcgi_params;
}
PATH_TRANSLATED
的安全风险,这一行会将用户请求的路径信息直接映射到文件系统路径,可能被恶意用户利用来访问系统上的任意文件。
现代 Nginx 和 PHP-FPM 默认配置了安全限制,防止路径遍历攻击:
open_basedir
限制doc_root
限制- Nginx 的安全模块检测
这个配置导致 "Access denied" 错误的主要原因是 安全限制 。php开启这个就会产生错误信息Access denied.
通常来说,大多数现代 PHP 应用不需要 PATH_TRANSLATED
参数,移除它即可解决问题。
前端/调试
环境版本node v20.19.2
,npm 11.6.2
,npm 在低依赖包有报错信息,安装依赖就可以看见欢迎页面了,uni-app使用HBuilder X的启动,服务就可以正常运行了,万里长征第一步就这样完成了。
bash
npm install
npm run dev
😄 Hello ~ 欢迎使用CRMEB标准版,我们将竭诚为您服务!
info - [提示] 点击这里查看更多商品~ https://doc.crmeb.com
info - [提示] 点击这里可以查看开发文档喔~ https://www.crmeb.com
info - [提示] 点击这里可以查看我们的论坛社区~ https://www.crmeb.com/ask
info - [你知道吗?] 按 Ctrl+C 可以停止服务呢~