LNMP 架构

一、简介

1. 常用架构

  • LAMP:Linux + Apache + MySQL/Mariadb + PHP/Perl/Python

    Note:PHP 处理动态页面请求,并与数据库建立关联。

  • LNMP:Linux + Nginx + MySQL/Mariadb + PHP/Perl/Python

    Note:国外常简称为 LEMP。

  • LNPP:Linux + Nginx + PostgreSQL + PHP/Perl/Python

2. 架构对比

  • LAMP 与 LNMP 的核心区别:Web 服务器不同
    • Apache:开源、稳定、模块丰富,但较为臃肿,内存和 CPU 开销大。
    • Nginx:功能丰富、运维简单,处理静态文件速度快且系统资源消耗极少。
  • LNMP 与 LNPP 的核心区别:数据库不同(分别为 MySQL/Mariadb、PostgreSQL)。

二、部署方法

1. 部署 Nginx

(1)安装依赖工具

yum install -y yum-utils

(2)配置 Nginx yum 源

[root@web04 yum.repos.d]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

(3)安装 Nginx 并调整用户 UID/GID

[root@web04 yum.repos.d]# yum install -y nginx
[root@web04 yum.repos.d]# usermod -u 990 nginx  # 使 UID 和 GID 一致
[root@web04 yum.repos.d]# id nginx  # 验证
uid=990(nginx) gid=990(nginx) groups=990(nginx)

2. 部署 PHP

(1)卸载旧版 PHP

rpm -qa php*  # 查看已安装版本
yum remove -y php  # 卸载

Note:若卸载失败,可使用 rpm -e --nodeps 忽略依赖强制卸载。

(2)安装新版 PHP 及必备扩展

yum install -y php
yum install -y php-mysqlnd php-json  # 必备扩展(缺失 php-json 会导致 WordPress 安装报错)

(3)验证 PHP 版本

[root@web04 ~]# php-fpm -v
PHP 7.2.24 (fpm-fcgi) (built: Oct 22 2019 08:28:36)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

(4)创建统一管理用户(www)

[root@web04 ~]# useradd -u 889 -M -s /sbin/nologin -c "nginx and php user" www  # 无家目录,不可登录
[root@web04 ~]# groupmod -g 889 www  # 统一 GID
[root@web04 ~]# id www  # 验证
uid=889(www) gid=889(www) groups=889(www)

(5)同步 Nginx 与 PHP 管理用户

  • 修改 Nginx 配置并重启

    sed -i.bak 's|nginx;$|www;|g' /etc/nginx/nginx.conf  # 将默认用户 nginx 改为 www
    grep "^user" /etc/nginx/nginx.conf  # 验证 user  www;
    systemctl restart nginx
    
  • 修改 PHP 配置并启动

    [root@web04 ~]# egrep "^user|^group" /etc/php-fpm.d/www.conf  # 验证配置(默认为 apache,需改为 www)
    user = www
    group = www
    
    [root@web04 ~]# systemctl start php-fpm
    [root@web04 ~]# systemctl enable php-fpm  # 开机自启
    

3. 部署 MySQL 服务(以 MariaDB 为例)

(1)二进制安装

  1. 准备安装包
    MariaDB 官网 下载 mariadb-10.5.7-linux-systemd-x86_64.tar.gz(含 systemd 配置文件)。

  2. 解压并创建软链接

    tar -xvf mariadb-10.5.7-linux-systemd-x86_64.tar.gz -C /opt
    ln -s /opt/mariadb-10.5.7-linux-systemd-x86_64 /opt/mariadb  # 方便管理和升级
    
  3. 创建数据库用户与目录

    groupadd mysql
    useradd -r -M -g mysql -s /sbin/nologin mysql  # 系统用户,无家目录
    mkdir -p /data/mariadb/data  # 数据目录
    chown -R mysql:mysql /opt/mariadb/  # 授权安装目录
    chown -R mysql:mysql /data/mariadb/  # 授权数据目录
    
  4. 配置环境变量

    [root@web04 ~]# vim ~/.bash_profile
    # 在 PATH 中添加 MariaDB 二进制目录
    PATH=$PATH:$HOME/bin:/opt/mariadb/bin
    [root@web04 ~]# source ~/.bash_profile  # 生效配置
    
  5. 修改配置文件

    [root@web04 ~]# vim /etc/my.cnf
    [mysqld]
    basedir=/opt/mariadb  # 安装目录
    datadir=/data/mariadb/data  # 数据目录
    
  6. 初始化数据目录

    [root@web04 ~]# cd /opt/mariadb/
    # --basedir=path:指定安装路径
    # --datadir=path:指定数据存放路径
    # --user=mysql:指定管理用户
    [root@web04 mariadb]# ./scripts/mariadb-install-db --defaults-file=/etc/my.cnf --user=mysql
    
  7. 启动服务(推荐 systemd 方式)

    • 复制 systemd 配置文件并修正路径

      [root@web04 ~]# cp /opt/mariadb/support-files/systemd/mariadb.service /usr/lib/systemd/system/
      [root@web04 ~]# vim /usr/lib/systemd/system/mariadb.service  # 将默认路径 /usr/local/mysql 改为实际路径 /opt/mariadb
      
    • 启动并验证

      systemctl daemon-reload
      systemctl start mariadb
      systemctl enable mariadb
      

(2)yum 安装

  1. 配置 yum 源(以清华源为例)

    [root@web04 ~]# vim /etc/yum.repos.d/mariadb.repo
    [mariadb]
    name = MariaDB
    baseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/10.5/centos8-amd64
    module_hotfixes=1
    gpgkey=https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB
    gpgcheck=1
    
  2. 安装服务端

    [root@web04 ~]# yum install -y mariadb-server
    [root@web04 ~]# rpm -qa | grep -i mariadb  # 验证安装
    MariaDB-client-10.5.7-1.el8.x86_64
    MariaDB-common-10.5.7-1.el8.x86_64
    MariaDB-server-10.5.7-1.el8.x86_64
    MariaDB-shared-10.5.7-1.el8.x86_64
    
  3. 数据目录授权

    mkdir -p /data/mariadb/data
    chown -R mysql:mysql /data/mariadb/
    chown -R mysql:mysql /var/log/mariadb/  # 日志目录授权(避免初始化报错)
    
  4. 初始化数据目录(yum 安装默认 basedir=/usr,无需额外指定)

    mysql_install_db --datadir=/data/mariadb/data --user=mysql
    
  5. 启动服务

    systemctl start mariadb
    systemctl enable mariadb
    

(3)通用配置(初始化后)

  1. 设置 root 密码

    mysqladmin -uroot password 'root'  # 简单方式
    # 或交互式配置(推荐)
    /usr/bin/mysql_secure_installation
    
  2. 登录数据库

    mysql -uroot -p  # 本地登录
    mysql -uroot -proot -h 10.0.0.53  # 远程登录(需授权)
    
  3. 配置远程登录权限

    -- 允许 root 从任意主机登录
    grant all on *.* to 'root'@'%' identified by 'root';  
    -- 刷新权限
    flush privileges;  
    -- 查看权限:
    select user,host,password from mysql.user;
    

三、架构原理

image-1765780556071

  • 静态页面处理流程:用户访问 → Nginx 直接处理并返回。
  • 动态页面处理流程:用户访问 → Nginx(通过 fastcgi_pass 转发)→ PHP(fastcgi → php-fpm → wrapper → PHP 解析器)→ 访问 MySQL 数据库 → 返回结果。

四、LNMP 服务间的关联配置

1. Nginx 与 PHP 关联

(1)配置步骤

  1. 修改 PHP 配置(/etc/php-fpm.d/www.conf

    [root@web04 ~]# vim /etc/php-fpm.d/www.conf
    # 核心配置
    user = www
    group = www
    # 监听方式(二选一)
    # listen = 127.0.0.1:9000  # TCP 方式(支持跨服务器)
    listen = /run/php-fpm/www.sock  # Unix socket 方式(本地通信,效率更高)
    # 监听权限(与 Nginx 用户一致)
    listen.owner = www
    listen.group = www
    listen.mode = 0660
    # 允许连接的客户端(TCP 方式生效)
    listen.allowed_clients = 127.0.0.1
    

    重启 PHP 使配置生效:

    systemctl reload php-fpm
    
  2. 修改 Nginx 配置(/etc/nginx/conf.d/www.conf

    [root@web04 ~]# vim /etc/nginx/conf.d/www.conf
    server {
        listen 80;
        server_name www.yingzai.cc;
        # 静态资源处理
        location / {
            root /html/www;
            index index.html;
        }
        # 动态资源(.php)处理
        location ~* \.php$ {
            root /html/www;  # 必须指定站点目录,否则报 file not found 错误
            fastcgi_index index.php;
            # 与 PHP 监听方式对应
            fastcgi_pass unix:/run/php-fpm/www.sock;  # 对应 Unix socket
            # fastcgi_pass 127.0.0.1:9000;  # 对应 TCP 方式
            include fastcgi_params;
            # 关键变量:指定 PHP 脚本路径
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
    }
    

    重启 Nginx 使配置生效:

    systemctl reload nginx
    

(2)测试验证

  1. 创建 PHP 测试文件

    [root@web04 ~]# vim /html/www/index.php
    <?php
    phpinfo();
    ?>
    

    验证语法:

    [root@web04 ~]# php /html/www/index.php  # 无报错则语法正确
    
  2. 浏览器访问:www.yingzai.cc/index.php,显示 PHP 信息页即成功。

(3)常见问题

  • 502 错误(TCP 方式):PHP 未监听 9000 端口。
    解决:在 www.conf 中启用 listen = 127.0.0.1:9000,重启 PHP 后验证端口:

    [root@web04 ~]# netstat -lnput | grep 9000
    
  • file not found 错误:Nginx 的 php location 未配置 root(站点目录)。
    解决:在 location ~* \.php$ 中添加 root /html/www;

  • 页面空白:PHP 代码语法错误。
    解决:执行 php 文件名 检查并修正语法。

2. PHP 与 MySQL 关联

(1)配置步骤

  1. 创建测试脚本(/html/www/mysql.php

    <?php
        $server_name = "localhost";
        $username = "root";
        $password = "root";
        // 连接 MySQL(Php7 起推荐 mysqli 或 PDO,弃用 mysql_connect())
        $conn = mysqli_connect($server_name, $username, $password, "mysql");
        if ($conn)
            echo "mysql connect successfully by root\n";
    ?>
    

(2)测试验证

  1. 本地验证

    php /html/www/mysql.php  # 输出 "mysql connect successfully by root" 即成功
    
  2. 浏览器访问:www.yingzai.cc/mysql.php,显示成功信息即正常。

(3)常见问题

  • 页面无法显示:缺少 PHP 数据库扩展。
    解决:安装扩展:

    yum install -y php-mysqlnd php-pdo
    
  • 连接报错(No such file or directory):PHP 无法找到 MySQL 的 socket 文件。
    解决:

    1. 查看 MySQL socket 路径:

      status;  -- 找到 "UNIX socket: /tmp/mysql.sock"
      
    2. 修改 PHP 配置(/etc/php.ini):

      [root@web04 ~]# vim /etc/php.ini
      pdo_mysql.default_socket= /tmp/mysql.sock
      mysqli.default_socket = /tmp/mysql.sock
      
    3. 重启 PHP:

      systemctl restart php-fpm