第十七周

1.nginx负载均衡中常见的算法及原理有哪些

#实现nginx负载均衡的组件
# 官方文档: http://nginx.org/en/docs/http/ngx_http_upstream_module.html
# 官方文档: http://nginx.org/en/docs/http/ngx_http_proxy_module.html
ngx_http_proxy_module proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池
ngx_http_upstream_module 负载均衡模块、可以实现网站的负载均衡功能及节点的健康检查

严格地说,nginx仅仅是作为nginx proxy 反向代理使用的,因为这个反向代理功能表现的效果是负载均衡集群的效果,所以本文称之为nginx负载均衡。

#那么反向代理和负载均衡由什么区别呢?
普通负载均衡软件,例如大名鼎鼎的LVS,其实现的功能只是对请求的数据包的转发(也可能会改写数据包)、传递,其中DR模式明显特征是从负载均衡下面的RS节点服务器来看,接收到的请求还是来自访问负载均衡服务器的客户端的真实用户,而反向代理就不一样了,从反向代理接收访问用户的请求后,会代理用户重新发起请求代理下的节点服务器,最后把数据返回给客户端用户,在节点服务器看来,访问的节点服务器的客户端用户就是反向代理服务器,而非真实的网站访问用户。
LVS等的负载均衡是转发用户请求的数据包,而nginx反向代理是接收用户的请求然后重新发起请求去请求其后面的节点。
#nginx 负载均衡调度算法
#nginx 官方文档: http://nginx.org/en/docs/http/load_balancing.html
调度算法一般分为两类:
静态调度算法,即负载均衡根据自身设定的规则进行分配,不考虑后端rs服务器的情况,例如 rr wrr ip_hash等都属于静态算法
动态掉段算法:即负载均衡会根据后端RS的当前负载状态来决定是否分发请求,例如连接数少的优先得到请求,响应时间短的优先获取请求。例如:least_conn算法fair等都属于动态调度算法

nginx支持以下负载平衡机制:
轮询/加权轮询:对应用程序服务器的请求以轮循机制方式分发,默认的负载均衡机制
最少连接:下一个请求分配给活动连接数最少的服务器
ip_hash:  哈希函数用于确定应为下一个请求选择哪个服务器(基于客户端的 IP 地址)


默认负载平衡配置,如果未专门配置负载平衡方法,则默认为加权轮循机制,默认的权重都是1
加权负载平衡,还可以通过使用服务器权重进一步影响nginx负载平衡算法。
未配置服务器权重,这意味着所有指定的服务器都被视为对特定负载平衡方法具有相同的条件。
特别是对于轮循机制,它还意味着在服务器之间或多或少地均匀分配请求 - 只要有足够的请求,并且请求以统一的方式处理并且完成得足够快


最少连接的负载平衡,另一个负载平衡规则是连接最少的。连接最少允许在某些请求需要更长时间才能完成的情况下更公平地控制应用程序实例上的负载。
使用连接最少的负载平衡,nginx将尝试不要用过多的请求使繁忙的应用程序服务器过载,而是将新请求分发到不太繁忙的服务器.当least_conn指令用作服务器组配置的一部分时,nginx中连接最少的负载平衡被激活

会话持久性:
请注意,使用轮循机制或连接最少的负载平衡,每个后续客户端的请求可能会分发到不同的服务器。无法保证同一客户端将始终定向到同一服务器。

如果需要将客户端绑定到特定的应用程序服务器 — 换句话说,使客户端的会话"粘性"或"持久性",以便始终尝试选择特定服务器 — 可以使用 ip_hash 负载平衡机制。

使用 ip 哈希时,客户端的 IP 地址用作哈希键,以确定应为客户端的请求选择服务器组中的哪个服务器。此方法可确保来自同一客户端的请求将始终定向到同一服务器,除非此服务器不可用。
要配置 ip 哈希负载平衡,只需将ip_hash指令添加到服务器



除了以上算法之外,还有一些第三方的调度算法,例如: url_hash 一致性hash算法 fair(动态调度算法)

fair(动态调度算法)
此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配,这是更加智能的调度算法。此中算法可以一句页面大小和加载时间长短智能地进行负载均衡,也就是根据户端服务器的响应时间来分配请求,响应时间短的优先分配。
nginx 本身不支持fair调度算法,此模块不与NGINX源一起分发.如果需要使用这种调度算法,必须下载nginx的相关模块 upstream_fair

#安装:
此模块不与NGINX源一起分发。您可以浏览其git存储库或下载tar球
https://github.com/gnosek/nginx-upstream-fair/tree/master

解压缩后,将以下选项添加到NGINX命令中:./configure

--add-module=path/to/upstream_fair/directory

然后和像往常一样。makemake install
url_hash算法
与ip_hash类似,这里时根据访问url的hash结果来分配请求的,让每个url定向到同一个后端服务器,后端服务器未缓存服务器时效果显著。
在upstream中加入hash 语句,server语句中不能写入 weight等其他参数,hash_method使用的时hash算法。
url_hash按照访问URL的hash结果来分配请求,时灭个url定向到同一个户端服务器,可以进一步提高后端缓存服务器的效率命中率

一致性hash算法
一致性hash算法一般用于代理后端业务为缓存服务的场景,通过将用户的URL或指定的字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI或者指定字符串都会被掉段到这一台服务器上,一次后端的每个节点缓存的内容都是不同的。一致性hash算法可以解决后端某个或者几个节点宕机后,缓存的数据动荡最小。
虽然nginx 本身不支持一致性hash算法,但是nginx的分支版本 tengine支持


#健康检查
nginx中的反向代理实现包括带内(或被动)服务器运行状况检查。如果来自特定服务器的响应因错误而失败,nginx 会将此服务器标记为失败,并将尝试在一段时间内避免为后续入站请求选择此服务器。

max_fails指令设置在fail_timeout期间应发生的与服务器通信的连续失败尝试次数。默认情况下,max_fails设置为 1。如果设置为 0,则对此服务器禁用运行状况检查。fail_timeout参数还定义了将服务器标记为失败的时长。在服务器发生故障后fail_timeout间隔后,nginx将开始使用实时客户端的请求正常探测服务器。如果探测成功,则服务器将标记为活动服务器

负载均衡配置示例:
#ip_hash
#当调度算法未ip_hash时,后端服务器在负载均衡掉段中的状态不能由 weight和backup,即使由也不会生效
#least_conn
#hash $request_uri


upstream myapp1 {
#ip_hash
#least_conn
#hash $request_uri;

    server srv1.example.com weight=3 max_fails=3 fail_timeout=15s ;
    server srv2.example.com weight=2 max_fails=3 fail_timeout=15s  down;
    server srv3.example.com weight=1 max_fails=3 fail_timeout=15s backup ;
}

2.nginx的rewrite指令

rewrite指令
官方文档:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

该模块用于使用 PCRE 正则表达式更改请求 URI、返回重定向以及有条件地选择配置。ngx_http_rewrite_module
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序一次对URI进行匹配,rewrite主要是针对客户请求的URL或者URI做具体的处理

rewrite可以配置在 server、location、if
语法格式:
rewrite regex replacement [flag];

rewrite将用户请求的uri基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI

注意:如果在同一级配置块中存在多个rewrite规则,那么会自上而下逐个检查;被某个条件规则替换完成后,会重新一轮的替换检查,隐含由循环机制,但是不超过10次;如果超过,提示500响应码,[flag] 所表示的标志位用于控制此循环机制。
如果替换后的URI是以http://或者https://开头,则替换结果会直接以重定向返回给客户端,即永久重定向 301

rewrite flag 使用介绍
利用nginx 的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时重定向302) permanent(永久重定向301) break和last,其中前两种是跳转型的flag,后两种是代理型。

跳转型指有客户的浏览器重新对新地址进行请求
代理型是在web服务器内部实现跳转
rewrite 格式

Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if

flag 说明:
redirect
临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新的URL 给客户端,由客户端重新使用相对路径,或者http://或者https://开头,状态码 302 

permanent
重写完成后以永久重定向方式直接返回写后生成的新url给客户端,由客户端重新发起新请求,状态码 301

break
重写完成后,停止对当前url在当前location 中后续的其他重写操作,而后直接跳转至重写规则配置块之后的其他配置;结束循环,建议在location 中使用
适用于一个URL一次重写

last
重写完成之后,停止对当前url在当前location 中后续的其他重写操作,而后对新url启动新一轮重写检查,不建议在location 中使用
适用于一个URL多次重写,要注意避免出现超过10次以及	url重写后返回错误的给用户
rewrite案例: 域名永久与临时重定向
域名的临时的调整,后期可能会变,之前的域名或者URL可能还用,或者跳转的目的域和URL还会跳转,这种情况下浏览器不会缓存跳转,临时重定向不会缓存域名接卸记录(A记录),但永久重定向会缓存。

域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳
转,这种情况浏览器不
会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存

域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器
不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久
重定向最大的本质区别。

示例:因业务需要,将访问源域名 www.magedu.org的请求永久重定向到 www.magedu.com 

www.magedu.org  -->  http://www.magedu.com/
浏览器发起两次请求 地址栏的地址从 www.magedu.org 变为 http://www.magedu.com/

rewrite 写法:
 rewrite  /   http://www.magedu.com permanent ;
 rewrite  ^/       http://www.magedu.com/ permanent ;
 rewrite  ^/(.*)   http://www.magedu.com/$1 permanent;
 rewrite  ^/(.*)   http://www.magedu.com/$1 permanent;

#server 配置
[root@vsftpd00 conf.d]# cat pc.conf 
server {
        listen       80;
        server_name   www.magedu.org;
        charset utf-8;
        proxy_set_header Host  $host;
        location / {
            root   html/beijing;
            index  index.html index.htm;

      rewrite / http://www.magedu.com;
      
      
      # proxy_pass http://myapp1;
      # rewrite ^(.*)$ https://$server_name$1 permanent;

            allow 192.168.80.0/24;
            deny all;

        }

}
#http永久跳转至https
域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到
客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息
http://beijing.magedu.org  永久重定向至  https://beijing.magedu.org

#server 配置
[root@vsftpd00 conf.d]# cat beijing.conf 
server {

        listen       80;
        server_name  www.bj.org;
       
        charset utf-8;

        access_log  logs/beijing.access.log  main;

        proxy_set_header Host  $host;

        
        location / {
            root   html/beijing;
            index  index.html index.htm;

             proxy_pass http://myapp1;
             rewrite ^(.*)$ https://$server_name$1 permanent;

             allow 192.168.80.0/24;
             deny all;

        }


         error_page  404              /404.html;
        
        # 访问页面发送 404  则 将 404 转为 302  重定向到网站主页
        ## error_page  404 =302              /index.html;

        # redirect server error pages to the static page /50x.html

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;
        }



}

#https 

server  {
   
   listen  443 ssl ;

   server_name beijing.magedu.org ;
   

   ssl_certificate      /app/nginx/ca/bj/beijing.magedu.org.pem;
   ssl_certificate_key  /app/nginx/ca/bj/beijing.magedu.org.key;
    
   keepalive_timeout   60;
   ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
   ##ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
   ssl_ciphers HIGH:!aNULL:!MD5;
   ssl_session_cache   shared:SSL:10m;
   ssl_session_timeout 10m;

   location   / {

        root  html/beijing ;

        index index.html index.htm; 
        } 

}

3.实现反向代理客户端IP透传

实现反向代理客户端IP透传的案例应该给出完整的步骤,但是下面还有个LNMP的综合案例,因此,此处就不写出完整的步骤了。在LNMP综合案例给出完整的步骤,避免重复的步骤
#允许重新定义或附加字段到传递给代理服务器的请求标头
#设定发往后端服务器的请求报文的请求首部的值 
#在代理服务器上设置 http 报头信息 
#设置http请求header项传给后服务器节点,例如: 可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址
#允许在传递给代理服务器的请求标头中重新定义或附加字段 。该value可以包含文本,变量,以及它们的组合

节点服务器多虚拟主机:
#当反向代理服务器向后重新发起请求时候,要携带主机头信息,以明确告诉节点服务器要找哪个虚拟主机
#这是节点服务器多虚拟主机时候的关键配置 
#在代理向后端服务器发送的 http 请求头中加入 host 字段信息后,若后端服务器配置有多个虚拟主机,它就可以识别代理的是哪个虚拟主机,这是节点服务器多虚拟主机时候的关键配置
#Syntax:	proxy_set_header field value;
#Default:proxy_set_header Host $proxy_host;
#proxy_set_header Connection close;
#Context:	http, server, location
proxy_set_header Host  $host;

反向代理客户端IP透传:

#在反向代理请求后端节点服务器的请求头中增加获取客户端IP的字段信息 然后节点后端服务器可以通过程序或者相关配置接收 X-Forwarded-For 传过来的客户真实IP 
#在代理向后端服务器发送的 http 请求头中加入 X-Forwarded-For 字段信息,用于后端服务器程序 日志等接收 记录真实的用户IP 而不是代理服务器的IP
#Syntax:	proxy_set_header field value;
#Default:	proxy_set_header Host $proxy_host;
#proxy_set_header Connection close;
#Context:	http, server, location 

#只添加客户端IP到请求报文头部,转发至后端服务器
proxy_set_header X-Real-IP $remote_addr;
#添加客户端IP和反向代理服务器IP到请求报文头部
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#proxy_set_header X-Forwarded-For $remote_addr;
仅在代理服务器上设置了该头部字段后还不够,因为后端服务器仅仅只是获取到它,默认并没有将其记录下来。所以需要在后端的服务的日志格式设置上记录此项或者在其他有需求的地方设置它

nginx主配置文件nginx.conf中日志格式定义中已经定义了接收客户端真实IP的变量"$http_x_forwarded_for"
如果后端服务器是nginx的话在主配置文件中去掉日志格式定义的注释即可,日志会自动记录来自客户端的真实IP地址

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

   access_log  logs/access.log  main;


#后端服务器日志不但记录了来自nginx代理服务器的IP地址而且还记录了来自真实客户端的IP地址
#192.168.80.130 代理服务器
#192.168.80.5   客户端服务器

192.168.80.130 - - [20/Dec/2021:18:19:46 +0800] "GET / HTTP/1.0" 200 19 "-" "curl/7.29.0" "192.168.80.5"
192.168.80.130 - - [20/Dec/2021:18:19:47 +0800] "GET / HTTP/1.0" 200 19 "-" "curl/7.29.0" "192.168.80.5"
192.168.80.130 - - [20/Dec/2021:18:19:48 +0800] "GET / HTTP/1.0" 200 19 "-" "curl/7.29.0" 
仅在代理服务器上设置了该头部字段后还不够,因为后端服务器仅仅只是获取到它,默认并没有将其记录下来。所以需要在后端的服务的日志格式设置上记录此项或者在其他有需求的地方设置它
#tomcat主配置文件  server.xml 记录代理服务器和真实客户端IP的
# "%{X-FORWARDED-FOR}i"  接收代理httpt头穿过来的真实客户端IP地址

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%{X-FORWARDED-FOR}i %h %l %u %t &quot;%r&quot; %s %b %{User-Agent}i %T" resolveHosts='false' /> 

#tomcat日志
#真实客户端地址192.168.80.5
#代理服务器IP地址  192.168.80.130

[root@web03 logs]# tail -f localhost_access_log.2021-12-20.txt
192.168.80.5 192.168.80.130 - - [20/Dec/2021:19:06:38 +0800] "HEAD / HTTP/1.0" 200 - curl/7.29.0 0.001
192.168.80.5 192.168.80.130 - - [20/Dec/2021:19:06:38 +0800] "HEAD / HTTP/1.0" 200 - curl/7.29.0 0.001
192.168.80.5 192.168.80.130 - - [20/Dec/2021:19:06:38 +0800] "HEAD / HTTP/1.0" 200 - 


4.利用LNMP实现wordpress站点搭建

LNMP简易架构图

Snap9.png

LNMP环境需求说明

需要5台服务器
nginx负载负载均衡器一台(日后扩展keepalived解决高可用再增加一台): nginx-lb00 192.168.80.18 
web服务器2台:(nginx php-fpm 部署wordpress应用程序)
web01 192.168.80.101
web02 192.168.80.102
数据库服务器一台:(日后扩展为主从再增加一台) mysql-node00 192.168.80.100
nfs文件共享服务器一台:(日后增加一台做备份服务器) nfs00 192.168.80.9

问题说明:
1.此文中服务都未做高可用、未作数据实时同步备份、数据库也未做主动,仅仅是单点
2.后端的多台web服务器部署了wordpress实际上起不到任何负载均衡的效果,web01服务器配置开通与数据库的连接,在web01上发布文章,访问web02地址可用看到web01发布的文章连接,点击之后会跳转至web01服务器,we02服务器永远都用不到,就像web02根本就不存在的样子,是个假web集群,看了网上很多文章,什么lnmp集群架构,负载均衡搭建wordpress环境等文章可是把人唬的不轻啊。
3.那为什么还要写这个文章呢?,还非要故弄玄虚,搞个什么负载均衡集群,高可用架构,直接一台服务器都搞定不就完事了吗?你说呢?

推翻上面的需求,一切从简,没有必要搞那么费劲,还是个假的集群:
就2台服务器搞定:
nginx php-fpm 服务器一台: nginx-lb00 192.168.80.18 
数据库服务器一台: mysql-node00 192.168.80.100

L:Linux CentOS Linux release 7.9.2009 (Core) https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Everything-2009.iso
N:nginx nginx-1.18.0 http://nginx.org/download/nginx-1.18.0.tar.gz
M:mysql mysql-5.7.35 https://dev.mysql.com/downloads/mysql/
P:php php-7.4.27 https://www.php.net/distributions/php-7.4.27.tar.gz
php程序 wordpress-5.8.2-zh_cn.tar https://cn.wordpress.org/latest-zh_CN.tar.gz

二进制安装部署MySQL-5.7.35数据库

#直接部署一个单示例的数据即可,日后根据实际需求可扩展为主从架构
#文件
#install_mysql_v08.sh
#mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
[root@mysql-node00 ~]# ls
install_mysql_v08.sh  mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz  

#数据库单实例脚本,脚本中直接创建 wordpress 程序所需的数据库以及账号
[root@mysql-node00 ~]# cat install_mysql_v08.sh


###. /etc/init.d/functions


#centos7  install  mysql5.7  mysql8.0


src_dir=`pwd`

mysql_version=$(ls -1rth mysql*.tar.[xg]z|tail -n 1)


mysql_root_password='mysql#123456'

#echo $mysql_version

check () {

        [ $UID -ne 0 ] && { echo  "user is not root"; false  ;exit ; }

        #yum -y -q  install libaio numcatl-libs &>/dev/null

        osv=`uname -r |grep -o "el[78]"`

                case  $osv in

                el7)

                rpm -q libaio &>/dev/null || yum install -y -q  libaio &>/dev/null

                rpm -q numcatl-libs  &>/dev/null || yum install -y -q  numcatl-libs  &>/dev/null

                rpm -q mariadb-libs  &>/dev/null && rpm -e   --nodeps `rpm -q mariadb-libs` &>/dev/null
                ;;

                el8)

                rpm -q numcatl-libs  &>/dev/null || yum install -y -q  numcatl-libs  &>/dev/null

                rpm -q mariadb-libs  &>/dev/null && rpm -e   --nodeps `rpm -q mariadb-libs` &>/dev/null

                rpm -q ncurses-compat-libs &>/dev/null || yum install -y -q  ncurses-compat-libs  &>/dev/null

                ;;

                *)

                echo "is not Linux release  el8 or el7 "
                exit

        esac

        id mysql &>/dev/null||{ useradd -r -s /sbin/nologin mysql  ;  }

        cd $src_dir

        if [ ! -e $mysql_version ];then

                echo "mysql 二进制安装文件不存在"
                echo "请上传mysql二进制安装文件到${src_dir}目录下"
                exit

        elif [ -e /usr/local/mysql ];then

                echo "数据库已经存在,立刻退出"

                exit

        else

                return

        fi

}

install_mysql() {

echo "开始安装 $mysql_version 数据库....."
cd  $src_dir
tar xf  $mysql_version -C /usr/local/
mysql_dir=`echo $mysql_version|sed -nr 's/^(.*[0-9]).*/\1/p'`
ln -s /usr/local/${mysql_dir} /usr/local/mysql
chown -R root:root /usr/local/mysql/
echo  'PATH=/usr/local/mysql/bin/:$PATH' >/etc/profile.d/mysql.sh
chmod u+x  /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh
export  PATH=/usr/local/mysql/bin/:$PATH

echo  "配置/etc/my.cnf文件"

cat >/etc/my.cnf <<-EOF

[client]
default-character-set=utf8mb4
socket=/data/datadb/mysql.sock
[mysql]
default-character-set=utf8mb4
prompt=(\\u@\\h) [\\d]>\\_

[mysqld]
character-set-server=utf8mb4
skip_name_resolve=1
server-id=${RANDOM:0:2}
log-bin=/data/binlog/mysql-bin
log-bin-index=/data/binlog/mysql-bin.index
datadir=/data/datadb/
socket=/data/datadb/mysql.sock
log-error=/data/datadb/mysql.log
pid-file=/data/datadb/mysql.pid

EOF


[ -d /data/datadb ] || mkdir -p  /data/{datadb,binlog}/
chown -R mysql:mysql  /data

mysqld --initialize --user=mysql --datadir=/data/datadb

[ $? -ne 0 ] && { echo  "数据库初始化失败,退出" ; exit ; } ||  { echo  "数据库初始化成功" ; }

cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
sleep 5
mysql_initpass=$(awk '/A temporary password/{print $NF}'  /data/datadb/mysql.log)
mysqladmin -uroot -p${mysql_initpass}  password  ${mysql_root_password} &>/dev/null

cat>>/root/wordpress.sql<<'eof'
create database wordpress;
create database discu;
grant all  on wordpress.* to wordpress@'192.168.80.%' identified by 'mysql#123456' ;
grant all  on discu.* to discu@'192.168.80.%' identified by 'mysql#123456' ;
use mysql;
select user,host from user ;
eof


/usr/local/mysql/bin/mysql -uroot -p${mysql_root_password}</root/wordpress.sql

echo  "数据库安装成功"

}

main() {

check

install_mysql

}

main
#直接部署一个单示例的数据即可,日后根据实际需求可扩展为主从架构
#文件
#install_mysql_v08.sh
#mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz

[root@mysql-node00 ~]# ls
install_mysql_v08.sh  mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz  

#执行install_mysql_v08.sh
[root@mysql-node00 ~]# sh install_mysql_v08.sh
开始安装 mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz 数据库.....
配置/etc/my.cnf文件
数据库初始化成功
Starting MySQL.                                            [  OK  ]
mysql: [Warning] Using a password on the command line interface can be insecure.
user    host
discu   192.168.80.%
wordpress       192.168.80.%
mysql.session   localhost
mysql.sys       localhost
root    localhost
数据库安装成功

源码编译安装部署nginx-1.18.0

#install_nginx.sh 
[root@web01 ~]# cat install_nginx.sh 
#!/bin/bash
#http://nginx.org/download/nginx-1.20.1.tar.gz

src_dir=`pwd`
nginx_file=nginx-1.18.0.tar.gz
nginx_name=$(echo ${nginx_file%*.tar.gz})
url_nginx=http://nginx.org/download/nginx-1.18.0.tar.gz


install_base=/app
install_path=${install_base}/${nginx_name}

cpus=`lscpu|awk -F: '/^CPU\(s\):/ {print $2}'`

#创建用户
groupadd nginx -g 666 
id nginx &>/dev/null || useradd -r -s /sbin/nologin -g 666 -u 666 nginx


#依赖包安装
install_package() {

osv=`uname -r |grep -o "el[78]"`

case  $osv in

el7)

for i in wget curl  make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
do
        rpm -q $i &>/dev/null || yum install -y $i
done

cat>>/etc/sysctl.conf<<eof
fs.file-max=65535
net.ipv4.ip_forward = 1
eof
sysctl -p
;;

el8)
for i in wget curl  make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
do
        rpm -q $i &>/dev/null || yum install -y $i
done
cat>>/etc/sysctl.conf<<eof
fs.file-max=65535
net.ipv4.ip_forward = 1
eof
sysctl -p

;;

*)

echo "is not Linux release  el8 or el7  is  ubuntu "

apt update && apt install -y wget curl  make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev

esac

}

install_nginx() {

wget $url_nginx
#源码编译
tar xvf $nginx_file
cd $nginx_name

./configure --prefix=$install_path --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

if [ $? -eq 0 ];then

make -j ${cpus} && make install
echo "PATH=$install_base/nginx/sbin:${PATH}">/etc/profile.d/nginx.sh
chmod u+x  /etc/profile.d/nginx.sh
export PATH=$install_base/nginx/sbin:${PATH}
source   /etc/profile.d/nginx.sh

cd $install_base&&pwd
ln -s  $nginx_name/ nginx

chown -R nginx:nginx  $install_path
chown -R nginx:nginx  ${install_base}/nginx

else

 echo  "configure is error "
 exit 1

fi

cat >/lib/systemd/system/nginx.service<<EOF

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=$install_base/nginx/logs/nginx.pid
ExecStartPre=/bin/rm -f $install_base/nginx/logs/nginx.pid
ExecStartPre=$install_base/nginx/sbin/nginx -t
ExecStart=$install_base/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl restart  nginx&& systemctl enable  nginx


}

main() {

install_package
install_nginx

}

main

[root@web01 ~]# sh install_nginx.sh 
....
#监听80
[root@web01 ~]# ss -lnt |grep -E "9000|80"
LISTEN     0      511    127.0.0.1:9000                     *:*                  
LISTEN     0      511          *:80                       *:*     

配置Nginx支持fastcgi

#对默认的配置文件进行修改,保持默认文件完整性
[root@web01 ~]# cd /app/nginx/conf
[root@web01 conf]# vim nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

#打开日志去掉#
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
   
    server {
        listen       80;
        #修改域名
        server_name  www.qq.com;

        #charset koi8-r;

        access_log  logs/host.access.log  main;
       #增加一行允许客户端上传的文件的最大大小默认1M,调整到 80M php 中也需要进行相关调整才起作用
        client_max_body_size  80m;
        location / {
            #定义网站的根目录
            root  /data/www/html/wordpress;
            #增加一个 index.php
            index index.php  index.html index.htm;
        }
         
        #去掉注释#
        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        
        #这里{} 内都 去掉注释 # 
        location ~ \.php$ {
            #修改网站的根目录
            root           /data/www/html/wordpress;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME
            #这里修改成
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name
 
            include        fastcgi_params;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

[root@web01 conf]# nginx -t 
nginx: the configuration file /app/nginx-1.18.0/conf/nginx.conf syntax is ok
nginx: configuration file /app/nginx-1.18.0/conf/nginx.conf test is successful

[root@web01 conf]# systemctl restart nginx

源码编译安装部署PHP-7.4.27

[root@web01 ~]# cat install_php7427.sh
#!/bin/bash
#=====================================================================================================
#File Name:           b.sh
#Date:                2021-10-22 21-38-04
#Author:              Create by gong hai rong
#Description:         This script function is
#Shell Version:       GNU bash version 4.1.2(2)-release x86_64-redhat-linux-gnu
#Copyright (C):       2021 All rights reserved
#=====================================================================================================

 src_dir=`pwd`
 php_file=php-7.4.27.tar.gz
 php_base=/app

 php_name=$(echo ${php_file%*.tar.gz})
 php_home=${php_base}/${php_name}

[ -d $php_base ]  &>/dev/null || mkdir -p $php_base &>/dev/null

cpus=`lscpu|awk -F: '/^CPU\(s\):/ {print $2}'`

install_package()  {

for i in wget make autoconf automake libtool cmake gcc gcc-c++ openssl openssl-devel pcre pcre-devel zlib zlib-devel sqlite sqlite-devel libxml2-devel libjpeg-turbo-devel libjpeg-turbo-utils libpng-devel libicu-devel libcurl-devel libxslt-devel freetype-devel gd gd-devel libzip libzip-devel bzip2-devel gmp-devel readline-devel gdbm-devel oniguruma oniguruma-devel
do
rpm -q $i &>/dev/null || yum install -y $i
done

}


install_php()  {

#cd $php_base

tar  xvf $php_file&&cd $php_name&&pwd
./configure \
--prefix=$php_home \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl \
--with-zlib \
--with-config-file-path=$php_base/php/etc \
--with-config-file-scan-dir=$php_base/php/etc \
--enable-mbstring \
--enable-xml \
--enable-sockets \
--enable-fpm \
--enable-maintainer-zts \
--disable-fileinfo

if [ $? -eq 0 ];then 
 
  make -j ${cpus} && make install

ln -s $php_home     $php_base/php    

else 

  echo -e "configure is failed plase check configure "
  exit 

fi 

#整合配置文件
#php.ini
#源码文件
cp ${src_dir}/${php_name}/php.ini-production  $php_base/php/lib/php.ini
cp ${src_dir}/${php_name}/php.ini-production  $php_base/php/etc/php.ini


#源码编译后
#php-fpm.conf
#cp $php_base/php/etc/php-fpm.conf.default        $php_base/php/etc/php-fpm.conf
cp $php_base/php/etc/php-fpm.conf.default        $php_base/php/etc/php-fpm.conf

cp $php_base/php/etc/php-fpm.d/www.conf.default  $php_base/php/etc/php-fpm.d/www.conf

sed -ri.org  's/nobody/nginx/g'  $php_base/php/etc/php-fpm.d/www.conf





#PATH 
echo "PATH=$php_base/php/sbin:$php_base/httpd/bin:"'$PATH'>/etc/profile.d/php.sh
source  /etc/profile.d/php.sh


#service 
#cp /app/php-7.4.21/sapi/fpm/php-fpm.service   /usr/lib/systemd/system/
cp ${src_dir}/${php_name}/sapi/fpm/php-fpm.service   /usr/lib/systemd/system/php-fpm.service



php-fpm -t
if [  $? -eq 0 ];then 
  
  systemctl start php-fpm && systemctl enable php-fpm 

else 

  echo  " start php-fpm is failed "

fi 

}

#run fun 
main () {

install_package
install_php
}

main 

#执行源码编译安装php
[root@web01 ~]# sh install_php7427.sh
......


#php 参数修改

#php上传文件大小限制
[root@web01 ~]# vim /app/php/etc/php.ini 
#找到下面几个配置项进行修改 值都调整大些
post_max_size = 30M
upload_max_filesize = 20M
max_file_uploads = 200

#post_max_size设置允许的帖子数据的最大大小 。 此设置也会影响文件上传。 要上传大文件,此值必须大于 upload_max_filesize  一般来说,memory_limit 应该大于 post_max_size。 当使用int时,其值以字节来衡量
#upload_max_filesize = 20M  上传文件的最大允许大小
#max_file_uploads = 200 可以通过单个请求上传的最大文件数

#监听 9000
[root@web01 ~]# ss -lnt |grep -E "9000|80"
LISTEN     0      511    127.0.0.1:9000                     *:*                  
LISTEN     0      511          *:80                       *:*    
#php测试页面
[root@web01 ~]# mkdir  -p /data/www/html/wordpress/
[root@web01 ~]#  echo  '<?php phpinfo() ?>' >/data/www/html/wordpress/test.php

#验证php测试页面
[root@web01 wordpress]# curl -I 192.168.80.101/test.php
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 Dec 2021 08:20:09 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.4.27

部署wordpress-5.8.2-zh_cn

#wordpress-5.8.2-zh_cn.tar.gz
[root@web01 ~]# tar xvf wordpress-5.8.2-zh_cn.tar.gz
[root@web01 ~]# cp -r wordpress/*  /data/www/html/wordpress/
[root@web01 ~]# chown -R nginx:nginx /data/www/html/wordpress/

初始化web页面发布文章

初始化wordpress的过程按照向导一步一步即可(填写之前创建好的有关数据库的信息等),就不再截图了(之前lamp的博文里面有了)。
发布文章也省略了

废了半天的劲不如用一台机器,写个脚本把源码编译安装、配置修改等都一次做了,一个脚本都搞定。

lnmp基础脚本

以上案例比较杂乱,这里简化下提供几个基础脚本,先把结构搭建起来,根据实际部署的应用再去做微调。
一切简化在一台机器上,脚本独立不合并,为了简单

基础脚本不是像某高人写的什么一键搭建LNMP/LAmp环境、实现web集群、高可用那样。

文件:
install_mysql_v08.sh
install_nginx.sh
install_php7427.sh
mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
nginx-1.18.0.tar.gz
nginx.conf
php-7.4.27.tar.gz
#install_mysql_v08.sh
#mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
[root@centos7-templates ~]# cat install_mysql_v08.sh
#=====================================================================================================
#File Name:           install_mysql_v08.sh
#Date:                2021-12-21 23-47-26
#Author:              Create by gonghairong
#Description:         This script function is
#Shell Version:       GNU bash version 4.1.2(2)-release x86_64-redhat-linux-gnu
#Copyright (C):       2021 All rights reserved
#=====================================================================================================

###. /etc/init.d/functions


#centos7  install  mysql5.7  mysql8.0


src_dir=`pwd`

mysql_version=$(ls -1rth mysql*.tar.[xg]z|tail -n 1)


mysql_root_password='mysql#123456'

#echo $mysql_version

check () {

        [ $UID -ne 0 ] && { echo  "user is not root"; false  ;exit ; }

        #yum -y -q  install libaio numcatl-libs &>/dev/null

        osv=`uname -r |grep -o "el[78]"`

                case  $osv in

                el7)

                rpm -q libaio &>/dev/null || yum install -y -q  libaio &>/dev/null

                rpm -q numcatl-libs  &>/dev/null || yum install -y -q  numcatl-libs  &>/dev/null

                rpm -q mariadb-libs  &>/dev/null && rpm -e   --nodeps `rpm -q mariadb-libs` &>/dev/null
                ;;

                el8)

                rpm -q numcatl-libs  &>/dev/null || yum install -y -q  numcatl-libs  &>/dev/null

                rpm -q mariadb-libs  &>/dev/null && rpm -e   --nodeps `rpm -q mariadb-libs` &>/dev/null

                rpm -q ncurses-compat-libs &>/dev/null || yum install -y -q  ncurses-compat-libs  &>/dev/null

                ;;

                *)

                echo "is not Linux release  el8 or el7 "
                exit

        esac

        id mysql &>/dev/null||{ useradd -r -s /sbin/nologin mysql  ;  }

        cd $src_dir

        if [ ! -e $mysql_version ];then

                echo "mysql 二进制安装文件不存在"
                echo "请上传mysql二进制安装文件到${src_dir}目录下"
                exit

        elif [ -e /usr/local/mysql ];then

                echo "数据库已经存在,立刻退出"

                exit

        else

                return

        fi

}

install_mysql() {

echo "开始安装 $mysql_version 数据库....."
cd  $src_dir
tar xf  $mysql_version -C /usr/local/
mysql_dir=`echo $mysql_version|sed -nr 's/^(.*[0-9]).*/\1/p'`
ln -s /usr/local/${mysql_dir} /usr/local/mysql
chown -R root:root /usr/local/mysql/
echo  'PATH=/usr/local/mysql/bin/:$PATH' >/etc/profile.d/mysql.sh
chmod u+x  /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh
export  PATH=/usr/local/mysql/bin/:$PATH

echo  "配置/etc/my.cnf文件"

cat >/etc/my.cnf <<-EOF

[client]
default-character-set=utf8mb4
socket=/data/datadb/mysql.sock
[mysql]
default-character-set=utf8mb4
prompt=(\\u@\\h) [\\d]>\\_

[mysqld]
character-set-server=utf8mb4
skip_name_resolve=1
server-id=${RANDOM:0:2}
log-bin=/data/binlog/mysql-bin
log-bin-index=/data/binlog/mysql-bin.index
datadir=/data/datadb/
socket=/data/datadb/mysql.sock
log-error=/data/datadb/mysql.log
pid-file=/data/datadb/mysql.pid

EOF


[ -d /data/datadb ] || mkdir -p  /data/{datadb,binlog}/
chown -R mysql:mysql  /data

mysqld --initialize --user=mysql --datadir=/data/datadb

[ $? -ne 0 ] && { echo  "数据库初始化失败,退出" ; exit ; } ||  { echo  "数据库初始化成功" ; }

cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
sleep 5
mysql_initpass=$(awk '/A temporary password/{print $NF}'  /data/datadb/mysql.log)
mysqladmin -uroot -p${mysql_initpass}  password  ${mysql_root_password} &>/dev/null
#run sql
cat>>/root/wordpress.sql<<'eof'
create database wordpress;
create database discu;
grant all  on wordpress.* to wordpress@'192.168.80.%' identified by 'mysql#123456' ;
grant all  on discu.* to discu@'192.168.80.%' identified by 'mysql#123456' ;
use mysql;
select user,host from user ;
eof
/usr/local/mysql/bin/mysql -uroot -p${mysql_root_password}</root/wordpress.sql
echo  "数据库安装成功"

}

main() {

check

install_mysql


}

main

#nginx.conf
#nginx.conf配置文件提前准备好,install_nginx.sh脚本中需要拷贝
#nginx-1.18.0.tar.gz
#nginx.conf
#install_nginx.sh

[root@centos7-templates ~]# cat nginx.conf

user  nginx nginx;
worker_processes  auto;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        client_max_body_size  8m;
        #只添加客户端IP到请求报文头部,转发至后端服务器
        proxy_set_header X-Real-IP $remote_addr;
        ##添加客户端IP和反向代理服务器IP到请求报文头部
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        

        ##proxy_set_header X-Forwarded-For $remote_addr;
        #access_log  logs/host.access.log  main;

        location / {
            #root  /data/www/html/wordpress;
            root   html;
            index index.php  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
            #隐藏php软件版本信息
            fastcgi_hide_header X-Powered-By;
        }



        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

#install_nginx.sh

[root@centos7-templates ~]# cat install_nginx.sh
#!/bin/bash

#!/bin/bash
#=====================================================================================================
#File Name:           /tmp/install_nginx_v00.sh
#Date:                2021-12-21 23-47-26
#Author:              Create by gonghairong
#Description:         This script function is
#Shell Version:       GNU bash version 4.1.2(2)-release x86_64-redhat-linux-gnu
#Copyright (C):       2021 All rights reserved
#=====================================================================================================



#http://nginx.org/download/nginx-1.20.1.tar.gz

src_dir=`pwd`
nginx_file=nginx-1.18.0.tar.gz
nginx_name=$(echo ${nginx_file%*.tar.gz})
#url_nginx=http://nginx.org/download/nginx-1.18.0.tar.gz


install_base=/app
install_path=${install_base}/${nginx_name}



cpus=`lscpu|awk -F: '/^CPU\(s\):/ {print $2}'`

#创建用户
groupadd nginx -g 666
id nginx &>/dev/null || useradd -r -s /sbin/nologin -g 666 -u 666 nginx


#依赖包安装
install_package() {

osv=`uname -r |grep -o "el[78]"`

case  $osv in

el7)

for i in wget curl  make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
do
        rpm -q $i &>/dev/null || yum install -y $i
done

cat>>/etc/sysctl.conf<<eof
fs.file-max=65535
net.ipv4.ip_forward = 1
eof
sysctl -p
;;

el8)
for i in wget curl  make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
do
        rpm -q $i &>/dev/null || yum install -y $i
done
cat>>/etc/sysctl.conf<<eof
fs.file-max=65535
net.ipv4.ip_forward = 1
eof
sysctl -p

;;

*)

echo "is not Linux release  el8 or el7  is  ubuntu "

apt update && apt install -y wget curl  make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev

esac

}

install_nginx() {

#wget $url_nginx
#源码编译
tar xvf $nginx_file
cd $nginx_name

./configure --prefix=$install_path --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

if [ $? -eq 0 ];then

make -j ${cpus} && make install
echo "PATH=$install_base/nginx/sbin:${PATH}">/etc/profile.d/nginx.sh
chmod u+x  /etc/profile.d/nginx.sh
export PATH=$install_base/nginx/sbin:${PATH}
source   /etc/profile.d/nginx.sh

cd $install_base&&pwd
ln -s  $nginx_name/ nginx

cp  $install_base/nginx/conf/nginx.conf{,.bak}
cp  $src_dir/nginx.conf $install_base/nginx/conf/

chown -R nginx:nginx  $install_path
chown -R nginx:nginx  ${install_base}/nginx

else

 echo  "configure is error "
 exit 1

fi

cat >/lib/systemd/system/nginx.service<<EOF

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=$install_base/nginx/logs/nginx.pid
ExecStartPre=/bin/rm -f $install_base/nginx/logs/nginx.pid
ExecStartPre=$install_base/nginx/sbin/nginx -t
ExecStart=$install_base/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl restart  nginx&& systemctl enable  nginx


}

main() {

install_package
install_nginx

}

main
#nstall_php7427.sh
#php-7.4.27.tar.gz

[root@centos7-templates ~]# cat install_php7427.sh



#!/bin/bash
#=====================================================================================================
#File Name:           install_php7427.sh
#Date:                2021-10-22 21-38-04
#Author:              Create by gong hai rong
#Description:         This script function is
#Shell Version:       GNU bash version 4.1.2(2)-release x86_64-redhat-linux-gnu
#Copyright (C):       2021 All rights reserved
#=====================================================================================================

#centos 7

cpus=`lscpu|awk -F: '/^CPU\(s\):/ {print $2}'`


 src_dir=`pwd`
 php_file=php-7.4.27.tar.gz
 php_base=/app



 php_name=$(echo ${php_file%*.tar.gz})
 php_home=${php_base}/${php_name}





install_package()  {


p="
wget
make
autoconf
automake
libtool
cmake
gcc
gcc-c++
openssl
openssl-devel
pcre
pcre-devel
zlib
zlib-devel
sqlite
sqlite-devel
libxml2-devel
libjpeg-turbo-devel
libjpeg-turbo-utils
libpng-devel
libicu-devel
libcurl-devel
libxslt-devel
freetype-devel
gd
gd-devel
libzip
libzip-devel
bzip2-devel
gmp-devel
readline-devel
gdbm-devel
oniguruma
oniguruma-devel
"
for i in $p;
do
    rpm -q $p  &> /dev/null || yum -q -y install $i
done


}


install_php()  {

#cd $php_base
[ -d $php_base ]  &>/dev/null || mkdir -p $php_base &>/dev/null

tar  xvf $php_file&&cd $php_name&&pwd
./configure \
--prefix=$php_home \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl \
--with-zlib \
--with-config-file-path=$php_base/php/etc \
--with-config-file-scan-dir=$php_base/php/etc \
--enable-mbstring \
--enable-xml \
--enable-sockets \
--enable-fpm \
--enable-maintainer-zts \
--disable-fileinfo

if [ $? -eq 0 ];then

  make -j ${cpus} && make install

ln -s $php_home     $php_base/php

else

  echo -e "configure is failed plase check configure "
  exit

fi

#整合配置文件
#php.ini
#源码文件
cp ${src_dir}/${php_name}/php.ini-production  $php_base/php/lib/php.ini
cp ${src_dir}/${php_name}/php.ini-production  $php_base/php/etc/php.ini


#源码编译后
#php-fpm.conf
#cp $php_base/php/etc/php-fpm.conf.default        $php_base/php/etc/php-fpm.conf
cp $php_base/php/etc/php-fpm.conf.default        $php_base/php/etc/php-fpm.conf

cp $php_base/php/etc/php-fpm.d/www.conf.default  $php_base/php/etc/php-fpm.d/www.conf

sed -ri.org  's/nobody/apache/g'  $php_base/php/etc/php-fpm.d/www.conf

#upload file size
#opcache
#post_max_size = 8M
#upload_max_filesize = 2M
#max_file_uploads = 20
#upload_max_filesize = 2M
sed -i.org -e 's/post_max_size = 8M/post_max_size = 30M/' -e 's/upload_max_filesize = 2M/upload_max_filesize = 20M/'  -e 's/;opcache.enable=1/opcache.enable=1/' $php_base/php/etc/php.ini



echo  '<?php phpinfo() ?>' >/app/nginx/html/index.php
chown nginx:nginx /app/nginx/html/index.php


#PATH
echo "PATH=$php_base/php/sbin:$php_base/httpd/bin:"'$PATH'>/etc/profile.d/php.sh
source  /etc/profile.d/php.sh


#service
#cp /app/php-7.4.21/sapi/fpm/php-fpm.service   /usr/lib/systemd/system/
cp ${src_dir}/${php_name}/sapi/fpm/php-fpm.service   /usr/lib/systemd/system/php-fpm.service



php-fpm -t
if [  $? -eq 0 ];then

  systemctl start php-fpm && systemctl enable php-fpm

else

  echo  "start php-fpm is failed "
  exit 1

fi

}

#run fun
main () {

install_package
install_php
}

main
#按照顺序执行脚本,验证脚本是否达到LNMP基本环境
#nginx.conf 配置文件注释这项配置 fastcgi_hide_header X-Powered-By;

#php
[root@centos7-templates ~]# curl -I http://127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 Dec 2021 18:25:49 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.4.27

#html
[root@centos7-templates ~]# curl -I http://127.0.0.1/index.html
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 Dec 2021 18:25:56 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Dec 2021 18:09:10 GMT
Connection: keep-alive
ETag: "61c21846-264"
Accept-Ranges: bytes

根据测试结果LNMP基本环境已经具备,后续看根据实际情况部署应用程序、连接数据库即可。