LNMP环境部署
LNMP:linux nginx mariaDB/mysql PHP/Python
每次访问需要服务器执行一遍代码,服务端将结果交给客户端,执行了这个过程的网站就是动态网站,即使这个页面内容没有变化。
补充:
PHP只能用来做网页,不能做软件开发
windows里的shell是bat
做网站使用的主流语言是php和java 一部分是python 例如 知乎 豆瓣
环境部署所需软件:
mysql* (等下具体解释)
php
php-fpm(是解释服务,php8.0无需单独安装,装完php就有了)
php-mysql(扩展包,php8.0无需单独安装)
补充:软件的模块化设计。想用谁就下载哪个模块
PHP--mysql #让PHP可以连接mysql的模块功能,php8.0之后--with-mysqli此选项开启支持
PHP--oracle数据库 #因为可能要连很多数据库,公司可能只用一种,所以那么多没用,必须要模块化
开始前准备:
一定要把httpd关了:systmctl stop httpd 因为apche用的也是80,卸载apache、mariadb(没有可忽略)
服务端部署:
1.使用yum安装基础依赖包
yum -y install gcc openssl-devel pcre-devel
2.安装Nginx
见上一篇的安装步骤
[root@proxy ~]# make && make install
3.安装mysql
(1)装mysql包的前提:
停止mariadb服务:
systemctl stop mariadb
删除/etc/my.cnf配置文件此配置文件由RHEL自带的mariadb-libs库提供:
rm -rf /etc/my.cnf
删除数据rm -rf /var/lib/mysql/* (这一步应该是装完mysql软件做的操作)
卸载软件包(没有会显示未安装软件包):
rpm -e --nodeps mariadb-server mariadb mariadb-libs //忽略依赖强制卸载
(2)安装mysql时可能会缺少某些依赖包,需提前单独安装(红帽光盘软件源里一般都有):
yum -y install perl-Data-Dumper perl-JSON perl-Time-HiRes
(3)进入解压完那些mysql.rpm的目录里面,依次安装mysql的相关软件包:
rpm -ivh mysql-community-common-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-plugins-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-icu-data-files-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-8.0.37-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-8.0.37-1.el7.x86_64.rpm //不装这个包没有/usr/bin/mysql_config
rpm -ivh mysql-community-libs-compat-8.0.37-1.el7.x86_64.rpm //不装这个不支持snmp,装不了net-snmp-devel包,这个包在zabbix中用到
(4)压缩包里所含的软件包内容:
./mysql-community-client #客户端应用程序,用于存放数据库管理命令
./mysql-community-common #数据库和客户端库共享文件
./mysql-community-devel #客户端应用程序的库和头文件
./mysql-community-embedded #嵌入式函数库
./mysql-community-embedded-compat #嵌入式兼容函数库
./mysql-community-embedded-devel #头文件和库文件作为mysql的嵌入式库文件
./mysql-community-libs #数据库客户端应用程序的共享库
./mysql-community-libs-compat #客户端应用程序的共享兼容库
./mysql-community-minimal-debuginfo
./mysql-community-server #用来提供数据库服务的软件
./mysql-community-test
du -sh mysql-5.7.17.tar #这条命令可以查看这个目录大小,大概是900多M
rpm -qa | grep -i mysql #查看这个mysql软件是否安装了,及详细状态
(5)安装完以后需要初始化数据库:
mysqld --initialize --console
(6)给mysql用户赋权使其对相关目录有权限:
chown -R mysql:mysql /var/lib/mysql
(7)启动mysql服务,并设置开机自启动
systemctl start mysqld
systemctl enable mysqld
4.php环境部署:
软件包下载:
php官方下载地址:https://www.php.net/downloads下载tar.gz包,本次下载使用的是8.2.21,参数以本次为准
8.0以后的php的tar包里在编译安装时会默认安装php-fpm所以不需要单独下载
(1)先更换yum源到阿里云的
touch /etc/yum.repos.d/epel.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo && yum clean all && yum makecache
//下载并替换epel.repo文件
(2)yum安装php所需要的依赖:
#C编译器:例如GCC或Clang
#Autotools:包括autoconf和automake
#Bison和Flex:用于生成解析器和词法分析器
#libxml2:用于XML解析
#libssl-dev:用于加密和解密SSH和SSL连接
yum -y install
gcc gcc-c++ autoconf automake libtool make libxml2 libxml2-devel openssl oniguruma oniguruma-devel \
openssl-devel sqlite-devel libpng libpng-devel libpsl libpsl-devel libicu-devel libcurl-devel libjpeg libjpeg-devel \
freetype freetype-devel openldap-devel
cp -frp /usr/lib64/libldap* /usr/lib/
#这是php-ldap模块的库文件,有的时候64位的这个地址库文件在的这个目录,但是php编译时识别不到,所以提前复制一份到能识别的目录
(3.1)编译php:
./configure \
--prefix=/usr/local/php --with-mysqli --with-zlib --with-curl --with-gettext --with-openssl --enable-fpm \
--enable-mbstring --enable-xml --enable-session --enable-ftp --enable-pdo --enable-gd --enable-bcmath --enable-sockets \
--with-jpeg --with-freetype --with-ldap --with-ldap-sasl
(3.2)php编译参数详解:./configure --help可以查参数项
--prefix=/usr/local/php
#指定PHP的安装路径
--with-config-file-path=/usr/local/php/etc
#指定php.ini的位置
--with-mysql=/usr/bin/mysql
#启用MySQL支持,并指定MySQL的可执行文件的路径,PHP7貌似已经取消了支持,编译都没有了--with-mysql参数
--with-mysqli=/usr/local/mysql/bin/mysql_config
#mysqli扩展技术不仅可以调用MySQL的存储过程、处理MySQL事务,而且还可以使访问数据库工作变得更加稳定。
--prefix=/usr/local/php
#指定 php 安装目录
--with-config-file-path=/usr/local/php/etc
#指定php.ini位置
--enable-fpm
#php进程管理服务,比如当用户访问网页时,php-fpm可以自动执行php a.sh这样的动作,而不是管理员手动操作
--enable-safe-mode
#打开安全模式
--enable-ftp
#打开ftp的支持
--enable-zip
#打开对zip的支持
--with-bz2
#打开对bz2文件的支持
--with-libXML-dir
#打开libxml2库的支持
--with-zlib-dir
#打开zlib库的支持
--enable-bcmath
#打开图片大小调整,用到zabbix监控的时候用到了这个模块
--enable-pdo
#PHP数据对象PDO扩展为PHP访问数据库定义了一个轻量级的一致接口,PDO提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。
--with-apxs2=/usr/local/apache/bin/apxs
#整合apache,apxs功能是使用mod_so中的LoadModule指令,加载指定模块到 apache,要求 apache 要打开SO模块
--without-iconv
#关闭iconv函数,各种字符集间的转换
--with-XMLrpc
#打开xml-rpc的c语言
--enable-gd
#打开gd库的支持
--enable-gd-native-ttf
#支持TrueType字符串函数库
--with-curl
#打开curl浏览工具的支持
--with-curlwrappers
#运用curl工具打开url流
--with-ttf
#打开freetype1.*的支持,可以不加了
--with-xsl
#打开XSLT 文件支持,扩展了libXML2库 ,需要libxslt软件
--with-gettext
#打开gnu 的gettext 支持,编码库用到
--with-pear
#打开pear命令的支持,PHP扩展用的
--enable-calendar
#打开日历扩展功能
--enable-mbstring
#该模块主要用于检测和转换编码,提供对应的多字节操作的字符串函数。如果要开启此功能,需要提前安装oniguruma和oniguruma-devel包,这个包是处理正则表达式的库
--enable-sockets
#打开 sockets 支持
--enable-exif
#图片的元数据支持
--enable-magic-quotes
#魔术引用的支持
--disable-rpath
#关闭额外的运行库文件
--disable-debug
#关闭调试模式
--with-mime-magic=/usr/share/file/magic.mime
#魔术头文件位置
--enable-fpm
#打上PHP-fpm 补丁后才有这个参数,CGI方式安装的启动程序,PHP5.3.3开始就已经内置了php-fpm
--enable-fastCGI
#支持fastcgi方式启动PHP
--enable-force-CGI-redirect
#重定向方式启动PHP
--with-ncurses
#支持ncurses 屏幕绘制以及基于文本终端的图形互动功能的动态库
--enable-pcntl
#freeTDS需要用到的,可能是链接mssql 才用到
--with-mcrypt
#mcrypt算法的扩展
--with-mhash
#mhash算法的扩展
--enable-inline-optimization
#优化线程
--with-openssl
#openssl的支持,加密传输时用到的
--enable-dbase
#建立DBA 作为共享模块
--with-pcre-dir=/usr/local/bin/pcre-config
#perl的正则库案安装位置
--with-gdbm
#dba的gdbm支持
--enable-tokenizer
#从 PHP 4.4.0 开始,这些函数默认是被激活的. 对于旧版本在配置和编译 PHP 是使用 --enable-tokenizer 选项. 也能使用 --disable-tokenizer 选项禁用 tokenizer 支持.
#PHP 的 Windows 版本已内建对此扩展的支持。不需要载入额外的扩展来使用这些函数。
(4)安装php:
make && make install
#注意一定是两个&,不然会报错,如出现报错,可以make clean解决问题后,再执行make && make install重新安装,无需继续./config编译
#php安装时间较长
如果报错:/usr/bin/ld: ext/ldap/ldap.o: undefined reference to symbol 'ber_strdup'
可以在php源码目录里vim Makefile
在开头是'EXTRA_LIBS'的行结尾加上 '-llber'
安装完以后的重要信息:
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20220829/
Installing PHP CLI binary: /usr/local/php/bin/
Installing PHP CLI man page: /usr/local/php/php/man/man1/
Installing PHP FPM binary: /usr/local/php/sbin/
Installing PHP FPM defconfig: /usr/local/php/etc/
Installing PHP FPM man page: /usr/local/php/php/man/man8/
Installing PHP FPM status page: /usr/local/php/php/php/fpm/
Installing phpdbg binary: /usr/local/php/bin/
Installing phpdbg man page: /usr/local/php/php/man/man1/
Installing PHP CGI binary: /usr/local/php/bin/
Installing PHP CGI man page: /usr/local/php/php/man/man1/
Installing build environment: /usr/local/php/lib/php/build/
Installing header files: /usr/local/php/include/php/
Installing helper programs: /usr/local/php/bin/
program: phpize
program: php-config
Installing man pages: /usr/local/php/php/man/man1/
page: phpize.1
page: php-config.1
Installing PDO headers: /usr/local/php/include/php/ext/pdo/
安装完成以后设置一个软连接,就可以直接使用php命令了
ln -s /usr/local/php/bin/php /usr/bin/php
#放到/bin里就是全局用户都可以使用
查看版本信息
php -v
php -m
#可以查看编译安装的功能
安装完PHP以后的php-fpm如何使用:
约定几个目录
/usr/local/php/sbin/php-fpm
/usr/local/php/etc/php-fpm.conf
使用前:
mv /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf
mv /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
#此时fpm的conf文件需要改名才能启动
php-fpm的启动参数
可以提前给php-fpm制作软连接:
ln -s /usr/local/php/sbin/php-fpm /usr/sbin/php-fpm
#放到/sbin里就是全局用户都可以使用
# 测试php-fpm配置是否正确,两条命令功能一致
/usr/local/php/sbin/php-fpm -t
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf -t
#-c是指定php.ini文件的位置,但是8.0以后好像看不到这个文件,但是能执行成功
# 启动php-fpm
/usr/local/php/sbin/php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf
#-c的意思是在/usr/local/php/etc/php.ini找ini文件,这个是php的配置文件
# 关闭php-fpm
kill -INT 进程id
#可以用netstat -ntulp | grep php-fpm命令查
# 重启php-fpm
kill -USR2 进程id
#设置php-fpm开机自启动及systemctl管理
vim /etc/systemd/system/php-fpm.service
[Unit]
Description=php-fpm
[Service]
Type=forking
ExecStart=/usr/local/php/sbin/php-fpm
PrivateTmp=true
[Install]
WantedBy=multi-user.target
systemctl enable php-fpm
(5)然后服务端本机新建php脚本/usr/local/nginx/html/a.php此时效果
<?php
$i=33; #这两行是指令,一定要写分号,php定义变量也需要$
echo $i;
?>
验证的话需要执行命令:
php /usr/local/nginx/html/a.php
但是这种访问网页的方式,会把这个网页整个下载一遍,然后看到的是网页源代码,不合理,所以要做动静分离!
做以下操作:
启动nginx
启动mysql:
systemctl start mysql
systemctl enable mysql
启动php解释器的管理服务:
systemctl start php-fpm
systemctl enable php-fpm
设置防火墙与SELinux(非必需操作,如果有则关闭)
firewall-cmd --set-default-zone=trusted
setenforce 0
查看各个服务是否存活
netstat -ntulp | grep:80 或者 9000(php-fpm)或者 3306 #查看使用的协议情况,和服务名,没有则需要启动
改nginx配置文件:
如果用户要静态页面,直接给,如果要动态页面,就交给9000端口的服务去处理。
利用的就是Nginx配置文件里的location实现这两分支功能
用户访问" / " 即nginx根目录下的任一网页,返回静态页面 访问.php结尾的网页文件,则由php-fpm执行返回源码
FastCGI技术点补充:
是一种转译器!linux本身无法翻译php语言,由FastCGI技术进行转译,将FastCGI写入FPM解释器,实现linux与php互通!注意,FastCGI的内存消耗问题,一个PHP-FPM解释器将消耗约25M的内存。
以下是静态页面:
server {
listen 80;
server_name www.c.com;
location / { # / 是指根网页目录,可以匹配一切,但是这个优先级最低,Location就是匹配用户的地址栏
root html;
index index.html index.htm;
}
以下是同www.c.com域名但是结尾以.php结尾的网页设置,也就是动态网页,当然用户输入的必须是www.c.com/index.php才可以动态访问
location ~ \.php$ { # ~符号代表开启正则匹配 \是转译.否则会被当作正则的任意字符 也就是以所有以.php结尾的网页都给这个server写的内容
root html;
index index.php;
fastcgi_pass 127.0.0.1:9000; #将请求转发给本机9000端口也就是PHP解释器php-fpm
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 这一行要注释掉
include fastcgi.conf; #启用调用文件fastcgi.conf,这里面写的是内置变量,以前的错了
}
Nginx是利用多进程功能,将客户的访问请求交给多个PHP解释器处理,php-fpm处理完再返回给nginx。(Nginx配置文件支持正则表达)
以下几点需要明白:
多进程的程序:开启多个程序的进程
程序:APP没启动之前,在硬盘上
进程:正在执行的程序 好多人同时看好多页面,只有多进程才能做到,否则是看完一个关了才能看别的。进程占用的是内存
线程:可以在进程底下再启动多个线程去做进程的工作细致划分。共享进程占用的内存。
可以利用ps aux | grep php 查看进程的状态
这时候要配置php-fpm配置文件来配合Nginx(实验中不需要修改该文件)
[root@proxy etc]# vim /usr/local/php/etc/php-fpm.d/www.conf
[www]
listen = 127.0.0.1:9000 //指定PHP服务的端口号
pm.max_children = 32 //允许开启最大进程数量
pm.start_servers = 15 //默认就开启的最小进程数量
pm.min_spare_servers = 5 //最少需要几个待命的进程,因为启动进程也需要时间
pm.max_spare_servers = 32 //最多允许几个进程处于空闲状态
总结部署lnmp的3步骤
1.安装nginx mysql php等
2.启动3个服务
3.修改nginx配置文件改两行,和php-fpm配置文件
******************************************************************************************************************************
排错!
Nginx的默认访问日志文件为/usr/local/nginx/logs/access.log
Nginx的默认错误日志文件为/usr/local/nginx/logs/error.log
PHP默认错误日志文件为/var/log/php-fpm/www-error.log
如果动态网站访问失败,可用参考错误日志,查找错误信息。
tail 命令默认看最后十行
tailf /usr/local/nginx/logs/error.log 可以实时看nginx错误日志,再有错误发生,会弹出信息
常见3种错误
没启动某个服务
nginx自己的配置错了
网页文件的语法错了 这种错误不会有日志提示
************************************************************************************************************
目前数据库功能没有体现!要让PHP支持数据库!这个功能在lnmp里的php_scripts里,叫mysql.php 拷贝到网站根目录底下
然后客户输入www.a.com/mysql.php 验证即可
如果对方敲ip地址不敲域名。就遵循匹配及停止,只打开第一个server!
*************************************************************************************************************
地址重写!rewrite
用户输入的域名360buy,被重写成了jd!
http://baidu https://baidu
或者文件不在了,换位置了
因为没有人会去打https 所以用地址重写功能
每次修改完配置文件别忘了重启动服务
案例1:当用户访问www.a.com/a.html的时候,自动跳到www.a.com/b.html
修改nginx配置文件
在servername www.a.com;
下面加一行
rewrite /a.html /b.html; #别忘了写一个b.html在网站根目录里
第二种,域名跳www.a.com以及下面的所有页面都跳到tmooc.cn
在servername www.a.com;加一行
rewrite ^/ http://www.tmooc.cn; #一个旧地址(支持正则表达式)这个/是指在地址栏输入的所有以www.a.com开头的地址都跳到 www.tmooc.cn 这个域名里
第三种,访问www.a.com老域名下的子页面,会跳到新域名里名称一样的子页面, 就需要正则 () 了
在servername www.a.com;加一行
rewrite ^/(.*) http://www.tmooc.cn/$1 #找到所有以根目录开头的行,将根后面的所有复制,然后粘贴,这里\1用$1表示 nginx自己的规则
第四种,电脑打开www.sina.com/x 电脑打开是宽屏
手机打开www.sina.com/x 手机打开是窄屏
最终显示的结果不一样,前提有两套页面
在servername www.a.com;里写
实现其他浏览器和火狐浏览器访问相同链接返回的页面不同(可以基于手机,浏览器)
先准备两个页面,当用户在不同浏览器输入www.a.com/a.html反还不同页面
/usr/local/nginx/html/phone/a.html 文件名一样,让人觉得是一个页面
/usr/local/nginx/html/a.html
想要实现上述功能需要,以下相关知识的协助:
需要nginx的日志文件/usr/local/nginx/logs/access.log
关于日志文件显示的内容,它的所有含义,都在nginx的配置文件里定义了
以下是nginx配置文件定义的日志文件每一列的含义
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
1.远程访问我们nginx的ip地址 2.- 3.访问我们nginx的客户端用户名-代表没有用户名 4.[ 本地时间 ] 5.客户请求什么页面
6.状态是什么样200代表一切正常404是找不到页面 7.这个页面有多少字节 8.没有的时候是- 原意思是从哪个链接过来的(例如百度搜索新浪)如果百度要钱,这个是参考依据 9.代表客户端的用户信息包含用户操作系统,用户浏览器
利用第9条,标示功能,来实现功能要求
怎么写规则:
server {
listen 80;
server_name www.a.com;
if ($http_user_agent ~* firefox) { #如果是对应标示firefox,就执行地址重写,不管访问根网站下面哪个子页面,都跳转到firefox目录下的对应子页面。~代表的就是开启正则匹配 *在nginx里是不区分大小写
rewrite ^/(.*) /phone/$1;
}
location / {
root html;
index a.html;
}
}
题外:用户标示:用户使用浏览器时,可以更改自己的系统是手机或者是电脑端,伪装
只要用户访问首页,就会默认先访问一遍favicon.ico这个文件对应的是就是在地址栏中的网站logo
rewrite 旧地址 新地址 [选项];
选项含义:
last 不再读其他rewrite
break 不再读其他语句,结束请求
redirect 临时重定向
permament 永久重定向
例:rewrite /a.html /b.html last;
rewrite /b.html /c.html; 不写last,访问a时会出现c里的页面,写了之后就只会出现b的内容,当然如果访问b的话,还会进入c的页面
例:location /a.html {
rewrite /a.html /b.html break; 不写break,只写last就没用了,因为location会强制执行,break就退的很彻底!当然访问b.html还可以进入/c.html
location /b.html {
rewrite /b.html /c.html;
例:rewrite /a.html /b.html redirect;
permanment;告诉别人,a.html不会回来了,但是其实没卵用,用户根本看不到,
是给搜索引擎看的,它把里面的内容记录下来,如果是临时就不会改,后面写了永久就会改。