安装依赖环境
yum install -y gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
解压源码 tar -zxvf nginx-1.16.1.tar.gz
创建临时目录 mkdir -p /var/temp/nginx
在nginx源码根目录下,输入如下命名,构建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
make编译 make
安装 make install
cd /usr/local/nginx
启动 nginx ./sbin/nginx
注意事项,
1.需要开放默认端口80
设置nginx命令在全局可以使用 ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
然后就可以在任何地方是用nginx命令了
如果想使用systemctl来管理nginx,可以执行以下步骤
1.关闭nginx . nginx -s stop
2.vim /etc/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
PrivateTmp=true
PIDFile=/var/run/nginx/nginx.pid
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx
systemctl status nginx
systemctl restart nginx
master进程: 主进程
worker进程: 工作进程
一般来说master进程和worker进程都是1,可以使用ps -ef | grep nginx
来查看
如果需要修改,则可以进入nginx.conf修改:
vim nginx.conf
#nginx使用的用户
#user nobody;
# 工作进程数量,如果需要修改工作进程数量,则修改这里就好了
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#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_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#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 html;
# index index.html index.htm;
# }
#}
}
当修改完后,需要执行nginx -t查看配置文件是否正确,如果正确的话就可以重启nginx,使配置文件生效了
在master与worker的关系,类似老板跟员工的关系,master是老板,worker是员工,master给worker发送信号,worker负责干活
信号:
图示如下:
如下图所示,如果有一个请求,各个work进程会进行争锁。谁抢到是谁的。需要注意Nginx 所有worker进程协同工作的关键(共享内存).
[accept_mutex的介绍]
当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「惊群问题」
BIO,同步阻塞方式
每个worker可以处理大量的连接,cpu越强大,worker数量也可设置的更多,默认每个worker并发请求处理数量为1024.
vim nginx.conf
找到event{}
events {
# 默认使用epoll
use epoll;
# 每个worker允许连接的客户端最大连接数,默认1024,
worker_connections 1024;
}
#worker执行使用的用户,默认使用nobody ps -ef | grep nginx可以看到执行的用户
user root;
# 工作进程数量,如果需要修改工作进程数量,则修改这里就好了
worker_processes 1;
#nginx的6中日志级别(从左到右,级别越来越高) debug info notice warn error crit
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#nginx进程号保存位置
pid logs/nginx.pid;
#
events {
# 默认使用epoll,如果服务器是linux则使用默认就好了
use epoll;
#每个worker允许连接的客户端最大连接数
worker_connections 1024;
}
#http相关网络传输指令块
http {
# 导入mime.types 数据传输类型指令块,提高可读性
include mime.types;
# 默认type类型
default_type application/octet-stream;
#配置日志格式 $ 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 on;
# 和sendfile配套使用,当数据包累计到一定大小再发送
#tcp_nopush on;
#客户端连接服务器超时时间配置,单位:秒
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip压缩开关
#gzip on;
#代表是一个虚拟主机,可以把配置文件写入conf.d文件夹中,一个服务对应一个配置文件,使用include导入
include conf.d/*.conf
server {
#监听的端口号
listen 80;
#监听的域名
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#路由,/ 根目录
location / {
root html;
index index.html index.htm;
}
# error_page 错误匹配重定向到错误页面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#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_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#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 html;
# index index.html index.htm;
# }
#}
}
解决办法:
cut_nginx_log.sh
内容为:#!/bin/bash
# nginx日志文件地址
LOG_PATH="/var/log/nginx/"
# 这里演示为了按分钟切割
RECORD_TIME=$(date -d "yesterday" + %Y-%m-%d+%H:%M)
#nginx.pid文件路径
PID=/var/run/nginx/nginx.pid
# 把当前的access.log重命名
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
# 把当前的error.log重命名
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
# 向nginx主进程发送信息,用于重新打开日志
kill -USR1 `cat $PID`
cut_nginx_log.sh
赋予可执行权限chmod +x ./cut_nginx_log.sh
安装定时任务 yum install -y crontabs
crontab -e
编辑并添加一行新的任务:(注意替换脚本路径)
*/1 * * * * /usr/local/nginx/sbin/cut_nginx_log.sh
重启定时任务 service crond restart
附:定时任务常用命令
定时任务表达式
Cron表达式,分为5或6个域,每个域代表一个含义,如下所示
分 | 时 | 日 | 月 | 星期几 | 年(可选) |
---|---|---|---|---|---|
取值范围 | 0-59 | 0-23 | 1-31 | 1-12 | 1-7 |
常用表达式
*/1 * * * *
59 23 * * *
0 1 * * *
参考文档
server {
listen 1998;
server_name localhost;
location / {
# 资源根路径
root /home/resource;
# 设置主页
index index.html;
}
}
重启nginx nginx -s restart
,然后通过服务器ip:1998/imgs/文件名 访问文件。如果无法访问检查下防火墙或安全组
其实在conf配置文件中,一个server中可以包含多个location进行路径匹配
location / {
# 资源根路径
root /home/resource;
# 设置主页
index index.html;
}
# 别名形式访问
location /static {
alias /home/resource;
}
修改nginx.conf 开启gzip为on gzip on;
设置gzip
# 限制最小压缩,小于一个字节的文件就不会压缩了
gzip_min_length 1;
# 设置压缩比,范围1-9,值越大,压缩比越大,对cpu压力也更大
gzip_comp_level 3;
# 设置压缩的文件类型
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/json;
location是一种路径匹配规则
location /
location / {
root html;
index index.html;
}
# 精确匹配 /home/resource/imgs/face1.png
location = /resource/imgs/face1.png {
root /home;
index index.html;
}
# *代表不区分大小写 从home文件夹下一层一层匹配
location ~* \.(GIF|PNG|BMP|JPG|JPEG) {
root /home;
}
# 区分大小写的精准正则匹配 从home文件夹下一层一层匹配
location ~ \.(GIF|PNG|BMP|JPG|JPEG) {
root /home;
}
# *代表不区分大小写 从home文件夹下一层一层匹配 从/home/resource/imgs/开始匹配
location ^~ /resource/imgs {
root /home;
}
vim /etc/hosts
C:\windows\System32\drivers\etc\hosts
使用switchHosts来简化hosts修改配置
下载地址:switchHosts
SwitchHosts 除了可以帮助你快速切换不同的 hosts 设置、编辑 hosts 文件外,它还有着一些很不错的特性,比如:
基本上,有了 SwitchHosts,你就可以对 hosts 为所欲为了,轻松一键切换毫无鸭梨。而且,远程 hsots 方案也可以非常方便经常换电脑使用的人,配置一次到处使用!这一点也是它的亮点。
不过值得注意的是,由于 SwitchHosts 修改 hosts 文件是属于修改系统文件的行为,比如macOS 和 Linux系统需要输入开机密码,Windows系统下某些安全软件可能会提示“有风险”,有问题的话试试将 SwitchHosts 加入排除列表或者信任列表里即可。
Hosts修改后不生效怎么办?
不过值得注意的是,由于 SwitchHosts 修改 hosts 文件是属于修改系统文件的行为,比如macOS 和 Linux系统需要输入开机密码,Windows系统下某些安全软件可能会提示“有风险”,有问题的话试试将 SwitchHosts 加入排除列表或者信任列表里即可。
怎么情除dns缓存?
如果这样还不生效,那么只能再试试重启电脑了,一般都OK了。要这样还是不行,可能就是你的 hosts 写错了。
配置拦截器
@Configuration
public class CorsConfig {
public CorsConfig(){
}
@Bean
public CorsFilter corsFilter(){
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
// 设置是否可以发送cookie
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
corsSource.registerCorsConfiguration("/**", config);
return new CorsFilter(corsSource);
}
}
在controller上使用@CrossOrigin注解
# 允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许的请求方法, *表示所有方法
add_header 'Access-Control-Allow-Method' *;
# 允许所有请求的头
add_header 'Access-Control-Allow-Headers' *;
示例:
server {
listen 1998;
server_name localhost;
# 允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许的请求方法, *表示所有方法
add_header 'Access-Control-Allow-Method' *;
# 允许所有请求的头
add_header 'Access-Control-Allow-Headers' *;
location / {
# 资源根路径
root /home/resource;
# 设置主页
index index.html;
}
}
server {
listen 1998;
server_name localhost;
# 允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许的请求方法, *表示所有方法
add_header 'Access-Control-Allow-Method' *;
# 允许所有请求的头
add_header 'Access-Control-Allow-Headers' *;
# 对源站点校验,是否是test.com下的站点
valid_referers *.test.com;
# 非法引入会进入下方的判断
if ($invalid_referer){
return 404;
}
location / {
# 资源根路径
root /home/resource;
# 设置主页
index index.html;
}
}
nginx core实现了底层的通讯协议,为其他模块和Nginx进程构建了基本的运行时环境,并且构建了其他各模块的协作基础。
http模块和mail模块位于nginx core和各功能模块的中间层,这2个模块在nginx core之上实现了另外一层抽象,分别处理与http协议和email相关协议(SMTP/IMAP/POP3)有关的事件,并且确保这些事件能被以正确的顺序调用其它的一些功能模块。
(1) event module:搭建了独立于操作系统的事件处理机制的框架,以及提供了各具体事件的处理,包括ngx_event_module、ngx_event_core_module和ngx_epoll_module等,Nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项。
(2) phase handler:此类型的模块也被直接称为handler模块,主要负责处理客户端请求并产生待响应内容,比如ngx_http_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。
(3) output filter:也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改,比如可以实现对输出的所有html页面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作。
(4) upstream:实现反向代理功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端,upstream模块是一种特殊的handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。
(5) load-balancer:负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。
(6) extend module:根据特定业务需要编写的第三方模块。
下面将会以http请求处理为例来说明请求、配置和模块是如何串起来的。
当Nginx读取到一个HTTP Request的header时,首先查找与这个请求关联的虚拟主机的配置,如果找到了则这个请求会经历以下几个阶段的处理(phase handlers):
NGX_HTTP_POST_READ_PHASE: 读取请求内容阶段
NGX_HTTP_SERVER_REWRITE_PHASE: Server请求地址重写阶段
NGX_HTTP_FIND_CONFIG_PHASE:配置查找阶段
NGX_HTTP_REWRITE_PHASE:Location请求地址重写阶段
NGX_HTTP_POST_REWRITE_PHASE:请求地址重写提交阶段
NGX_HTTP_PREACCESS_PHASE: 访问权限检查准备阶段
NGX_HTTP_ACCESS_PHASE: 访问权限检查阶段
NGX_HTTP_POST_ACCESS_PHASE: 访问权限检查提交阶段
NGX_HTTP_TRY_FILES_PHASE: 内容产生阶段
NGX_HTTP_LOG_PHASE:日志模块处理阶段
在内容产生阶段,为了给一个request产生正确的response,Nginx必须把这个请求交给一个合适的content handler去处理。如果这个request对应的location在配置文件中被明确指定了一个content handler,那么Nginx就可以通过对location的匹配,直接找到这个对应的handler,并把这request交给这个content handler去处理。这样的配置指令包括perl、flv、proxy_pass、mp4等。
如果一个request对应的location并没有直接配置的content handler,那么Nginx依次作如下尝试:
(1) 如果一个location里面有配置random_index on,那么随即选择一个文件发送给客户端。
(2) 如果一个location里面有配置index指令,那么发送index指令指定的文件给客户端。
(3) 如果一个location里面有配置autoindex on,那么就发送请求地址对应的服务端路径下的文件列表给客户端。
(4) 如果这个request对应的location上有设置gzip_static on,那么就查找是否有对应的.gz文件存在,如果有的话,就发送这个客户端(客户端支持gzip的情况下).
(5) 请求的URI如果对应的一个静态文件,static module就发送静态文件的内容到客户端。
内容产生阶段完成以后,生成的输出会被传递到filter模块去进行处理。filter模块也是与location相关的。所有的filter模块都被组织成了一条链。输出会依次穿越所有的filter,直到有一个filter模块的返回值表明已经处理完成。 接下来就可以发送response给客户端了。
什么是负载均衡:Load balancing,即负载均衡,是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
为什么需要负载均衡:
负载均衡(Load Balance),意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。是解决高性能,单点故障(高可用),扩展性(水平伸缩)的终极解决方案。
更多关于负载均衡的资料
基于IP+端口的负载均衡
也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
常见的四层负载均衡实现软件:
F5:硬件负载均衡器,功能很好,但是成本很高。
lvs:重量级的四层负载软件
nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活,1.9版本后支持
haproxy:模拟四层转发,较灵活
从第七层"应用层"开始, 根据虚拟的url或IP,主机名接收请求,再转向相应的处理服务器。
在四层负载均衡的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。
对应的负载均衡器称为七层交换机(L7 switch),除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息,实现七层负载均衡。此种负载均衡器能理解应用协议。
实现七层负载均衡的软件有:
haproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移;
nginx:只在http协议和mail协议上功能比较好,性能与haproxy差不多;
apache:功能较差
Mysql proxy:功能尚可。
总的来说,一般是lvs做4层负载;nginx做7层负载(也能做4层负载, 通过stream模块);haproxy比较灵活,4层和7层负载均衡都能做
所谓DNS地域是基于地理的负载均衡 例子: 北方的用户访问北京的机房, 南方的用户访问深圳的机房,DNS负载均衡的本质是DNS解析同一个域名可以访问不同的IP地址 例如: 同样是www.baidu.com,北京用户解析后获取的地址是61.135.165.224(北京机房IP),南方用户解析后获取的地址是14.215.177.38(深圳机房IP)
DNS负载均衡实现简单,成本低,但也存在粒度太粗、负载均衡算法少等缺点。
优点
1. 简单、成本低: 负载均衡工作交给DNS服务器处理,无须自己开发或者维护负载均衡设备
2. 就近访问,提升访问速度: DNS解析时可以根据请求来源IP 解析成距离用户最近的服务器地址,可以加快访问速度,改善性能。
缺点
1. 更新不及时:DNS缓存带时间比较长,修改DNS配置厚,由于缓存的原因,还有有很多用户会继续访问修改前的IP,这样带访问会失败, 达不到负载均衡带目的,并且也会影响用户正常的使用
2. 扩展性差: DNS负载均衡的控制权在域名商那里,无法根据业务特点针对其做更多的定制化功能和扩展特性
3. 分配策略比较简单:DNS负载均衡支持带算法少, 不能区分服务器的差异(无法根据系统与服务状态来判断负载),也无法感知后端服务器带状态。
四层负载均衡只是对请求进行转发,七层负载均衡可以对请求进行处理,然后再转发。
四层负载均衡就像银行的自助排号机,每一个达到银行的客户根据排号机的顺序,选择对应的窗口接受服务;而七层负载均衡像银行大堂经理,先确认客户需要办理的业务,再安排排号。这样办理理财、存取款等业务的客户,会根据银行内部资源得到统一协调处理,加快客户业务办理流程。
nginx服务器和3个tomcat服务器需要可以通信
图示
具体实现:
1.服务器信息
nginx: 192.168.65.100
tomcat1: 192.168.65.101
tomcat2: 192.168.65.102
tomcat3: 192.168.65.103
2.启动3台tomcat服务器
3.配置nginx服务器, 在conf.d中新建tomcatGroup.conf
# 配置上游服务器
upstram tomcats {
server 192.168.65.101:8080;
server 192.168.65.102:8080;
server 192.168.65.103:8080;
}
server{
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcats;
}
}
4.重启nginx服务 nginx -s restart
进入浏览器访问:192.168.65.100查看结果