写在前面 这则笔记主要整理lnmp相关的内容,主要包括3个部分:
系统环境:
linux: centos7.4
nginx:1.14
mysql:5.6
php:7
LNMP简介 LNMP架构是什么? 所谓LNMP,就是Linux系统下Nginx+MySQL+PHP这种网站服务器架构。
与LAMP不同,LNMP的工作模式:
在LAMP中,提供web服务的是apache;而在LNMP中,提供web服务的是Nginx;
在Apache中,PHP是作为一个模块存在的;在Nginx中,PHP是作为一个独立服务存在的,这个服务叫做php-fpm;
Nginx直接处理静态请求(支持的并发更高,速度比Apache快),动态请求转发给php-fpm处理。
nginx 的优缺点:
php-fpm又是什么? 这里涉及到到一些新的概念,整理如下:
CGI
,即公共网关接口Common Gateway Interface
,简单地说,就是网页的表单和你写的程序之间通信的一种协议。CGI针对每个http请求都是fork一个新进程来进行处理,处理过程包括解析php.ini文件,初始化执行环境等,然后这个进程会把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。
FastCGI
,是CGI的更高级的一种方式,是用来提高CGI程序性能的。Fastcgi则会先fork一个master,解析配置文件,初始化执行环境,然后再fork多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复劳动,提高了工作效率。
PHP-CGI
,是PHP自带的FastCGI管理器。只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理。所以,就出现了很多进程调度的工具,比如spawn-fcgi。
PHP-FPM
,是PHP FastCGI管理器,之前是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。从PHP5.3.3版本开始,PHP内核集成了PHP-FPM之后就方便多了,使用–enalbe-fpm这个编译参数安装即可。
系统环境准备 Linux系统环境
LNMP需要预留5G以上的剩余空间;
安装MySQL 5.6或5.7及MariaDB 10必须1G以上内存;
安装vim yum install -y vim-enhanced
提前安装 好GCC编译器 yum install -y gcc
系统防火墙设置,关闭firewalld;安装并配置好itables,开放80、3306端口;同时,selinux设置为disabled
必装软件:
语言环境变量设置 1 2 3 4 5 vim /etc/envirment //增加两行 LANG=en_US.utf-8 LC_ALL=en_US.utf-8
关闭firewalld 1 2 3 4 //关闭firewalld systemctl stop firewalld.service //禁止开机启动 systemctl disable firewalld.service
安装配置iptables 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //安装iptables yum install -y iptables-services //编辑配置文件,重点是开放80、3306端口 vim /etc/sysconfig/iptables # sample configuration for iptables service # you can edit this manually or use system-config-firewall # please do not ask us to add additional ports/services to this default configuration *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT //开放80端口,针对httpd -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT //开放3306端口,针对mysql -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT //重启防火墙使配置生效 [root@stevey ~]# systemctl restart iptables.service //设置防火墙开机启动 [root@stevey ~]# systemctl enable iptables.service
关闭selinux 1 2 3 vim /etc/selinux/config //找到SELINUX=enforcing这一行,将enforcing 改为 disabled,保存退出并重启虚拟机
阶段成果
软件环境安装 mysql 安装 第一步:下载二进位制包 1 2 3 4 5 6 7 wget http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz //解压 tar -zvxf mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz //进入安装包 cd mysql-5.6.36-linux-glibc2.5-x86_64
第二步:创建mysql账户及目录 1 2 3 4 5 6 7 8 9 10 11 创建mysql安装目录 mkdir -p /usr/local/mysql //创建mysql用户 -s指定shell useradd -s /sbin/nologin mysql //创建数据库文件 mkdir -p /data/mysql //更改用户名和所属组权限 chown -R mysql:mysql /data/mysql
第三步:安装依赖项 1 2 3 4 5 //安装依赖包perl-Module-Install yum install -y perl-Module-Install //安装依赖包libaio yum install -y libaio
第四步:编译安装 1 2 3 4 5 6 7 8 9 10 11 12 //将编译好的二进位制包移动到/usr/local/mysql目录下 mv /usr/local/src/mysql-5.6.36-linux-glibc2.5-x86_64/* /usr/local/mysql/ //进入mysql目录 cd /usr/local/mysql/ //编译参数 ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql //校验结果 [root@VM_0_14_centos mysql]# echo $? 0 //返回0说明成功
第五步:修改环境变量 1 2 3 4 5 //修改配置文件 vim ~/.bash_profile //将mysql路径加入环境变量 PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
第六步:配置mysql 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //复制配置文件 cp support-files/my-default.cnf /etc/my.cnf //编辑配置文件 vim /etc/my.cnf //修改以下配置 log_bin = root //15行 basedir = /usr/local/mysql datadir = /data/mysql port = 3306 server_id = 128 socket = /tmp/mysql.sock //去掉以下配置前面的的型号 innodb_buffer_pool_size = 128M join_buffer_size = 128M sort_buffer_size = 2M read_rnd_buffer_size = 2M
第七步:配置启动脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 cd /usr/local/mysql //复制启动脚本到/etc/init.d/mysqld cp support-files/mysql.server /etc/init.d/mysqld //修改文件权限 chmod 755 /etc/init.d/mysqld //编辑启动脚本 vim /etc/init.d/mysqld //更改data保存目录 basedir=/usr/local/mysql datadir=/data/mysql
第八步:设置开机启动 1 2 3 4 5 6 7 8 9 10 11 //进入系统服务目录 /etc/init.d/ cd /etc/init.d/ //将mysqld 服务加入系统服务列表 chkconfig --add mysqld //设置开机启动 chkconfig mysqld on //启动mysqld service mysqld start
校验是否启动 方法一:查看进程,结果应大于2行
方法二:查看端口监听情况
1 netstat -lnp |grep mysqld
TroubleShooting:mysqld服务未启动
重启服务即可
nginx 安装 第一步:下载源码包 1 2 3 4 5 6 7 8 //源码包放到/usr/local/src目录 cd /usr/local/src //下载 wget https://nginx.org/download/nginx-1.14.0.tar.gz //解压 tar -zxvf nginx-1.14.0.tar.gz
第二步:安装依赖包
gcc、gcc+ 安装方法:yum install -y gcc gcc-c++
PCRE库 安装方法:yum install -y pcre pcre-devel
zlib库 安装方法:yum install -y zlib zlib-devel
OpenSSL开发库(支持https) 安装方法:yum install -y openssl openssl-devel
第三步:创建用户及安装目录 1 2 3 4 5 6 //创建安装目录 mkdir -p /usr/local/nginx //创建用户 groupadd nginx useradd -M -s /sbin/nologin -g nginx nginx
第四步:编译安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //进入源码包 cd nginx-1.14.0 //编译参数 ./configure \ --prefix=/usr/local/nginx \ --pid-path=/usr/local/nginx/logs/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --user=nginx \ --group=nginx \ --with-http_ssl_module \ --with-http_flv_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre //编译安装 make && make install
第五步:启动nginx 1 2 3 4 5 6 7 8 9 10 //设置软链接 ln -s /usr/local/nginx/sbin/nginx /usr/sbin //语法检查 [root@VM_0_14_centos nginx-1.14.0]# 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 //启动nginx nginx
校验成果
1 2 3 4 5 6 [root@VM_0_14_centos nginx-1.14.0]# ps -aux | grep nginx root 12551 0.0 0.1 45928 1120 ? Ss 17:09 0:00 nginx: master process nginx nginx 12552 0.0 0.1 48460 1976 ? S 17:09 0:00 nginx: worker process root 12557 0.0 0.0 112704 976 pts/3 R+ 17:09 0:00 grep --color=auto nginx [root@VM_0_14_centos nginx-1.14.0]# netstat -lnp | grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12551/nginx: master
第六步:编写启动脚本并加入系统服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 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
1 chmod a+x /etc/init.d/nginx
1 2 chkconfig --add nginx chkconfig nginx on
注: 这里遇到一个很奇怪的错误,nginx启动失败;restart
也不行,后来尝试init 6
重启主机后成功。
测试结果如下,nginx成功启动
php安装 第一步:下载并解压源码包 1 2 3 4 5 6 7 cd /usr/local/src/ //wget命令下载 wget http://cn2.php.net/distributions/php-7.2.6.tar.gz //解压源码包 tar -zxvf php-7.2.6.tar.gz
第二步:安装依赖包 1 2 //安装依赖包 yum install -y libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel gmp gmp-devel libmcrypt libmcrypt-devel readline readline-devel libxslt libxslt-devel
第三步:创建账号 1 useradd -s /sbin/nologin php-fpm
第四步:编译安装 1 2 3 4 5 6 7 8 //进入安装目录 cd /usr/local/src/php-7.2.6 //编译参数 ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --with-fpm-user=php-fpm --with-fpm-group=php-fpm --enable-mysqlnd --with-mysqli --with-pdo-mysql --enable-fpm --with-gd --with-iconv --with-zlib --enable-xml --enable-shmop --enable-sysvsem --enable-inline-optimization --enable-mbregex --enable-mbstring --enable-ftp --with-openssl --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --enable-session --with-curl --with-jpeg-dir --with-freetype-dir --enable-opcache //编译安装 make && make install
TroubleShooting:虚拟内存不足导致make失败 因为php的安装包比较大,因此经常会在make的时候出现虚拟内存不够报错的情况。笔者在本地虚拟机和云主机的配置都是1G内存,也都遇到了这个情况,解决的办法是手动增加swap交换空间。
手动增加swap空间的步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //建立swapfile [root@tencentcvm php-7.2.6]# mkdir -p /usr/img/ [root@tencentcvm php-7.2.6]# rm -rf /usr/img/swap [root@tencentcvm php-7.2.6]# dd if=/dev/zero of=/usr/img/swap bs=1024 count=2048000 2048000+0 records in 2048000+0 records out 2097152000 bytes (2.1 GB) copied, 19.5733 s, 107 MB/s //格式化swap [root@tencentcvm php-7.2.6]# mkswap /usr/img/swap Setting up swapspace version 1, size = 2047996 KiB no label, UUID=0d8a402b-11d0-4e0d-afa0-05c002b3df07 //挂载swap [root@tencentcvm php-7.2.6]# swapon /usr/img/swap swapon: /usr/img/swap: insecure permissions 0644, 0600 suggested. 修改文件夹权限 [root@tencentcvm php-7.2.6]# chmod 0600 /usr/img/swap
修改完成后,在重新执行make
1 2 3 make clean make && make install
注:安装完成别忘记修改环境变量,将/usr/local/php-fpm/sbin
和 /usr/local/php-fpm/bin
加入环境变量。
这两个目录下分别有这些命令:
1 2 3 4 5 6 7 vi .bash_profile //加入以下变量,变量之间用英文冒号隔开 /usr/local/php-fpm/bin:/usr/local/php-fpm/sbin [root@steve ~]# source !$ source .bash_profile
第五步:修改 php配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 //查看php配置信息 php -i | head //移动php.ini文件 [root@steve php-7.2.6]# mv php.ini-production /usr/local/php-fpm/etc/php.ini //进入配置文件 cd /usr/local/php-fpm/etc //重命名配置文件 cp php-fpm.conf.default ./php-fpm.conf //修改配置文件 vi php-fpm.conf //加入以下内容 [global] pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] listen = /tmp/php-fcgi.sock listen.mode = 666 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 //检查语法错误 php-fpm -t
注意: 这里有一个提示:
之所以出现这一行,是因为下面红框中的内容,即include=/usr/local/php-fpm/etc/php-fpm.d/*.conf
。 lnmp环境支持虚拟主机,也就是同一台服务器上运行多个网站,每个网站的配置信息,联通php的配置文件都可以分开写,/usr/local/php-fpm/etc/php-fpm.d/
目录下就是关于php-fpm的配置文件。
第六步:设置开机启动 1 2 3 4 5 6 7 8 9 10 11 //复制启动脚本 cp /usr/local/src/php-7.2.6/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm //更改权限 chmod 755 /etc/init.d/php-fpm //启动服务 service php-fpm start //开机启动 chkconfig php-fpm on
补充:mariaDB安装 mariaDB跟mysql一样,但是是开源的,可以用来替代mysql。
centos7本身自带了mariaDB5.5版,我们需要先把这个卸载掉,之后再安装最新的MariaDB10.2版。
实现步骤:
第一步:备份数据库 1 cp -a /var/lib/mysql/ /var/lib/mysql.bak
第二步:添加MariaDB存储库 按照mariaDB官方给的方法,修改yum配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //升级yum yum update //编辑yum源 vim /etc/yum.repos.d/MariaDB10.repo //加入以下内容: # MariaDB 10.2 CentOS repository list - created 2018-05-15 06:14 UTC # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.2/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1 //先清除之前到缓存 yum clean all //生成缓存 yum makecache
第三步:删除系统自带的MariaDB 5.5 1 yum remove mariadb-server mariadb mariadb-libs
第四步:安装MariaDB 10 1 yum install -y MariaDB-server MariaDB-client
注: mariaDB有170多M,但是是从国外的服务器下载,所以超级慢,此处可以休息休息。
第五步:启动服务 1 2 3 4 5 6 7 8 //启动服务 systemctl start mariadb //设置开机启动 systemctl enable mariadb //检查服务状态 systemctl status mariadb
第六步:初始化密码设定 1 mysql_secure_installation
根据提示,设置以下内容:
第七步:创建用户以及设置权限 1 2 //数据库登陆 mysql -u[用户名,默认是root] -p[密码,输入刚刚初始化设定的密码]
第八步:测试是否启动 1 2 3 4 5 6 7 8 //检测进程是否启动 [root@steve ~]# ps -aux | grep mysqld root 5460 0.0 0.0 112704 976 pts/1 R+ 13:28 0:00 grep --color=auto mysqld mysql 30064 0.0 4.1 1307692 78408 ? Ssl 11:27 0:02 /usr/sbin/mysqld //查看端口情况 [root@steve ~]# netstat -lnp | grep 3306 tcp6 0 0 :::3306 :::* LISTEN 30064/mysqld
至此,安装部分暂告一段落,下面是配置部分
lnmp基础配置 nginx 配置 配置文件简介
路径
类型
作用
/etc/nginx/conf.d/default.conf
配置文件
nginx主配置文件
/etc/logrotate.d/nginx
配置文件
用于logrotate服务的日志切割
/etc/nginx/nginx.conf /etc/nginx/fastcgi_params /etc/nginx/uwsgi_params /etc/nginx/scgi_params
配置文件
cgi配置相关、fastcgi配置
/etc/nginx/koi-utf /etc/nginx/win-utf /etc/nginx/koi-win
配置文件
编码转换映射转化文件
/etc/nginx/mime.types
配置文件
设置http协议的Content-Type与扩展名对应关系 ,处理一些识别不了的扩展名的时候需要用到
/usr/lib/systemd/system/nginx.service /usr/lib/systemd/system/nginx-debug.service /etc/sysconfig/nginx /etc/sysconfig/nginx-debug
配置文件
用于配置出系统守护进程管理器管理方式
/usr/sbin/nginx /usr/sbin/nginx-debug
命令
nginx服务终端命令
/usr/share/doc/nginx-1.12.2/COPYRIGHT /usr/share/man/man8/nginx.8.gz
文件、目录
nginx的手册和帮助文件
/var/cache/nginx/
目录
nginx的缓存目录
/var/log/nginx/
目录
nginx的日志目录
nginx.conf
为主配置文件;
inlcude是一个指令,当一个服务器上有多个网站共享时,通过设置include可以很方便的对虚拟主机站点进行管理。
Standard name
Description
nginx.conf
主配置文件
fastcgi.conf
FastCGI相关配置
proxy.conf
代理相关配置
sites.conf
虚拟主机配置
修改配置文件后需要重启nginx
1 2 3 4 5 //重启nginx systemctl restart nginx.service //重新记载配置文件 systemctl reload nginx.service
nginx 的基础配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 vi /usr/local/nginx/conf/nginx.conf //加入以下内容 user nginx nginx; worker_processes 2; error_log /usr/local/nginx/logs/nginx_error.log crit; pid /usr/local/nginx/logs/nginx.pid; worker_rlimit_nofile 65535; 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"'; server_names_hash_bucket_size 3526; server_names_hash_max_size 4096; sendfile on; tcp_nopush on; keepalive_timeout 65; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 8m; server_tokens off; client_body_buffer_size 512k; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_intercept_errors on; gzip off; gzip_min_length 1k; gzip_buffers 32 4k; gzip_http_version 1.0; gzip_comp_level 5; gzip_types text/css text/xml application/javascript application/atom+xml application/rss+xml text/plain application/json; gzip_vary on; server { listen 80; server_name localhost; index index.html index.htm index.php; root /usr/local/nginx/html; #charset koi8-r; location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/tmp/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; } } }
检查语法并重新加载服务
1 2 3 4 5 6 7 //语法检查 [root@tencentcvm ~]# 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 //重新加载服务 [root@tencentcvm ~]# nginx -s reload
配置虚拟主机 同一台服务器,可以设置多个网站,每个网站采用单独的配置文件;
1 2 3 4 vi /usr/local/nginx/conf/nginx.conf //在最后一个大括号之前加一行 include vhost/*.conf;
1 2 3 4 5 //新建虚拟主机文件夹 //该目录下所有配置文件均会被加载 mkdir -p /usr/local/nginx/conf/vhost cd /usr/local/nginx/conf/vhost
1 2 3 4 5 6 7 8 9 10 11 12 vi default.conf //加入如下配置 server { listen 80 default_server; //default_server 表示默认虚拟主机 server_name steve.discuz.com; index index.html index.htm index.php; root /data/ngix/default; } //保存退出
1 2 3 4 5 6 7 8 //创建项目目录 mkdir -p /data/nginx/default/ //创建索引页 touch index.html //添加内容到测试页面 echo 'default_server' > /data/nginx/default/index.html
1 2 3 4 5 //检查语法错误 nginx -t //重新记载服务 nginx -s reload
1 2 //测试 curl -x172.16.155.128:80 steve-discuz.com
TroubleShooting:拒绝访问
解决思路:
如下所示:
1 2 steve:~ steveyuan$ curl -x 172.16.155.128:80 steve-discuz.com/index.html default_server
再测一个并不存在的域名,如下图所示,依然返回默认虚拟主机的页面内容,说明虚拟主机配置成功。
用户认证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cd /usr/local/nginx/conf/vhost vi test.com.conf //添加以下配置 server { listen 80; server_name steve-test.com; index index.html index.htm index.php; root /data/ngix/test.com; location / { auth_basic 'Auth'; auth_basic_user_file /usr/local/nginx/conf/htpasswd; } }
1 2 3 4 5 6 7 8 9 10 11 //创建项目文件夹 mkdir -p /data/nginx/test.com //创建index.html touch index.html //安装httpd yum install -y httpd //生成用户密码文件 htpasswd -c /usr/local/nginx/conf/htpasswd steve
1 2 3 4 5 //语法检查 nginx -t //重新加载服务 nginx -s reload
1 echo 'test' > /data/nginx/test.com/index.html
域名重定向 前提准备:
1 > /usr/local/nginx/conf/vhost/test.com.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 vi test.com.conf server { listen 80; server_name test.com test1.com test2.com; index index.html index.htm index.php; root /data/nginx/test.com; if ($host != 'test.com') { rewrite ^/(.*)$ http://test.com/$1 permanent; //permanent为永久重定向,相当于httpd中的R=301;还有一个常用选项叫做redirect,相当于httpd 的 R=301; } }
1 2 3 4 5 //检查语法 nginx -t //重新加载服务 nginx -s reload
1 curl -x 172.16.155.128:80 test1.com
如下图所示,域名重定向成功
拓展知识:rewrtie的四种flag 上面例子当中的重定向也是通过rewrite模块实现的,这里补充一些rewrite模块的知识。
对于rewrtie有四种不同的flag,分别是redirect、permanent、break和last,具体如下:
flag
说明
redirect
临时跳转
permanent
永久跳转,一般是为了对搜索引擎友好
last
将rewrite后的地址重新在server标签执行
break
将rewrite后地址重新在当前的location标签执行
静态文件不记录日志和过期时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 vim /usr/local/nginx/conf/vhost/test.com.conf //增加如下内容: location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ //匹配脱义静态文件 { expires 7d; //配置过期时间 access_log off; } location ~ .*\.(js|css)$ //匹配js,css文件 { expires 12h; access_log off; }
如下图所示:
1 2 3 nginx -t nginx -s reload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 //创建测试文件 cd /data/nginx/test.com //创建测试文件 [root@stevey test.com]# echo 'js' > /data/nginx/test.com/1.js [root@stevey test.com]# echo 'jpeg' > /data/nginx/test.com/1.jpeg //测试访问 steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 test1.com/1.js <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html> steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 test1.com/1.jpeg <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html> //查看访问日志 (没有js和jpeg的访问记录) [root@stevey test.com]# cat /tmp/nginx/test.log 172.16.155.1 - - [10/Jun/2018:22:30:21 +0800] "HEAD http://test1.com/123.html HTTP/1.1" 301 0 "-" "curl/7.54.0" 172.16.155.1 - - [10/Jun/2018:22:30:35 +0800] "HEAD http://test1.com/asdasd.html HTTP/1.1" 301 0 "-" "curl/7.54.0"
Nginx防盗链 防盗链的目的在于节约服务器资源,防止揩油行为。
vim /usr/local/nginx/conf/vhost/test.com.conf
1 2 3 4 5 6 7 8 9 10 11 //增加如下配置: location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ { expires 7d; valid_referers none blocked server_names *.test.com ; //定义白名单 if ($invalid_referer) { return 403; } //如果不是白名单里就返回403 access_log off; }
1 2 3 nginx -t nginx -s reload
注: 这里有个问题,为什么定义的是403,返回的是404呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 steve:steveBlog steveyuan$ curl -e "http://www.test.com/1.txt" -x 172.16.155.128:80 -I test.com/1.gif HTTP/1.1 404 Not Found Server: nginx Date: Mon, 11 Jun 2018 05:37:47 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive steve:steveBlog steveyuan$ curl -e "http://www.test.com/" -x 172.16.155.128:80 -I test.com/1.gif HTTP/1.1 404 Not Found Server: nginx Date: Mon, 11 Jun 2018 05:39:34 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive
Nginx访问控制
第一步:编辑配置文件(根据实际情况,白名单或黑名单任选其一)
1 2 3 4 5 6 7 8 9 10 //配置白名单 vi /usr/local/nginx/conf/vhost/test.com.conf //增加白名单,只允许以下几个ip访问 location /admin/ { allow 127.0.0.1; deny all; }
1 2 3 4 5 6 7 8 9 //配置黑名单 vi /usr/local/nginx/conf/vhost/test.com.conf //增加黑名单,不允许以下几个ip访问 location /admin/ { deny 172.16.157.0/24; //禁止一个网段 }
针对user-agent 进行限制
1 2 3 4 5 6 7 8 9 vi /usr/local/nginx/conf/vhost/test.com.conf //增加白名单,只允许以下几个ip访问 //这里制定目录,该配置针对全站生效 if ($http_user_agent ~ 'spider|romato') { return 403; //等同于deny all }
注: 在配置httpd的时候,需先定义order顺序;在Nginx里并没有这个选项,它就会从上到下逐一去匹配,一旦找到匹配项,就会做deny 处理,返回403错误。
1 2 3 nginx -t nginx -s reload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //白名单测试(虚拟机本机访问) [root@stevey admin]# curl -x 127.0.0.1:80 test.com/admin/test.html 123,ok //白名单测试(宿主机访问,此ip不在白名单上) steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 -I test.com/admin/test.html HTTP/1.1 403 Forbidden Server: nginx Date: Mon, 11 Jun 2018 06:09:38 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive //黑名单测试 [root@stevey admin]# curl -x 127.0.0.1:80 test.com/admin/test.html 123,ok //限制user-agent访问的测试 steve:steveBlog steveyuan$ curl -A 'spider' -x 172.16.155.128:80 test.com/admin/test.html <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx</center> </body>
目录访问限制 除了对全站进行配置,还可以对指定的目录进行配置,主要用到location语句,配置语句类似于
1 2 3 4 location ~ [目录] { 配置规则 }
示例:
目的: upload目录下的.php文件不能访问,但是除了.php的其他后缀文件就能访问。
1 2 3 4 5 6 7 8 vim /usr/local/nginx/conf/vhost/test.com.conf //增加如下内容: location ~ .*(upload|image)/.*\.php$ //意思是匹配upload或者image目录下的.php文件 { deny all; }
nginx中location的基本语法 语法
命令行格式:
1 2 3 location [=|~|~*|^~] patt { }
常用符号含义:
匹配顺序
精确匹配 location = /abc { }
匹配路径的前缀,如果找到停止搜索 location ^~ /abc { }
不区分大小写的正则匹配 location ~* /abc { }
正则匹配 location ~ /abc { }
普通路径前缀匹配 location /abc { }
举例说明:
1 2 3 4 location = / { # 只匹配"/". [ configuration A ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ocation ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] } location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] } location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 # 但是正则和最长字符串会优先匹配 [ configuration B ] }
1 2 3 4 5 location ~* \.(gif|jpg|jpeg)$ { # 匹配所有以 gif,jpg或jpeg 结尾的请求 # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则 [ configuration E ] }
Nginx代理 ipv4时代,公网ip资源稀缺,假设公司有多台服务器,但只有一个ip,就可以通过代理的方式,让没有公网ip的服务器提供web服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cd /usr/local/nginx/conf/vhost vim proxy.conf //增加如下内容: server { listen 80; server_name test.com; location / { proxy_pass http://172.16.155.128/; //指定要代理的域名所在的服务器IP,即Web服务器的地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
注:该配置文件没有设置root文件目录的路径,因为它是代理服务器,不需要访问本地服务器上的任何文件;
1 2 3 nginx -t nginx -s reload
Nginx访问日志 跟apache一样,nginx也有访问日志的功能。相比较而言,nginx访问日志的设定还要更简洁明了一些。
日志格式
注: combined日志格式,相当于apache的combined日志格式。
1 2 3 log_format combined '$remote_addr - $remote_user [$time_local] ' ' "$request" $status $body_bytes_sent ' ' "$http_referer" "$http_user_agent" ';
注: lof_format的默认值
1 2 3 4 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '"$status" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$gzip_ratio" $request_time $bytes_sent $request_length';
注: nginx位于负载均衡器,squid,nginx反向代理之后,web服务器无法直接获取到客户端真实的IP地址了。 $remote_addr获取反向代理的IP地址。反向代理服务器在转发请求的http头信息中,可以增加X-Forwarded-For信息,用来记录 客户端IP地址和客户端请求的服务器地址。
1 2 3 log_format porxy '$http_x_forwarded_for - $remote_user [$time_local] ' ' "$request" $status $body_bytes_sent ' ' "$http_referer" "$http_user_agent" ';
常用的配置参数
参数
注释
$remote_addr
客户端IP地址
$http_x_forwarded_for
代理服务器IP
$remote_user
客户端用户名称
$request
请求的URL和HTTP协议
$status
请求返回的状态码,例如:200、301、404等
$body_bytes_sent
发送给客户端的字节数,不包括响应头的大小;
$bytes_sent
发送给客户端的总字节数。
$connection
连接的序列号。
$connection_requests
当前通过一个连接获得的请求数量。
$msec
日志写入时间,单位为秒。
$pipe
如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer
记录从哪个页面链接访问过来的,可以根据该参数进行防盗链设置
$http_user_agent
客户端浏览器相关信息
$request_length
请求的长度,包括请求行,请求头和请求正)。
$request_time
请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601
ISO8601标准格式下的本地时间。
$time_local
通用日志格式下的本地时间。
$sent_http_content_range
这是一个传递到客户端的头,这类头的前缀为”sent_http_” 。
$upstream_http_
这是有upstream模块产生了日志,因此它的前缀将会是这个前缀。
日志相关命令 access_log
access_log 设定日志的路径、格式、buffer大小,是否压缩等。如果不想启用日志则access_log off ;
语法:
1 2 access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; access_log off;
示例:
1 access_log logs/access.log combined;
注: 该命令分为三个字段:
关键字:其中关键字access_log不能更改;
日志文件:可以指定存放日志的路径;
格式标签:给日志文件套用指定的日志格式;
设置日志格式
语法:
1 log_format name [escape=default|json] string ...;
示例:
1 2 3 log_format combined '$remote_addr - $remote_user [$time_local] ' ' "$request" $status $body_bytes_sent ' ' "$http_referer" "$http_user_agent" ';
注: 该命令分为三个部分:
open_log_file_cache 该命令为频繁使用的日志文件描述符所在的路径变量设置缓存。
语法:
1 open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time] | off
指令选项:
max - 缓存中存储的最大文件描述符数;
inactive - 设置缓存中在某个时间段内没有使用的文件描述符将被移除,默认为10秒;
min_uses - 在一定时间内(inactive指定),一个文件描述符最少使用多少次后被放入缓存,默认为1;
valid - 设置检查同名文件存在的时间,默认是60秒;
off - 关闭 cache;
示例
1 open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
nginx 日志配置:以test.com为例
1 2 3 4 vi /usr/local/nginx/conf/vhost/test.com.conf //加入一行配置 access_log /tmp/nginx/test.log combined
1 2 3 nginx -t nginx -s reload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //测试访问 steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 test1.com/123.html -I HTTP/1.1 301 Moved Permanently Server: nginx Date: Sun, 10 Jun 2018 14:30:21 GMT Content-Type: text/html Content-Length: 178 Connection: keep-alive Location: http://test.com/123.html steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 test1.com/asdasd.html -I HTTP/1.1 301 Moved Permanently Server: nginx Date: Sun, 10 Jun 2018 14:30:35 GMT Content-Type: text/html Content-Length: 178 Connection: keep-alive Location: http://test.com/asdasd.html //查看日志 [root@stevey test.com]# cat /tmp/nginx/test.log 172.16.155.1 - - [10/Jun/2018:22:30:21 +0800] "HEAD http://test1.com/123.html HTTP/1.1" 301 0 "-" "curl/7.54.0" 172.16.155.1 - - [10/Jun/2018:22:30:35 +0800] "HEAD http://test1.com/asdasd.html HTTP/1.1" 301 0 "-" "curl/7.54.0"
Nginx日志切割
1 2 3 4 5 6 7 8 9 10 11 12 13 vi /usr/local/sbin/nginx_log_rotate.sh #!/bin/bash ## 假设nginx的日志存放路径为/data/logs/ d=`date -d "-1 day" +%Y%m%d` //这个日期是昨天的日期,因为日志切割是第二天才执行这个脚本的。 logdir="/data/logs" nginx_pid="/usr/local/nginx/logs/nginx.pid" cd $logdir for log in `ls *.log` do mv $log $log-$d done /bin/kill -HUP `cat $nginx_pid` //跟Nginx的-s重新加载配置文件一样
1 chomod u+x /usr/local/sbin/nginx_log_rotate.sh
1 2 3 4 5 crontab -e //添加任务计划 //增加如下内容: 0 0 * * * /bin/bash /usr/local/sbin/nginx_log_rotate.sh
Nginx的负载均衡 负载均衡,是很多大型网站必备的服务器资源分配策略,从字面上的意思来理解,就是N台服务器分担负载,合理使用资源,获得更好的用户体验。
比如,如果你在运营一个类似京东、淘宝、12306这样的大型网站,假设只有一台服务器,当用户访问量过大,服务器处理不了时就会宕机,用户访问就会很慢甚至卡死。为了避免这种情况,很多大型网站都有很多台服务器,同时来提供服务。
当然,这些服务不可能是完全一致的,有的配置高,有的配置稍微差一点;如果做到既能够充分利用服务器的资源,不浪费;又不会让服务器压力过大呢?这就是均衡负载做的工作。
nginx均衡负载的实现方法 Nginx负载均衡是通过upstream模块来实现的,内置实现了三种负载策略:
方法一:轮循(默认) Nginx根据请求次数,将每个请求均匀分配到每台服务器
示例:
同一个应用有3个实例分别运行在srv1-srv3。当没有特别指定负载均衡方法时, 默认为round-robin/轮询。所有请求被代理到服务器集群myapp1, 然后nginx实现HTTP负载均衡来分发请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 http { upstream myapp1 { server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } }
方法二:最少连接 将请求分配给连接数最少的服务器。Nginx会统计哪些服务器的连接数最少。
示例:
1 2 3 4 5 6 upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; }
方法三:IP Hash 利用URI HASH绑定处理请求的服务器。具体而言,第一次请求时,根据该客户端的IP算出一个HASH值,将请求分配到集群中的某一台服务器上。后面该客户端的所有请求,都将通过HASH算法,找到之前处理这台客户端请求的服务器,然后将请求交给它来处理。
1 2 3 4 5 6 upstream myapp1 { ip_hash; server srv1.example.com; server srv2.example.com; server srv3.example.com; }
基于权重的负载均衡 上述的三种默认策略,并没有制定服务器的权重,这意味着所有列出的服务器被认为是完全平等的。但实际上并非如此,有的机器使用时间久,配置低;有的则是新机器,内存大、配置过,两者的处理能力显然是不同的,所以可以通过使用服务器权重来影响nginx的负载均衡算法。
举例来说:
下列配置中,配置最好的服务器101被赋予了最高权重,被分配的任务最多;其次是100;最后是102;
1 2 3 4 5 upstream tomcats { server 192.168.0.100:8080 weight=2; // 每6次访问有2次分配到该服务器 server 192.168.0.101:8080 weight=3; // 这台机器配置最好,每6次访问有3次分配到该服务器 server 192.168.0.102:8080 weight=1; // 每6次访问有1次分配到该服务器 }
配置中的参见参数
参数
说明
max_fails
默认为1。某台Server允许请求失败的次数,超过最大次数后,在fail_timeout时间内,新的请求将不会分配给这台机器。如果设置为0,Nginx会将这台Server置为永久无效状态
fail_timeout
默认为10秒,某台Server请求失败次数达到max_fails后,在fail_timeout期间内,nginx会认为这台Server暂时不可用,不会将请求分配给它
backup
备份机,所有服务器挂了之后才会生效
down
标识某一台server不可用
max_conns
限制分配给某台Server处理的最大连接数量,超过这个数量,将不会分配新的连接给它。默认为0,表示不限制
resolve
将server指令配置的域名,指定域名解析服务器。需要在http模块下配置resolver指令,指定域名解析服务
nginx配置ssl 基础从http 到 https http的工作原理 HTTP协议,是互联网上应用最广泛的一种网络传输协议,默认使用80端口,主要用来在计算机网络之间进行通信。
HTTP请求/响应的步骤:
客户端连接到Web服务器,默认端口为80,建立一个TCP套接字连接;
通过TCP套接字,发送HTTP请求;
服务器接受请求并返回HTTP响应;
Web服务器主动关闭TCP套接字,释放TCP连接;客户端被动关闭TCP套接字,释放TCP连接;
客户端浏览器解析HTML内容;
HTTP协议的缺点:
由于HTTP协议采用明文传输,所以天生有两大弊端:
隐私泄露:因为全都是明文传输;
安全隐患:页面劫持、中间人攻击;
为了克服上述弊端,HTTPS应运而生。
HTTPS的工作原理
这里涉及到一些加密的概念:
形象的解释,就是加密和解密用的是同一把钥匙,采用相同的秘钥进行加密和解密。
与对称加密算法不同的是,非对称加密算法使用的加密密钥和解密密钥是不同的。
RSA公钥密码算法是公钥密码算法中的一种,RSA中的加密和解密都可以使用公钥或者私钥,但是用公钥加密的密文只能使用私钥解密,用私钥加密的密文智能使用公钥解密。
SSL证书 上述过程看起来已经比较安全了,但还是有可能出现中间人攻击。举例来说,如有有人伪造了服务器的公钥与客户端进行握手,那后面的过程进行看似很“安全”,其实已经失去意义了。
为了进一步提升安全性,就催生了由第三方权威机构颁发的SSL证书。
SSL证书大概是这样的:
操作系统在出厂时会内置这个机构的机构信息和公钥。在实践过程中,A网站得到这张证书后,会在与用户通信的过程中将证书发送给客户端,客户端会检测证书的颁发机构。
如果是受信任的证书机构,应用程序会使用预置的 CA证书的公钥去解密最后的指纹内容和指纹算法,之后与网站发来的证书指纹内容进行比对,如果一致,就可以放心进行下一步的通信过程。
实现步骤:
1 2 3 4 5 //检测是否安装openssl rpm -qf `which openssl` //如没有,执行以下命令安装 yum install -y openssl
1 2 3 4 5 //秘钥放在配置文件夹下 cd /usr/local/nginx/conf/ //生成秘钥 openssl rsa -in server.key -out server.key
第二步:创建服务器证书的申请文件server.csr
1 openssl req -new -key server.key -out server.csr
1 penssl req -new -x509 -key server.key -out ca.crt -days 3650
第四步:创建自当前日期起有效期为期十年的服务器证书server.crt
1 openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt
至此,一共生成5个文件,其中,server.crt和server.key就是你的nginx需要的证书文件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //修改nginx配置文件 //将ssl_certificate改为server.crt的路径,将ssl_certificate_key改为server.key的路径. server { listen 443; server_name localhost; ssl on; ssl_certificate /root/Lee/keys/server.crt;#配置证书位置 ssl_certificate_key /root/Lee/keys/server.key;#配置秘钥位置 #ssl_client_certificate ca.crt;#双向认证 #ssl_verify_client on; #双向认证 ssl_session_timeout 5m; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on;
1 2 3 nginx -t nginx -s reload
Nginx解析php 在LAMP中,PHP是作为httpd的一个模块出现的;而在LNMP中,PHP是以一个服务(php-fpm)的形式存在的,首先要启动php-fpm服务,然后Nginx再和php-fpm通信。也就是说,处理PHP脚本解析的工作是由php-fpm处理完成后把结果传递给Nginx,Nginx再把结果返回给用户。
什么是php-fpm? php进程管理的基本概念:
CGI:
是 Web Server 与 Web Application 之间数据交换的一种协议;
FastCGI:
同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。同样,SCGI 协议与 FastCGI 类似;
PHP-CGI:
是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序;
PHP-FPM:
是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理;
php-cgi
和php-fpm
的关系
PHP-CGI就是PHP实现的自带的FastCGI管理器,但是它本身不给力,有明显的不足:
基于上述因素,就出现了一些第三方补充解决方案,比如PHP-FPM,它的优点包括:
如上图所示,当nginx收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程。
nginx支持php
1 2 3 4 5 6 7 8 9 10 11 vim /usr/local/nginx/conf/vhost/test.com.conf //增加配置如下: location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/tmp/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /data/nginx/test.com$fastcgi_script_name; }
说明:
fastcgi_pas用来指定php-fpm的地址,如果php-fpm监听的是127.0.0.1:9000,那么这里也要改成相同地地址,否则会报502错误。
factcgi_parm SCRIPT_FILENAME后面的路径为该站点根目录,与之前root定义的路径一致,否则会报404错误。
502错误常见原因:
一是配置错误:nginx找不到php-fpm了,所以报错;
正确做法: astcgi_pass后面可以是socket或者是ip:port
1 2 3 fastcgi_pass unix:/tmp/php-fcgi.sock; //或者 fastcgi_pass 127.0.0.1:9000;
二是资源耗尽:nmp架构在处理php时,nginx直接调取后端的php-fpm服务,如果nginx的请求量偏高,又没有给php-fpm配置足够的子进程,那么一旦资源耗尽,就会出现502错误,
正确做法: 调整php-fpm.conf中的pm.max_children数值,一般4G内存机器可以设置为150,8G为300以此类推;
1 2 3 nginx -t nginx -s reload
1 2 3 4 5 6 7 8 9 10 //进入文件目录 cd /data/nginx/test.com //建立测试php网页 touch 1.php //编辑测试网页,加入以下内容 <?php echo 'this is a php test'; ?>
1 2 steve:steveBlog steveyuan$ curl -x 172.16.155.128:80 test.com/1.php this is a php
php-fpm进程管理 命令行格式:
其中,signal常用选项如下:
quit - 处理完当前请求再关闭;
reload - 重新载入配置文件;
reopen - 重新打开日志文件;
stop - 立即关闭;
php-fpm的pool 前面提到过,php-fpm的一个重要功能,就是可以管理进程,这里涉及到一个pool的概念,nginx启动服务后,会产生1个master进程+N个worker进程,共同构成一个进程池(pool),其中
先看目前的php-fpm 的pool,执行以下命令:
配置文件解读 php-fpm的配置文件在 /usr/local/php-fpm/etc/php-fpm.conf
,查看该文件
1 cat /usr/local/php-fpm/etc/php-fpm.conf
如上图所示:
[global] 全局配置
[www] 当前的pool设定
listen = /tmp/php-fcgi.sock
以sock的方式监听
user = php-fpm
指定运行的用户
group = php-fpm
指定运行的组
pm = dynamic
//定义php-fpm
的子进程启动模式,dynamic
为动态进程管理,一开始只启动少量的子进程,根据实际需求,动态地增加或者减少子进程,最多不会超过pm.max_children
定义的数值。另外一种模式是static
,这种模式下子进程数量由pm.max_children
决定,一次性启动这么多,不会减少也不会增加;
pm.max_children = 50
//最大子进程数,ps -aux
可以查看;
pm.start_servers = 20
//针对dynamic模式,它定义php-fpm服务在启动服务时产生的子进程服务时产生的子进程数量;
pm.min_spare_servers = 5
//针对dynamic模式,定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程;
pm.max_spare_servers = 35
//针对dynamic模式,定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程;
pm.max_requests = 500
//针对dynamic模式,定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出;
此外,在配置文件的末尾,还有一行很关键的配置;
与nginx虚拟主机的配置类似,当同一台服务器上多个网站是,我们可以把;include=/usr/local/php-fpm/etc/php-fpm.d/*.conf
注释分号去掉,这样就可以在/usr/local/php-fpm/etc/php-fpm.d
下,为每个虚拟主机配置不同的pool,各个网站之间的pool进程池彼此独立,互不影响。
设置多个pool 方法一:在/usr/local/php-fpm/etc/php-fpm
里面增加pool
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [root@hanfeng etc]# vi /usr/local/php-fpm/etc/php-fpm.conf [global] pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] listen = /tmp/php-fcgi.sock listen.mode = 666 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 [steve.com] listen = /tmp/steve.sock listen.mode = 666 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
1 2 3 nginx -t nginx -s reload
默认主机的pool设定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //进入nigix虚拟主机配置文件夹 [root@stevey etc]# cd /usr/local/nginx/conf/vhost/ [root@stevey vhost]# ls default.conf test.com.conf //配置test.com.conf vi test.com.conf //相关配置 location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/tmp/php-fcgi.sock; //这个就是www的默认pool fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /data/nginx/test.com$fastcgi_script_name; }
新建steve.com的pool设定(假设已经有新的steve.com虚拟主机)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@hanfeng vhost]# vim steve.com.conf server { listen 80 default_server; server_name steve.com; index index.html index.htm index.php; root /data/nginx/steve.com; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/tmp/steve.com.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /data/nginx/steve.com$fastcgi_script_name; }
方法二:跟nginx虚拟主机类似,php-fpmye也支持把配置文件拆分出来。
1 2 3 4 5 6 7 vi php-fpm.conf //主文件只保留global设定 [global] pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log include = etc/php-fpm.d/*.conf //这行很关键,修改后各个虚拟主机的pool设定会保存在 `etc/php-fpm.d/` 目录下。
1 2 3 4 5 6 7 //创建/php-fpm.d/的目录 mkdir -p etc/php-fpm.d 进入配置目录 cd etc/php-fpm.d //新建www.conf,并修改设定 vim www.conf
修改www的配置文件1 2 3 4 5 6 7 8 9 10 11 12 [www] listen = /tmp/php-fcgi.sock listen.mode = 666 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
新建steve.com.conf,并修改相关设定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 vim steve.com.conf [steve.com] listen = /tmp/steve.com.sock listen.mode = 666 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
1 2 3 4 //检查语法 /usr/local/php-fpm/sbin/php-fpm -t 重启服务 /etc/init.d/php-fpm restart
php-fpm慢执行日志slow log 慢执行日志是php-fpm提供的一个很有用的功能,通过查询和分心慢执行日志,方便我们有针对性滴进行优化。
开启slow log步骤:
第一步:编辑php-fpm配置文件
1 2 3 4 5 6 7 //PHP 5.3.3 之前设置如下: <value name="request_slowlog_timeout">5s</value> <value name="slowlog">logs/php-fpm-slowlog.log</value> //PHP 5.3.3 之后设置以下如下: request_slowlog_timeout = 5s slowlog = /usr/local/php/log/php-fpm-slowlog.log
注:
第二步:重启php-fpm服务
1 2 3 4 //检查语法 /usr/local/php-fpm/sbin/php-fpm -t 重启服务 /etc/init.d/php-fpm restart
第三步:查看slow log
1 2 3 4 5 6 cat /usr/local/php/log/php-fpm-slowlog.log [19-Dec-2013 16:54:49] [pool www] pid 18575 script_filename = /home/web/htdocs/sandbox_canglong/test/tt.php [0x0000000003a00dc8] curl_exec() /home/web/htdocs/sandbox_canglong/test/tt.php:2 [0x0000000003a00cd0] exfilter_curl_get() /home/web/htdocs/sandbox_canglong/test/tt.php:6
说明:
注:开启slow log
后,在错误日志文件中也有相关记录
open_basedir open_basedir 是php的一个安全设定,就是就访问权限限定在某个文件夹;就算该网站被黑,也只能在特定的文件夹内操作,而不会危及整个服务器的安全。
可以配置open_basedir的地方一共有以下三处,修改方法如下:
1 php_admin_value[open_basedir]=/home/wwwroot/:/proc/:/tmp/
方法二:编辑nginx fastcgi_param
1 2 # set php open_basedir fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/";
1 2 3 4 [HOST=www.iamle.com] open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/ [PATH=/home/wwwroot/www.iamle.com/] open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/
open_basedir 安全设置建议 三管齐下:
先设置fpm-php中pool池中的总open_basedir;
再对nginx中单个server 通过 fastcgi_param PHP_ADMIN_VALUE 设置;
最后对php.ini设置 [HOST=XXX] [PATH=XXX]
1 2 3 4 5 6 7 8 9 10 11 12 13 //第一步:在php-fpm.conf对应的pool池中行尾配置 php_admin_value[open_basedir]=/home/wwwroot/:/proc/:/tmp/ //第二步:在nginx fastcgi fastcgi_param配置 #这里用$document_root是一种取巧的方法,也可以设置绝对路径 # set php open_basedir fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/"; //第三步:在php.ini行尾配置 [HOST=www.iamle.com] open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/ [PATH=/home/wwwroot/www.iamle.com/] open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/