LNMP:指的是Linux、nginx、mysql(或者mariadb)、php。是目前最常用最经典的web服务环境组合之一,除lnmp外,还有lamp。

lnmp工作流程:

用户通过浏览器请求nginx web服务:
如果请求的是静态资源,则由nginx解析返回给用户;
如果是动态请求(.php),那么nginx就会把它通过FastCGI接口(Fast Common Gateway Interface)发送给PHP引擎服务(FastCGI进程php-fpm)进程解析,如果这个动态请求要读取数据库数据,那么PHP就会继续向后请求MySQL(或者MariaDB)数据库,以读取需要的数据,并最终通过nginx服务把获取的数据返回给用户。

Nginx FastCGI运行原理

nginx不支持对外部动态程序的直接调用或解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux中是socket,为了调用CGI程序,还需要一个FastCGI的wrapper(可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定的socket上,比如端口或者文件socket。
当nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接收到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本来读取返回的数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给nginx,最后nginx将返回的数据发送给客户端。

FastCGI主要优点:

把动态语言和HTTP服务器分离出来,使nginx专门处理静态请求及向后转发的动态请求,而PHP/PHP-FPM服务器则专门解析PHP动态请求。

实验环境:

RHEL7.3 ip:192.168.10.206 主机名:node1

一、依赖包安装

[root@node1 ~]yum install gcc gcc-c++ libxml2-devel openssl libcurl-devel gd-devel -y

二、编译安装mariadb

这里使用mariadb5.5.60二进制包。
1、下载mariadb5.5.60二进制包。

[root@node1  ~]#wget http://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-5.5.60/bintar-linux-x86_64/mariadb-5.5.60-linux-x86_64.tar.gz

2、解压mariadb到/usr/local目录中

为了方便,解压后创建软连接为mysql,并且修改属主属组为mysql

[root@node1 ~]#tar xf mariadb-5.5.60-linux-x86_64.tar.gz -C /usr/local/
[root@node1 ~]#cd /usr/local/
[root@node1 local]#ln -sv mariadb-5.5.60-linux-x86_64/ mysql
[root@node1 local]#cd mysql/
[root@node1 mysql]#usradd -r -s /sbin/nologin mysql
[root@node1 mysql]#chown -R mysql.mysql ./*

3、创建数据库数据存放目录
数据库数据存放目录为:/data/mariadb/

[root@node1 ~]# mkdir /data/mariadb -p

4、数据库初始化安装
数据库初始化安装选项:

–user:用户,也就是前面创建的mysql用户
–basedir:数据库的解压目录,在前面的操作中,mariadb数据库解压到/usr/local目录中,并且做了软连接,软连接名称为:mysql,所以–basedir=/usr/local/mysql
–datadir:数据数据存放的目录。

[root@node1 mysql]# ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/  --datadir=/data/mariadb/

5、数据库配置文件

默认情况下,/etc/目录中有一个my.cnf文件,可以使用这个默认的文件。也可以使用mariadb解压包中的配置文件。在这里不使用默认的my.cnf文件。
把解压包中support-files/my-large.cnf复制到/etc/目录中,文件名为:my.cnf

  [root@node1 mysql]#rm -f /etc/my.cnf
  [root@node1 mysql]#cp  support-files/my-large.cnf /etc/my.cnf

修改/etc/my.cnf文件

[root@node1 mysql]#sed -i '/thread_concurrency = 8/adatadir = /mydata/mariadb\ninnodb_file_per = on\nskip_name_resolve = on' /etc/my.cnf

如下所示:

# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8
datadir=/data/mariadb
innodb_file_per=on
skip_name_resolve=on

datadir:数据库数据存放的目录

6、配置数据库服务

将解压目录的support-files/mysql.server文件复制到/etc/rc.d/init.d/目录中重命名为mariadb,并且为其添加可执行权限,添加到系统管理。

[root@node1 mysql]#cp support-files/mysql.server /etc/rc.d/init.d/mariadb
[root@node1 mysql]#chmod +x /etc/rc.d/init.d/mariadb 
[root@node1 mysql]#chkconfig --add mariadb

7、配置数据环境变量
mysql命令放在/usr/local/mysql/bin/目录中。如果不配置环境变量,执行mysql命令得使用该命令的绝对路径:/usr/local/mysql/bin/mysql,不太方便。所以把该路径添加到系统环境变量中,方便使用。设置环境变量方法如下:

 [root@node1 mysql]#echo 'export PATH=/usr/local/mysql/bin:$PATH'>/etc/profile.d/mysql.sh
[root@node1 mysql]#chmod +x /etc/profile.d/mysql.sh
[root@node1 mysql]#source /etc/profile.d/mysql.sh

8、启动mariadb服务
启动mariadb服务方法:

方法1:使用systemctl start mariadb命令

 [root@node1 ~]# systemctl start mariadb

方法2:使用/etc/rc.d/init.d/mariadb start命令

  [root@node1 ~]# /etc/rc.d/init.d/mariadb start

启动之后,查看mariadb服务:

  [root@node1  ~]# ps aux | grep mariadb
    root      70288  0.5  0.0 115428  1720 ?        S    00:12   0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mariadb --pid-file=/data/mariadb/test2.pid
    mysql     70618  1.3  6.5 816520 121984 ?       Sl   00:12   0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mariadb --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mariadb/test2.err --pid-file=/data/mariadb/test2.pid --socket=/tmp/mysql.sock --port=3306
    root      70650  0.0  0.0 112704   960 pts/2    S+   00:13   0:00 grep --color=auto mariadb

OK,mariadb数据二进制包安装成功。

三、编译安装php

这里演示最新版的php-7.2.5,编译安装php需要用到libmcrypt,此软件包没有在基本yum源,要安装libmcrypt软件,要么下载其源码包编译安装,要么先安装epel,再使用epel源yum安装。这里演示libmcrypt源码包安装。
1、编译安装libmcrypt
下载libmcrypt源码包,下载地址:
http://iweb.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz

[root@node1  ~]#wget https://www.linuxprobe.com/Software/libmcrypt-2.5.8.tar.gz
[root@node1  ~]#tar xf libmcrypt-2.5.8.tar.gz 
[root@node1  ~]# cd libmcrypt-2.5.8
[root@node1 libmcrypt-2.5.8]#./configure && make && make install

2、编译安装php7.2.5
下载地址:http://am1.php.net/distributions/php-7.2.5.tar.gz

[root@node1 ~]#wget http://am1.php.net/distributions/php-7.2.5.tar.gz
[roo@node1 ~]#tar xf php-7.2.5.tar.gz 
[roo@node1 ~]#cd php-7.2.5
[root@node1 php-7.2.5]#./configure --prefix=/usr/local/php7\
--with-config-file-path=/etc/php7\
--with-config-file-scan-dir=/etc/php7.d\
--with-mysqli=/usr/local/mysql/bin/mysql_config\
--with-pdo-mysql=/usr/local/mysql/\
--with-mysql-sock=/tmp/mysql.sock\
--with-fpm-user=nginx\
--with-fpm-group=nginx\
--enable-fpm\
--with-libxml-dir\
--with-gd\
--with-jpeg-dir\
--with-png-dir\
--with-freetype-dir\
--with-iconv-dir\
--with-zlib-dir\
--enable-soap\
--enable-ftp\
--enable-mbstring\
--enable-exif\
--with-pear\
--with-curl\
--with-openssl

3、配置php
3.1 php配置文件
在前面的编译中,设置了php的配置文件存放目录为/etc/php7,其他配置文件目录为/etc/php7.d。
要自行创建这两个目录。
将php解压目录中的php.ini-production文件复制到/etc/php7目录中,并且重命名为php.ini。

[root@node1php-7.2.5]#mkdir /etc/php7{,.d}
[root@node1 php-7.2.5]#cp php.ini-production  /etc/php7/php.ini

3.2 php-fpm服务文件
将php解压目录中的sapi/fpm/init.d.php-fpm的文件复制到/etc/rc.d/init.d/目录中,并且重命名为php-fpm。

[root@node1 php-7.2.5]#cp sapi/fpm/init.d.php-fpm  /etc/rc.d/init.d/php-fpm
[root@node1 php-7.2.5]#chmod +x /etc/rc.d/init.d/php-fpm
[root@node1 php-7.2.5]#chkconfig --add php-fpm

3.3 php-fpm配置文件
php的安装目录下的/etc/目录中有一个php-fpm的配置文件的样例,将这个样例文件复制一份即可。

[root@node1 php-7.2.5]# cd /usr/local/php7/etc/
[root@node1 etc]# cp php-fpm.conf.default php-fpm.conf

3.4 www配置文件
在php安装目录下的/etc/php-fpm.d/目录有一个www的配置文件样例,将此文件复制一份即可。

[root@node1 etc]# pwd
/usr/local/php7/etc
[root@node1 etc]# cp php-fpm.d/www.conf.default php-fpm.d/www.conf

4、启动php-fpm
[root@node1 ~]# systemctl start php-fpm

[root@node1 ~]# ps aux | grep php-fpm

root      97021  0.0  0.2 301276  4072 ?        Ss   16:08   0:00 php-fpm: master process (/usr/local/php7/etc/php-fpm.conf)

nginx     97022  0.0  0.2 301276  3964 ?        S    16:08   0:00 php-fpm: pool www

nginx     97023  0.0  0.2 301276  3964 ?        S    16:08   0:00 php-fpm: pool www

root      97025  0.0  0.0 112704   964 pts/1    S+   16:09   0:00 grep --color=auto php-fpm

OK,php-fpm启动成功,至此,php编译安装成功。

四、编译安装nginx

nginx官网:http://nginx.org/
1、下载nginx
这里使用使用最新版演示

[root@node1 ~]# wget http://nginx.org/download/nginx-1.14.0.tar.gz

2、编译安装nginx

[root@node1 ~]# tar xf nginx-1.14.0.tar.gz  
[root@node1 ~]# cd nginx-1.14.0  
[root@node1 nginx-1.14.0]#./configure --prefix=/usr/local/nginx\
--user=nginx\
--group=nginx\
--http-log-path=/mydata/logs/nginx/access.log\
--error-log-path=/mydata/logs/nginx/error.log\
--with-http_ssl_module\
--with-http_realip_module\
--with-http_flv_module\
--with-http_mp4_module\
--with-http_gunzip_module\
--with-http_gzip_static_module\
--with-http_image_filter_module\
--with-http_stub_status_module
[root@test2 nginx-1.14.0]# make && make install

3、配置nginx
nginx配置文件存放目录为:/usr/local/nginx/conf
主配置文件:nginx.conf

[root@node1 conf]# pwd
/usr/local/nginx/conf
root@node1 conf]# ls
fastcgi.conf          fastcgi_params.default  mime.types          nginx.conf.default   uwsgi_params
fastcgi.conf.default  koi-utf                 mime.types.default  scgi_params          uwsgi_params.default
fastcgi_params        koi-win                 nginx.conf          scgi_params.default  win-utf

主配置文件nginx.conf修改后内容如下:

[root@node1 nginx]# vim conf/nginx.conf
user  nginx nginx;
worker_processes 2;

error_log /mydata/logs/nginx/error.log crit;
worker_rlimit_nofile 51200;

events {
   use epoll;
   worker_connections  6000;
}

http {
  include       mime.types;
  default_type  application/octet-stream;
  server_names_hash_bucket_size 3526;
  server_names_hash_max_size 4096;
  log_format combined_realip '$remote_addr $http_x_forwarded_fof [$time_local]'
  ' $host "$request_uri" $status'
  ' "$http_referer" "$http_user_agent"';

  sendfile        on;
  tcp_nopush     on;


  keepalive_timeout  30;
  client_header_timeout 3m;
  client_body_timeout 3m;
  send_timeout 3m;
  connection_pool_size 256;
  client_header_buffer_size 1k;
  large_client_header_buffers 8 4k;
  request_pool_size 4k;
  output_buffers 4 32k;
  postpone_output 1460;
  client_max_body_size 10m;
  client_body_buffer_size 256k;
  client_body_temp_path /usr/local/nginx/client_body_temp;
  proxy_temp_path /usr/local/nginx/proxy_temp;
  fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
  fastcgi_intercept_errors on;
  tcp_nodelay on;

  gzip  on;
  gzip_min_length 1k;
  gzip_buffers 4 8k;
  gzip_comp_level 5;
  gzip_http_version 1.1;
  gzip_types text/plain application/x-javascript text/css text/htm application/xml;

  include /usr/local/nginx/conf.d/*.conf;

}

上面的nginx.conf中的并没有server段,因为把server段从主配置文件分离出来,放在conf.d目录中,文件名为:server.conf

[root@node1 nginx]# mkdir conf.d
[root@node1 nginx]# vim conf.d/server.conf
server {
listen       80;
server_name  node1;
location / {
    root   /usr/local/nginx/html;
    index  index.php index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /usr/local/nginx/html;
}
location ~ \.php$ {
    root           /usr/local/nginx/html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME   /usr/local/nginx/html$fastcgi_script_name;
    include        fastcgi_params;
}

}

做好上面的配置后,检查一下配置文件有没有错误:

 root@node1 nginx]# sbin/nginx -t
 nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
 nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

OK,配置没有错。

4、创建测试页
上面server.conf配置中,设置的网站目录为:/usr/local/nginx/html/,在此目录中创建一个测试页:index.php,并将默认的index.html重命名

[root@node1 nginx]# mv html/index.html  html/index.html.bak 
[root@node1 nginx]# vim /usr/local/nginx/html/index.php
<?php
    $link=new mysqli('127.0.0.1','root','');
    if($link)
            echo "connect mariadb Success";
    else
            echo "connect mariadb Failure";
    mysqli_close($link);
    phpinfo();
 ?>

5、启动nginx服务
创建nginx服务启动脚本,服务脚本放在/etc/rc.d/init.d/目录中,文件名为nginx,脚本内容如下:

[root@node1 ~]# vim /etc/rc.d/init.d/nginx
#!/bin/bash
# nginx - this script starts and stops the nginx daemon
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse 
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=([^ ]*).*/1/g' -`
if [ -z "`grep $user /etc/passwd`" ]; then
useradd -M -s /bin/nologin $user
fi
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
#configtest || return $?
stop
sleep 1
start
}
reload() {
#configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac

将此脚本添加可执行权限,并且添加到系统管理。

[root@node1 ~]# chmod +x /etc/rc.d/init.d/nginx
[root@node1 ~]# chkconfig --add nginx

启动nginx服务:

[root@node1 ~]# systemctl start nginx

nginx服务启动情况:

[root@test2 ~]# ps aux | grep nginx
nginx     97022  0.0  0.2 301276  3964 ?        S    16:08   0:00 php-fpm: pool www
nginx     97023  0.0  0.2 301276  3964 ?        S    16:08   0:00 php-fpm: pool www
root     117655  0.0  0.0  72928  1348 ?        Ss   17:16   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    117656  0.0  0.2  75416  4036 ?        S    17:16   0:00 nginx: worker process
nginx    117657  0.0  0.2  75416  4036 ?        S    17:16   0:00 nginx: worker process
root     117661  0.0  0.0 112704   964 pts/0    S+   17:16   0:00 grep --color=auto nginx

OK,nginx服务启动成功。

五、防火墙和SELinux设置

添加防火墙规则放行80、3306、9000端口

CentOS、RHEL系统7.x版本开始,防火墙默认管理工具是firewall。所以这里使用firewall工具设置防火墙规则。

[root@node1 ~]# firewall-cmd --permanent --add-port=80/tcp
success
[root@node1 ~]# firewall-cmd --permanent --add-port=3306/tcp
success
[root@node1 ~]# firewall-cmd --permanent --add-port=9000/tcp
success
[root@node1 ~]# firewall-cmd --reload
success

开启selinux并设置规则

查看selinux开启情况:

[root@node1 ~]# cat /etc/selinux/config | grep -i selinux=
# SELINUX= can take one of these three values:
SELINUX=enforcing

SELINUX=enforcing,说明selinux已开启,如果不是enforcing,请修改为enforcing。

设置selinux策略:

[root@node1 ~]# setsebool -P httpd_can_network_connect 1

六、测试

完成以上全部设置之后,在浏览器输入:192.168.10.206,看看效果。

OK至此,lnmp搭建成功。

**

nginx的基本设置

请看我的另一篇博文nginx的基本设置