slave每隔一段时间监听master,当master数据发生改变,master将数据写进二进制日志,slave开启一个io线程请求二进制日志,master在每个io线程上开启dump线程,将二进制日志传给slave,slave接收到二进制日志,将二进制日志放到中继日志,slave开启sql线程,将中继日志中的数据逐一执行
manager定时探测集群中的master节点,当master出现故障,manager会自动将最新数据的slave提升为新的master,然后将其他的slave指向新的master,整个故障转移过程对客户端应用程序完全透明
(1)若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。
(2)无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中,同时Master还会记录修改数据的所有命令并缓存在数据文件中。
(3)后台进程完成缓存操作之后,Master机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
(4)Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Master同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。
(1)由哨兵节点定期监控发现主节点是否出现了故障。每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。
(2)当主节点出现故障,此时哨兵节点会通过Raft算法实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。所以整个运行哨兵的集群的数量不得少于3个节点。
(3)由leader哨兵节点执行故障转移,过程如下:
●将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
●若原主节点恢复也变成从节点,并指向新的主节点;
●通知客户端主节点已经更换。
需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。
Redis集群引入了哈希槽的概念
Redis集群有16384个哈希槽(编号0-16383)
集群的每组节点负责一部分哈希槽
每个Key通过CRC16校验后对16384取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,
然后直接自动跳转到这个对应的节点上进行存取操作
应用程序配置文件优化:
性能优化:
IO多路复用 ? ? ? ? ? ? ? use epoll;
设置工作进程数 ? ? ? ? ? worker_processes ?与CPU数量相同或auto;
工作进程静态绑核 ? ? ? ? worker_cpu_affinity
设置并发 ? ? ? ? ? ? ? ? worker_connections ? ? ? worker_rlimit_nofile
连接保持超时 ? ? ? ? ? ? keepalive_timeout ?服务器超时时间 [客户端超时时间];
网页压缩 ? ? ? ? ? ? ? ? gzip on;
页面缓存时间 ? ? ? ? ? ? expires 时间;
安全优化:
隐藏版本号 ? ? ? ? ? ? ? server_tokens off; ? ? ? 修改源代码
防盗链 ? ? ? ? ? ? ? ? ? rewrite?
设置运行用户/组 ? ? ? ? ?user ?用户名 组名;
限制单个ip的访问频率 ? ? limit_req
限制单个ip的连接数 ? ? ? limit_conn
日志分割 ? ? ? ? ? ? ? ? 脚本 + crontab
系统内核优化:
/etc/sysctl.conf ?内核参数配置文件
net.ipv4.tcp_syncookies = 1 ? ? ? ? ? ? ? ? ?开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击
net.ipv4.tcp_tw_reuse = 1 ? ? ? ? ? ? ? ? ? ?开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接
net.ipv4.tcp_tw_recycle = 1 ? ? ? ? ? ? ? ? ?开启TCP连接中TIME-WAIT sockets的快速回收
net.ipv4.tcp_fin_timeout = 30 ? ? ? ? ? ? ? ?修改系默认的 TIMEOUT 时间(MSL值)
net.ipv4.tcp_max_tw_buckets = 5000 ? ? ? ? ? 系统同时保持TIME-WAIT的最大数量
net.ipv4.ip_local_port_range = 1024 65535 ? ?外向连接的端口范围
net.ipv4.tcp_max_syn_backlog = 8192 ? ? ? ? ?系统能接受的tcp半连接的最大队列数
net.core.somaxconn = 10000 ? ? ? ? ? ? ? ? ? 每一个端口最大的 Listen 监听队列的长度
net.ipv4.tcp_keepalive_time = 1200 ? ? ? ? ? 发送keepalive探测包消息的频率
/etc/security/limits.conf ? 内核限制文件
* ?? ?soft ?? ?noproc?? ??? ??? ?65535 ? ? ?打开的进程数
* ?? ?hard ?? ?noproc?? ??? ??? ?65535
* ?? ?soft ?? ?nofile?? ??? ??? ?65535 ? ? ?打开的文件数
* ?? ?hard ?? ?nofile?? ??? ??? ?65535
* ?? ?soft ?? ?memlock ?? ??? ?unlimited ? ? 不做内存锁定
* ?? ?hard ?? ?memlock ?? ??? ?unlimited
用过哪些nginx模块?
http_gzip_module ? ? ? ? ? ? ?网页压缩模块
http_stub_status_module ? ? ? 状态统计模块
http_auth_basic_module ? ? ? ?网页用户认证模块
http_fastcgi_module ? ? ? ? ? fastcgi转发php-fpm的模块
http_rewrite_module ? ? ? ? ? URL重写模块
http_ssl_module ? ? ? ? ? ? ? https安全加密模块
http_limit_conn_module ? ? ? ?限制最大连接数模块
http_limit_req_module ? ? ? ? 限制最大访问频率模块
http_proxy_module ? ? ? ? ? ? 请求转发模块
http_image_filter_module ? ? ?图片处理模块
http_upstream_*_module ? ? ? ?负载均衡服务器列表模块
stream_*_module ? ? ? ? ? ? ? 四层代理转发模块
tomcat 的优化:
1)配置文件优化
修改 server.xml 文件
maxThreads(最大线程数/并发) ?processorCache(进程缓冲) ?acceptCount(等待队列数) ?enableLookups(关闭DNS反向解析) ?URIEncoding(网页字符集编码UTF-8) maxKeepAliveRequests(长连接最大请求数) ?connectionTimeout(连接超时时间) ?compression(开启页面压缩)
2)系统内核优化
/etc/security/limits.conf ? ? nofile ?nproc ?memlock
/etc/sysctl.conf ? net.ipv4.tcp_tw_reuse=1 ? net.ipv4.tcp_tw_recycle=1 ? net.ipv4.tcp_fin_timeout=30 ?
? ? ? ? ? ? ? ? ? ?net.ipv4.tcp_max_tw_buckets=5000 ? ?net.ipv4.ip_local_port_range=1024 65535?
3)JVM优化
在 catalina.sh 中设置 JAVA_OPTS 参数
JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -XX:PermSize=1024m -XX:MaxPermSize=1024m -Xmn768m"
-server ?表示启用JDK的Server模式,实现在多核服务器性能更佳
-Xms2048m -Xmx2048m ?设置JVM堆内存初始值和最大最一样大,一般设置为物理内存的 1/2
-XX:PermSize=1024m -XX:MaxPermSize=1024m ? 设置永久代(非堆内存)初始值和最大最一样大,一般设置为物理内存的 1/4
初始值和最大最设置一样大的原因:可以减少GC次数和内存伸缩带来的频繁内存申请,从而减少一定的系统开销。
-Xmn 设置JVM堆内存新生代的大小,一般设置为堆内存的 3/8
-XX:ParallelGCThreads=2 ? 设置并行GC(垃圾回收)线程数,提高垃圾回收效率
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/tomcat/temp/oom.hprof ?设置进程发生OOM异常退出会进行DUMP备份
-XX:+DisableExplicitGC ?禁止调用System.gc()方法,防止误调用系统gc方法导致系统的JVM堆内存大起大落而使系统响应效率严重降低
Nginx的优点:
●工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构。Nginx正则规则比HAProxy更为强大和灵活。
●Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,LVS对网络稳定性依赖比较大,稳定要求相对更高。
●Nginx安装和配置、测试比较简单、方便,有清晰的日志用于排查和管理,LVS的配置、测试就要花比较长的时间了。
●可以承担高负载压力且稳定,一般能支撑几万次的并发量,负载度比LVS相对小些。
●Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等。
●Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。
●Nginx作为Web正向加速缓存越来越成熟了,速度比传统的Squid服务器更快,很多场景下都将其作为向代理加速器。
●Nginx作为静态网页和图片服务器,这方面的性能非常优秀,同时第三方模块也很多。
Nginx的缺点:
●Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些。
●对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。
●不支持Session的直接保持,需要通过ip_hash和cookie的引导来解决。
LVS的优点:
●抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生。因此负载均衡软件里的性能最强的,对内存和cpu资源消耗比较低。
●LVS工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案。
●无流量,LVS只分发请求,而流量并不从它本身出去,这点保证了均衡器IO的性能不会收到大流量的影响。
●应用范围较广,因为LVS工作在4层,所以它几乎可对所有应用做负载均衡,包括http、数据库等。
LVS的缺点:
●软件本身不支持正则表达式处理,不能做动静分离。相对来说,Nginx/HAProxy+Keepalived则具有明显的优势。
●如果是网站应用比较庞大的话,LVS/DR+Keepalived实施起来就比较复杂了。相对来说,Nginx/HAProxy+Keepalived就简单多了。
HAProxy的优点:
●HAProxy也是支持虚拟主机的。
●HAProxy支持8种负载均衡策略。
●HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,Cookie的引导,同时支持通过获取指定的url来检测后端服务器的状态。
●HAProxy跟LVS类似,本身就只是一款负载均衡软件,单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
●HAProxy支持TCP协议的负载均衡转发。
?
(1)NAT 地址转换
调度器会作为所有节点服务器的默认网关,也是客户端的访问入口和节点服务器返回响应消息的出口,所以调度器会承载双向流量的负载压力,可能会为整个群集的性能瓶颈。由于节点服务器都会处于内网环境,使用私网IP,所以具有一点的安全行。
(2)TUN IP隧道 ? IP Tunnel ?
调度器仅作为客户端的访问入口,节点服务器的响应消息是直接返回客户端的,不需要经过调度器。但是由于节点服务器需要部署在不同的公网环境,所以要有独立的公网IP,而且调度器与节点服务器是通过专用的IP隧道实现相互通信,因此IP隧道模式的成本较高、安全性较低,且数据IP隧道传输的过程中需要额外的封装和解封装,性能也会受到一定的影响。
(3)DR 直接路由 ?Direct Routing
调度器仅作为客户端的访问入口,节点服务器的响应消息是直接返回客户端的,不需要经过调度器。(与NAT模式的区别)
节点服务器与调度器是部署在同一个物理网络里,因此不需要建议专用的IP隧道。(与IP隧道模式的区别)
DR模式是企业首选的LVS模式。
NAT:通过网络地址转换实现的虚拟服务器,大并发访问时,调度器的性能成为瓶颈
DR:使用路由技术实现虚拟服务器,节点服务器需要配置VIP,注意MAC地址广播
TUN:通过隧道方式实现虚拟服务器。
1、NAT模式(VS-NAT)
原理:首先负载均衡器接收到客户的请求数据包时,根据调度算法决定将请求发送给哪个后端的真实服务器(RS)。然后负载均衡器就把客户端发送的请求数据包的目标IP地址及端口改成后端真实服务器的IP地址(RIP)。真实服务器响应完请求后,查看默认路由,把响应后的数据包发送给负载均衡器,负载均衡器在接收到响应包后,把包的源地址改成虚拟地址(VIP)然后发送回给客户端。
优点:集群中的服务器可以使用任何支持TCP/IP的操作系统,只要负载均衡器有一个合法的IP地址。
缺点:扩展性有限,当服务器节点增长过多时,由于所有的请求和应答都需要经过负载均衡器,因此负载均衡器将成为整个系统的瓶颈。
2、直接路由模式(VS-DR)
原理:首先负载均衡器接收到客户的请求数据包时,根据调度算法决定将请求发送给哪个后端的真实服务器(RS)。然后负载均衡器就把客户端发送的请求数据包的目标MAC地址改成后端真实服务器的MAC地址(R-MAC)。真实服务器响应完请求后,查看默认路由,把响应后的数据包直接发送给客户端,不需要经过负载均衡器。
优点:负载均衡器只负责将请求包分发给后端节点服务器,而RS将应答包直接发给用户。所以,减少了负载均衡器的大量数据流动,负载均衡器不再是系统的瓶颈,也能处理很巨大的请求量。
缺点:需要负载均衡器与真实服务器RS都有一块网卡连接到同一物理网段上,必须在同一个局域网环境。
3、IP隧道模式(VS-TUN)
原理:首先负载均衡器接收到客户的请求数据包时,根据调度算法决定将请求发送给哪个后端的真实服务器(RS)。然后负载均衡器就把客户端发送的请求报文封装一层IP隧道(T-IP)转发到真实服务器(RS)。真实服务器响应完请求后,查看默认路由,把响应后的数据包直接发送给客户端,不需要经过负载均衡器。
优点:负载均衡器只负责将请求包分发给后端节点服务器,而RS将应答包直接发给用户。所以,减少了负载均衡器的大量数据流动,负载均衡器不再是系统的瓶颈,也能处理很巨大的请求量。
缺点:隧道模式的RS节点需要合法IP,这种方式需要所有的服务器支持“IP Tunneling”。
轮询(Round Robin);
加权轮询(Weighted Round Robin);
最少连接(Least Connections);
加权最少连接(Weighted Least Connections);
源地址哈希值(source hash)
现象:主服务器和备服务器同时拥有VIP
原因:因为主服务器和备服务器之间的通信链路中断,导致备服务器无法收到主服务器发送的VRRP通告消息,备服务器误认为主服务器故障了并通过IP命令生成VIP
解决:关闭主服务器或备服务器其中一个的keepalived服务
预防:
(1)主服务器和备服务器之间添加双链路通信
(2)在主服务器上添加脚本进行判断与备服务器通信链路是否中断,如果确实是链路中断则自行关闭keepalived服务
(3)利用第三方应用或监控系统检测是否发送脑裂故障,如果发送脑裂故障则通过第三方应用或监控系统来关闭主服务器或备服务器上的keepalived服务
四层反向代理:基于 IP + PORT 实现的代理转发(根据IP和PORT来转发请求),通常用于做客户端的访问入口和负载均衡器等应用场景。
配置:
1)编译安装需要 ./configure --with-stream 添加四层代理模块
2)在 http 同层级,一般在 http 配置块上面添加 stream 配置块,在里面定义服务器池、监听端口和转发配置
stream {
? ? upstream backend {
?? ? ? ?server IP1:PORT1 weight=1;
?? ? ? ?....
? ? ? ? [调度策略];
?? ?}
? ? server {
?? ? ? ?listen PROT;
?? ? ? ?proxy_pass backend; ? ? ? #注:四层代理不需要添加协议
?? ?}
}
http {....}
七层反向代理:基于 http、https、mail 等七层应用协议的代理转发(根据用户访问请求的URL路径来转发请求),通常用于动静分离等应用场景。
配置:
1)在 http 配置块中设置 upstream 定义 后端/上游服务器池的名称和节点参数
http {
? ? ....
? ? upstream backend {
?? ? ? ?server IP1:PORT1 weight=1;
?? ? ? ?....
? ? ? ? [调度策略];
?? ?}
2)在 server 配置块中用 location 匹配用户访问请求的URL路径,使用 proxy_pass 基于协议转发请求
? ? server {
?? ? ? ?location ~ .*\./jsp {
?? ??? ? ? ?proxy_pass http://backend;
?? ??? ?
? ? ? ? ? ? proxy_set_header HOST $host;
? ? ? ? ? ? proxy_set_header X-Real-IP $remote_addr;
? ? ? ? ? ? proxy_set_header X-Forworded-For $proxy_add_x_forwarded_for;
?? ??? ?}
?? ?}
}
Keepalived首先做初始化先检查state状态,master为主服务器,backup为备服务器。
然后再对比所有服务器的priority,谁的优先级高谁是最终的主服务器。
优先级高的服务器会通过ip命令为自己的电脑配置一个提前定义好的浮动IP地址。
抢占模式即MASTER从故障中恢复后,会将VIP从BACKUP节点中抢占过来。非抢占模式即MASTER恢复后不抢占BACKUP升级为MASTER后的VIP
非抢占式俩节点state必须为bakcup,且必须配置nopreempt。
注意:这样配置后,我们要注意启动服务的顺序,优先启动的获取master权限,与优先级没有关系了。
ctime(status time):
当修改文件的权限或者属性的时候,就会更新这个时间,ctime并不是create time,更像是change time,
只有当更新文件的属性或者权限的时候才会更新这个时间,但是更改内容的话是不会更新这个时间。
atime(accesstime):
当使用这个文件的时候就会更新这个时间。
mtime(modification time):
当修改文件的内容数据的时候,就会更新这个时间,而更改权限或者属性,mtime不会改变,这就是和ctime的区别。
从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。
rewrite 对访问的域名或者域名内的URL路径地址重写
location 对访问的路径做访问控制或者代理转发