LAMP/LNMP 最佳实践
LAMP/LNMP 组件
LAMP:Linux+Apache+Mysql/Mariadb+PHP/Python/Perl。
LNMP:Linux+Nginx+Mysql/Mariadb+PHP/Python/Perl。
- Linux:操作系统,提供程序运行基础。
- Apache/Nginx:Web 服务器,提供网页访问。
- Mysql/Mariadb:数据库,提供数据管理。
- PHP/Python/Perl:脚本语言,提供动态执行生成。
PHP FastCGI 进程管理器,是PHP的一个扩展模块,用于管理PHP 进程池的软件,用于接受web服务器的请求。PHP-FPM 全名 PHP FastCGI Process Manager,作为FastCGI进程管理器,与Web服务器(例如Nginx、Apache等)配合使用。
PHP-FPM的主要功能是管理和调度PHP脚本的执行。它通过创建和管理PHP进程池来处理PHP请求。每个PHP进程池中运行多个PHP-FPM进程,每个进程可以处理一个或多个PHP请求。PHP-FPM会根据配置的参数来管理这些进程的数量、生命周期和资源分配。
PHP-FPM提供了一些高级功能,例如进程池的动态调整、请求限制和超时控制、进程重生、日志记录等。它还支持基于Unix域套接字或TCP/IP套接字的进程间通信,以及基于文件和共享内存的进程管理。
LAMP/LNMP 工作原理
客户端通过HTTP协议请求web服务器资源
web 服务器根据资源类型进行处理:
静态资源:web直接把资源返回至客户端。
动态资源:通过指定的通讯方式将脚本网页交给后端程序执行。如果运算期间需要连接mysql数据库,则通过mysql连接器连接mysql。后端程序将运算结果返回给web服务。
web服务将结果返回给客户端。
PHP 与 WEB 协同工作模式
PHP 与 WEB 协同工作模式:
- CGI:Web 进程动态调用相应脚本解释器执行动态页面 ,执行完后再释放。特点:性能差。
- Modules:Web 进程动态加载相应模块执行动态页面 。特点:性能较好。
- FastCGI:后端进程独立运行管理,通过独立的网络套接字接口接收Web进程传过来的请求。特点:真正地实现前后端分离。适合于性能要求比较高的场景。Web 服务器需要开启反向代理功能,将请求转发到后端服务器。
ALL-IN-ONE
以部署 wordpress 应用为例。
实验环境
主机名 | IP 地址 | 角色 |
---|---|---|
server.sh.cloud | 10.1.8.10 | all |
以部署 wordpress 应用为例。
部署数据库
# 安装服务端
[root@server ~ 18:53:44]# yum install -y mariadb-server
# 启用并启动服务
[root@server ~ 18:55:17]# systemctl enable --now mariadb
# 配置防火墙
[root@server ~ 18:56:21]# firewall-cmd --permanent --add-service=mysql
[root@server ~ 18:56:48]# firewall-cmd --reload
# 加固 MariaDB
[root@server ~ 18:56:48]# mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.
Set root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]
... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
# 交互式提示您进行更改,包括:
# - 为root帐户设置密码,例如redhat。
# - 禁止root帐户从本地主机外部访问数据库。
# - 删除匿名用户帐户。
# - 删除用于演示的test数据库。
准备数据库
[root@server ~ 18:57:38]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database wordpress;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> create user wp@'%' identified by '000000';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant all privileges on wordpress.* to 'wp'@'%';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
部署 Nginx 服务
[root@server ~ 19:01:00]# yum install -y nginx
[root@server ~ 19:01:40]# echo 'hello world!' > /usr/share/nginx/html/index.html
[root@server ~ 19:02:05]# systemctl enable nginx.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
部署 PHP 服务
部署 php 服务
[root@server ~ 19:02:18]# yum install -y php php-fpm php-mysqlnd
[root@server ~ 19:03:22]# systemctl enable php-fpm.service --now
# 修改配置文件
[root@server ~ 19:03:48]# vim /etc/nginx/default.d/php.conf
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
[root@server ~ 19:04:17]# systemctl restart nginx.service
准备 php 测试文件
# 准备 index.php
[root@server ~ 19:04:34]# cat > index.php <<EOF
> <?php
> echo "<h1>Hello World !</h1>\n";
> ?>
> EOF
# 准备 test-mysql.php
[root@server ~ 19:04:58]# cat > test-mysql.php <<'EOF'
> <?php
> $link=mysqli_connect('10.1.8.10','wp','000000');
> if($link)
> echo "<h1>Connect Mysql Success !</h1>\n";
> else
> echo "<h1>Connect Mysql Failed !</h1>\n";
> $link->close();
> ?>
> EOF
# 准备 info.php
[root@server ~ 19:05:10]# cat > info.php <<EOF
> <?php
> phpinfo()
> ?>
> EOF
# 移动到 Nginx 服务器默认主目录
[root@server ~ 19:07:05]# mv *.php /usr/share/nginx/html
php 程序测试
[root@server ~ 19:07:42]# php -f /usr/share/nginx/html/index.php
<h1>Hello World !</h1>
[root@server ~ 19:08:47]# php -f /usr/share/nginx/html/test-mysql.php
<h1>Connect Mysql Success !</h1>
浏览器测试
部署 wordpress 应用
下载 wordpress,上传到家目录。
# 如果 Web 服务是 Nginx,则解压文件到/usr/share/nginx/html
[root@server ~ 19:18:37]# unzip -o wordpress-4.9.4-zh_CN.zip -d /usr/share/nginx/html/
[root@server ~ 19:19:06]# chown -R nginx:nginx /usr/share/nginx/html/wordpress/
# php-fpm 进程默认以 apache 用户身份运行,修改运行用户为 nginx,并重启服务
[root@server ~ 19:19:58]# vim /etc/php-fpm.d/www.conf
user=nginx
group=nginx
[root@server ~ 19:20:56]# systemctl restart php-fpm.service
客户端配置 server.sh.cloud 名称解析。访问http://server.sh.cloud/wordpress/。
根据提示创建文件,然后单击现在安装。
后续步骤省略。
Standalone
以部署 wordpress 应用为例。
实验环境
主机名 | IP 地址 | 角色 |
---|---|---|
www.sh.cloud | 10.1.8.21 | apache |
php.sh.cloud | 10.1.8.22 | php |
db.sh.cloud | 10.1.8.23 | mariadb |
storage.sh.cloud | 10.1.8.24 | nfs |
所有节点关闭防火墙和SELinux。
预配置
所有节点配置名称解析:
[root@server ~ 19:38:32]# cat >> /etc/hosts << EOF
> 10.1.8.21 www.sh.cloud www
> 10.1.8.22 php.sh.cloud php
> 10.1.8.23 db.sh.cloud db
> 10.1.8.24 storage.sh.cloud storage
> EOF
[root@server ~ 19:40:09]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.1.8.21 www.sh.cloud www
10.1.8.22 php.sh.cloud php
10.1.8.23 db.sh.cloud db
10.1.8.24 storage.sh.cloud storage
部署存储服务器
由于静态文件和动态文件没有分开,所以 Web 服务器和 PHP 服务器都要存一份。实验环境通过NFS共享提供wordpress应用。
下载 wordpress,上传到家目录。
[root@storage ~ 19:43:58]# yum install -y nfs-utils
[root@storage ~ 19:44:50]# mkdir -m 777 /www
[root@storage ~ 19:45:02]# echo '/www 10.1.8.0/24(rw)' > /etc/exports
[root@storage ~ 19:45:09]# systemctl enable nfs-server.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
# 准备 wordpress资源
[root@storage ~ 19:45:33]# unzip -o wordpress-4.9.4-zh_CN.zip -d /www/
# 准备网页测试文件
[root@storage ~ 19:45:54]# echo 'Hello World !' > /www/index.html
[root@storage ~ 19:46:21]# cat > /www/index.php <<EOF
> <?php
> echo "<h1>Hello World !</h1>\n";
> ?>
> EOF
[root@storage ~ 19:46:27]# cat > /www/test-mysql.php <<'EOF'
> <?php
> $link=mysqli_connect('db.sh.cloud','wp','000000');
> if($link)
> echo "<h1>Connect Mysql Success !</h1>\n";
> else
> echo "<h1>Connect Mysql Failed !</h1>\n";
> $link->close();
> ?>
> EOF
[root@storage ~ 19:46:57]# cat > /www/info.php <<EOF
> <?php
> phpinfo();
> ?>
> EOF
部署数据库服务器
[root@db ~ 19:47:34]# yum install -y mariadb-server
[root@db ~ 19:48:11]# systemctl enable mariadb.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
# 加固 MariaDB
[root@db ~ 19:48:33]# mysql_secure_installation
# 交互式提示您进行更改,包括:
# - 为root帐户设置密码,例如redhat。
# - 禁止root帐户从本地主机外部访问数据库。
# - 删除匿名用户帐户。
# - 删除用于演示的test数据库。
# 准备wordpress数据库和用户
[root@db ~ 19:49:01]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE wordpress;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> CREATE USER wp@'%' identified by '000000';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress.* TO 'wp'@'%';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
部署 Nginx 服务器
# 部署 Nginx 服务
[root@www ~ 19:43:53]# yum install -y nginx
[root@www ~ 19:51:01]# systemctl enable nginx.service --now
# 安装 nfs 工具
[root@www ~ 19:51:10]# yum install -y nfs-utils
# 挂载存储
[root@www ~ 19:51:38]# echo 'storage.sh.cloud:/www /usr/share/nginx/html nfs defaults 0 0' >> /etc/fstab
[root@www ~ 19:51:52]# mount -a
[root@www ~ 19:51:57]# df -h /usr/share/nginx/html/
Filesystem Size Used Avail Use% Mounted on
storage.sh.cloud:/www 50G 1.8G 49G 4% /usr/share/nginx/html
[root@www ~ 19:52:11]# ls /usr/share/nginx/html/
index.html index.php info.php test-mysql.php wordpress
部署 PHP 服务器
部署 php 服务
[root@php ~ 19:43:51]# yum install -y php php-fpm php-mysqlnd
[root@php ~ 19:53:35]# vim /etc/php-fpm.d/www.conf
#使用;号注释掉原有listen行
;listen = 127.0.0.1:9000
# 新增listen 监听所有ip的9000端口
listen = 9000
# 支持监听特定ip的9000端口,例如listen = 10.1.8.22:9000
# 使用;号注释掉原有 listen.allowed_clients 行
# 允许所有客户端访问
;listen.allowed_clients = 127.0.0.1
[root@php ~ 19:55:18]# systemctl enable php-fpm.service --now
[root@www ~ 19:52:18]# id nginx
uid=997(nginx) gid=995(nginx) groups=995(nginx)
[root@php ~ 19:55:20]# useradd -u 997 -s /sbin/nologin nginx
挂载存储
# 安装 nfs 工具
[root@php ~ 19:55:41]# yum install -y nfs-utils.x86_64
# 挂载存储
[root@php ~ 19:56:11]# echo 'storage.sh.cloud:/www /www nfs defaults 0 0' >> /etc/fstab
[root@php ~ 19:56:17]# mkdir /www
[root@php ~ 19:56:20]# mount /www
[root@php ~ 19:56:22]# df -h /www
Filesystem Size Used Avail Use% Mounted on
storage.sh.cloud:/www 50G 1.8G 49G 4% /www
[root@php ~ 19:56:25]# ls /www
index.html index.php info.php test-mysql.php wordpress
php 程序测试
[root@php ~ 19:56:28]# php /www/index.php
<h1>Hello World !</h1>
[root@php ~ 19:56:43]# php /www/test-mysql.php
<h1>Connect Mysql Success !</h1>
# 执行 info.php 的输出内容太多,这里省略。
配置 Nginx 对接 PHP
[root@www ~ 19:55:32]# cat > /etc/nginx/conf.d/vhost-www.conf <<'EOF'
> server {
> listen 80;
> server_name www.sh.cloud;
>
> # 静态资源处理
> location / {
> root /usr/share/nginx/html;
> index index.html index.htm index.php;
> }
>
> # PHP 请求处理
> location ~ \.php$ {
> # 配置 PHP-FPM 监听的地址和端口
> fastcgi_pass php.sh.cloud:9000;
> fastcgi_index index.php;
> # 配置 php 服务器上 wordpress 应用所在位置
> fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name;
> include fastcgi_params;
> }
> }
> EOF
# 重启服务
[root@www ~]# systemctl restart nginx
配置存储权限
# 更改拥有者为nginx对应的uid
[root@storage ~ 19:57:10]# chown -R 997 /www
# php-fpm 进程默认以 apache 用户身份运行,修改运行用户为 nginx,并重启服务
[root@php ~ 19:57:15]# useradd -u 997 -s /sbin/nologin nginx
[root@php ~ 19:59:08]# vim /etc/php-fpm.d/www.conf
user=nginx
group=nginx
[root@php ~ 19:59:34]# systemctl restart php-fpm.service
测试应用
客户端配置 www.sh.cloud 名称解析。访问http://www.sh.cloud/wordpress/。
其他问题
配置网站连接数据库的时候,如果出现如下界面,则表明nginx没有权限修改网站主目录。
处理方法1:
# 更改拥有者为nginx对应的uid
[root@storage ~ 18:47:46]# chown -R 997 /www
# php-fpm 进程默认以 apache 用户身份运行,修改运行用户为 nginx,并重启服务
[root@php ~ 18:48:51]# useradd -u 997 -s /sbin/nologin nginx
[root@php ~ 18:48:56]# vim /etc/php-fpm.d/www.conf
user=nginx
group=nginx
[root@php ~ 18:49:07]# systemctl restart php-fpm
配置完成后,单击现在安装,继续。后续步骤省略。
处理方法2:
根据提示:在存储节点创建配置文件。
[root@storage ~ 18:49:17]# vim /www/wordpress/wp-config.php
<?php
/**
* WordPress基础配置文件。
*
* 这个文件被安装程序用于自动生成wp-config.php配置文件,
* 您可以不使用网站,您需要手动复制这个文件,
* 并重命名为“wp-config.php”,然后填入相关信息。
*
* 本文件包含以下配置选项:
*
* * MySQL设置
* * 密钥
* * 数据库表名前缀
* * ABSPATH
*
* @link https://codex.wordpress.org/zh-cn:%E7%BC%96%E8%BE%91_wp-config.php
*
* @package WordPress
*/
// ** MySQL 设置 - 具体信息来自您正在使用的主机 ** //
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');
/** MySQL数据库用户名 */
define('DB_USER', 'wp');
/** MySQL数据库密码 */
define('DB_PASSWORD', 'sh@123');
/** MySQL主机 */
define('DB_HOST', 'db.sh.cloud');
/** 创建数据表时默认的文字编码 */
define('DB_CHARSET', 'utf8mb4');
/** 数据库整理类型。如不确定请勿更改 */
define('DB_COLLATE', '');
/**#@+
* 身份认证密钥与盐。
*
* 修改为任意独一无二的字串!
* 或者直接访问{@link https://api.wordpress.org/secret-key/1.1/salt/
* WordPress.org密钥生成服务}
* 任何修改都会导致所有cookies失效,所有用户将必须重新登录。
*
* @since 2.6.0
*/
define('AUTH_KEY', '7yZqc1!YY*8Um(;hw#Cu@&C<oRt|(Qjd!exg|n=#>(&/v|1(:=-E?KB;AGUVy&7.');
define('SECURE_AUTH_KEY', '{sdmX?Io3}r8 km:r{g/uigwrcWPWO+7740kuiXMzYR&Nu7kQlt8s@7y.-#X_2Xt');
define('LOGGED_IN_KEY', 'uk^ s?-9K5xyNPT8nXI$t)$K6vb71qP[}[pZvk^::WN &%GO;*702MmI(U#TFgH+');
define('NONCE_KEY', 'zLA^fMij!?X +#vs+G` nGf6gel<a*QNhYL[5$}91nkif7ylJMAiqxotzgZ]/{:x');
define('AUTH_SALT', '-%_ji|zC-:#7dJZ7W6+@XZvJ^Ij,I%^R69K]kZobmWi{6.+w8Sw!u]~;FJ-d+?a)');
define('SECURE_AUTH_SALT', '?r*#JoJ}Xy~kSXEzWRZI;a3MBMd*RDbx<KQI@T4e?8 pKE~08c=Q(I_<Sd.OZ}lk');
define('LOGGED_IN_SALT', ')u7KKy1$#82.ZY8#^X99=#Vgzaw>g!>_f-_3LFoOM^Wi8+N@R`x`re$bJQA1;2^I');
define('NONCE_SALT', '<_HUy#}dPUtcJ0$fsq/>N(Ds53rEV6)?VEtSm,Djs7]L6]3;Q}2Xov|VL/P;`Fg$');
/**#@-*/
/**
* WordPress数据表前缀。
*
* 如果您有在同一数据库内安装多个WordPress的需求,请为每个WordPress设置
* 不同的数据表前缀。前缀名只能为数字、字母加下划线。
*/
$table_prefix = 'wp_';
/**
* 开发者专用:WordPress调试模式。
*
* 将这个值改为true,WordPress将显示所有用于开发的提示。
* 强烈建议插件开发者在开发环境中启用WP_DEBUG。
*
* 要获取其他能用于调试的信息,请访问Codex。
*
* @link https://codex.wordpress.org/Debugging_in_WordPress
*/
define('WP_DEBUG', false);
/**
* zh_CN本地化设置:启用ICP备案号显示
*
* 可在设置→常规中修改。
* 如需禁用,请移除或注释掉本行。
*/
define('WP_ZH_CN_ICP_NUM', true);
/* 好了!请不要再继续编辑。请保存本文件。使用愉快! */
/** WordPress目录的绝对路径。 */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** 设置WordPress变量和包含文件。 */
require_once(ABSPATH . 'wp-settings.php');
配置完成后,单击现在安装,继续。后续步骤省略。