Nginx服务
安装和启动
- 解压源码
tar -xvf nginx-xx.xx.xx.tar.gz
- 配置(模块有很多,这里以ssl为例)
# 配置安装路径,指定服务运行时使用的用户,安装HTTP SSL模块
./configure --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
- 编译和安装
make -j4 && make install
- 创建用户
user -M nginx -s /sbin/nologin
- 启动,关闭,重启,查看配置
# 启动
/usr/local/nginx/sbin/nginx
# 关闭 killall nginx也可行
/usr/local/nginx/sbin/nginx -s stop
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
# 查看版本和配置
/usr/local/nginx/sbin/nginx -V
网站认证
- 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
server {
...
auth_basic "请输入用户名和密码"; # 提示信息
auth_basic_user_file "/usr/local/nginx/pass"; # 存放网站账户的文件
...
}
- 创建验证文件
yum install -y httpd-tools
# 第一次需要创建pass文件,所以需要加-c
htpasswd -c /usr/local/nginx/pass test
New password: # 输入密码
Re-type new password: # 再次输入密码
Adding password for user test01
# 添加第二个用户,不要加-c
htpasswd /usr/local/nginx/pass bhlu
New password: # 输入密码
Re-type new password: # 再次输入密码
Adding password for user test02
- 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
多域名访问
- 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
http {
...
server {
listen 80;
server_name www.a.com; # www.a.com这个域名
root html_b; # 网站根目录
index index.html; # 主页文件
}
server {
listen 80;
server_name www.b.com; # www.b.com这个域名
root html_b; # 网站根目录
index index.html; # 主页文件
}
}
- 创建网站根目录和主页文件
mkdir /usr/local/nginx/{html_a,html_b}
echo "aaa" > /usr/local/nginx/html_a/index.html
echo "bbb" > /usr/local/nginx/html_b/index.html
- 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
配置加密网站
- 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
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 https; # 设置网站根目录
index index.html index.htm;
}
}
- 创建网站根目录,并创建主页文件
mkdir /usr/local/nginx/https
echo "test https~~~" > /usr/local/nginx/https/index.html
- 生成私钥
openssl genrsa > /usr/local/nginx/conf/cert.key
# 输出
Generating RSA private key, 2048 bit long modulus
..........................................................................................................................................................................................+++
........................+++
e is 65537 (0x10001)
- 根据私钥生成公钥
openssl req -x509 -key /usr/local/nginx/conf/cert.key > /usr/local/nginx/conf/cert.pem
# 输出
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn # 国家
State or Province Name (full name) []:JiangSu # 省份
Locality Name (eg, city) [Default City]:WuXi # 城市
Organization Name (eg, company) [Default Company Ltd]:test # 公司
Organizational Unit Name (eg, section) []:test # 部门
Common Name (eg, your name or your server's hostname) []:test-server # 服务器名称
Email Address []:test@test.com # 电子邮件
- 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
- 进行测试
curl -k https://www.a.com
# test https~~~
LNMP
LNMP环境
L
:linux
操作系统N
:Nginx
网站服务M
:mariadb(mysql)
数据库P
:php
编写动态网站的语言工具
- 初始化
nginx
服务
# 关闭之前实验的nginx,并将配置恢复默认
killall nginx
cp /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf
cp:是否覆盖"/usr/local/nginx/conf/nginx.conf"? y
- 安装相关软件包
# 数据库相关,这里为了简单,使用的是mariadb,mariadb(数据库客户端)、mariadb-server(数据库服务端)、mariadb-devel(数据库开发环境依赖包)
yum install -y mariadb mariadb-server mariadb-devel
systemctl start mariadb && systemctl enable mariadb
systemctl status mariadb
# php相关,php(解释器)、php-fpm(帮助nginx解析php编写的动态网站的服务)、php-mysql(php与mysql关联的软件包)
yum install -y php php-fpm php-mysql
systemctl start php-fpm && systemctl enable php-fpm
systemctl status php-fpm
# php-fpm的配置文件在/etc/php-fpm.d/www.conf,里面包含了端口,服务端口,最小守护进程数量等,一个服务进程大概是25M左右
- 准备动态网站页面
cp /data/test.php /usr/local/nginx/html/
- 启动
nginx
服务,设置相关配置
# 启动
/usr/local/nginx/sbin/nginx
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
# 匹配以.php结尾的
location ~ \.php$ {
root html; # 网站位置
fastcgi_pass 127.0.0.1:9000; # 找本地9000端口
fastcgi_index index.php; # 默认主页
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # 这行无用,需要注释
include fastcgi.conf; # 这里需要修改,使用了是另一个配置文件
}
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
地址重写
格式:rewrite 匹配路径 实际路径 选项
- 选项
redirect
:临时重定向,302permanent
:永久重定向,301last
:不再读其他rewrite
,还是除rewrite
之外的其他语句的break
:不再读其他语句
- 访问
a.html
实际显示b.html
vim /usr/local/nginx/conf/nginx.conf
...
rewrite ^/a\.html$ /b.html;
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
- 访问本地的任意页面,跳转到指定网站的同页面
vim /usr/local/nginx/conf/nginx.conf
...
rewrite /(.*) http://www.test.com/$1;
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
- 根据浏览器的不同访问不同的页面
vim /usr/local/nginx/conf/nginx.conf
...
# $http_user_agent是nginx内置变量,存储了用户的信息
if ($http_user_agent ~* firefox){
rewrite /(.*) /firefox/$1;
}
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
last
选项
# last
vim /usr/local/nginx/conf/nginx.conf
...
server {
...
location / {
rewrite /a.html /b.html last; # 这里使用last,不再读其他的rewrite
...
}
rewrite /b.html /c.html;
}
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
# 测试
curl 127.0.0.1/a.html # 结果是b.html的页面
break
选项
# last
vim /usr/local/nginx/conf/nginx.conf
...
server {
...
location / {
rewrite /a.html /b.html break; # 这里如果使用的是last,那么访问a.html,会显示c.html的内容,所以这里需要使用break
...
}
location /b.html {
rewrite /b.html /c.html;
}
}
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
# 测试
curl 127.0.0.1/a.html # 结果是b.html的页面
代理功能(网站业务)
环境
proxy
:192.168.3.1web1
:192.168.3.100web2
:192.168.3.200
- 开启
web1
和web2
的网站服务(这里使用httpd
服务)
# web1和web2
yum install -y httpd
systemctl start httpd
# web1
echo "web1" > /var/www/html/index.html
# web2
echo "web2" > /var/www/html/index.html
- 在
proxy
主机上使用nginx
的代理功能
# 将之前的nginx服务删除
killall nginx
rm -rf /usr/local/nginx
# 安装nginx
tar -xvf nginx-1.17.6.tar.gz
cd nginx-1.17.6/
./configure
make && make install
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
# 创建集群,集群名称叫做web
upstream web {
server 192.168.3.100:80;
server 192.168.3.200:80;
}
server {
listen 80;
...
localtion / {
proxy_pass http://web; # 调用集群
root html;
index index.html index.htm;
}
...
}
...
}
...
# 启动nginx
/usr/local/nginx/sbin/nginx
- 测试是否成功
for i in {1..5}; do curl 192.168.3.1; done
# web1 web2 web1 web2 web1
- 集群优化,设置权重,配置健康检查,相同客户机访问相同服务器
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
# 创建集群,集群名称叫做web
upstream web {
ip_hash; # 相同客户机访问相同服务器
server 192.168.3.100:80;
# weight=2: 权重2,默认权重是1
# max_fails=2: 检测两次如果都失败,则判为故障
# fail_timeout=30: 故障机器30s再次测试
server 192.168.3.200:80 weight=2 max_fails=2 fail_timeout=30;;
}
server {
listen 80;
...
localtion / {
proxy_pass http://web; # 调用集群
root html;
index index.html index.htm;
}
...
}
...
}
...
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
- 再次测试
for i in {1..5}; do curl 192.168.3.1; done
# web1 web2 web2 web1 web2
如果想要将集群中某个主机不参与集群活动
server 192.168.3.200 down;即可
四层代理(其他业务)
环境
proxy
:192.168.3.1server1
:192.168.3.100server2
:192.168.3.200
- 将nginx恢复默认配置
/usr/local/nginx/sbin/nginx -s stop
cp /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf
cp:是否覆盖"/usr/local/nginx/conf/nginx.conf"? y
- 重新配置编译,添加四层代理模块
# 先查看之前nginx编译所带模块
/usr/local/nginx/sbin/nginx -V
# 因为上个实验没有加模块,所以最后一行只有configure arguments:
cd ~/nginx-1.17.6/
./configure --with-stream # --with-stream 四层代理,如果之前的nginx有模块,需要在后面加上去
make # 注意这里只需编译即可,不需要安装
# 检查新编译的nginx是否符合要求
./objs/nginx -V
# 最后一行: configure arguments: --with-stream
# 将新编译的nginx拷贝过去
cp ./objs/nginx /usr/local/nginx/sbin/nginx
cp:是否覆盖"/usr/local/nginx/sbin/nginx"? y
# 启动nginx试试
/usr/local/nginx/sbin/nginx
- 配置四层代理
vim /usr/local/nginx/conf/nginx.conf
...
# 新业务,跟http同级
stream {
# 新集群,叫backend,这里以集群的sshd服务作为示例
upstream backend {
server 192.168.3.100:22;
server 192.168.3.200:22;
}
server {
listen 10022; # 监听端口号,访问这个端口号,就会跳转到集群中
proxy_pass backend; # 调用集群
}
}
http {
...
}
# 加载配置,如果安装的nginx没有加--with-stream,这里会报错
/usr/local/nginx/sbin/nginx -s reload
- 测试是否成功
ssh -p 10022 root@192.168.3.1
# 进入server1
ssh -p 10022 root@192.168.3.1
# 进入server2
常见的nginx问题
- 配置404报错
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
server {
...
error_page 404 /404.html; # 设置404页面
...
}
}
...
- 查看网站后台数据
# 需要添加一个新的模块--with-http_stub_status_module
# 查看现在的nginx
killall nginx
/usr/local/nginx/sbin/nginx -V
# nginx version: nginx/1.17.6
# built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
# configure arguments: --with-stream
# 重新编译并拷贝过去
cd ~/nginx-1.17.6/
./configure --with-stream --with-http_stub_status_module # 添加上之前的模块
make
cp ./objs/nginx /usr/local/nginx/sbin/nginx
cp:是否覆盖"/usr/local/nginx/sbin/nginx"? y
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
server {
...
location / {
root html;
index index.html index.htm;
}
# 添加下面几行
location /status {
stub_status on; # 显示后台的数据
allow 192.168.3.1; # 只允许192.168.3.1查看
deny all; # 拒绝其他
}
...
}
}
...
# 启动nginx
/usr/local/nginx/sbin/nginx
# 本机测试查看,其他机器访问会报错403
curl 192.168.3.1/status
: << 'EOF'
Active connections: 1
server accepts handled requests
14 14 14
Reading: 0 Writing: 1 Waiting: 0
Active connections: 当前活动的连接数量,即当前有多少用户访问该网站
accepts: 已接收客户端的连接总数
handled: 已处理客户端的连接总数
requests: 客户端发送的请求数
Reading: 当前服务器正在读取客户端请求头的数量
Writing: 当前服务器正在写响应信息的数量
Waiting: 当前多少客户端在等待服务器的响应
EOF
nginx优化
- 缓存文件在客户端
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
server {
...
# 添加下面三行,~是包含,并且后面支持正则,*是忽略大小写
location ~* \.(.jpg|html|txt|mp3)$ {
expries 30d; # 将上述访问的文件在客户机缓存30天
}
...
}
}
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
# firefox访问测试http://ip/index.html
# firefox查看缓存方法,about:cache,查看disk文件的列表,Expires(到期时间)
- 支持超长地址(默认情况是不支持长地址栏的,会报414错误)
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
...
http {
...
# 添加下面两行
client_header_buffer_size 200k; # 用户访问网站的头部信息支持200k
large_client_header_buffers 4 200k; # 如果200k不够,增加到4个200k
server {
...
}
}
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
- 优化nginx并发
client
端
# 安装测试软件
yum install -y httpd-tools
# 设置服务器的打开文件数量大小
ulimit -n # 查看
ulimit -n 100000 # 临时设置
vim /etc/security/limits.conf # 永久设置,设置完之后需要重启才能生效
: << 'EOF'
# 大概是53、54行
* soft nofile 100000 # 软件限制
* hard nofile 100000 # 硬件限制
EOF
# 测试5000个用户,访问5000次,一个用户一次,-c指定用户量,-n指定总访问数,这里访问的时候最后一定要补上/
ab -c 5000 -n 5000 http://ip/
# 提示: socket: Too many open files (24)
server
端进行优化
# 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
: << 'EOF'
...
worker_processes 2; # nginx进程数量,通常跟cpu的核心数一样
events {
worker_connections 50000; # 每个进程支持的并发访问量
}
...
EOF
# 重新加载配置
/usr/local/nginx/sbin/nginx -s reload
# 配置服务器的打开文件数量,这里使用的是临时的方法,实际环境肯定是配置永久的,可参考client
ulimit -n 100000
最后client
端进行测试
ab -c 5000 -n 5000 http://ip/
# ... 100% ...代表成功
使用集群中主机过多导致用户重复登录网站的问题
环境
proxy
:nginx
代理服务器,192.168.3.2web1
:集群主机,lnmp
环境,192.168.3.100web2
:集群主机,lnmp
环境,192.168.3.200这个实验主要体现的是集群中网站服务的session放在同一个地方,并不是各放各的
- 两个
web
主机安装网站服务
# web1,web2都需要操作
# 1. 编译安装nginx
yum install -y gcc make openssl-devel pcre-devel
tar -xvf nginx-1.17.6.tar.gz
cd nginx-1.17.6/
./configure
make && make install
# 2. 安装数据库和php并启动
yum install -y mariadb mariadb-server mariadb-devel php php-mysql php-fpm
systemctl start mariadb
systemctl start php-fpm
# 3. 安装php与memcached服务关联的软件包
yum install -y php-pecl-memcache
# 4. 配置php-fpm的session存放位置,放在代理服务器的memcache,memcache的默认端口是11211
vim /etc/php-fpm.d/www.conf
: << 'EOF'
# 一般是在最后两行
php_value[session.save_handler] = memcache # 表示session不存在本地,而是去找memcache
php_value[session.save_path] = tcp://192.168.3.2:11211 # memcache服务器的地址以及端口,这里使用的是proxy服务器,也可以是其他服务器
EOF
# 5. 重启php-fpm
systemctl restart php-fpm
# 6. 准备php文件
cp -r ~/test/* /usr/local/nginx/html/
# 7. 配置nginx
vim /usr/local/nginx/conf/nginx.conf
: << 'EOF'
...
http {
server {
...
location / {
root html;
index index.php index.html index.htm;
}
...
# 具体可以参考之前lnmp示例
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
...
}
}
...
EOF
# 8. 启动nginx
/usr/local/nginx/sbin/nginx
# 最后可以先测试一下两个代理服务器nginx是否成功运行
proxy
服务器
# 1. 编译安装nginx
yum install -y gcc make openssl-devel pcre-devel
tar -xvf nginx-1.17.6.tar.gz
cd nginx-1.17.6/
./configure
make && make install
# 2. 安装memcache并启动测试,telnet是用于测试的
yum install -y memcached telnet
systemctl start memcached
telnet 192.168.3.88 11211 # 连接测试
# ============ memcache操作 ============
set name 0 200 4 # 设置abc变量,0代表不压缩,数据存储200秒,存4个字符(此时变量如果存在,则覆盖,不存在就是新建)
bhlu # 输入4个字符
STORED # 提示
get name # 获取变量信息
VALUE name 0 4 # 输出
bhlu # 输出
END # 提示
replace name 0 200 6 # 修改变量name信息,此时变量必须存在
maomao # 输入
STORED # 提示
add age 0 100 2 # 添加age变量,如果已经存在,则添加失败
25 # 输入
STORED # 提示
delete age # 删除变量age
DELETED # 提示
flush_all # 删除所有数据
quit # 退出
# =====================================
# 3. 配置nginx,设置集群
vim /usr/local/nginx/conf/nginx.conf
: << 'EOF'
...
http {
...
# 创建集群
upstream web {
server 192.168.3.100:80;
server 192.168.3.200:80;
}
server {
...
location / {
proxy_pass http://web; # 调用集群
}
}
...
}
...
EOF
# 4. 启动nginx
/usr/local/nginx/sbin/nginx
使用systemctl进行控制
# 首先关闭nginx
killall nginx
# 编写Unit文件
vim /usr/lib/systemd/system/nginx.service
: << 'EOF'
[Unit]
Description=The Nginx Server # 描述
After=network.target remote-fs.target nss-lookup.target # 执行nginx前需要开启这些服务
[Service]
Type=forking # 多线程类型程序,设置为forking
ExecStart=/usr/local/nginx/sbin/nginx # systemctl start nginx的执行命令
ExecReload=/usr/local/nginx/sbin/nginx -s reload # systemctl reload nginx的执行命令
ExecStop=/bin/kill -s QUIT ${MAINPID} # systemctl stop nginx的执行命令
[Install]
WantedBy=multi-user.target # 支持开机自启
EOF
# 激活
systemctl daemon-reload
# 测试
systemctl start nginx
systemctl status nginx
curl 127.0.0.1
systemctl stop nginx
systemctl status nginx
curl 127.0.0.1
systemctl restart nginx
systemctl status nginx
curl 127.0.0.1