主要内容:
部署LNMP架构(linux、Nginx、MariaDB、PHP)、Nginx+FastCGI动静分离、Nginx地址重写
环境准备:还原配置文件
[root@proxy ~]# cd /usr/local/nginx/
[root@proxy nginx]# sbin/nginx
[root@proxy nginx]# cp conf/nginx.conf.default conf/nginx.conf
cp:是否覆盖"conf/nginx.conf"? y
[root@proxy nginx]# sbin/nginx -s reload
[root@proxy nginx]# sbin/nginx -V
configure arguments: --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
环境准备:如果Nginx异常,需要按照以下方式重新创建
[root@proxy nginx]# /usr/local/nginx/sbin/nginx -s stop
[root@proxy nginx]# cd ~/lnmp_soft/nginx-1.17.6/
[root@proxy nginx-1.17.6]# killall nginx
[root@proxy nginx-1.17.6]# rm -rf /usr/local/nginx/
[root@proxy nginx-1.17.6]# make install
[root@proxy nginx-1.17.6]# cd /usr/local/nginx/
[root@proxy nginx]# ls
conf html logs sbin
[root@proxy nginx]# sbin/nginx -V
configure arguments: --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
一、LNMP概述
前言:目前的网站一般都会有动态和静态数据,默认nginx 仅可以处理静态数据,用户访问任何数据都是直接返回对应的文件,如果访问的是一个脚本的话,就会导致直接返回一个脚本给用户,而用户没有脚本解释器,因此需要整合LNMP(Linux、Nginx、MySQL、PHP)实现动态网站效果。
LNMP 是一种常见的 Web 服务器架构,代表 Linux、Nginx、MySQL(或 MariaDB)和 PHP(或 Perl、Python)。这种架构广泛用于搭建高性能的动态网站和 Web 应用程序。
- L:Linux 基础操作系统(Ubuntu、CentOS、Debian)
- N:一般指Nginx Web服务器(实现HTTP 和反向代理)
- M:一般指MySQL或MariaDB数据库管理系统(用于存储和管理网站和应用的数据)
- P:用于 Web服务器端 开发脚本语言(PHP、Perl、Python)
LNMP 架构的优势:
- 高性能:Nginx 的高并发处理能力和低资源消耗,结合 PHP-FPM(FastCGI Process Manager)的高效处理,提供卓越的性能。
- 可扩展性:通过 Nginx 的反向代理和负载均衡功能,可以轻松扩展系统以处理更多请求。
- 安全性:Nginx 提供多种安全功能,如 SSL/TLS 支持、访问控制和限速,保护网站和应用免受攻击。
- 灵活性:支持多种编程语言和数据库系统,可以根据需求选择合适的组件。
总结:LNMP 架构通过结合 Linux 操作系统的稳定性、Nginx 的高性能、MySQL 的数据管理能力和 PHP 的动态内容生成,提供了一个强大且灵活的 Web 服务器解决方案。无论是小型网站还是大型应用,LNMP 都能满足高性能和可扩展性的需求。
安装思路:LNMP在CentOS系统中,源码安装Nginx,使用RPM包安装MariaDB、PHP、PHP-FPM软件。操作过程中需要安装的软件列表如下:
- ① nginx(WEB服务器)
- ② mariadb(数据库客户端软件)、mariadb-server(数据库服务器软件)、mariadb-devel(其他客户端软件的依赖包)
- ③ php(解释器)、php-fpm(进程管理器服务)、php-mysql(PHP的数据库扩展包)
Nginx+FastCGI实现动静分离,通过localhost{}判断用户访问的是静态还是动态数据
案例:构建LNMP平台
步骤1:LNMP各软件包和依赖包安装并启动服务
1)安装使用yum安装基础依赖包
[root@proxy ~]# yum -y install gcc make //安装编译工具
[root@proxy ~]# yum -y install pcre-devel //依赖包,使nginx支持正则
[root@proxy ~]# yum -y install openssl-devel //依赖包,支持基于ssl技术的网站
2)安装Nginx
[root@proxy lnmp_soft]# tar -xf nginx-1.17.6.tar.gz //释放nginx的源码包
[root@proxy lnmp_soft]# cd nginx-1.17.6/ //切换到源码包目录
[root@proxy nginx-1.17.6]# ./configure --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
[root@proxy nginx-1.17.6]# make //编译
[root@proxy nginx-1.17.6]# make install //安装
[root@proxy ~]# useradd -s /sbin/nologin nginx //添加Nginx用户
3)安装MariaDB
[root@proxy ~]# yum -y install mariadb-server //安装数据库服务端
[root@proxy ~]# yum -y install mariadb //安装数据库客户端
[root@proxy ~]# yum -y install mariadb-devel //安装数据库依赖包(支持lnmp)
4)安装PHP、安装PHP扩展
[root@proxy ~]# yum -y install php //安装PHP环境(相当于解释器)
[root@proxy ~]# yum -y install php-mysql //安装PHP与数据库关联的软件包
[root@proxy ~]# yum -y install php-fpm //安装可使Nginx具备动态网站解析能力的软件包
步骤2:启动Nginx、MySQL、PHP服务
1)启动Nginx服务
[root@proxy ~]# /usr/local/nginx/sbin/nginx
[root@proxy ~]# netstat -nuptl | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7321/nginx: master
2)启动MySQL服务
[root@proxy ~]# systemctl start mariadb.service
[root@proxy ~]# netstat -nuptl | grep :3306 //mariadb端口号3306
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 7218/mysqld
[root@proxy ~]# systemctl status mariadb
3)启动PHP服务
[root@proxy ~]# systemctl start php-fpm.service
[root@proxy ~]# netstat -nuptl | grep :9000 //php-fpm端口号9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 7276/php-fpm: maste
[root@proxy ~]# systemctl status php-fpm
步骤3:修改nginx配置文件并启动服务(通过localhost实现动静页面分离)
[root@proxy nginx]# vim conf/nginx.conf //先通过65,71s/#//取消注释(除69)
43 location / {
44 root html;
45 index index.php index.html index.htm;
46 }
//设置默认首页为index.php,当用户在浏览器地址栏中只写域名或IP,不说访问什么页面时,服务器会把默认首页index.php返回给用户
65 location ~ \.php$ { //~是使用正则表达式,匹配包含以.php结尾
66 root html; //网站页面位置,不用改,保持默认
67 fastcgi_pass 127.0.0.1:9000; //当用户访问了.php结尾的文件,就让nginx将请求转发给本机9000端口,php-fpm服务(端口号9000)
68 fastcgi_index index.php; //动态网站的默认页面,无需修改
69 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
70 include fastcgi.conf; //将fastcgi_params修改为:fastcgi.conf配置文件(注意【;】结尾),加载Fast-CGI参数配置文件
71 }
[root@proxy conf]# /usr/local/nginx/sbin/nginx -s reload //重置文件
步骤4:创建PHP页面,测试LNMP架构能否解析PHP页面
[root@proxy ~]# cd ~/lnmp_soft/ //可参考lnmp_soft/php_scripts/test.php
[root@proxy lnmp_soft]# cd php_scripts/
[root@proxy php_scripts]# pwd
/root/lnmp_soft/php_scripts
[root@proxy php_scripts]# cp test.php /usr/local/nginx/html/
查看测试页面 test.php 内容:
<html>
<body>
This is HTML message
</br>
<?php
$c = 12;
$d = 2;
if($c > $d){echo "c is bigger";}
else{ echo "d is bigger";}
?>
</body>
</html>
测试:Firefox浏览器访问192.168.2.5/test.php(# systemctl stop firewalld)
常见报错:Nginx未将test.php做解析,直接返回给用户
- 分析:/conf/nginx.conf配置文件中的PHP配置错误(指定端口9000)
常见报错:php-fpm服务未开启、或者SELinux错误
[root@proxy nginx]# systemctl restart php-fpm
步骤5:创建PHP测试页面,连接并查询MariaDB数据库
[root@proxy ~]# cd ~/lnmp_soft/php_scripts/ //可参考lnmp_soft/php_scripts/mysql.php
[root@proxy php_scripts]# ls
mem.php test.php
mysql.php web_demo.tar.gz
...
[root@proxy php_scripts]# cp mysql.php /usr/local/nginx/html/
查看测试页面 mysql.php 内容:
<?php
$mysqli = new mysqli('localhost','root','','mysql');
//注意:root为mysql数据库的账户名称,密码需要修改为实际mysql密码,无密码则留空即可;
//localhost是数据库的域名或IP,mysql是数据库的名称;
if (mysqli_connect_errno()){
die('Unable to connect!'). mysqli_connect_error();
}
$sql = "select * from user";
$result = $mysqli->query($sql);
while($row = $result->fetch_array()){
printf("Host:%s",$row[0]);
printf("</br>");
printf("Name:%s",$row[1]);
printf("</br>");
}
?>
测试1:Firefox浏览器访问192.168.2.5/mysql.php
测试2:Firefox浏览器访问并刷新192.168.2.5/mysql.php,可看到新增的用户记录
[root@proxy html]# mysql
MariaDB [(none)]> create user ANJ@localhost identified by '123'; //创建用户
MariaDB [(none)]> quit
补充:LNMP常见问题,如果动态网站访问失败,可用参考错误日志,查找错误信息
- Nginx的默认访问日志文件为:/usr/local/nginx/logs/access.log
- Nginx的默认错误日志文件为:/usr/local/nginx/logs/error.log
- PHP默认错误日志文件为:/var/log/php-fpm/www-error.log
二、FastCGI原理(快速公共网关接口)
工作流程:
- ① Web Server启动时载入FastCGI进程管理器(通过PHP-FPM负责调度FastCGI);
- ② FastCGI进程管理器初始化,启动多个解释器进程;
- ③ 当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个解释器;
- ④ FastCGI子进程完成处理后返回结果,将标准输出和错误信息从同一连接返回Web Server;
FastCGI技术目前支持语言:PHP、C/C++、JAVA、Perl、Python、Ruby等
缺点:内存消耗大,因为是多进程,所以进程消耗更多的服务器内存,PHP-CGI解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数;
补充:Nginx+PHP(FastCGI)服务器在3万并发连接下
- ①开10个Nginx进程消耗150M内存(10*15M)
- ②开64个PHP-CGI进程消耗1280M内存(20M*64)
查看php-fpm.d配置文件(不需要修改该文件)
[root@proxy ~]# cat /etc/php-fpm.d/www.conf
2 [www]
12 listen = 127.0.0.1:9000 //php-fpm监听端口号
24 listen.allowed_clients = 127.0.0.1
39 user = apache
41 group = apache
60 pm = dynamic
70 pm.max_children = 50 //最大调度FastCGI解释器进程数量(上限)
75 pm.start_servers = 5 //默认开始调度5个FastCGI解释器进程数量
...
[root@proxy ~]# pstree | grep php //通过进程树可查看5个FastCGI进程数量
|-php-fpm---5*[php-fpm]
三、地址重写(rewrite)
URL 地址重写(URL rewriting)是一种技术,用于在服务器端修改或转换 URL 的外观,使其对用户更加友好、易于理解和记忆,同时也可以用于实现 SEO 优化、隐藏技术细节、实现重定向等功能。在 LNMP 架构中,Nginx 提供了强大的 URL 重写功能,通过配置 rewrite 指令来实现。
作用:获得一个来访的URL请求,然后改写成服务器可以处理的另一个URL的过程
- 用户体验:更简洁、易读的 URL 有助于用户理解和记忆。
- SEO 优化:搜索引擎更喜欢语义化的 URL,有助于提高网站的搜索排名。
- 隐藏技术细节:可以隐藏服务器端的技术实现细节,提高安全性。
- 重定向:可以将旧的 URL 重定向到新的 URL,避免链接失效。
1、Nginx 中的 URL 重写
Nginx 使用 rewrite
模块 来实现 URL 重写。rewrite
指令的基本语法如下:
rewrite regex replacement [flag];
regex
:用于匹配 URL 的正则表达式。replacement
:重写后的 URL。flag
:可选标志,用于控制重写行为。
常见标志(flag)
last
:停止处理当前的rewrite
指令,并开始一个新的请求。
break
:停止处理当前的rewrite
指令,但继续处理其他指令。
redirect
:返回 302 临时重定向(HTTP 状态码 302)。
permanent
:返回 301 永久重定向(HTTP 状态码 301)。
正则表达式匹配模式
- 区分大小写匹配:~
- 不区分大小写匹配:~*
- 区分大小写不匹配:!~
- 不区分大小写不匹配:!~*
示例 1:将动态 URL 重写为静态 URL
假设有一个动态生成的 URL:
http://example.com/index.php?page=about
我们希望将其重写为更友好的静态 URL:
http://example.com/about
可以在 Nginx 配置文件中添加如下 rewrite
指令:
server {
listen 80;
server_name example.com;
location / {
rewrite ^/about$ /index.php?page=about break;
# 其他配置...
}
}
示例 2:实现 301 永久重定向
假设有一个旧的 URL:
http://example.com/old-page
我们希望将其永久重定向到新的 URL:
http://example.com/new-page
可以在 Nginx 配置文件中添加如下 rewrite
指令:
server {
listen 80;
server_name example.com;
location /old-page {
rewrite ^/old-page$ /new-page permanent;
}
}
示例 3:隐藏技术细节
假设有一个动态生成的 URL:
http://example.com/index.php?id=123
我们希望将其隐藏技术细节,重写为:
http://example.com/item/123
可以在 Nginx 配置文件中添加如下 rewrite
指令:
server {
listen 80;
server_name example.com;
location /item {
rewrite ^/item/(.*)$ /index.php?id=\$1 break;
# 其他配置...
}
}
例如1:基本的地址重写
修改配置文件(访问a.html重定向到b.html)
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
...
42 rewrite /a.html /b.html; //旧地址a.html,新地址b.html
[root@proxy ~]# echo "AA" > /usr/local/nginx/html/a.html
[root@proxy ~]# echo "BB" > /usr/local/nginx/html/b.html
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload //重新加载配置文件
测试:Firefox浏览器访问192.168.2.5/a.html,以a.html域名显示b.html内容
例如2:添加正则表达式,实现规范的输入网页URL访问请求,输入错误,则404报错
思考:只要包含”/a.html”即可访问(不严谨),使用正则表达式实现书写规范
访问页面:http://192.168.2.5/a.htmlzzhhh
访问页面:http://192.168.2.5/abc/a.html
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite ^/a.html$ /b.html; //前后添加正则【^URL$】
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问192.168.2.5/abc/a.html(必须严格匹配a.html)
例如3:通过rewrite选项redirect实现地址重定向(redirect 跳转地址栏)
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite ^/a.html$ /b.html redirect; //redirect实现地址重定向
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问192.168.2.5/a.html,重定向到b.html,而不是以a.html域名显示b.html内容(可观察浏览器地址栏的变化)
例如4:旧地址位置可以写任何参数,只要浏览器访问请求(地址栏)匹配即可
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite ^/haha$ /b.html redirect;
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
注意:虽地址栏可填任何参数,但要带“/”,该“/”非根目录,表示为/usr/local/nginx/html
测试:Firefox浏览器访问192.168.2.5/haha,重定向到b.html
例如5:访问192.168.2.5的请求重定向至www.tmooc.cn
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite / http://www.tmooc.cn;
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问192.168.2.5/或者192.168.2.5,域名跳转到新网址
补充:因直接访问http://192.168.2.5即访问192.168.2.5/index.html默认页面,所以旧地址位置以包含“/”,所以可以此方式也能跳转到新网址;
例如6:访问192.168.2.5/下面子页面,重定向至www.tmooc.cn/下相同的页面
应用场景:访问并收藏了一个旧地址,再次访问时已发生新网页跳转,新网页跳转后依然加载的是旧地址页面即可。
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite /(.*) http://www.tmooc.com/$1;
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问192.168.2.5/a.html,域名跳转到新网址/旧地址页面
- 正则表达式:【()】功能:保留、组合成一个整体
- rewrite /(.*) http://www.tmooc.com/$1;
- 解释:【$1】引用前【()】保留参数
例如7:实现火狐浏览器访问与其它浏览器访问相同链接返回的页面不同
① 创建网页目录以及对应的页面文件:
[root@proxy ~]# echo "I am other WEB" > /usr/local/nginx/html/test.html
[root@proxy ~]# mkdir -p /usr/local/nginx/html/firefox/
[root@proxy ~]# echo "Firefox-WEB" > /usr/local/nginx/html/firefox/test.html
② 修改Nginx服务配置
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
.. ..
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
if ($http_user_agent ~* firefox) { //识别客户端firefox浏览器
rewrite ^(.*)$ /firefox/$1;
}
}
解释1:~符号代表正则匹配,*符号代表不区分大小写(Nginx独有符号);(.*)代表复制用户查看的页面,$1代表粘贴;
解释2:Nginx的内置变量http_user_agent存放用户信息,例如客户端使用什么浏览器。当用户来访信息中包含firefox(忽略大小写),则判断条件成立,并执行地址重写;
③ 重新加载配置文件
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
测试:
[root@proxy ~]# curl http://192.168.2.5/test.html
I am other WEB
Firefox浏览器访问http://192.168.2.5/test.html,如图所示:
Google浏览器访问http://192.168.2.5/test.html,如图所示:
例如8:再次修改nginx配置文件,在2个地址重写rewrite情况下,增加last选项
last:停止执行其它重写规则,地址栏不改变;(仅作用在同一个location{}中)
停止处理当前的rewrite
指令,并开始一个新的请求。
[root@proxy ~]# cd /usr/local/nginx/html/
[root@proxy html]# echo "AAA" > a.html
[root@proxy html]# echo "BBB" > b.html
[root@proxy html]# echo "CCC" > c.html
① 实验前:
[root@proxy html]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite /a.html /b.html;
43 rewrite /b.html /c.html;
...
[root@proxy html]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问 http://192.168.2.5/a.html,如图所示:
解释:未增加Last选项,地址栏不变,2个地址重写的跳转:a.html —> b.html —> c.html
② 测试后:增加Last选项
[root@proxy html]# vim /usr/local/nginx/conf/nginx.conf
42 rewrite /a.html /b.html last; //增加Last选项
43 rewrite /b.html /c.html;
...
[root@proxy html]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问http://192.168.2.5/a.html,如图所示:
解释:增加Last选项,地址栏不变,2个地址重写的跳转:a.html —> b.htmll
例如9:再次修改nginx配置文件,在2个地址重写rewrite情况下,增加break选项
break:停止执行其它重写规则,完成本次请求就不再读其它语句(可作用在不同location{}中的rewrite)
停止处理当前的
rewrite
指令,但继续处理其他指令。
① 实验前:
[root@proxy html]# vim /usr/local/nginx/conf/nginx.conf
44 location / {
45 rewrite /a.html /b.html last; //已增加Last选项,按理应停止
46 root html;
47 index index.html index.htm;
48 }
49 location /b.html{ //增加了新的location{}及rewrite地址重写
50 rewrite /b.html /c.html;
51 }
[root@proxy html]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问http://192.168.2.5/a.html,如图所示:
解释:虽增加Last选项,但由于第一个rewrite的last选项在单独的一个location{},第二个rewrite在另一个loaction{},last选项仅作用在同一个location{}中的rewrite,所以2个地址重写的跳转:a.html —> b.html —> c.html;
② 实验后:增加break选项
[root@proxy html]# vim /usr/local/nginx/conf/nginx.conf
44 location / {
45 rewrite /a.html /b.html break; //增加break选项
46 root html;
47 index index.html index.htm;
48 }
49 location /b.html{
50 rewrite /b.html /c.html;
51 }
[root@proxy html]# /usr/local/nginx/sbin/nginx -s reload
测试:Firefox浏览器访问http://192.168.2.5/a.html,如图所示:
解释:增加break选项,地址栏不变,2个地址重写不同location{}的跳转:a.html —> b.htmll
补充:permanent选项与redirect选项功能差不多
- Redirect选项 临时重定向 网站状态码 302
- Premanent选项 永久重定向 网络状态码 301
针对搜索引擎例如百度、360等,Python爬虫不识别302
[root@proxy html]# vim /usr/local/nginx/conf/nginx.conf
44 rewrite /a.html /b.html permanent;
[root@proxy html]# /usr/local/nginx/sbin/nginx -s reload
补充:index index.html index.htm; 记录
- index 指定默认页面,当访问http://192.168.2.5,可忽略页面,因index已指定的默认页面index.html;
- index.html 默认索引页面
- index.htm 备用页面(当index.html页面没有,则使用备用)
思维导图:
小结:
本篇章节为【第二阶段】OPERATION-DAY2 的学习笔记,这篇笔记可以初步了解到 部署LNMP架构(linux、Nginx、MariaDB、PHP)、Nginx+FastCGI动静分离、Nginx地址重写。
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解