.Net微服务实战之负载均衡(上)
系列文章
相关源码:https://github.com/SkyChenSky/Sikiro
PS:最近开始在找工作,如果在广州地区需要技术管理岗的(.Net架构师、技术经理)可以随时联系我,微信:SkyChen_Gong。
分布式?集群?负载均衡?
我曾经面试过一家企业,当时描述完我在老东家完成的微服务架构后,面试官问了我一个问题:
面试官:您有做过分布式系统吗?
我:有,刚刚我描述的微服务架构就是分布式的……
面试官:不不不,我意思是你有没有尝试过把一个站点部署到多台服务器上?
我:哦……你意思是我有没有用过类似nginx这些工具做负载均衡是吧?有,现在我们就这么做的。但是我对分布式理解是工作方式,但是你描述的更多具体称之为集群或者负载均衡。
面试官:对对,大家的站在的观点不一样所以理解的不一样(尴尬的笑了笑)
PS:首先我申明下我没有对该面试官有任何贬低嘲讽之意,也没刻意突出谁对谁错,面试完了后我回去回想了下我的回答并找到些资料做出以下总结。
分布式
分布式计算是指系统的工作方式,主要分为数据分布式和任务分布式:
数据分布式也称为数据并行,把数据拆分后,利用多台计算机并行执行多个相同任务。优点是缩短所有任务总体执行时间,缺点是无法减少单个任务的执行时间。
任务分布式也称为任务并行,单个串行的任务拆分成多个可并行子任务。优点是提高性能、可扩展性、可维护性,缺点是增加设计复杂性。
负载均衡
负载均衡(Load Balance),简称LR,就是将并发的用户请求通过规则后平衡、分摊到多台服务器上进行执行,以此达到压力分摊、数据并行的效果。
集群
集群是系统在负载均衡结果后的物理表现,系统(服务)通过部署到多台服务器以达到共同提供相同的功能,可以称这一组服务为某某集群,例如Redis集群,某Web站点集群。
负载均衡器
作用
负载均衡器的分类有很多,而他们的作用主要体现于架构要素的其中三个:可用性、性能、安全。
可用性,多台服务器的部署避免了单点故障。
性能,一台Web站点能提供每秒4000次的并发请求,5台服务器构成的一个集群就可以达到20000。
安全,通过反向代理到真实服务器,避免直接路由到高危Web服务,避免开放危险端口。
算法
常用的负载均衡算法主要以下4个:
- 加权轮询
- 随机
- 最少链接数
- 哈希
分类
从制造上主要分为软件负载和硬件负载:
软负载,包含了Nginx、LVS、HAProxy等。
硬负载,包含了F5、Array等。
从量级上主要分为:百万级、数十万级、万级:
百万级,硬负载,例如F5、Array。
数十万级,第四层负载,LVS、HAProxy。
万级,第七层负载,Nginx。
当然从成本上,硬负载绝对是土豪公司的工具,便宜的十来万RMB,贵则上百万RMB。而软负载只需要一台Linux服务器的钱就足够了。此外LVS的部署复杂度相比于Nginx会高那么一点,但是Nginx的七层负载的灵活性是四层负载的无法比拟的。
在实际工作中大家更多会接触到上图的架构模型,从功能职责上又可以划分地域级、集群级和应用级的负载:
地域级的负载均衡使用的是DNS的智能解析来完成的,DNS全称Domain Name System,中文叫域名系统(服务)协议,一般都会采用云服务厂商的DNS系统,我们知道域名是需要花钱购买的,而厂商会附带一个免费的域名解析套餐,如果需要对域名进行域名智能解析,就需要付费给厂商获取相应的服务。
Nginx作为应用级负载也有自己的并发处理上限,如果超过上限了那么只能通过再上一层加一个更高处理性能的负载均衡器作为解决,而LVS可以很好担任集群级的负载重任。如果是土豪公司可以在自己选择使用硬负载来代替LVS,硬负载虽然贵也有自己的优势,例如防火墙、加密、高性能处理等。
Nginx
Nginx是一个高性能的反向代理服务器,也是稳定且高效的基于七层的负载均衡器。Nginx可以根据以随机、加权轮询,IP哈希、URL哈希等方式调度后端真是服务器,Nginx也支持对后端服务器的健康检查功能。
LVS
LVS即Linux Virtual Server,翻译中文为 Linux虚拟服务器,目前LVS是已经被集成到Linux内核模块中,LVS的工作模式分为NAT模式、TUN模式以及DR模式。那么在实战中,更多会Keepalived + LVS一起集成使用,Keepalived可以自动将LVS备用调度器升级为主调度器,最终实现整个集群系统的高负载、高可用。
本篇的重点主要讲解Keepalive + LVS + Nginx + .Net Core的搭建与使用。
效果图
PS:上图是我完成搭建后录制的视频转gif,因为中间有等待的一分钟,为了观看效果剪断了。
Web1与Web2是同一个Nginx,Web3和Web4是同为另外的一个Nginx。在图里可见需要过一段时间才能从一个Nginx切换到另外一个Nginx,原因主要是LVS会根据访问客户端的IP+端口在会话时间内重复的转发到同一个目标服务器。而控制这个会话时间的可以通过设置ipvsadm --persistent 与--set这两个参数决定。
LVS的三种工作模式
NAT(Network Address Translation)-网络地址转换模式。
首先,外部请求会经过LVS的VIP(Virtual IP Address);接着,LVS会根据预设的调度算法选择一台真实的服务器进行数据请求包转发,转发前会把原数据包的目标地址与目标端口修改为真实服务器的地址与端口;最后,LVS在得到响应数据包后会把源地址与源端口改为VIP及调度器相应的端口。因为由于所有的请求与响应都会经过LVS调度器转发,因此容易成为集群的瓶颈。
TUN-隧道模式
因为NAT会的瓶颈问题,因此TUN模式采用用了请求与响应数据分离的思路,让调度器仅处理数据请求,让真实服务器响应数据包直接返回给客户端,需要注意的是该模式下的真实服务器需要与外部网络连接。另外TUN模式下需要在LVS调度器与真实服务器之间创建隧道连接,同样会增加服务器的负担。
DR(Direct Routing)-直接路由模式
DR模式也是采用请求与响应分离的思路,由真实服务器直接响应客户端,但是它的报文转发方法有所不同,在不修改数据报文的情况下,将数据帧的MAC地址修改为需要转发到的真实服务器MAC地址,免去了TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是LVS调度器与真实后端服务器必须在一个局域网内。
LVS的部署
接下来的部署操作将实现上图Keepalived + LVS +Nginx的多层负载均衡,LVS将是以DR模式实现。
两台LVS服务器(主从)
yum install gcc
yum -y install openssl-devel
yum -y install libnl libnl-devel
yum install -y libnfnetlink-devel
yum -y install net-tools
yum install vim -y
安装keepalived 和 ipvsadm
yum install -y keepalived ipvsadm
LVS-Master服务器
修改Keepalived配置:
vim /etc/keepalived/keepalived.conf
复制以下配置覆盖进去
注意:real_server填写的是Nginx服务器的IP地址
global_defs {
router_id LVS_MASTER # 设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 {
state MASTER #指定Keepalived的角色,MASTER为主,BACKUP为备 记得大写
interface ens33 #网卡id 不同的电脑网卡id会有区别 可以使用:ip a查看
virtual_router_id #虚拟路由编号,主备要一致
priority #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
advert_int #检查间隔,默认为1s
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.174.128/ #定义虚拟IP(VIP)为192.168.174.,可多设,每行一个
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.174.128 {
delay_loop # 设置健康检查时间,单位是秒
lb_algo rr # 设置负载调度的算法为wlc
lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
nat_mask 255.255.255.0
persistence_timeout
protocol TCP
real_server 192.168.88.137 {
weight
TCP_CHECK {
connect_timeout
nb_get_retry
delay_before_retry
connect_port
}
}
real_server 192.168.88.139 {
weight
TCP_CHECK {
connect_timeout
nb_get_retry
delay_before_retry
connect_port
}
}
}
LVS-BackUp服务器
修改Keepalived配置:
vim /etc/keepalived/keepalived.conf
复制以下配置覆盖进去
注意:real_server填写的是Nginx服务器的IP地址,state改为BACKUP,priority改为比Master小。
global_defs {
router_id LVS_SLAVE # 设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 {
state BACKUP #指定Keepalived的角色,MASTER为主,BACKUP为备 记得大写
interface ens33 #网卡id 不同的电脑网卡id会有区别 可以使用:ip a查看
virtual_router_id #虚拟路由编号,主备要一致
priority #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
advert_int #检查间隔,默认为1s
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.174.128/ #定义虚拟IP(VIP)为192.168.174.,可多设,每行一个
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.174.128 {
delay_loop # 设置健康检查时间,单位是秒
lb_algo rr # 设置负载调度的算法为wlc
lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
nat_mask 255.255.255.0
persistence_timeout
protocol TCP
real_server 192.168.88.137 {
weight
TCP_CHECK {
connect_timeout
nb_get_retry
delay_before_retry
connect_port
}
}
real_server 192.168.88.139 {
weight
TCP_CHECK {
connect_timeout
nb_get_retry
delay_before_retry
connect_port
}
}
}
两台Nginx服务器
执行以下命令
vim /etc/sysconfig/network-scripts/ifcfg-lo:
填写以下配置并保存
DEVICE=lo:
IPADDR=192.168.88.128
NETMASK=255.255.255.255
BROADCAST=192.168.88.128
ONBOOT=yes
NAME=lvs_vip
修改ARP
vim /etc/sysctl.conf
填写配置并保存
net.ipv4.conf.all.arp_ignore =
net.ipv4.conf.all.arp_announce =
net.ipv4.conf.lo.arp_ignore =
net.ipv4.conf.lo.arp_announce =
重启网卡
sysctl -p
systemctl restart network
那么以上关于LVS部分就搭建好了。
Nginx的部署
在两台Nginx服务器都执行以下指令
rpm -Uvh http://nginx.org/packages/centos//noarch/RPMS/nginx-release-centos--.el7.ngx.noarch.rpm yum install -y nginx
user nginx;
worker_processes ;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; events {
worker_connections ;
} http {
#开始
upstream 192.168.88.139{
server localhost: weight=;
server localhost: weight=;
}
server {
listen ;
server_name 192.168.88.139;
charset utf8; client_max_body_size 50m;
client_body_buffer_size 256k; location / {
proxy_pass http://192.168.88.139;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
#结束
}
systemctl start nginx.service
systemctl enable nginx.service
firewall-cmd --permanent --zone=public --add-port=/tcp
firewall-cmd --reload
以上关于Nginx的部分就完成了搭建。可以通过以下指令查看LVS的调度与连接信息。
查看LVS调度信息
ipvsadm -Ln
查看LVS连接信息
ipvsadm -Lnc
.Net Core部署
添加下载源:
rpm -Uvh https://packages.microsoft.com/config/centos//packages-microsoft-prod.rpm
下载安装:
sudo yum install aspnetcore-runtime-2.2
通过FTP把Web站点文件复制两份并上传到服务器,然后启动后台进程:
nohup dotnet Test1.dll --server.urls "http://*:5001" &
nohup dotnet Test1.dll --server.urls "http://*:5002" &
FTP服务器的搭建
yum install -y vsftpd
vim /etc/vsftpd/vsftpd.conf
把已有的三项配置修改了:
anonymous_enable=NO
listen=YES
#listen_ipv6=YES
systemctl start vsftpd
systemctl enable vsftpd
firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload
vim /etc/vsftpd/user_list
vim /etc/vsftpd/ftpusers
#root
setenforce
vim /etc/selinux/config
#将SELINUX=enforcing改为SELINUX=permissive
FTP客户端—FileZilla下载地址
https://filezilla-project.org/download.php?type=client
结束
以上为本篇的所有内容了,负载均衡在实际工作中涉及的地方挺多的,因此我将分为上下两篇,该篇为负载均衡的上篇主要从大方向DNS、LVS、Nginx进行了分享,下篇会从微服务架构里使用到的组件API网关和注册中心进行探讨,如果大家在实践上遇到任何问题,或者有更好的建议可以到评论反馈给我。
.Net微服务实战之负载均衡(上)的更多相关文章
- .Net微服务实战之负载均衡(下)
系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战 ...
- .Net微服务实战之必须得面对的分布式问题
系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战 ...
- .Net微服务实战之可观测性
系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战 ...
- 微服务实战(二):使用API Gateway
微服务实战(一):微服务架构的优势与不足 微服务实战(二):使用API Gateway 微服务实战(三):深入微服务架构的进程间通信 微服务实战(四):服务发现的可行方案以及实践案例 微服务实践(五) ...
- Spring Cloud微服务实战阅读笔记(一) 基础知识
本文系<Spring Cloud微服务实战>作者:翟永超,一书的阅读笔记. 一:基础知识 1:什么是微服务架构 是一种架构设计风格,主旨是将一个原本独立的系统拆分成多个小型服务 ...
- 微服务实战(六):选择微服务部署策略 - DockOne.io
原文:微服务实战(六):选择微服务部署策略 - DockOne.io [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺点.随后的文章讨论了微服务不同 ...
- 微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io
原文:微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io 这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三 ...
- 微服务实战(二):使用API Gateway - DockOne.io
原文:微服务实战(二):使用API Gateway - DockOne.io [编者的话]本系列的第一篇介绍了微服务架构模式.它讨论了采用微服务的优点和缺点,除了一些复杂的微服务,这种模式还是复杂应用 ...
- 微服务实战(一):微服务架构的优势与不足 - DockOne.io
原文:微服务实战(一):微服务架构的优势与不足 - DockOne.io [编者的话]本文来自Nginx官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战 ...
随机推荐
- MySQL LOAD DATA INFILE—批量从文件(csv、txt)导入数据
最近做的项目,有个需求(从Elastic Search取数据,业务运算后),每次要向MySQL插入1300万数据左右.最初用MySQL的executemany()一次插入10000条数据,统计的时间如 ...
- idea的maven项目无法引入junit类
本机:java版本:1.8 pom中是junit版本:4.12 出现问题:在使用@Test 无法引入 : org.junit.Test; 解决方法:junit在pom.xml改为 4.12-beta- ...
- SpringMVC 学习笔记(五)
47. 尚硅谷_佟刚_SpringMVC_文件上传.avi 参看博客https://www.cnblogs.com/hanfeihanfei/p/7931758.html相当的经典 我是陌生人关于Sp ...
- BERT的前世今生
Transformer Transformer来自论文: All Attention Is You Need 别人的总结资源: 谷歌官方AI博客: Transformer: A Novel Neura ...
- IntelliJ IDEA安装配置、搭建Spring MVC
安装前必备软件: 1.jdk1.8.0_144安装包 2.IntelliJ IDEA 2016.1.1(64) 3.Tomcat安装包 4.Mysql.MySQL-JDBC驱动安装包 5.Jetbra ...
- python+opencv实现图像缩放
x, y = img_.shape[0:2] img_ = cv2.resize(img_, (int(y/2), int(x/2))) 实现图像长宽缩小为原来的一半
- 【总结】Github通过Git Bash上传文件到仓库
1-ML新文件夹连接仓库gir clone(最好用SSH不需要输入账户密码 SSH需要设置秘钥) 2-ML中设立空文件夹与项目同名(要新建 打开隐藏文件选项 文件夹内不许有文件会报错) 3-在项 ...
- 循环&&数组&&方法&&面向对象
day03 数值的默认值 类型 初始化的值 byte,short,int,long 0 float,double 0.0 char 空格 boolean false 引用类型 null JVM的内存 ...
- 分布式配置中心(Native - Config)
本章只讲 Spring Cloud 本地配置方式,可以很方便的高可用集群,且存在良好通讯,不用担心云服务器与内网之间GIT带来的不便,GIT(网上GIT教程一搜一大把了….) - 快速开始 Sprin ...
- css 分割线样式_css实现文章分割线的多种方法总结
这篇文章整理css如何实现文章分割线的多种方式,分割线在页面中可以起到美化作用,那么就来看看使用css实现分割线样式的多种方法.效果如下: 方式一:单个标签实现分隔线: html: <div c ...