以下记录收集网络资源整理而成
官方网址:http://nginx.org/en/download.html
其中 “Stable version” 代表最新稳定版本
我这里下载的是 nginx-1.16.1.tar.gz 压缩包
下载完成后使用工具(如:xftp等)上传到 Linux 系统上
yum install -y gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
解压压缩包,解压得到的是源码,需要编译
tar zxf nginx-1.16.1.tar.gz
创建临时目录,注意应该是 /var/temp/nginx 目录
mkdir -p /var/temp/nginx
进入到之前解压得到的源码目录(nginx-1.16.1)
执行以下命令,创建makefile文件
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
命令 | 解释 |
---|---|
–prefix | 指定nginx安装目录 |
–pid-path | 指向nginx的pid |
–lock-path | 锁定安装文件,防止被恶意篡改或误操作 |
–error-log | 错误日志 |
–http-log-path | http日志 |
–with-http_gzip_static_module | 启用gzip模块,在线实时压缩输出数据流 |
–http-client-body-temp-path | 设定客户端请求的临时目录 |
–http-proxy-temp-path | 设定http代理临时目录 |
–http-fastcgi-temp-path | 设定fastcgi临时目录 |
–http-uwsgi-temp-path | 设定uwsgi临时目录 |
–http-scgi-temp-path | 设定scgi临时目录 |
命令执行完成后,可以看到出现了Makefile文件
开始编译
make
安装
make install
成功后,执行
whereis nginx
命令,发现安装在了/usr/local/nginx目录下
进入到whereis 查询到的目录,我这里是/usr/local/nginx,
会发现存在三个目录,分别是:conf,html以及sbin
进入sbin目录,执行
./nginx
此时nginx 进程已经启动,通过ps -ef命令可以查看
可以看到存在一个master进程和一个worker进程
关闭linux防火墙后(注我这里是虚拟机环境)
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
在浏览器就可以访问目标linux主机ip,出现如下图
至此 nginx安装成功
在nginx的目录下的conf文件夹下存在一个nginx.conf文件就是linux的配置文件
nginx.conf的配置结构
main 全局配置
event 工作模式及连接数
http{ http模块相关配置
upstream 集群,内网服务器
server{ 虚拟主机配置,可以有多个
location 路由规则
}
}
核心配置文件解析
#worker进程的操作用户
#user nobody;
#worker进程数量,一般不大于CPU核心数
worker_processes 1;
#日志级别 debug info notice warn error crit
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
# 工作模式,默认使用epoll
use epoll
# 每个worker允许的最大连接数
worker_connections 1024;
}
http {
# 包含的文件
include mime.types;
default_type application/octet-stream;
#main代表变量名,可以在下方直接引用,$开头的是nginx默认参数
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#sendfile 使用高效文件传输,提升传输性能。
#启用后才能使用 tcp_nopush ,是指当数据表累积一定大小后才发送,提高了效率。
sendfile on;
#tcp_nopush on;
#keepalive_timeout 设置客户端与服务端请求的超时时间,保证客户端多次请求的时候不会重复建立新的连接,节约资源损耗
keepalive_timeout 65;
#gzip 启用压缩,html/js/css压缩后传输会更快
#gzip on;
# server 可以在 http 指令块中设置多个虚拟主机
server {
#listen 监听端口
#server_name localhost、ip、域名
#location 请求路由映射,匹配拦截
#root 请求位置
#index 首页设置
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
日志默认参数解析
参数名 | 参数意义 |
---|---|
$remote_addr | 客户端ip |
$remote_user | 远程客户端用户名,一般为:’-’ |
$time_local | 时间和时区 |
$request | 请求的url以及method |
$status | 响应状态码 |
$body_bytes_send | 响应客户端内容字节数 |
$http_referer | 记录用户从哪个链接跳转过来的 |
$http_user_agent | 用户所使用的代理,一般来时都是浏览器 |
$http_x_forwarded_for | 通过代理服务器来记录客户端的ip |
创建一个shell文件,我是在"/usr/local/nginx/sbin"目录下
vi cut_my_log.sh
打开文件,复制以下内容,并保存退出
#!/bin/bash
LOG_PATH="/var/log/nginx/"
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
PID=/var/run/nginx/nginx.pid
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
#向Nginx主进程发送信号,用于重新打开日志文件
kill -USR1 `cat $PID`
注意LOG_PATH路径以及PID,通过
./nginx -V
命令可以查看自己的相关配置
为刚才的脚本添加可执行权限
chmod +x cut_my_log.sh
手动执行
./cut_my_log.sh
命令,查看log路径,发现日志已切割
yum install -y crontabs
crontab -e 编辑并且添加一行新的任务
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh
为做测试,这里是每隔1分钟执行一次脚本
重启定时任务
systemctl restart crond
或者是
service crond restart
systemctl start crond //启动服务
systemctl stop crond //关闭服务
systemctl restart crond //重启服务
systemctl reload crond //重新载入配置
crontab -e // 编辑任务
crontab -l // 查看任务列表
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:
常用表达式:
每分钟执行:
*/1 * * * *
每日凌晨(每天晚上23:59)执行:
59 23 * * *
每日凌晨1点执行:
0 1 * * *
使用crontab -e命令可以修改表达式,比如将之前表达式修改为每日1点执行一次
首先上传几个文件,我放在了/opt/static文件下
修改nginx.conf文件,修改server模块
server {
listen 80;
server_name localhost;
location / {
root /opt/static;
index index.html;
}
}
使用 /usr/local/nginx/sbin/nginx -t 命令检查配置文件,发现没有问题
重新加载配置
/usr/local/nginx/sbin/nginx -s reload
在浏览器输入ip即可打开index.html
使用 ip/文件名 ,即可访问具体的某个文件,比如
http://192.168.2.30/2.jpg
会显示之前上传的2.jpg这个文件
复制改写一个server
server {
listen 81;
server_name localhost;
location / {
root /opt;
index index.html;
}
}
重新加载配置
浏览器输入 ip:port ,会显示Forbidden,因为我们在/opt目录下没有一个叫index.html的文件
此时需要输入 ip:port/static 才可以显示index.html
除了 root
还有一个 alias
可以起到类似的效果
改写一个server,当location 只包含 /
时,需要在alias最后面加一个/
,否则会找不到文件,我下面的例子实际上可以不在最后加/
server {
listen 82;
server_name localhost;
location /ss {
alias /opt/static/;
index index.html;
}
}
加载配置后,使用 ip:port/ss 可以访问资源
root
与 alias
访问路径的解释:
假设服务器存在 /opt/static/2.jpg 这个文件
location /static {
root /opt;
}
访问路径就是 ip:port/static/2.jpg,这个请求被解释为
root + location + 后续url路径
即 /opt + /static + 2.jpg
,
显然在服务器里的确存在一个 /opt/static/2.jpg
的资源
也就是 ip:port后面的url路径在你的服务器里面必须真实存在,否则访问不到
location /ss {
alias /opt;
}
访问路径就是 ip:port/ss/static/2.jpg,这个请求被解释为
(location 替换为 alias) + 后续url路径
即 (/ss 替换为 /opt) + /static/2.jpg
也就是 /opt/static/2.jpg
相关于给 /opt 起了一个别名叫 /ss
location / {
root /opt;
}
location = /static/a.txt{
root /opt;
}
#符合图片的显示
location ~* \.(jpg|png|jpeg) {
root /opt;
}
#png必须小写才能匹配到
location ~ \.(TXT|jpg|png|jpeg) {
root /opt;
}
location ^~ /static{
root /opt;
}
在server块中加入以下配置
#允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
#对源站点验证,校验域名或IP
valid_referers *.abc.com;
#非法引入会进入下方判断
if ($invalid_referer) { return 404; }
首先启动几个应用服务器,我这里是启动了springBoot打包的jar,在不同端口上
在http模块中加入upstream模块
upstream myJar{
server 192.168.2.1:80;
server 192.168.2.1:81;
server 192.168.2.1:82;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myJar;
}
}
加载配置后,访问ip可以看到返回结果确实是应用服务器的结果,此时默认的负载均衡策略是轮询
默认情况下是普通轮询,权重都是1
下面看一下加权轮询负载均衡
upstream myJar{
server 192.168.2.1:80 weight=2;
server 192.168.2.1:81;
server 192.168.2.1:82;
}
发现80端口的服务器,会响应两次,81和82的只会响应一次,如此往复
ip_hash负载均衡
upstream myJar{
ip_hash;
server 192.168.2.1:80;
server 192.168.2.1:81 down;
server 192.168.2.1:82;
}
注意 如果需要将后台服务器临时移除,应标记 down
参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash
当应用服务器扩容或宕机后,nginx会重新进行hash,可能导致session丢失(本来a请求访问的一直是服务器1,结果服务器2宕机了,重新hash后,导致a请求访问到了服务器3,但是之前session一直维持在服务器1中)
针对ip_hash的缺点,出现了一致性hash算法,可以减小服务扩容或宕机带来的影响
一致性hash需要安装第三方模块 ngx_http_consistent_hash
,这里暂时不展开
url_hash 负载均衡
upstream myJar{
hash $request_uri;
server 192.168.2.1:80;
server 192.168.2.1:81 down;
server 192.168.2.1:82;
}
根据请求的url进行hash
least_conn负载均衡
upstream myJar{
least_conn;
server 192.168.2.1:80;
server 192.168.2.1:81 down;
server 192.168.2.1:82;
}
会将请求转发到连接数最少的那个服务器上
在文档http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server中可以看到server 后面可以带上一些参数
参数 | 作用 |
---|---|
max_conns | 限制每台server的连接数,用于保护避免过载,可起到限流作用 |
max_fails | 表示失败几次,则标记server已宕机,剔出上游服务 |
fail_timeout | 服务不可用的时间段;在fail_timeout时间内连续失败max_fails次,表示服务不可用,在下一个fail_timeout时间段内不会有新请求链接到该服务器,如此往复 |
backup | 标记为备用服务 |
down | 标记服务永不可用 |
slow_start等 | 还有其他商业版本的参数不介绍了 |
使用 keepalive 提高吞吐量
upstream myJar{
least_conn;
server 192.168.2.1:80;
server 192.168.2.1:81;
server 192.168.2.1:82;
keepalive 16;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myJar;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
其中
keepalived : 设置长连接处理的数量
proxy_http_version :设置长连接http版本为1.1
proxy_set_header :清除connection header 信息
expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标
(起到控制页面缓存的作用)
语法:expires [time|epoch|max|pff]
默认值:off
expires指令控制HTTP应答中的“Expires”和“Cache-Control”Header头部信息,启动控制页面缓存的作用
time:可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。
time值还控制"Cache-Control"的值:
负数表示no-cache
正数或零表示max-age=time
epoch:指定“Expires”的值为 1 January,1970,00:00:01 GMT
max:指定“Expires”的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年。
-1:指定“Expires”的值为当前服务器时间-1s,即永远过期。
off:不修改“Expires”和"Cache-Control"的值
使用举例
server {
listen 80;
server_name localhost;
location / {
alias /opt/static/;
# expires 10s;
# expires @10h30m;
# expires -1h;
# expires epoch;
# expires off;
expires max;
}
}
# proxy_cache_path 设置缓存目录
#keys_zone 设置共享内存以及占用空间大小
#max_size 设置缓存大小
#inactive 超过此时间则被清理
#use_temp_path 临时目录,使用后会影响nginx性能
proxy_cache_path /usr/local/nginx/upstream_cache
keys_zone=mycache:5m max_size=1g
inactive=1m use_temp_path=off;
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myJar;
# 启用缓存,和keys_zone一致
proxy_cache mycache;
# 针对200和304状态码缓存时间为8小时
proxy_cache_valid 200 304 8h;
}
}
访问请求后,可以发现在 /usr/local/nginx/upstream_cache 下面存在缓存文件
进入到nginx的解压目录/opt/nginx-1.16.1下
运行
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--with-http_ssl_module
再次执行编译make,然后进入objs目录下,
如果nginx还在运行的话,先关闭,然后复制nginx文件到/usr/local/nginx/sbin 那里
#关闭进程
/usr/local/nginx/sbin/nginx -s stop
#覆盖nginx文件
cp nginx /usr/local/nginx/sbin/
进入要存放ssl文件的目录,我这里是 /usr/local/nginx/mySSL
首先执行如下命令生成一个key
openssl genrsa -des3 -out ssl.key 1024
然后他会要求你输入这个key文件的密码。不推荐输入。因为以后要给nginx使用。每次reload nginx配置时候都要你验证这个PAM密码的。
由于生成时候必须输入密码。你可以输入后 再删掉。
mv ssl.key xxx.key
openssl rsa -in xxx.key -out ssl.key
rm xxx.key
然后根据这个key文件生成证书请求文件
openssl req -new -key ssl.key -out ssl.csr
以上命令生成时候要填很多东西 一个个看着写吧(可以随便,毕竟这是自己生成的证书)
最后根据这2个文件生成crt证书文件
openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
这里365是证书有效期 推荐3650哈哈。这个大家随意。最后使用到的文件是key和crt文件。
摘自https://www.cnblogs.com/weifeng1463/p/7943633.html
在nginx.conf中加入ssl相关配置
upstream myJar{
server 192.168.2.1:80;
server 192.168.2.1:81;
server 192.168.2.1:82;
}
server {
listen 443 ssl;
server_name localhost;
location / {
proxy_pass http://myJar;
}
#配置ssl证书
ssl_certificate /usr/local/nginx/mySSL/ssl.crt;
#配置证书秘钥
ssl_certificate_key /usr/local/nginx/mySSL/ssl.key;
#ssl会话cache
ssl_session_cache shared:SSL:1m;
#ssl会话超时时间
ssl_session_timeout 5m;
#配置加密套件,写法遵循openssl标准
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}
加载配置后,浏览器输入https://ip:port即可访问
配置http自动跳转https
server{
listen 80;
server_name localhost;
rewrite ^(.*)$ https://$host$1 permanent;
}
下载地址https://www.keepalived.org/download.html
我这里使用的 keepalived-2.0.18.tar.gz 版本
上传到linux,解压
进入到解压目录,可以看到一个configure文件
安装依赖
yum install -y libnl libnl-devel
执行
./configure --prefix=/usr/local/keepalived --sysconf=/etc
编译安装
make && make install
使用ip addr 查看网卡及ip
网卡名称是ens33,ip是192.168.2.30
编辑 /etc/keepalived/keepalived.conf 文件
global_defs {
# 路由id:当前安装keepalived的节点主机标识符,保证全局唯一
router_id keep_30
}
vrrp_instance VI_1 {
# 表示状态是MASTER主机还是备用机BACKUP
state MASTER
# 该实例绑定的网卡
interface ens33
# 保证主备节点一致即可
virtual_router_id 51
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 100
# 主备之间同步检查时间间隔,单位秒
advert_int 2
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
192.168.2.29
}
}
执行 /usr/local/keepalived/sbin/keepalived
命令,
再次查看ip,发现ens33网卡绑定了192.168.2.29 虚拟ip
此时通过 http://192.168.2.29 可以访问应用服务
进入到keepalived的解压目录下,具体是/opt/keepalived-2.0.18/keepalived/etc
里面存在init.d
和sysconfig
文件夹
执行
cp init.d/keepalived /etc/init.d/
cp sysconfig/keepalived /etc/sysconfig/
systemctl daemon-reload
这时就可以开始使用systemctl 开启和关闭 keepalived 服务了
准备另一台linux系统机器,里面安装nginx和keepalived
我这里直接使用虚拟机的克隆,并更改ip为192.168.2.31
修改31机器的keepalived配置文件/etc/keepalived/keepalived.conf
global_defs {
# 路由id:当前安装keepalived的节点主机标识符,保证全局唯一
router_id keep_31
}
vrrp_instance VI_1 {
# 表示状态是MASTER主机还是备用机BACKUP
state BACKUP
# 该实例绑定的网卡
interface ens33
# 保证主备节点一致即可
virtual_router_id 51
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 50
# 主备之间同步检查时间间隔,单位秒
advert_int 2
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
192.168.2.29
}
}
对比30机器的配置,其实就是修改了router_id
,state
和priority
三项内容
两机器的nginx配置nginx.conf加入以下配置
server{
listen 80;
server_name localhost;
location / {
root html;
index index.html;
}
}
分别更改index.html,使之有区别
同时启动两机器的nginx和keepalived服务
执行以下步骤:
访问结果如下:
可以看到,当30宕机后,请求到达31机器,当30恢复后,请求重新回到了30机器,实现了高可用
以上方法在某个机器宕机后,可以自动转移故障,但是仅当nginx宕机后,依旧会导致服务不可用
编写nginx重启检测脚本
vi /etc/keepalived/check_nginx_status.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
# 判断nginx是否宕机,如果宕机了,尝试重启
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
# 等待一小会再次检查nginx,如果没有启动成功,则停止keepalived,使其启动备用机
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
进入文件目录,加上可执行权限 chmod +x check_nginx_status.sh
配置keepalived监听nginx脚本
vrrp_script check_nginx_alive {
script "/etc/keepalived/check_nginx_status.sh"
interval 2 # 每隔两秒运行上一行脚本
weight 10 # 如果脚本运行成功,则升级权重+10
}
在 vrrp_instance 中新增监控的脚本
track_script {
check_nginx_alive # 追踪 nginx 脚本
}
此时keepalived的完整文件为:
global_defs {
# 路由id:当前安装keepalived的节点主机标识符,保证全局唯一
router_id keep_30
}
vrrp_script check_nginx_alive {
script "/etc/keepalived/check_nginx_status.sh"
interval 2 # 每隔两秒运行上一行脚本
weight 10 # 如果脚本运行成功,则升级权重+10
}
vrrp_instance VI_1 {
# 表示状态是MASTER主机还是备用机BACKUP
state MASTER
# 该实例绑定的网卡
interface ens33
# 保证主备节点一致即可
virtual_router_id 51
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 100
# 主备之间同步检查时间间隔,单位秒
advert_int 2
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_nginx_alive # 追踪 nginx 脚本
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
192.168.2.29
}
}
重启keepalived 使配置生效 systemctl restart keepalived
手动关闭nginx进程,访问192.168.2.29可发现依旧正常,nginx服务被自动重启
显然,有一半的机器资源被浪费了
修改30的keepalived配置文件
添加
vrrp_instance VI_2 {
# 表示状态是MASTER主机还是备用机BACKUP
state BACKUP
# 该实例绑定的网卡
interface ens33
# 保证主备节点一致即可
virtual_router_id 52
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 50
# 主备之间同步检查时间间隔,单位秒
advert_int 2
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
192.168.2.28
}
}
修改了vrrp_instance
,state
,virtual_router_id
,priority
,virtual_ipaddress
修改31的keepalived配置文件
添加
vrrp_instance VI_2 {
# 表示状态是MASTER主机还是备用机BACKUP
state MASTER
# 该实例绑定的网卡
interface ens33
# 保证主备节点一致即可
virtual_router_id 52
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 100
# 主备之间同步检查时间间隔,单位秒
advert_int 2
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
192.168.2.28
}
}
重启30,31的keepalived服务
即30,31互为主备,存在两个虚拟ip192.168.2.29
以及192.168.2.28
,
通过DNS轮询,可以使用户请求发给29或28这两个虚拟ip,使得两个机器可以同时提供服务