一、 Nginx简介
Nginx是一个高性能的Web服务器和反向代理的软件。 Web服务器:就是运行我们web服务的容器,提供web功能,还有tomcat也提供类似的功能。 代理是软件架构和网络设计中,非常重要的一个概念。
二、Nginx的反向代理(附加正向代理)
有两种代理:正向代理和反向代理。 首先,看一张关于正向代理和反向代理的图片
正向代理
正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。
使用场景
正向代理的典型用途是为防火墙内的局域网客户端提供访问服务器的途径,正向代理还可以使用缓冲特性减少网络利用率。
科学上网(翻墙)
有时候,用户想要访问某国外网站,该网站无法在国内直接访问,但是我们可以访问到一个代理服务器,这个代理服务器可以访问到这个国外网站。这样呢,用户对该国外网站的访问就需要通过代理服务器来转发请求,并且该代理服务器也会将请求的响应再返回给用户。这个上网的过程就是用到了正向代理。
用途
- 突破访问显示:通过代理服务器,可以突破自身ip访问限制,访问国外网站等
- 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,会将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度
- 隐藏客户端真实ip:上网者可以通过正向代理的方法隐藏自己的ip,免受攻击
反向代理
概念
反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。
对于客户端来说,反向代理就相当于目标服务器,只需要将反向代理当作目标服务器一样发送请求就可以了,并且客户端不需要进行任何设置。
特点
正向代理需要配置代理服务器,而反向代理不需要做任何设置。
反向代理是代理服务器,为服务器收发请求,使真实服务器对客户端不可见。
使用场景
反向代理的典型用途是将防火墙外的服务器提供给客户端访问,反向代理还可以为后端的多台服务器提供负载均衡,或者为后端较慢的服务器提供缓冲服务。
用途
- 隐藏服务器真实ip:使用反向代理,可以对客户端隐藏服务器的ip地址
- 负载均衡:反向代理服务器可以做负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上
- 提高访问速度:反向代理服务器可以对静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度
- 提供安全保障:反向代理服务器可以作为应用层防火墙,为网站提供对基于web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等。
三、Nginx的负载均衡
什么是负载均衡?
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简单来说就是:现有的请求使服务器压力太大无法承受,所有我们需要搭建一个服务器集群,去分担原先一个服务器所承受的压力,那现在我们有ABCD等等多台服务器,我们需要把请求分给这些服务器,但是服务器可能大小也有自己的不同,所以怎么分?如何分配更好?又是一个问题。
Nginx给出来三种关于负载均衡的方式:
轮询法(默认方法):
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
适合服务器配置相当,无状态且短平快的服务使用。也适用于图片服务器集群和纯静态页面服务器集群。
轮询的访问,先访问8081,在访问8082
配置例子:
# server list
upstream myServers {
server localhost:8081;
server localhost:8082;
}
server {
listen 9002;
server_name www.jowell.com;
location / {
proxy_pass http://myServers;
}
}
weight权重模式(加权轮询):
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
这种方式比较灵活,当后端服务器性能存在差异的时候,通过配置权重,可以让服务器的性能得到充分发挥,有效利用资源。weight和访问比率成正比,用于后端服务器性能不均的情况。权重越高,在被访问的概率越大
比如当前有两个线程正在访问8081,8082一个,那么下次来了线程就访问8082地址。
配置例子:
# server list
upstream myServers {
least_conn;
server localhost:8081;
server localhost:8082;
}
server {
listen 9002;
server_name www.jowell.com;
location / {
proxy_pass http://myServers;
}
}
ip_hash:
上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。
我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
配置例子:
# server list
upstream myServers {
ip_hash;
server localhost:8081;
server localhost:8082;
}
server {
listen 9002;
server_name www.jowell.com;
location / {
proxy_pass http://myServers;
}
}
四、Nginx的使用
官网:https://nginx.org/
4.1、Linx安装
1、安装:yum
yum install yum-utils
2、切换目录 查看是否有 nginx.repo 文件
cd /etc/yum.repos.d/
3、创建文件
vim nginx.repo
文件内容
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
4、Nginx的安装
yum install nginx
5、启动验证
进入到 /usr/sbin 目录
cd /usr/sbin/
启动命令
./nginx
验证nginx本机访问是否成功
curl localhost:80
如果出现:Welcome to nginx!,证明nginx启动成功。
6、 检查防火墙:
systemctl status firewalld
关闭防火墙
systemctl stop firewalld
这样,在宿主机的浏览器中就可以访问了。
7、访问
到此nginx安装成功。
4.2、Nginx常用命令
查看nginx版本号:
nginx -v
启动Nginx命令1:
nginx
启动Nginx命令2:
systemctl start nginx
查看正在进行中Nginx的信息
ps -ax | grep nginx
关闭Nginx命令:
nginx -s stop
根据进程PID关闭
kill -s QUIT 895246
优雅的停止nginx:
nginx -s quit
重新加载配置:
nginx -s reload
4.3 反向代理使用(单台机器)
1、启动一个 tomcat,浏览器地址栏输入 127.0.0.1:8080,出现如下界面
2、通过修改本地 host 文件,将 www.jowell.com 映射到 127.0.0.1
3、在 nginx.conf 配置文件中增加如下配置:
1 server {
2 listen 80;
3 server_name www.jowell.com;
4
5 location / {
6 proxy_pass http://127.0.0.1:8080;
7 }
8 }
如上配置,我们监听80端口,访问域名为www.jowell.com,不加端口号时默认为80端口,访问域名时会跳转到127.0.0.1:8080路径上
4.4 负载均衡
4.1 简介
通俗:将负载变的均衡。
负载(请求、工作任务)、均衡(算法 ,中间件)。
负载均衡的主要作用如下:
高并发:负载均衡通过算法调整负载,尽力均匀的分配应用集群中各节点的工作量,以此提高应用集群的并发处理能力(吞吐量)。
伸缩性:添加或减少服务器数量,然后由负载均衡进行分发控制。这使得应用集群具备伸缩性。
高可用:负载均衡器可以监控候选服务器,当服务器不可用时,自动跳过,将请求分发给可用的服务器。这使得应用集群具备高可用的特性。
安全防护:有些负载均衡软件或硬件提供了安全性功能,如:黑白名单处理、防火墙,防 DDos 攻击等。
‘
4.2 实验
目的:
1。通过浏览器多次访问一个地址(http://www.jowell.com)。
2。nginx接受上面的请求,并进行转发。
3。那么每个请求的响应,是来自于不同的tomcat提供的。(2台tomcat,端口:8081,8082)。
两台tomcat,不同的响应内容:“8081”和“8082”。
步骤:
1。准备2个tomcat,端口分别8081、8082,并做好响应的页面,启动,测试。
2。配置nginx.conf。
upstream myServers {
server localhost:8081;
server localhost:8082;
}
server {
listen 9002;
server_name www.jowell.com;
location / {
proxy_pass http://myServers;
}
}
保存后重新加载配置:
nginx -s reload
测试:
浏览器多次请求请求:http://www.jowell.com
上面的例子没写负载均衡算法和权重,那么默认就是轮询算法。
其它算法可自行测试。
4.5 动静分离
4.5.1 介绍
动静分离是指在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。
nginx 的动静分离,指的是由 nginx 将客户端请求进行分类转发,静态资源请求(如html、css、图片等)由静态资源服务器处理,动态资源请求(如 jsp页面、servlet程序等)由 tomcat 服务器处理,tomcat 本身是用来处理动态资源的,同时 tomcat 也能处理静态资源,但是 tomcat 本身处理静态资源的效率并不高,而且还会带来额外的资源开销。利用 nginx 实现动静分离的架构,能够让 tomcat 专注于处理动态资源,静态资源统一由静态资源服务器处理,从而提升整个服务系统的性能 。
4.5.2 使用nginx实现动静分离
准备静态资源
创建两个目录:
- /data/www/*.html
- /data/images/*.png
配置Nginx.conf server
server {
listen 9003;
server_name www.zxczxc.com;
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
访问:www.zxczxc.com/index.html 转换成:/data/www/index.html
访问:www.zxczxc.com/images/cap.png 转换成:/data/images/cap.png
测试:
通过url去匹配静态资源即可。静态:static。
4.6 nginx实现高可用
保证高可用:集群化、冗余。
核心:冗余。自动故障转移。
1、Nginx高可用组成
2、准备两台服务器
3、两台服务器安装nginx,以及下面文件
结构:
index.html内容:
另一台同理。
测试访问主节点16服务器:
4.6.1、安装keepalived
1、keepalived简介
keepalived起初是为LVS设计的专门用来监控集群系统中各个服务节点的状态如果某个服务节点出现异常或者工作出现故障,keepalived将检测到,并将出现故障的服务节点从集群系统中剔除,而在故障节点恢复正常后,keepalived又可以自动将该服务节点重新加入集群中,这些工作全部自动完成。这部分功能类似于nginx 等反向代理的应用探活功能实现后端服务高可用。
后来又加入了VRRP的功能,VRRP(Virtual Router Redundancy Protocol),虚拟路由协议出现的目的是为了解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,因此keepalived一方面具有服务器状态检测和故障隔离功能,另一方面也有HA cluster功能;这个功能实现各种中间件高可用。
2、keeplived 实现高可用示意图:
3、安装命令:
yum install keepalived
两台服务器都安装
4、keepalived配置及启动
配置ip
要先查看一下自己当前的ip
配置文件位置
vim /etc/keepalived/keepalived.conf
如下配置是配置nginx挂了,但是服务器没挂的情况
track_script {
check_nginx
}
vrrp_script check_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2 #每隔2秒运行一次
weight 10 # 运行成功 权重加10
}
设置检测脚本
vim /etc/nginx/checkNginx.sh
#!/bin/bash
#时间变量,用于记录日志
d=`date --date today +%Y-%m-%d_%H:%M:%S`
#计算nginx进程数量
n=`ps -C nginx --no-heading|wc -l`
#如果进程为0,则启动nginx,并且再次检测nginx进程数量,
if [ $n -eq "0" ]; then
/usr/sbin/nginx -c /etc/nginx/nginx.conf
sleep 3
#如果还为0,说明nginx无法启动,此时需要关闭keepalived
n2=`ps -C nginx --no-heading|wc -l`
if [ $n2 -eq "0" ]; then
echo "$d nginx down,keepalived will stop" >> /var/log/check_nginx.log
systemctl stop keepalived
fi
fi
设置脚本执行权限
chmod 755 /etc/nginx/checkNginx.sh
启动keepalived服务
必须先停止 selinux
如果不关闭是无法执行检测脚本的
临时关闭
setenforce 0
重启后永久生效
sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/’ /etc/selinux/config
设置开机自启
chkconfig keepalived on
启动keepalived
systemctl start keepalived
查看状态
systemctl status keepalived
两台主机配置文件
主:
! Configuration File for keepalived
global_defs {
}
vrrp_instance VI {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16
}
track_script {
check_nginx
}
}
vrrp_script check_nginx {
script "/etc/nginx/checkNginx.sh"
interval 2 #每隔2秒运行一次
weight 10 # 运行成功 权重加10
}
}
从:
! Configuration File for keepalived
global_defs {
}
vrrp_instance VI {
state BACKUP
interface eth0
virtual_router_id 51
priority 20
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16
}
track_script {
check_nginx
}
}
vrrp_script check_nginx {
script "/etc/nginx/checkNginx.sh"
interval 2 #每隔2秒运行一次
weight 10 # 运行成功 权重加10
}
}
4.6.2 keepalived配置文件讲解
1、全局配置
global_defs {
notification_email { #邮箱服务器,一般公司内也不设置
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL #标识这台机器ID,默认情况下是主机名,可以配置成主机名
vrrp_skip_check_adv_addr #所有报文都检查比较消耗性能,此配置为如果收到的报文和上一个报文是同一个路由器则跳过检查报文中的源地址
vrrp_strict #严格遵守VRRP协议,不允许状况:1,没有VIP地址,2.配置了单播邻居,3.在VRRP版本2中有IPv6地址
vrrp_garp_interval 0 #ARP报文发送延迟
vrrp_gna_interval 0 #消息发送延迟
#vrrp_mcast_group4 224.0.0.18 #指定组播IP地址,默认值:224.0.0.18 范围:224.0.0.0到239.255.255.255
#vrrp_iptables #避免生成iptables input链 规则,sip any 拒绝 dip any
}
2、VRRP配置
vrrp_instance VI_1 { #虚拟路由器名称,在一个keepalived可以启多个虚拟路由器,每个虚拟路由器的名字都不一样
state MASTER #当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP,一般都是配置backup,该值无法决定身份,最终还是通过比较priority
interface eth0 #绑定为当前虚拟路由器使用的物理接口,如:ens32,eth0,bond0,br0
virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,同一组虚拟路由器的vrid必须一致
priority 100 #当前物理节点在此虚拟路由器的优先级,范围:1-254,每个keepalived主机节点此值不同
advert_int 1 #vrrp通告的时间间隔,默认1s
authentication { #认证机制
auth_type PASS #AH(不推荐)或PASS
auth_pass 1111 #预共享密钥,仅前8位有效,同一个虚拟路由器的多个keepalived节点必须一样
}
virtual_ipaddress { #虚拟IP
10.0.0.100 #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认为/32
10.0.0.101/24 dev eth1 #指定VIP的网卡
10.0.0.102/24 dev eth2 label eth2:1 #指定VIP的网卡label
}
}
修改完文件后,重新启动。
4.6.3、测试
访问的是10.0.2.16服务器,也就是主节点.
把主节点服务器停掉继续访问
访问的是从节点。
总结来说,当用户访问Keepalived管理的虚拟IP时,实际上是访问到了承载VIP的主节点上的Nginx服务器,Nginx再根据其配置将请求透明地转发给后端真实服务器进行处理,从而实现了负载均衡和服务高可用。
五、Lua
1、介绍
lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
设计的目的:嵌入到应用程序当中,提供灵活的扩展和定制化的功能。
2、LUA基本语法
①、Lua 保留字(关键字)
and、 break、 do、 else、 elseif、 end、 false、 for、 function、 if、 in、 local、 nil、 not、 or、 return、 then、 true、( repeat、 until)、 while 注: Lua中没有continue
②、Lua符号
算术运算符 + -*/% ^ 求幂 - 取反
关系运算符 == ~= < > <= >=
逻辑运算符 and or not
其他运算符 … #
其他符号 … 不定参数 . :
③、Lua 类型
1、nil 空类型
类似 C++中的nullptr_t
2、boolean 只有两个可选值:true(真) 和 false(假),Lua 把 false 和 nil 看作是 “假”,其他的都为“真”
3、number 默认只有一种 number 类型 – double(双精度)类型
4、string 字符串由一对双引号或单引号来表示
5、*table Lua 中的表(table)其实是一个“关联数组”(associative arrays),数组的 索引可以是数字或者是字符串
6、function 函数类型 函数可以存在变量里
7、thread 在 Lua 里,最主要的线程是协同程序。它跟线程差不多,拥有自己独立的栈、 局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
8、userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的 类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中 调用
3、 安装
检查机器上是否有lua
lua
打开官网:http://lua.org
curl -L -R -O https://www.lua.org/ftp/lua-5.4.6.tar.gz
tar zxf lua-5.4.6.tar.gz
cd lua-5.4.6
make all test
make install
查看版本
lua -v
六、OpenResty
1、介绍
- OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。
- 用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
- OpenResty通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将
Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。 - OpenResty的目标是让你的Web服务直接跑在Nginx服务内部,充分利用 Nginx 的非阻塞 I/O 模
型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及Redis 等都进行一致的高性能响应。
官网:http://openresty.org/en/
2、OpenResty安装
安装wget
yum install wget
下载资源库
wget https://openresty.org/package/centos/openresty.repo
安装OpenResty
yum install openresty
启动OpenResty
cd /usr/local/openresty/nginx/sbin
./nginx
查看是否启动
ps -ef | grep nginx
访问
ip地址:80
3、OpenResty+redis的案例
redis自行安装
进入到配置文件
cd /usr/local/openresty/nginx/conf
修改配置文件
vim nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name www.jowell.com;
root html;
index index.html;
charset utf-8;
location / {
default_type text/plain;
set $redis_key "jowell"; # redis的key
redis_pass 127.0.0.1:6379; #redis地址
error_page 404 = @fetch;
}
location @fetch {
root html;
}
}
}
重新加载配置
./nginx -s reload
创建html测试:
访问
因为redis没设置值,所以正常访问。
redis设置jowell的key
再次访问
这个可以用nginx做限流,比如服务端达到一定访问量,往nginx配置好的key设置值,然后用户到达nginx就限流了,就访问不了服务。当下降到一定访问量的时候,清楚redis的key。
4、openresty-lua-redis案例
1、新建lua文件
cd /usr/local/openresty/nginx
mkdir lua
cd lua
2、编写lua
-- 引用resty的redis
local redis = require "resty.redis";
local red = redis:new();
-- 连接redis
local ok,err = red:connect("127.0.0.1",6379);
-- 判断连接是否正常
if not ok then
ngx.say("faild to connect",err);
return
end
-- 判断设置key是否正常
ok,err = red:set("dKey","dValue");
if not ok then
ngx.say("failed to set dKey",err);
return
end
-- 设置成功
ngx.say("dKey set dValue success")
return
3、进入到conf目录
/usr/local/openresty/nginx/conf
4、新建nginx配置文件:nginx-openresty-lua-redis.conf
vim nginx-openresty-lua-redis.conf
5、配置文件
worker_processes 1;
error_log logs/error_log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
#如下地址可以看成把lua里的内容,当成配置文件内容的一种配置。
location / {
default_type text/html;
content_by_lua_file /usr/local/openresty/nginx/lua/lua-openresty-redis.lua;
}
}
}
7、测试
此时redis空值
访问
ip地址:80
5、nginx+lua+redis限流实战
新建配置文件:
ip-limit-log.lua文件内容:
ngx.log(ngx.INFO,"ip limit log");
ip-limit-access.lua 文件内容
ngx.log(ngx.INFO,"ip limit access");
local redis = require "resty.redis";
local red = redis:new();
--链接redis
red:connect("127.0.0.1",6379);
-- 需要写链接成功的判断。
--判断是否限流
limit = red:get("limit");
if limit == '1' then
return ngx.exit(503);
end
inc = red:incr("testLimit");
if inc <= 2 then
red:expire("testLimit",1);
else
red:set("limit",1);
red:expire("limit",10);
end
新建nginx配置文件
cd /usr/local/openresty/nginx/conf
mkdire nginx-ip-limit.conf
文件内容
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
default_type text/html;
access_by_lua_file /usr/local/openresty/nginx/lua/ip-limit-access.lua;
log_by_lua_file /usr/local/openresty/nginx/lua/ip-limit-log.lua;
proxy_pass http://localhost:8081/; #这里我的tomcat地址,模拟转发请求
}
}
}
重启nginx
当前我的目录
重启
./nginx -p ../../nginx/ -c /usr/local/openresty/nginx/conf/nginx-ip-limit.conf
测试访问
ip:地址:80
各一秒正常访问
快速请求,此时限流了