• LNMP系统服务搭建过程详解


        和LAMP不同的是LNMP中的N指的是Nginx(类似于Apache的一种web服务软件)其他都一样。目前这种环境应用的也是非常之多。Nginx设计的初衷是提供一种快速高效多并发的web服务软件。在静态页面的处理上Nginx的确胜Apache一筹,然而在动态页面的处理上Nginx并不比Apache有多少优势。但是,目前还是有很多爱好者对Nginx比较热衷,随着Nginx的技术逐渐成熟,它在web服务软件领域的地位越来越高。下边记录一下LNMP架构搭建的详细过程。

    一、MySQL数据库的安装

    1. 系统环境

    CentOS 6.4 x86_64 Mini 版本安装

    2. 基础软件包安装

    [root@vip ~]# yum install gcc vim make wget -y

    3. 下载

    # 进入源码存放目录
    [root@vip ~]# cd /usr/local/src
    # 下载MySQL安装包
    [root@vip src]# wget downloads.mysql.com/archives/get/file/mysql-5.5.40-linux2.6-x86_64.tar.gz

    4. 解压安装

    # 解压
    [root@vip src]# tar -zxf mysql-5.5.40-linux2.6-x86_64.tar.gz
    # 设置安装路径
    [root@vip src]# mv mysql-5.5.40-linux2.6-x86_64 /usr/local/mysql

    5. 建立MySQL用户

    [root@vip src]# useradd -s /sbin/nologin -M mysql

    6. 准备数据目录

    # 进入MySQL安装目录
    [root@vip src]# cd /usr/local/mysql
    # 创建MySQL数据目录
    [root@vip mysql]# mkdir -p /var/lib/mysql
    # 设置目录权限
    [root@vip mysql]# chown -R mysql:mysql /var/lib/mysql

    7. 初始化数据库

    [root@vip mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/var/lib/mysql
    when specifying MySQL privileges !
    Installing MySQL system tables...
    OK
    Filling help tables...
    OK  #看到2个OK说明初始化成功

    8. 拷贝配置文件

    [root@vip mysql]# /bin/cp support-files/my-large.cnf /etc/my.cnf

    9. 拷贝启动脚本

    # 拷贝启动脚本
    [root@vip mysql]# /bin/cp support-files/mysql.server /etc/init.d/mysqld
    # 赋予可执行权限
    [root@vip mysql]# chmod 755 /etc/init.d/mysqld

    10. 修改启动脚本

    [root@vip mysql]# vim /etc/init.d/mysqld
    # 修改设置内容如下
    basedir=/usr/local/mysql
    datadir=/var/lib/mysql

    11. 把MySQL添加到服务

    # 添加到service列表
    [root@vip mysql]# chkconfig --add mysqld
    # 设置开机启动
    [root@vip mysql]# chkconfig mysqld on

    12. 启动MySQL服务

    [root@vip mysql]# service mysqld start
    Starting MySQL... SUCCESS!

    13. 查看验证MySQL启动进程

    [root@vip mysql]# ps -e | grep mysql
     1830 pts/1    00:00:00 mysqld_safe
     2121 pts/1    00:00:00 mysqld

    14. 配置MySQL环境变量

    将 MySQL 客户端命令路径加入 PATH 环境变量中去。

    # 设置PATH环境变量
    [root@vip mysql]# echo 'export PATH=$PATH:/usr/local/mysql/bin' > /etc/profile.d/mysql.sh
    [root@vip mysql]# source /etc/profile.d/mysql.sh

    15. 登录MySQL测试

    [root@vip mysql]# mysql    # 默认没有密码
    Your MySQL connection id is 1
    Server version: 5.5.40-log MySQL Community Server (GPL)
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    ... ...
    mysql>

    二、PHP服务安装

    说明下,针对Nginx的php安装和针对apache的php安装是有区别的,因为Nginx中的php是以fastcgi的方式结合nginx的。可以理解为nginx代理了php的fastcgi,而apache是把php最为自己的模块来调用的。

    1、下载解压php压缩包

    cd /usr/local/src
    wget http://cn2.php.net/get/php-5.5.38.tar.gz/from/this/mirror
    mv mirror php-5.5.38.tar.gz
    tar zxf php-5.5.38.tar.gz

    2、创建php账号

    useradd -s /sbin/nologin php-fpm -M

    该账号用来运行php-fpm服务,在LNMP环境中,php是以一个服务来提供服务的。

    3、配置编译选项

    yum install -y libcurl-devel libtool-ltdl-devel
    yum install -y pcre pcre-devel apr apr-devel zlib-devel gcc make

    配置编译选项:

    cd php-5.5.38
    ./configure --prefix=/usr/local/php 
    --with-config-file-path=/usr/local/php/etc 
    --enable-fpm --with-fpm-user=php-fpm 
    --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql 
    --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir 
    --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir 
    --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap 
    --enable-gd-native-ttf --enable-ftp --enable-mbstring 
    --enable-exif --enable-zend-multibyte --disable-ipv6 
    --with-pear --with-curl --with-openssl

    4、编译安装PHP

    make
    make install

    5、修改配置文件

    cp php.ini-production /usr/local/php/etc/php.ini
    cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
    vim /usr/local/php/etc/php-fpm.conf

    把如下内容写入该文件:

    [global]
    pid = /usr/local/php/var/run/php-fpm.pid
    error_log = /usr/local/php/var/log/php-fpm.log
    [www]
    listen = 127.0.0.1:9000
    user = php-fpm
    group = php-fpm
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 20
    pm.min_spare_servers = 5
    pm.max_spare_servers = 35
    pm.max_requests = 500
    rlimit_files = 1024

    保存配置文件后,检验配置是否正确的方法为:

    /usr/local/php/sbin/php-fpm -t

    6、启动php-fpm

    首先要拷贝一个启动脚本到/etc/init.d/下:

    cp /usr/local/src/php-5.3.27/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

    给它更改权限为755

    chmod 755 /etc/init.d/php-fpm
    chkconfig --add php-fpm
    service php-fpm start

    设置开机启动,执行:

    chkconfig php-fpm on

    检测是否启动

    ps aux | grep php-fpm

    三、Nginx编译安装

    1、下载、解压Nginx

    cd /usr/local/src
    wget http://nginx.org/download/nginx-1.8.0.tar.gz
    tar zxvf nginx-1.8.0.tar.gz

    2、配置编译选项

    cd nginx-1.8.0
    ./configure --prefix=/usr/local/nginx 
    --with-http_realip_module --with-http_sub_module 
    --with-http_gzip_static_module 
    --with-http_stub_status_module --with-pcre

    3、编译安装Nginx

    make
    make install

    4、启动nginx

    /usr/local/nginx/sbin/nginx

    检查nginx是否启动:

    ps aux | grep nginx

    四、测试PHP解析

    首先配置 nginx 配置文件,使其能够支持php

    vim /usr/local/nginx/conf/nginx.conf

    找到:

    location = /50x.html {
        root html;
    }

    在其后面增加如下配置:

    location ~ .php$ {
        root 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;
    }

    重新加载:

    /usr/local/nginx/sbin/nginx -s reload

    创建测试文件:

    vim /usr/local/nginx/html/2.php
    <?php
        echo "test php scripts.";
    ?>

    测试:

    curl localhost/2.php
    test php scripts.

    显示成这样,才说明 PHP 解析正常。

    五、Nginx启动脚本和配置文件

    1、编写启动脚本并加入系统服务

    vim /etc/init.d/nginx

    写入如下内容:

    #!/bin/bash
    # chkconfig: - 30 21
    # description: http service.
    # Source Function Library
    . /etc/init.d/functions
    # Nginx Settings
    
    NGINX_SBIN="/usr/local/nginx/sbin/nginx"
    NGINX_CONF="/usr/local/nginx/conf/nginx.conf"
    NGINX_PID="/usr/local/nginx/logs/nginx.pid"
    RETVAL=0
    prog="Nginx"
    
    start() {
            echo -n $"Starting $prog: "
            mkdir -p /dev/shm/nginx_temp
            daemon $NGINX_SBIN -c $NGINX_CONF
            RETVAL=$?
            echo
            return $RETVAL
    }
    
    stop() {
            echo -n $"Stopping $prog: "
            killproc -p $NGINX_PID $NGINX_SBIN -TERM
            rm -rf /dev/shm/nginx_temp
            RETVAL=$?
            echo
            return $RETVAL
    }
    
    reload(){
            echo -n $"Reloading $prog: "
            killproc -p $NGINX_PID $NGINX_SBIN -HUP
            RETVAL=$?
            echo
            return $RETVAL
    }
    
    restart(){
            stop
            start
    }
    
    configtest(){
        $NGINX_SBIN -c $NGINX_CONF -t
        return 0
    }
    
    case "$1" in
      start)
            start
            ;;
      stop)
            stop
            ;;
      reload)
            reload
            ;;
      restart)
            restart
            ;;
      configtest)
            configtest
            ;;
      *)
            echo $"Usage: $0 {start|stop|reload|restart|configtest}"
            RETVAL=1
    esac
    
    exit $RETVAL

    保存后,更改权限:

    chmod 755 /etc/init.d/nginx
    chkconfig --add nginx
    chkconfig nginx on

    2、更改整理nginx配置

    首先清空原来的配置文件:

    > /usr/local/nginx/conf/nginx.conf
    快速清空文档。

    编辑文件写入如下内容:

    # vim /usr/local/nginx/conf/nginx.conf
    
    user nobody nobody;
    worker_processes 2;
    error_log /usr/local/nginx/logs/nginx_error.log crit;
    pid /usr/local/nginx/logs/nginx.pid;
    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_for [$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 vhosts/*.conf;
    }

    继续如下操作:

    cd /usr/local/nginx/conf
    mkdir vhosts
    cd vhosts
    vim default.conf

    写入如下内容:

    server
    {
        listen 80 default;
        server_name localhost;
        index index.html index.htm index.php;
        root /tmp/1233;
        deny all;
    }

    编辑www.123.com.conf文件,写入如下内容:

    server
    {
        listen 80; 
        server_name www.123.com;
        index index.html index.htm index.php;
        root /usr/local/apache2/htdocs;
    
        location ~ .php$ {
            include fastcgi_params;
            #fastcgi_pass unix:/tmp/php-fcgi.sock;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /usr/local/apache2/htdocs$fastcgi_script_name;
        }   
    }

    保存配置后,先检验一下配置文件是否有错误存在:

    /usr/local/nginx/sbin/nginx -t

    启动nginx服务:

    service nginx start

    查看是否有进程:

    ps aux | grep nginx

    六、php-fpm配置文件

    清空原始配置文件:

    > /usr/local/php/etc/php-fpm.conf

    编辑配置文件:

    vim /usr/local/php/etc/php-fpm.conf

    写入如下内容:

    [global]
    pid = /usr/local/php/var/run/php-fpm.pid
    error_log = /usr/local/php/var/log/php-fpm.log
    [www]
    listen = 127.0.0.1:9000
    user = php-fpm
    group = php-fpm
    listen.owner = nobody
    listen.group = nobody
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 20
    pm.min_spare_servers = 5 
    pm.max_spare_servers = 35
    pm.max_requests = 500 
    rlimit_files = 1024

    配置说明:

    global部分是全局配置,指定pid文件路径以及error_log路径。
    [www]是一个pool,其实还可以再写第二个pool,第二个pool和第一个不一样的地方,首先pool的name,比如叫做[www2]。然后listen肯定就不能一样了,比如可以listen=/tmp/php-fcgi2.sock。而user,group也可以和[www]中定义的不一样。listen.owner这个是定义/tmp/php-fcgi.sock这个文件的所有者是谁,在php5.4版本之后监听的socket文件权限默认变成了 rw-------,如果不定义listen.owner那么nginx调用这个socket的时候就没有权限了,故在这里我们定义listen.owner为nginx的子进程监听用户。

    pm = dynamic 表示以动态的形式启动,在php5.3 版本以后它可以支持动态和静态了,如果是静态,即 pm=static时,下面的配置只有pm.max_children管用。
    pm.max_children 表示启动几个 php-fpm 的子进程。如果是 dynamic,下面的配置会生效,pm.max_children 表示最大可以启动几个子进程。
    pm.start_servers 表示一开始启动几个子进程。
    pm.min_spare_servers 表示当 php-fpm 空闲时最少要有几个子进程,即如果空闲进程小于此值,则创建新的子进程。pm.max_spare_server 表示当 php-fpm 空闲时最多有几个子进程,即如果空闲进程大于此值,则会进行清理。
    pm.max_requests 表示一个子进程最多可以接受多少个请求,比如设置为 500 那么一个子进程受理 500 个请求后自动销毁。
    rlimit_files 表示每个子进程打开的多少个文件句柄。

    七、常见的502错误问题

    1、配置错误

    因为nginx找不到php-fpm了,所以报错,一般是fastcgi_pass后面的路径配置错误了,后面可以是socket或者是127.0.0.1:900。要注意与php-fpm.conf配置文件中[listen]字段值保持一致。

    2、资源耗尽

    lnmp架构在处理php时,nginx直接调取后端的php-fpm服务,如果nginx的请求量偏高,我们又没有给php-fpm配置足够的子进程,那么php-fpm就会资源耗尽,一旦资源耗尽nginx找不到php-fpm就会出现502错误??

    解决方案:
    去调整php-fpm.conf中的pm.max_children数值,使其增加,但是也不能无限增加,毕竟资源有限,一般4G内存机器如果跑php-fpm和nginx,不跑mysql可以设置为150,8G为300以此类推

    3、其它原因

    除了上面的两种错误还有其他的原因,很少有,我们可以借助nginx的错误日志来进行排查vim /usr/local/nginx/logs/nginx_error.log  我们也可以给日志定义级别vim/usr/local/nginx/conf/nginx.conf 找到error_log,默认是crit最严谨的就行,也可以改成debug显示的信息最全面,但是很容易撑爆我们的磁盘。检查nginx是以哪个用户身份运行

    ps aux | grep nginx
    vim /usr/local/php/etc/php-fpm.conf
    [www]
    listen.owner = nobody
    listen.group = nobody

    使用版本高于5.4(含5.4),默认监听的sock文件权限是所有者只读,用户组和其它用户没有任何权限。所以nginx的启动用户nobody没有办法读这个socket文件,最终导致502,这个问题可以在nginx的错误日志中发现。解决办法很简单,上面给出的配置文件就有避免这个问题的配置。

    listen.owner = nobody    //定义属主
    listen.group = nobody    //定义属组

    这两个配置就是定义socket的属主和属组是谁。除了这个还有一种方法这样nobody也可以有读取权限了。

    listen.mode = 777
  • 相关阅读:
    单链表的实现C语言版
    顺序表的基本方法实现C语言版
    算法
    Redis
    Linux安装python3.6.1
    Markdown 基本使用手册
    设计Django个人博客网站
    RabbitMQ消息队列
    堡垒机 Paramiko 模块
    进程、线程、协程总结
  • 原文地址:https://www.cnblogs.com/liwei0526vip/p/6433490.html
Copyright © 2020-2023  润新知