文章目录
一、Nginx概述
1. Nginx介绍
Nginx(engine x)是一个高性能的HTTP和反向代理web服务器。
Nginx是一款轻量级的Web服务器、反向代理服务器、电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。
其特点是占有内存少,并发能力强,可以支持 50000个并发。(解决Tomcat高并发和高可用问题)
国内使用Nginx的网站有:百度、京东、新浪、网易、腾讯、淘宝、CSDN等等。
Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
Nginx常见功能:请求转发、反向代理、负载均衡、动静分离。
请求转发:
负载均衡:
动静分离:
2. Nginx下载与安装
2.1 Nginx下载
官方下载网址:http://nginx.org/en/download.html
本文以nginx16.1为例:
-
windows版安装包下载地址:http://nginx.org/download/nginx-1.16.1.zip
-
linux版安装包下载地址:http://nginx.org/download/nginx-1.16.1.tar.gz
2.2 在Windows系统上安装Nginx
1、将nginx安装包解压到指定目录。
2、启动nginx: 双击nginx.exe可执行文件启动,或者cmd进入nginx主目录执行nginx.exe
命令启动。
启动nginx:
注:使用cmd启动nginx,如果关闭cmd窗口,nginx进程是不会停止的。
3、测试访问:http://localhost (http协议默认是80端口,所以80可以省略不写)
4、停止nginx: cmd进入nginx主目录,执行命令:nginx.exe -s stop
。
或者在任务管理器中结束进程。
2.3 在Linux系统上安装Nginx
本文以源码编译方式安装Nginx
1、安装依赖包(由于nginx是基于c语言开发的,所以需要安装c语言的编译环境,及正则表达式库等第三方依赖库)
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
2、查看系统上是否有nginx进程以及安装包:
# 查看系统上是否有nginx进程
ps -ef | grep nginx
# 查看系统上是否有nginx安装包
rpm -qa | grep nginx
3、使用wget命令下载nginx:(将nginx下载到/soft目录下)
wget http://nginx.org/download/nginx-1.16.1.tar.gz
扩展:
wget命令用来从指定的URL下载文件。wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。
若自己的linux中没有wget的话,可以通过yum install wget
命令安装wget。
4、解压nginx压缩包
tar -zxvf nginx-1.16.1.tar.gz
5、配置nginx编译环境
cd nginx-1.16.1
# 配置nginx安装位置
./configure --prefix=/usr/local/nginx
# --prefix指定的目录,就是nginx的安装目录
6、进行编译安装
# 使用&将两条命令一起执行
make & make install
ok到这步nginx已经安装成功了。
因为我们在第五步的时候配置了nginx安装位置,所以它会把nginx里面的东东安装到/usr/local/nginx
目录下:
3. Nginx目录结构
目录以树状结构展示:tree 目录名 ,如果系统上没有tree指令,使用yum下载即可:yum install -y tree。
我们可以切换到Nginx的安装目录(/usr/local/nginx),查看Nginx的目录结构:
nginx/
├── conf # 存放配置文件的
│ ├── fastcgi.conf
│ ├── fastcgi.conf.default
│ ├── fastcgi_params
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf # nginx核心配置文件
│ ├── nginx.conf.default
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── html # 存放静态资源的
│ ├── 50x.html
│ └── index.html
├── logs # 存放日志的
└── sbin # 存放可执行的
└── nginx # 启动、停止nginx服务
如下是nginx重要的目录以及文件:
目录/文件 | 说明 | 备注 |
---|---|---|
conf | 配置文件的存放目录 | |
conf/nginx.conf | Nginx的核心配置文件 | conf目录下有很多nginx的配置文件,我们主要操作这个核心配置文件 |
html | 存放静态资源(html、css等 ) | 部署到Nginx的静态资源都可以放在html目录中 |
logs | 存放nginx日志(访问日志、错误日志等) | |
sbin/nginx | 二进制文件,用于启动、停止Nginx服务 |
二、Nginx命令
1. Nginx常用命令
在Nginx中,二进制可执行文件(nginx)存放在sbin目录下,虽然只有一个可执行文件,但是我们可以通过该指令配合不同的参数达到更加强大的功能。在执行nginx相关命令时,如果没有配置环境变量的话,都需要在/usr/local/nginx/sbin/目录下执行。
1.1 启动nginx
./nginx
注:nginx服务启动后,默认就会有两个进程。
测试访问:(http协议默认是80端口,所以80端口号可以省略不写)
注意:要想正常访问Nginx,需要关闭防火墙或者开放指定端口号。
- 关闭防火墙:systemctl stop firewalld。
- 开放80端口:(①开放80端口:firewall-cmd --zone=public --add-port=80/tcp --permanent,②更新防火墙规则:firewall-cmd --reload)
1.2 停止nginx
./nginx -s stop
或者使用kill将进程干掉。
1.3 查看nginx版本
./nginx -v
1.4 检查配置文件
如果我们修改了nginx.conf核心配置文件,在启动Nginx服务之前,可以通过如下命令先检查一下conf/nginx.conf
文件的配置是否有错误。
./nginx -t
1.5 重新加载
当修改了Nginx配置文件后,需要重新加载才能生效,可以使用下面命令重新加载配置文件:
./nginx -s reload
2. 环境变量配置
配置环境变量后可以在任意目录下操作nginx,就不用单独切换到/nginx/sbin目录去执行命令。
vim /etc/profile
# 定义变量方式配置环境变量
export NGINX_HOME=/usr/local/nginx
export PATH=$NGINX_HOME/sbin:$PATH
# :wq保存退出
# 让配置的环境变量生效
source /etc/profile
接下来我们就可以在任意目录操作nginx命令了。
三、Nginx应用
1. 配置文件结构
nginx的配置文件(conf/nginx.conf)整体上分为三部分: 全局块、events块、http块。
- 全局块:配置和nginx运行相关的全局配置。
- events块:配置和网络连接相关的配置。
- http块:配置代理、缓存、日志记录、虚拟主机等配置。
在nginx配置文件中,以后我们经常配置的是http块。
在http块中可以包含多个server块(虚拟主机),每个server块可以配置多个location块(配置请求的路由)。
nginx配置详解:https://www.cnblogs.com/knowledgesea/p/5175711.html
扩展:nginx路径匹配。(默认匹配、精确匹配、正则匹配等等)
2. 部署静态资源
Nginx可以作为静态web服务器。相比Tomcat,Nginx处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到Nginx中。
将静态资源部署到Nginx非常简单,只需要将文件复制到Nginx安装目录下的html目录中即可。
1、在conf/nginx.conf文件的http块中创建一个虚拟机server:
server {
listen 8089; #监听的端口
server_name 192.168.203.157; #监听的服务器名称(ip或者域名)
location / { #匹配客户端请求url
root html; #指定静态资源根目录
index hello.html; #指定默认首页
}
}
:wq 保存退出
2、重新加载配置文件
nginx -s reload
3、创建一个hello.html页面,然后放到nginx/html目录下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.deng-box {
position: fixed;
top: -40px;
right: -20px;
z-index: 9999;
pointer-events: none
}
.deng-box1 {
position: fixed;
top: -30px;
right: 10px;
z-index: 9999;
pointer-events: none
}
.deng-box2 {
position: fixed;
top: -40px;
left: -20px;
z-index: 9999;
pointer-events: none
}
.deng-box3 {
position: fixed;
top: -30px;
left: 10px;
z-index: 9999;
pointer-events: none
}
.deng-box1 .deng,
.deng-box3 .deng {
position: relative;
width: 120px;
height: 90px;
margin: 50px;
background: #d8000f;
background: rgba(216, 0, 15, .8);
border-radius: 50% 50%;
-webkit-transform-origin: 50% -100px;
-webkit-animation: swing 5s infinite ease-in-out;
box-shadow: -5px 5px 30px 4px #fc903d
}
.deng {
position: relative;
width: 120px;
height: 90px;
margin: 50px;
background: #d8000f;
background: rgba(216, 0, 15, .8);
border-radius: 50% 50%;
-webkit-transform-origin: 50% -100px;
-webkit-animation: swing 3s infinite ease-in-out;
box-shadow: -5px 5px 50px 4px #fa6c00
}
.deng-a {
width: 100px;
height: 90px;
background: #d8000f;
background: rgba(216, 0, 15, .1);
margin: 12px 8px 8px 8px;
border-radius: 50% 50%;
border: 2px solid #dc8f03
}
.deng-b {
width: 45px;
height: 90px;
background: #d8000f;
background: rgba(216, 0, 15, .1);
margin: -4px 8px 8px 26px;
border-radius: 50% 50%;
border: 2px solid #dc8f03
}
.xian {
position: absolute;
top: -20px;
left: 60px;
width: 2px;
height: 20px;
background: #dc8f03
}
.shui-a {
position: relative;
width: 5px;
height: 20px;
margin: -5px 0 0 59px;
-webkit-animation: swing 4s infinite ease-in-out;
-webkit-transform-origin: 50% -45px;
background: orange;
border-radius: 0 0 5px 5px
}
.shui-b {
position: absolute;
top: 14px;
left: -2px;
width: 10px;
height: 10px;
background: #dc8f03;
border-radius: 50%
}
.shui-c {
position: absolute;
top: 18px;
left: -2px;
width: 10px;
height: 35px;
background: orange;
border-radius: 0 0 0 5px
}
.deng:before {
position: absolute;
top: -7px;
left: 29px;
height: 12px;
width: 60px;
content: " ";
display: block;
z-index: 999;
border-radius: 5px 5px 0 0;
border: solid 1px #dc8f03;
background: orange;
background: linear-gradient(to right, #dc8f03, orange, #dc8f03, orange, #dc8f03)
}
.deng:after {
position: absolute;
bottom: -7px;
left: 10px;
height: 12px;
width: 60px;
content: " ";
display: block;
margin-left: 20px;
border-radius: 0 0 5px 5px;
border: solid 1px #dc8f03;
background: orange;
background: linear-gradient(to right, #dc8f03, orange, #dc8f03, orange, #dc8f03)
}
.deng-t {
font-family: 华文行楷, Arial, Lucida Grande, Tahoma, sans-serif;
font-size: 3.2rem;
color: #dc8f03;
font-weight: 700;
line-height: 85px;
text-align: center
}
.night .deng-box,
.night .deng-box1,
.night .deng-t {
background: 0 0 !important
}
@-moz-keyframes swing {
0% {
-moz-transform: rotate(-10deg)
}
50% {
-moz-transform: rotate(10deg)
}
100% {
-moz-transform: rotate(-10deg)
}
}
@-webkit-keyframes swing {
0% {
-webkit-transform: rotate(-10deg)
}
50% {
-webkit-transform: rotate(10deg)
}
100% {
-webkit-transform: rotate(-10deg)
}
}
</style>
</head>
<body>
<div class="deng-box2">
<div class="deng">
<div class="xian"></div>
<div class="deng-a">
<div class="deng-b">
<div class="deng-t">年</div>
</div>
</div>
<div class="shui shui-a">
<div class="shui-c"></div>
<div class="shui-b"></div>
</div>
</div>
</div>
<div class="deng-box3">
<div class="deng">
<div class="xian"></div>
<div class="deng-a">
<div class="deng-b">
<div class="deng-t">新</div>
</div>
</div>
<div class="shui shui-a">
<div class="shui-c"></div>
<div class="shui-b"></div>
</div>
</div>
</div>
<div class="deng-box1">
<div class="deng">
<div class="xian"></div>
<div class="deng-a">
<div class="deng-b">
<div class="deng-t">乐</div>
</div>
</div>
<div class="shui shui-a">
<div class="shui-c"></div>
<div class="shui-b"></div>
</div>
</div>
</div>
<div class="deng-box">
<div class="deng">
<div class="xian"></div>
<div class="deng-a">
<div class="deng-b">
<div class="deng-t">快</div>
</div>
</div>
<div class="shui shui-a">
<div class="shui-c"></div>
<div class="shui-b"></div>
</div>
</div>
</div>
</body>
</html>
4、启动nginx
nginx
5、测试访问:http://192.168.203.157:8089、http://192.168.203.157:8089/hello.html
3. 反向代理
3.1 正向代理
正向代理服务器是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。
正向代理一般是在客户端设置代理服务器,通过代理服务器转发请求,最终访问到目标服务器。(例如vpn)
3.2 反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。用户不需要知道目标服务器的地址,也无须在用户端作任何设定,对于用户来说,访问反向代理服务器是完全无感知的。
示例:使用nginx实现反向代理。
1、启动第一台机器上的nginx服务器。
2、在第一台机器上的conf/nginx.conf文件中配置反向代理:
server {
listen 82;
server_name localhost;
location / {
proxy_pass http://192.168.203.158:8080/hello; #配置反向代理,将请求转发到指定服务
}
}
3、检查配置文件,并重新加载配置
nginx -t
nginx -s reload
4、启动第二台机器上的Java项目。
5、浏览器访问:http://192.168.203.157:82
注:别忘开放端口、或者关闭防火墙。
4. 负载均衡
早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。(水平扩展:集群、垂直扩展:升级硬件配置)
应用集群: 将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据。
负载均衡器: 将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理。
使用Nginx来实现负载均,而Nginx的负载均衡是基于反向代理的,只不过此时所代理的服务器不是一台,而是多台。
1、在nginx的配置文件nginx.conf中添加如下配置:
#upstream指令可以定义一组服务器 给他们起个名字,名字自定义(一会要用)
upstream 名字{
server 192.168.203.158:8080;
server 192.168.203.158:8081;
}
server {
listen 9001;
server_name localhost;
location / {
proxy_pass http:配置刚才自定义名字;
}
}
2、检查配置文件语法是否有问题,并重新加载nginx配置。
nginx -t
nginx -s reload
3、将业务相同、端口号不同的两个jar包上传到linux服务器。
4、运行linux上的这两个jar包,端口号分别是8080、8081。
由于我们执行 java -jar 指令会占用前台窗口,所以我们可以开启两个窗口进行测试。
nginx负载均衡默认是轮询加载。
负载均衡策略
处理上述默认的轮询策略以外,在Nginx中还提供了其他的负载均衡策略:
名称 | 说明 | 特点 |
---|---|---|
轮询 | 默认方式 | |
weight | 权重方式 | 根据权重分发请求,权重大的分配到请求的概率大。 |
ip_hash | 依据ip分配方式 | 根据客户端请求的IP地址计算hash值, 根据hash值来分发请求,同一个IP发起的请求,会发转发到同一个服务器上。 |
least_conn | 依据最少连接方式 | 哪个服务器当前处理的连接少,请求优先转发到这台服务器。 |
url_hash | 依据url分配方式 | 根据客户端请求url的hash值,来分发请求, 同一个url请求,会发转发到同一个服务器上。 |
fair | 依据响应时间方式 | 优先把请求分发给处理请求时间短的服务器。 |
例如: 配置权重
#upstream指令可以定义一组服务器
upstream targetserver{
server 192.168.203.157:8080 weight=2;
server 192.168.203.157:8081 weight=1;
}
上述配置的权重是相对的,在并发请求下,最终8080接收的请求数是8081的两倍。