一、nginx入门
- 什么是nginx?
nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定,所以现在很多知名的公司都在使用nginx。
Nginx相较于Apache、lighttpd具有占有内存少,稳定性高等优势。它最常的用途是提供反向代理服务。 - nginx应用场景:
- http服务器(带html目录,可以把静态资源放到该目录下即可访问静态html)。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
- 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
- 反向代理,负载均衡(好处:不暴露真实IP)。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
- Windows环境下安装Nginx:
- 下载windows版nginx:http://nginx.org/en/download.html
- 解压下载的zip文件,运行nginx.exe(注:存放目录中不允许有中文,否则会运行不成功),点击nginx.exe后会弹出命令窗口然后关闭,这是正常现象,验证是否成功,查看logs目录下的error.log有无报错,若无报错,浏览器访问:http://127.0.0.1/ 出现下图即表示成功:
- 若想使用nginx做http静态服务器,可以把静态资源放置在html目录下(默认是该目录),访问方式方式同tomcat等应用服务器。
- 关闭nginx:
- 使用命令行,在nginx.exe同级目录开启命令行,键入:
nginx.exe -s stop
进行停止。 - 使用任务管理器,找到nginx.exe进行KILL掉。
- nginx优缺点:
- 占内存小,可以实现高并发连接、处理响应快。
- 可以实现http服务器、虚拟主机、反向代理、负载均衡。
- nginx配置简单。
- 可以不暴露真实服务器IP地址。
- nginx.conf理解:
- nginx.conf文件的结构:
nginx的配置由特定的标识符(指令符)分为多个不同的模块。
指令符分为简单指令和块指令:
1. 简单指令格式:[name parameters;]
2. 块指令格式:和简单指令格式有一样的结构,但其结束标识符不是分号,而是大括号{},块指令内部可以包含simple directives 和block directives, 可以称块指令为上下文(e.g. events, http, server, location)
conf文件中,所有不属于块指令的简单指令都属于main上下文的,http块指令属于main上下文,server块指令http上下文。 - 配置静态访问:
Web server很重要一部分工作就是提供静态页面的访问,例如images, html page。nginx可以通过不同的配置,根据request请求,从本地的目录提供不同的文件返回给客户端。
打开安装目录下的nginx.conf文件,默认配置文件已经在http指令块中创建了一个空的server块,在nginx-1.8.0中的http块中已经创建了一个默认的server块。内容如下:
server {
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;
}
}
- nginx实现反向代理:
- 什么是反向代理?
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
例:
启动一个Tomcat 127.0.0.1:8080
使用nginx反向代理 www.chauncywang.com 直接跳转到127.0.0.1:8080 - 实现反向代理:
- 在本机C:\Windows\System32\drivers\etc\hosts文件中新增两个域名,映射127.0.0.1:
127.0.0.1 www.chauncywang1.com
127.0.0.1 www.chauncywang2.com
- 启动两个tomcat服务器,分别设置其启动端口为:8080、8888.
- 修改nginx.conf文件,监听以上两个域名,实现反向代理8080、8888端口的服务:
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.chauncywang1.com;
location / {
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 80;
server_name www.chauncywang2.com;
location / {
proxy_pass http://127.0.0.1:8888;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- 验证:使用浏览器分别访问以上两个域名跳转到不同端口的服务。
- nginx实现负载均衡:
- 什么是负载均衡?
负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
目的:减轻单台服务器压力。高并发解决方案之一。 - 负载均衡策略:
- 轮询(默认):
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
nginx.conf配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream myhttpServer{
server 127.0.0.1:8080;
server 127.0.0.1:8888;
}
server {
listen 80;
server_name www.chauncywang.com;
location / {
proxy_pass http://myhttpServer;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- 指定权重:
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
nginx.conf配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream myhttpServer{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8888 weight=3;
}
server {
listen 80;
server_name www.chauncywang.com;
location / {
proxy_pass http://myhttpServer;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- IP绑定 ip_hash(用的不多,但是可以解决session共享问题):
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session共享的问题,但是有缺陷,本质相当于未实现负载均衡,所以一般采用的不多。
- nginx宕机容错配置:
配置连接、发送、读取超时时间为1s,如果超时选择其他机器。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream myhttpServer{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8888 weight=1;
}
server {
listen 80;
server_name www.chauncywang.com;
location / {
proxy_pass http://myhttpServer;
index index.html index.htm;
proxy_connect_timeout 1;
proxy_send_timeout 1;
proxy_read_timeout 1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- 解决负载均衡问题的手段:
- LVS:
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
基于不同的网络技术,LVS支持多种负载均衡机制。包括:VS/NAT(基于网络地址转换技术)、VS/TUN(基于IP隧道技术)和VS/DR(基于直接路由技术)。 - Tengine(taobao开发的Nginx升级版):
Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如:淘宝网、天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。
从2011年12月开始,Tengine成为一个开源项目,Tengine团队在积极地开发和维护着它。 - HAProxy(高可用、负载均衡):
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进架构中,同时可以保护web服务器不被暴露到网络上。 - F5(属于硬负载均衡,硬件层面解决负载均衡问题):
F5负载均衡产品是常用的网络负载控制的产品之一,其功能强大,不仅包含负载均衡还包括应用交换、会话交换、状态监控、智能网络地址转换、通用持续性、响应错误处理、IPv6网关、高级路由、智能端口镜像、SSL加速、智能HTTP压缩、TCP优化、第7层速率整形、内容缓冲、内容转换、连接加速、高速缓存、Cookie加密、选择性内容加密、应用攻击过滤、拒绝服务(DoS)攻击和SYN Flood保护、防火墙过滤等功能。
PS:F5硬负载虽然功能强大但也较贵,一般非土豪不建议考虑。 - Keepalived(故障转移,备机,linux环境下的组件):
这里说的keepalived不是apache或者tomcat等某个组件上的属性字段,它也是一个组件,可以实现web服务器的高可用(HA highavailably)。它可以检测web服务器的工作状态,如果该服务器出现故障被监测到,将其剔除服务器群中,直至正常工作后,keepalived会自动检测到并加入到服务器群里面。实现主备服务器发生故障时ip瞬时无缝交接。它是LVS集群节点健康检测的一个用户空间守护进程,也是LVS的引导故障转移模块(director failover)。Keepalived守护进程可以检查LVS池的状态。如果LVS服务器池当中的某一个服务器宕机了。keepalived会通过一个setsockopt呼叫通知内核将这个节点从LVS拓扑图中移除。 - Memcached(分布式内存对象缓存系统,实现内存级别的session共享):
memcached是一个高性能分布式内存对象缓存系统,当初是Danga Interactive为了LiveJournal所发展开发的系统。 - Terracotta(java集群平台):
Terracotta是一款由美国Terracotta公司开发的著名开源Java集群平台。它在JVM与Java应用之间实现了一个专门处理集群功能的抽象层,以其特有的增量检测、智能定向传送、分布式协作、服务器镜像、分片等技术,允许用户在不改变现有系统代码的情况下实现Java应用的集群。支持数据的持久化、session的复制以及高可用(HA)。详情参考:https://topmanopensource.iteye.com/blog/1911679
- nginx搭建网关接口系统,解决请求跨域问题:
server {
listen 80;
server_name www.chauncy.com;
location /A {
proxy_pass http://a.a.com:8080/A;
index index.html index.htm;
}
location /B {
proxy_pass http://b.b.com:8888/B;
index index.html index.htm;
}
}
- nginx配置防盗链:
location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ {
valid_referers blocked http://www.chauncywang.com www.chauncywang.com;
if ($invalid_referer) {
return 403;
}
}
- nginx配置DDOS:
- 限制请求速度:
设置Nginx、Nginx Plus的连接请求在一个真实用户请求的合理范围内。比如,如果你觉得一个正常用户每两秒可以请求一次登录页面,你就可以设置Nginx每两秒钟接收一个客户端IP的请求(大约等同于每分钟30个请求)。
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
...
location / {
limit_req zone=one;
...
}
}
- 设置建议:
设置Nginx、Nginx Plus的连接数在一个真实用户请求的合理范围内。比如,你可以设置每个客户端IP连接/…不可以超过10个。
PS:一般防DDOS都是通过nginx这种中间件防,不会从代码层面防。
二、Linux操作nginx:
- linux安装nginx:
在Centos下,yum源不提供nginx的安装,可以通过切换yum源的方法获取安装。也可以通过直接下载安装包的方法,以下命令均需root权限执行:
首先安装必要的库(nginx 中gzip模块需要 zlib 库,rewrite模块需要 pcre 库,ssl 功能需要openssl库)。选定/usr/local为安装目录,以下具体版本号根据实际改变。
- 安装PCRE库:
$ cd /usr/local/
$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz
$ tar -zxvf pcre-8.36.tar.gz
$ cd pcre-8.36
$ ./configure
$ make
$ make install
- ./configure报错:
configure: error: You need a C++ compiler for C++ support.
解决办法:
yum install -y gcc gcc-c++ - 安装zlib库:
$ cd /usr/local/
$ wget http://zlib.net/zlib-1.2.8.tar.gz
$ tar -zxvf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure
$ make
$ make install
- 安装ssl:
$ cd /usr/local/
$ wget http://www.openssl.org/source/openssl-1.0.1j.tar.gz
$ tar -zxvf openssl-1.0.1j.tar.gz
$ cd openssl-1.0.1j
$ ./config
$ make
$ make install
- 安装nginx:
$ cd /usr/local/
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar -zxvf nginx-1.8.0.tar.gz
$ cd nginx-1.8.0
$ ./configure --prefix=/usr/local/nginx
$ make
$ make install
- 安装常见错误:
Nginx启动提示找不到libpcre.so.1解决方法
如果是32位系统
[root@lee ~]# ln -s /usr/local/lib/libpcre.so.1 /lib
如果是64位系统
[root@lee ~]# ln -s /usr/local/lib/libpcre.so.1 /lib64
然后在启动nginx就OK了
[root@lee ~]# /usr/local/nginx/sbin/nginx
- 启动nginx:
$ /usr/local/nginx/sbin/nginx
- 检查是否启动成功:
打开浏览器访问此机器的 IP,如果浏览器出现 Welcome to nginx! 则表示 Nginx 已经安装并运行成功。
常用命令:
重启:
$ /usr/local/nginx/sbin/nginx 启动命令
重启:
$ /usr/local/nginx/sbin/nginx –s reload
停止:
$ /usr/local/nginx/sbin/nginx –s stop
测试配置文件是否正常:
$ /usr/local/nginx/sbin/nginx –t
强制关闭:
$ pkill nginx - 启动Nginx + Keepalived高可用:
- Keepalived简介:
Keepalived是Linux下一个轻量级别的高可用解决方案。高可用(High Availability,HA),其实两种不同的含义:广义来讲,是指整个系统的高可用性,狭义来讲就是主机的冗余与接管。
它与HeartBeat RoseHA 实现类似的功能,都可以实服务或网络的高可用,但是又有差别,HeartBeat是一个专业的、功能完善的高可用软件,它提供了HA软件所需的基本功能,比如:心跳检测、资源接管,检测集群中的服务,在集群节点转移共享IP地址的所有者等等。HeartBeat功能强大,但是部署和使用相对比较麻烦。
与HeartBeat相比,Keepalived主要是通过虚拟路由冗余来实现高可用功能,虽然它没有HeartBeat功能强大,但是Keepalived部署和使用非常简单,所有的配置只需要一个配置文件即可完成。 - Keepalived是什么?
Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四、第五层交换机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现故障的服务从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。
后来Keepalived又加入了VRRP的功能,VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)出现的目的是解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,因此Keepalived一方面具有服务器状态检测和故障隔离功能,另一方面也有HA Cluster功能。
Keepalived心跳检测,自动重启,不仅可用于nginx还可用用于tomcat、mysql等。
Keepalived是一个免费开源的,用C编写的类似于layer3, 4 & 7交换机制软件,具备我们平时说的第3层、第4层和第5层交换机的功能。主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。
上图是Keepalived的功能体系结构,大致分两层:用户空间(user space)和内核空间(kernel space)。
内核空间:主要包括IPVS(IP虚拟服务器,用于实现网络服务的负载均衡)和NETLINK(提供高级路由及其他相关的网络功能)两个部份。
用户空间:
1. WatchDog:负载监控checkers和VRRP进程的状况。
2. VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均衡器,则VRRP不是必须的。
3. Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
4. IPVS wrapper:用户发送设定的规则到内核ipvs代码。
5. Netlink Reflector:用来设定vrrp的vip地址等。
Keepalived的所有功能是配置keepalived.conf文件来实现的。 - VRRP协议与工作原理:
在现实的网络环境中,主机之间的通信都是通过配置静态路由或者(默认网关)来完成的,而主机之间的路由器一旦发生故障,通信就会失效,因此这种通信模式当中,路由器成了一个单点瓶颈,为了解决这个问题,就引入了VRRP协议。
熟悉网络的人都知道VRRP是一种主备模式的协议,通过VRRP可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信,这其中涉及到两个概念:物理路由器和虚拟路由器。
VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由,这个虚拟路由器通过虚拟IP(一个或多个)对外提供服务,而在虚拟路由器内部十多个物理路由器协同工作,同一时间只有一台物理路由器对外提供服务,这台物理路由设备被称为:主路由器(Master角色),一般情况下Master是由选举算法产生,它拥有对外服务的虚拟IP,提供各种网络功能,如:APP请求,ICMP数据转发等,而且其它的物理路由器不拥有对外的虚拟IP,也不提供对外网络功能,仅仅接收Master的VRRP状态通告信息,这些路由器被称为"Backup的角色",当主路由器失败时,处于Backup角色的备份路由器将重新进行选举,产生一个新的主路由器进入Master角色,继续提供对外服务,整个切换对用户来说是完全透明的。
每个虚拟路由器都有一个唯一的标识号,称为VRID,一个VRID与一组IP地址构成一个虚拟路由器,在VRRP协议中,所有的报文都是通过IP多播方式发送的,而在一个虚拟路由器中,只有处于Master角色的路由器会一直发送VRRP数据包,处于Backup角色的路由器只会接收Master发过来的报文信息,用来监控Master运行状态,一般不会发生Backup抢占的情况,除非它的优先级更高,而当Master不可用时,Backup也就无法收到Master发过来的信息,于是就认定Master出现故障,接着多台Backup就会进行选举,优先级最高的Backup将称为新的Master,这种选举角色切换非常之快,因而保证了服务器的持续可用性。 - Keepalived的工作原理:
以上是Keepalived通过VRRP实现高可用性的工作原理,而Keepalived作为一个高性能集群软件,它还能实现对集群中服务器运行状态的监控以及故障隔离,其原理如下:
Keepalived工作在TCP/IP参考模型的三层、四层、五层,分别对应:网际层、传输层、应用层,根据TCP、IP参数模型各层所能实现的功能,Keepalived运行机制为:
- 在网际层:网际层包含:IP(互连网络协议)、ICMP(互联网络可控制报文协议)、ARP(地址解析协议)、RARP(反向地址转换协议),Keepalived在网络层采用最常见的工作方式是通过ICMP协议向服务器集群中的每一个节点发送一个ICMP数据包(类似于ping命令的功能),如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived将报告这个节点失效,并从服务器集群中剔除故障节点。
- 在传输层:提供了两个主要的协议:传输控制协议TCP和用户数据协议UDP,传输控制协议TCP可以提供可靠的数据输出服务、IP地址和端口,代表TCP的一个连接端,要获取TCP服务,需要在发送机的一个端口和接收机的一个端口上建立连接,而Keepalived在传输层里利用了TCP协议的端口连接和扫描技术来判断集群节点的端口是否正常,比如对于常见的WEB服务器80端口,或者SSH服务22端口,Keepalived一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉。
- 在应用层:可以运行FTP、TELNET、SMTP、DNS等各种不同类型的高层协议,Keepalived的运行方式也更加全面化和复杂化,用户可以通过自定义Keepalived工作方式,例如:可以通过编写程序或者脚本来运行Keepalived,而Keepalived将根据用户的设定参数检测各种程序或者服务是否运行正常,如果Keepalived的检测结果和用户设定的不一致时,Keepalived将把对应的服务器从服务器集群中剔除。
- 安装keepalived:
下载keepalived地址:http://www.keepalived.org/download.html
解压安装命令:
tar -zxvf keepalived-1.2.18.tar.gz -C /usr/local/
yum install -y openssl openssl-devel(需要安装一个软件包)
cd keepalived-1.2.18/ && ./configure --prefix=/usr/local/keepalived
make && make install - keepalived安装成Linux系统服务:
将keepalived安装成Linux系统服务,因为没有使用keepalived的默认安装路径(默认路径:/usr/local),安装完成之后,需要做一些修改工作:
首先创建文件夹,将keepalived配置文件进行复制:
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
然后复制keepalived脚本文件:
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
ln -s /usr/local/sbin/keepalived /usr/sbin/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/
可以设置开机启动:chkconfig keepalived on
安装完毕! - keepalived 常用命令:
service keepalived start
service keepalived stop - 配置nginx主备自动重启:
对配置文件进行修改:vim /etc/keepalived/keepalived.conf
keepalived.conf配置文件说明:
- Master:
! Configuration File for keepalived
global_defs {
router_id bhz005 ##标识节点的字符串,通常为hostname
}
## keepalived 会定时执行脚本并且对脚本的执行结果进行分析,动态调整vrrp_instance的优先级。这里的权重weight 是与下面的优先级priority有关,如果执行了一次检查脚本成功,则权重会-20,也就是由100 - 20 变成了80,Master 的优先级为80 就低于了Backup的优先级90,那么会进行自动的主备切换。
如果脚本执行结果为0并且weight配置的值大于0,则优先级会相应增加。
如果脚本执行结果不为0 并且weight配置的值小于0,则优先级会相应减少。
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" ##执行脚本位置
interval 2 ##检测时间间隔
weight -20 ## 如果条件成立则权重减20(-20)
}
## 定义虚拟路由 VI_1为自定义标识。
vrrp_instance VI_1 {
state MASTER ## 主节点为MASTER,备份节点为BACKUP
## 绑定虚拟IP的网络接口(网卡),与本机IP地址所在的网络接口相同(我这里是eth6)
interface eth6
virtual_router_id 172 ## 虚拟路由ID号
mcast_src_ip 192.168.1.172 ## 本机ip地址
priority 100 ##优先级配置(0-254的值)
Nopreempt ##
advert_int 1 ## 组播信息发送间隔,俩个节点必须配置一致,默认1s
authentication {
auth_type PASS
auth_pass bhz ## 真实生产环境下对密码进行匹配
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.1.170 ## 虚拟ip(vip),可以指定多个
}
}
- Backup:
! Configuration File for keepalived
global_defs {
router_id bhz006
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eth7
virtual_router_id 173
mcast_src_ip 192.168.1.173
priority 90 ##优先级配置
advert_int 1
authentication {
auth_type PASS
auth_pass bhz
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.1.170
}
}
- nginx_check.sh 脚本:
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
- ginx_check.sh脚本授权。赋予可执行权限:chmod +x /etc/keepalived/nginx_check.sh
- 分别启动两台机器的nginx后,启动两台机器的keepalived
/usr/local/nginx/sbin/nginx
service keepalived start
ps -ef | grep nginx
ps -ef | grep keepalived
- 启动完成后,进行测试,先看一下俩台机器的ip a 命令下 都会出现一个虚拟ip,停掉 一个机器的keepalived,命令:service keepalived stop。结果:发现当前停掉的机器已经不可用,keepalived会自动切换到另一台机器上。
- nginx配置负载均衡:
搭建好Nginx + Keepalived后,本地创建项目,运行两个不同端口的服务,修改nginx配置文件,实现Nginx负载均衡+ Keepalived。
三、集群情况下Session共享解决方案
- 因为Session是存在于服务器端的,只要做了集群肯定是要解决Session共享的问题。
- Session共享解决方案:
- nginx或者haproxy做的负载均衡:
用Nginx 做的负载均衡可以添加ip_hash这个配置,
用haproxy做的负载均衡可以用 balance source这个配置。
从而使同一个ip的请求发到同一台服务器。
这种方式不靠谱,相当于未实现负载均衡,所以市面上应用的不多。 - 利用数据库同步session:
这种方式也可以解决session共享的问题,但是更不靠谱,基本不会采用这种方式。 - 利用cookie同步session数据,原理图如下:
这种方式也不靠谱,缺点:安全性差、http请求都需要带参数增加了带宽消耗。 - 使用Session集群存放Redis(一般电商项目都采用此方式):
- 原理(重写Session):多台服务器集群肯定连接同一个redis,当用户第一次请求到一台服务器,创建session,往redis存一份,第二次请求到另一台服务器,先从session里面找,没找到从redis中找,找到后创建session。
- 项目搭建:
- 创建springboot项目。
- 引入maven依赖:
<!--spring boot 与redis应用基本环境配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用,不然启动Spring boot会报错 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
- 创建SessionConfig:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
//这个类用配置redis服务器的连接
//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
// 冒号后的值为没有配置文件时,制动装载的默认值
@Value("${redis.hostname:localhost}")
String HostName;
@Value("${redis.port:6379}")
int Port;
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
connection.setPort(Port);
connection.setHostName(HostName);
return connection;
}
}
- 初始化Session:
//初始化Session配置
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer{
public SessionInitializer() {
super(SessionConfig.class);
}
}
- 控制器层代码:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@EnableAutoConfiguration
@RestController
public class SessionController {
public static void main(String[] args) {
SpringApplication.run(SessionController.class, args);
}
@Value("${server.port}")
private String port;
@RequestMapping("/index")
public String index() {
return "server-------port:" + port;
}
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request, String sessionKey, String sessionValue) {
HttpSession session = request.getSession(true);
session.setAttribute(sessionKey, sessionValue);
return "success,port:" + port;
}
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request, String sessionKey) {
HttpSession session =null;
try {
session = request.getSession(false);
} catch (Exception e) {
e.printStackTrace();
}
String value=null;
if(session!=null){
value = (String) session.getAttribute(sessionKey);
}
return "sessionValue:" + value + ",port:" + port;
}
}
三、高并发解决方案:
- 业务数据库:数据切分(分区分表分库)、读写分离。
- 业务应用:逻辑代码优化(算法优化)、公共数据缓存(分布式缓存)、服务分布式部署、网页静态化(动静分离)。
- 应用服务器 :反向静态代理、配置优化、负载均衡(apache分发,多tomcat实例)、集群。
- 系统环境:JVM调优。
- 页面优化:减少页面连接数、页面尺寸瘦身。
- CDN加速。