1 安装nginx
a.安装依赖包
[root@node20 lnmp_soft]# yum -y install gcc pcre-devel openssl-devel
[root@node20 lnmp_soft]# useradd -s /sbin/nologin nginx
[root@node20 lnmp_soft]# tar -xf nginx-1.12.2.tar.gz
[root@node20 lnmp_soft]# cd nginx-1.12.2/
[root@node20 nginx-1.12.2]# ./configure \
> --prefix=/usr/local/nginx \
> --user=nginx \
> --group=nginx \
> --with-http_ssl_module
[root@node20 nginx-1.12.2]# make && make install
b.nginx命令
[root@node20 nginx-1.12.2]# /usr/local/nginx/sbin/nginx #启动nginx
[root@node20 nginx-1.12.2]# /usr/local/nginx/sbin/nginx -s stop
[root@node20 nginx-1.12.2]# /usr/local/nginx/sbin/nginx -s reload #重新加载文件
[root@node20 nginx-1.12.2]# ln -s /usr/local/nginx/sbin/nginx /sbin/ #软连接
c.测试
[root@node20 nginx-1.12.2]# curl http://192.168.4.20
2 用户认证
a.修改文件
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
auth_basic "Input Password:"; #提示
auth_basic_user_file "/usr/local/nginx/pass"; #密码文件
#charset koi8-r;
#access_log logs/host.access.log main;
b.生成密码文件
[root@node20 ~]# yum -y install httpd-tools
[root@node20 ~]# htpasswd -c /usr/local/nginx/pass tom #创建密码文件
New password:
Re-type new password:
Adding password for user tom
[root@node20 ~]# cat /usr/local/nginx/pass
tom:$apr1$P0QtAXeF$Gvf1AoRLCmTy91ph23MG2/
[root@node20 ~]# htpasswd /usr/local/nginx/pass alice #向密码文件追加用户
New password:
Re-type new password:
Adding password for user alice
[root@node20 ~]# cat /usr/local/nginx/pass #查看密码文件内容
tom:$apr1$P0QtAXeF$Gvf1AoRLCmTy91ph23MG2/
alice:$apr1$XjOgpqOZ$H4cnsQGid6iYYsKx9tp1E/
[root@node20 ~]# nginx -s reload #重新加载文件
[root@node20 ~]# firefox http://192.168.4.20 #测试加密认证
3 基于域名的虚拟主机
a.添加虚拟主机
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.a.com; #域名www.a.com
auth_basic "Input Password:"; #提示符
auth_basic_user_file "/usr/local/nginx/pass"; #认证密码文件
location / {
root html; #指定网站的根路径
index index.html index.htm;
}
}
server { #新添加的虚拟主机www.b.com
listen 80;
server_name www.b.com;
location / {
root www;
index index.html index.htm;
}
}
[root@node20 ~]# mkdir /usr/local/nginx/www #创建网站根目录
[root@node20 ~]# echo "www" >> /usr/local/nginx/www/index.html #创建首页文件
[root@node20 ~]# nginx -s reload
[root@node20 ~]# vim /etc/hosts
192.168.4.20 www.a.com www.b.com
b.测试
[root@node20 ~]# firefox http://www.a.com
[root@node20 ~]# firefox http://www.b.com
c.基于端口的虚拟主机
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 8080;
server_name web1.example.com;
location / {
root www;
index index.html index.htm;
}
}
server {
listen 8000;
server_name web2.example.com;
location / {
root www;
index index.html index.htm;
}
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# firefox http://192.168.4.20:8000
[root@node20 ~]# firefox http://192.168.4.20:8080
4 SSL虚拟主机
[root@node20 www]# cd /usr/local/nginx/conf
[root@node20 conf]# openssl genrsa > cert.key #生成私钥
[root@node20 conf]# openssl req -new -x509 -key cert.key > cert.pem #生成证书
[root@node20 conf]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 443 ssl;
server_name www.c.com;
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@node20 conf]# nginx -s reload
[root@node20 conf]# vim /etc/hosts
192.168.4.20 www.a.com www.b.com www.c.com
[root@node20 conf]# firefox https://www.c.com #用https访问
5 LNMP
a.装包
[root@node20 ~]# yum -y install gcc openssl-devel pcre-devel zlib-devel #依赖包
nginx的安装参考上面内容
[root@node20 conf]# yum -y install mariadb mariadb-server mariadb-devel #安装数据库
[root@node20 lnmp_soft]# yum -y install php php-mysql php-fpm-5.4.16-42.el7.x86_64.rpm
b.起动服务
[root@node20 ~]# nginx
[root@node20 ~]# systemctl start mariadb php-fpm
[root@node20 ~]# systemctl enable mariadb php-fpm
c.修改配置文件
[root@node20 ~]# vim /etc/php-fpm.d/www.conf
listen = 127.0.0.1:9000 #php端口号
pm.max_children = 50 #最大进程数
pm.start_servers = 5 #最小进程数
pm.min_spare_servers = 5 #最少需要几个空闲进程
pm.max_spare_servers = 35 #最多允许几个空闲进程
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.html index.htm index.php;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# vim /usr/local/nginx/html/test1.php #测试页面
<?php
$i="This is a test Page";
echo $i;
?>
[root@node20 ~]# vim /usr/local/nginx/html/test2.php #测试页面,连接数据库并查询
<?php
$mysqli = new mysqli('localhost','root','','mysql');
//注意:root为mysql账户名称,密码需要修改为实际mysql密码,无密码则留空即可
if (mysqli_connect_errno()){
die('Unable to connect!'). mysqli_connect_error();
}
$sql = "select * from user";
$result = $mysqli->query($sql);
while($row = $result->fetch_array()){
printf("Host:%s",$row[0]);
printf("</br>");
printf("Name:%s",$row[1]);
printf("</br>");
}
?>
d.测试
[root@node20 ~]# firefox http://192.168.4.20/test1.php
[root@node20 ~]# firefox http://192.168.4.20/test2.php
e.地址重写
(1)访问a.html,重定到b.html(网页内容改变)
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm index.php;
rewrite /a.html /b.html; #rewrite 旧地址 新地址 选项
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# echo "aa" >> /usr/local/nginx/html/a.html
[root@node20 ~]# echo "bb" >> /usr/local/nginx/html/b.html
[root@node20 ~]# firefox http://192.168.4.20/a.html
(2)访问a.html,重定到b.html(地址跳转)
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm index.php;
rewrite /a.html /b.html redirect; #rewrite 旧地址 新地址 选项
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# firefox http://192.168.4.20/a.html
(3) 访问一个ip请求跳转到baidu.com
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
rewrite ^/ http://www.baidu.com/;
#rewrite ^/(.*)$ http://www.baidu.com/$1; #访问一个ip下所有都重定向到baidu下相同页面
location / {
root html;
index index.html index.htm index.php;
#rewrite /a.html /b.html redirect; #rewrite 旧地址 新地址 选项
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# firefox http://192.168.4.20/
(4)不同浏览器访问相同连接返回不同页面
[root@node20 ~]# echo "I am Normal page" >> /usr/local/nginx/html/test.html
[root@node20 ~]# mkdir -p /usr/local/nginx/html/firefox/
[root@node20 ~]# echo "firefox page" >> /usr/local/nginx/html/firefox/test.html
[root@node20 ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm index.php;
}
if ($http_user_agent ~* firefox) {
rewrite ^(.*)$ /firefox/$1;
}
}
[root@node20 ~]# nginx -s reload
[root@node20 ~]# firefox http://192.168.4.20/test.html
[root@node20 ~]# curl http://192.168.4.20/test.html
I am Normal page
(5) 地址重写格式
rewrite 旧地址 新地址 [选项];
last 不再读其他rewrite
break 不再读其他语句,结束请求
redirect 临时重定向
permament 永久重定向
6 nginx反向代理(相当于轮询)
a.
[root@web1 ~]# echo web1 > /usr/local/nginx/html/index.html
[root@web1 ~]# cat /usr/local/nginx/html/index.html
web1
[root@web2 ~]# echo web2 > /usr/local/nginx/html/index.html
[root@web2 ~]# cat /usr/local/nginx/html/index.html
web2
[root@proxy ~]# vim /usr/local/nignx/conf/nginx.conf
upstream webserver{
server 192.168.4.6:80;
server 192.168.4.7:80;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://wevserver;
}
[root@proxy conf]# curl http://192.168.4.8
web1
[root@proxy conf]# curl http://192.168.4.8
web2
b.配集群池
[root@proxy conf]# vim nginx.conf
upstream webserver{
server 192.168.4.6 weight=1 max_fails=1 fail_timeout=30;
server 192.168.4.7 weight=2 max_fails=2 fail_timeout=30;
server 192.168.4.203 down;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://webserver;
}
#weight设置服务器权重值,默认值为1
#max_fails设置最大失败次数
#fail_timeout设置失败超时时间,单位为秒
#down标记服务器已关机,不参与集群调度
[root@proxy conf]# nginx -s reload
[root@proxy conf]# curl http://192.168.4.8
web2
[root@proxy conf]# curl http://192.168.4.8
web1
[root@proxy conf]# curl http://192.168.4.8
web2
[root@proxy conf]# curl http://192.168.4.8
web2
[root@proxy conf]# curl http://192.168.4.8
web1
c.集群的调度算法
[root@proxy conf]# vim nginx.conf
upstream webserver{
ip_hash; # 通过ip_hash设置调度规则为:相同客户端访问相同服务器
server 192.168.4.6 weight=1 max_fails=2 fail_timeout=10;
server 192.168.4.7 weight=2 max_fails=2 fail_timeout=10;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://webserver;
}
[root@proxy conf]# nginx -s reload
[root@proxy conf]# curl http://192.168.4.8 #多访问几次,关闭web1,访问,打开web1,访问,关闭web2访问
7 TCP/UDP调度器
代理服务器proxy要重新编译安装
[root@proxy nginx-1.12.2]# ./configure \
> --with-http_ssl_module \
> --with-stream #开启4层反向代理
[root@proxy nginx-1.12.2]# make && make install
[root@node08 conf]# vim nginx.conf
stream{
upstream backend {
server 192.168.4.6:22; #后端SSH服务器的IP端口
server 192.168.4.7:22;
}
server {
listen 12345; #nginx监听的端口
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass backend;
}
}
http {
include mime.types;
default_type application/octet-stream;
[root@node08 conf]# ssh 192.168.4.8 -p 12345 #多次访问
8 nginx常见问题及处理
a.自定义报错页面
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
error_page 404 /40x.html; #去掉注释,40x.html即报错页面的内容
[root@proxy ~]# vim /usr/local/nginx/html/40x.html #生成错误页面
报错了。。。。。。
[root@proxy conf]# firefox http://192.168.4.6/xxxxx
b.查看服务状态信息
要重新编译安装nginx,并使用--with-http_stub_status_module开启状态页面模块
[root@web1 lnmp_soft]# cd nginx-1.12.2/
[root@web1 nginx-1.12.2]# ./configure \
> --with-http_ssl_module \
> --with-stream \
> --with-http_stub_status_module
[root@web1 nginx-1.12.2]# make && make install
[root@web1 nginx-1.12.2]# vim /usr/local/nginx/conf/nginx.conf
location /status {
stub_status on;
#deny IP地址;
#allow IP地址;
}
[root@web1 ~]# nginx -s reload
[root@web1 ~]# curl http://192.168.4.5/status
Active connections: 1
server accepts handled requests
10 10 3
Reading: 0 Writing: 1 Waiting: 0
Active connections:当前活动的连接数量。
Accepts:已经接受客户端的连接总数量。
Handled:已经处理客户端的连接总数量。
(一般与accepts一致,除非服务器限制了连接数量)。
Requests:客户端发送的请求数量。
Reading:当前服务器正在读取客户端请求头的数量。
Writing:当前服务器正在写响应信息的数量。
Waiting:当前多少客户端在等待服务器的响应。
c.优化并发量
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
.. ..
worker_processes 2; //与CPU核心数量一致
events {
worker_connections 65535; //每个worker最大并发连接数
use epoll;
}
.. ..
[root@proxy ~]# nginx -s reload
d.优化内核参数
[root@proxy ~]# ulimit -a //查看所有属性值
[root@proxy ~]# ulimit -Hn 100000 //设置硬限制(临时规则)
[root@proxy ~]# ulimit -Sn 100000 //设置软限制(临时规则)
[root@proxy ~]# vim /etc/security/limits.conf
.. ..
* soft nofile 100000
* hard nofile 100000
#该配置文件分4列,分别如下:
#用户或组 硬限制或软限制 需要限制的项目 限制的值
e.优化Nginx数据包头缓存
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
.. ..
http {
client_header_buffer_size 1k; //默认请求包头信息的缓存
large_client_header_buffers 4 4k; //大请求包头部信息的缓存个数与容量
.. ..
}
[root@proxy ~]# nginx -s reload
f.定义对静态页面的缓存时间
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
expires 30d; //定义客户端缓存时间为30天
}
}
[root@proxy ~]# cp /usr/share/backgrounds/day.jpg /usr/local/nginx/html
[root@proxy ~]# nginx -s reload
g.日志切割
日志文件越来越大怎么办?单个文件10G? 如何切割?(非常常见的面试题)
步骤:1. 把旧的日志重命名
2. kill USR1 PID(nginx的进程PID号)
1)手动执行
备注:/usr/local/nginx/logs/nginx.pid文件中存放的是nginx的进程PID号。
[root@proxy ~]# mv access.log access2.log
[root@proxy ~]# kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
2)自动完成
每周5的03点03分自动执行脚本完成日志切割工作。
[root@proxy ~]# vim /usr/local/nginx/logbak.sh
#!/bin/bash
date=`date +%Y%m%d`
logpath=/usr/local/nginx/logs
mv $logpath/access.log $logpath/access-$date.log
mv $logpath/error.log $logpath/error-$date.log
kill -USR1 $(cat $logpath/nginx.pid)
[root@proxy ~]# crontab -e
03 03 * * 5 /usr/local/nginx/logbak.sh
h.对页面进行压缩处理
[root@proxy ~]# cat /usr/local/nginx/conf/nginx.conf
http {
.. ..
gzip on; //开启压缩
gzip_min_length 1000; //小文件不压缩
gzip_comp_level 4; //压缩比率
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
//对特定文件压缩,类型参考mime.types
.. ..
}
i.服务器内存缓存
如果需要处理大量静态文件,可以将文件缓存在内存,下次访问会更快。
http {
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
//设置服务器最大缓存2000个文件句柄,关闭20秒内无请求的文件句柄
//文件句柄的有效时间是60秒,60秒后过期
//只有访问次数超过5次会被缓存