DNS域名解析过程:
高可用与高并发:系统设计不仅需要考虑实现业务功能,还要保证系统高并发、高可用、高可靠等。同时还应考虑系统容量规划(流量、容量等)、SLA指定(吞吐量、响应时间、可用性、降级方案等)、监控报警(机器负载、响应时间、可用率等)、应急预案(容灾、降级、限流、隔离、切流量、可回滚等)。
业务设计原则:
- 防重设计:页面请求防止重复提交,可以采用防重key、放重表、Token等。采用图形验证,防止机器攻击。
- **幂等设计:**消息中间件中应该注意因网络延迟的原因,导致消息重复消费。分布式系统中,保证生成的订单号唯一性,定时Job执行的幂等性问题等。第三方支付接口,在回调接口中,应该注意网络延迟,没有及时返回给第三方支付平台,注意回调幂等性问题。
- 流程定义: 复用流程系统,提供个性化的流程服务。
- ……
负载均衡:是一种计算机系统和网络管理的策略,旨在有效地分配工作负载或流量到多个资源,以确保系统资源充分利用、提高性能、增强可用性,以及防止某些资源过载。这通过在多个服务器、计算机或网络设备之间智能地分发任务或请求,以达到平衡系统负载的目的。
使用负载均衡后,实际用到的服务器会被集群多台,那么这时候就会产生很多分布式相关问题,比如:
- 分布式Session一致性问题
- 幂等性问题
- 分布式生成全局订单ID问题
Nginx:是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器。
**一般用户七层负载均衡,其吞吐量有一定的限制,**为了提高整体的吞吐量,会在DNS和Nginx之间引入LVS(软件负载均衡器)、F5(硬负载均衡器)可以做四层负载均衡,首先DNS解析到LVS(F5),让后LVS(F5)转发给Nginx,再有Nginx转发给真实的服务器。
- 四层负载均衡:在网络模型中的传输层中,基于主要是基于tcp协议报文实现负载均衡(比如LVS、haproxy就是四层负载均衡器),使用改写报文的源地址和目的地址。
- 七层负载均衡:在网络模型中应用层中,基于URL或者HTTP协议实现负载均衡,Web服务器。
目录如下:
Nginx-
|_ conf 配置目录
|_ contrib
|_ docs 文档目录
|_ logs 日志目录
|_ temp 临时文件目录
|_ html 静态页面目录
|_ nginx.exe 主程序
Nginx应用场景:
- http服务器:Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
- 虚拟主机:可以实现在一台服务器虚拟出多个网站,例如个人网站使用的虚拟机。
- 反向代理,负载均衡:当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会应为某台服务器负载高宕机而某台服务器闲置的情况。
- nginx 中也可以配置安全管理、比如可以使用Nginx搭建API接口网关,对每个接口服务进行拦截。
Nginx虚拟主机:
- 基于域名的虚拟主机,通过域名来区分虚拟主机(主要应用外部网站)
#配置虚拟主机aaa.test.com
server {
#监听的ip和端口,配置本机ip和端口
listen 192.168.25.128:80;
#虚拟主机名称是aaa.test.com,请求域名aaa.test.com的url将由此server配置解析
server_name aaa.test.com;
#所有的请求都以/开始,所有的请求都可以匹配此location
location / {
#使用root指令指定虚拟主机目录即网页存放目录
#比如访问http://ip/test.html将找到/usr/local/aaa_html/test.html
#比如访问http://ip/item/test.html将找到/usr/local/aaa_html/item/test.html
root /usr/local/aaa_html;
#指定欢迎页面,按从左到右顺序查找
index index.html index.htm;
}
}
#配置虚拟主机bbb.test.com
server {
listen 192.168.25.128:80;
server_name bbb.test.com;
location / {
root /usr/local/bbb_html;
index index.html index.htm;
}
}
- 基于端口的虚拟主机,通过端口来区分虚拟主机(主要应用于公司内部网站,外部网站的管理后台)
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#配置虚拟主机
server {
#监听的ip和端口,配置80
listen 80;
#虚拟主机名称这里配置ip地址
server_name 192.168.101.3;
#所有的请求都以/开始,所有的请求都可以匹配此location
location / {
#使用root指令指定虚拟主机目录即网页存放目录
#比如访问http://ip/test.html将找到/usr/local/html3/test.html
#比如访问http://ip/item/test.html将找到/usr/local/html3/item/test.html
root /usr/local/nginx/html80;
#指定欢迎页面,按从左到右顺序查找
index index.html index.htm;
}
}
#配置虚拟主机
server {
listen 8080;
server_name 192.168.101.3;
location / {
root /usr/local/nginx/html8080;
index index.html index.htm;
}
}
}
Nginx反向代理:指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
例子:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
}
Location指令:根据用户请求的URI来执行不同的应用,也就是根据用户请求的网站URL进行匹配,匹配成功即进行相关的操作。
- 以
=
开头表示精确匹配,如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。 ^~
开头表示uri以某个常规字符串开头,不是正则匹配~
开头表示区分大小写的正则匹配;~*
开头表示不区分大小写的正则匹配/
通用匹配, 如果没有其它匹配,任何请求都会匹配到
例子(以开头/ylw_8080拦截 默认开启不区分大小写:):
server {
listen 80;
server_name www.baidu.com;
### 以开头/ylw_8080 最终跳转到http://127.0.0.1:8080/;
location /ylw_8080/ {
proxy_pass http://127.0.0.1:8080/;
index index.html index.htm;
}
### 以开头/ylw_8080 最终跳转到http://127.0.0.1:8081/;
location /ylw_8081/ {
proxy_pass http://127.0.0.1:8081/;
index index.html index.htm;
}
}
上游服务器负载均衡:当上游服务器发生故障时,可以转移到其他上游服务器。负载均衡算法有:
- 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。
- weight(轮询权值):weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。
- ip_hash:每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。俗称IP绑定。
- fair(第三方):比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
- url_hash(第三方):按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。
权重配置例子:
upstream backServer{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=2;
}
server {
listen 80;
server_name www.xxx.com;
location / {
### 指定上游服务器负载均衡服务器
proxy_pass http://backServer;
index index.html index.htm;
}
}
ip_hash配置例子:
upstream backServer{
server 127.0.0.1:8080 ;
server 127.0.0.1:8081 ;
ip_hash;
}
server {
listen 80;
server_name www.xxx.com;
location / {
### 指定上游服务器负载均衡服务器
proxy_pass http://backServer;
###nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 1s;
###nginx发送给上游服务器(真实访问的服务器)超时时间
proxy_send_timeout 1s;
### nginx接受上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 1s;
index index.html index.htm;
}
}
rewrite:主要的功能就是实现URL的重写,以新的URI发起内部跳转。
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
location /xiao/ {
if ($http_user_agent ~ Mozilla/5.0) {
#如果是chrom浏览器
rewrite ^(.*)$ http://www.example.com; #返回客户端302
}
if ($http_user_agent ~ curl) {
# 如果是curl 发起请求
rewrite ^/xiao/(.*)$ /xiao/$1.txt break; #得到新的URI
}
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1; #提取了变量$1
}
if ($request_method = POST) {
return 405; #可以限制Request Method
}
if ($slow) {
limit_rate 10k; #这个配置会加在location里面
}
if ($invalid_referer) {
return 403;
}
HTTP 动态负载均衡:实现Upstream可配置化、动态化,无需人工重新加载nginx.conf
,类似分布式的配置中心。可以通过 Consul+upsync+Nginx 实现无需raload动态负载均衡(使用第三方应用nginx-upsync-module)
TCP反向代理:在网络模型中的传输层中,基于主要是基于tcp协议报文实现负载均衡(比如LVS
、haproxy
就是四层负载均衡器),使用改写报文的源地址和目的地址(使用第三方应用nginx_tcp_proxy_module)。
LVS+KeepAlived+Nginx实现高性能负载均衡集群:
- LVS:LVS的负载能力强,因为其工作方式逻辑非常简单,仅进行请求分发,而且工作在网络的第4层,没有流量,所以其效率不需要有过多的忧虑。因为工作在第4层,所以LVS可以对几乎所有应用进行负载均衡,包括Web、数据库等。
- KeepAlived :可以进行健康检查,而且能同时实现 LVS 的高可用性,解决 LVS 单点故障的问题,其实 KeepAlived 就是为 LVS 而生的。(KeepAlived基于
VRRP协议
实现的保证集群高可用的一个服务软件,主要功能是实现真机的故障隔离和负载均衡器间的失败切换,防止单点故障)
动静分离:动静分离是让动态网站里的动态网页根据一定规则把 不变的资源 和 经常变的资源 区分开来。将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。这里我们将静态资源放到nginx中,动态资源转发到tomcat服务器中。因此,动态资源转发到tomcat服务器我们就使用到了前面讲到的反向代理了。