负载均衡那些事儿

本文介绍了负载均衡的概念,旨在提高网络设备和服务器的处理能力,实现服务的高可用性。主要内容包括基于网络的负载均衡,如四层和七层负载均衡的工作原理,常见的负载均衡工具如Nginx、k8s、Ribbon、Feign和HAProxy的介绍,以及负载均衡的常见算法,如随机、轮询、最少连接和Hash等。同时,提到了在实际应用中如何结合k8s进行微服务的负载均衡和自动化部署。

点击上方蓝色字体,关注我们

1、 前言



 

负载均衡,英文:Load Balance,其含义是请求分发到多个粒度单元上进行执行操作,例如各种服务器、应用服务、中台服务、数据服务等,从而达到共同完成某项任务的目的。为了拓宽网络设备和服务器的带宽、增加吞吐量、加强网络请求处理能力、提高网络的灵活性和高可用性,负载均衡是一种廉价、有效、透明的方法,它为服务的高并发做了一次缓冲,让单个服务的压力瞬间减少,实现了服务的高可用,避免服务因为压力而面临宕机的危险。

 

2、负载均衡



 

2.1 基于网络的负载均衡

大家都知道,OSI 模型有 7 层结构,每层都可以有几个子层。OSI 的 7 层从上到下分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层:

在这七层结构中,高层次都是依赖于低层次的。层次越高,使用起来越方便。

 

根据负载均衡技术实现在 OSI 七层模型的不同层次,是可以给负载均衡分类的。

常见的实现方式中,主要可以在应用层、传输层、网络层和数据传输层做文章。所以,工作在应用层的负载均衡,我们通常称之为七层负载均衡、工作在传输层的我们称之为四层负载均衡。我们一个个来看看:

七层负载均衡

七层负载均衡工作在 OSI 模型的应用层,应用层协议较多,常用 http、dns、ftp 等。七层负载就可以基于这些协议来负载。这些应用层协议中会包含很多有意义的内容。比如同一个 Web 服务器的负载均衡,除了根据 IP 加 port 进行负载外,还可根据 URL 来决定是否要进行负载均衡。

四层负载均衡

四层负载均衡工作在 OSI 模型的传输层,由于在传输层,只有 TCP/UDP 协议,这两种协议中除了包含源 IP、目标 IP 以外,还包含源端口及目的端口。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。

 

2.2 负载均衡工具

负载均衡的工具,常见的有 Nginx、k8s、Ribbon、Feign、HAProxy 等。

 

Nginx

Nginx 主要用来作七层负载均衡,反向代理 http、https 的协议链接,同时也提供了 IMAP/POP3/SMTP 的服务。

upstream proxy_demo_aaa {
  server {{DEMO_SERVER_NODE1}} weight=5;
  server {{DEMO_SERVER_NODE2}} weight=6;
}

location ~ ^/demo-aaa/api(.*)$ {
  proxy_pass http://proxy_demo_aaa/api$1$is_args$args;
}

k8s

k8s 的负载均衡是基于 kube-proxy,其服务发现基于 kube-dns,最后由于每个 Service 对应的 pod 可以是多个,所以可以基于 kube-proxy 实现负载均衡,kube-proxy 进程其实就是一个智能的软件负载均衡器,他负责把 service 的请求转发到后端的某个 pod 实例。

Ribbon

Ribbon 是一个为客户端提供负载均衡功能的服务,它内部提供了一个叫做 ILoadBalance 的接口代表负载均衡器的操作,比如有添加服务器、选择服务器、获取所有的服务器列表、获取可用的服务器列表等等。

常见的,使用 RestTemplate 进行服务提供者、服务消费者之间的通信,只需为 RestTemplate 配置类添加@LoadBalanced 注解即可。

@Bean
@LoadBalanced
  public RestTemplate restTemplate() {
  return new RestTemplate();
}

Feign

Feign 是一个声明式负载均衡客户端使用 Feign 能让编写 WebService 的客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解,同时也支持 JAX-RS 标准的注解。Feign 也支持可拔插式的编码器和解码器。

@FeignClient(name = "provider-service", configuration = {Feign4HttpConfiguration.class, FeignLogConfiguration.class}, fallback = CustomerClientImpl.class)
public interface CustomerClient {

	@PostMapping("/save")
	String save();

	@GetMapping("/api/user/getUserInfo")
	Response<Object> getUserInfo();
}

HAProxy

HAProxy 是一个使用 C 语言编写的自由、开放源代码软件,其提供高可用性、负载均衡,以及基于 TCP 和 HTTP 的应用程序代理的功能。

 

2.3 负载均衡算法

 

常见的几种负载均衡的算法有:随机、轮询、最少链接、Hash、加权、重试等。

 
  1. 随机:即请求随机分配到各台服务器上,这是默认的策略机制。

  2. 轮询:将所有请求,依次分发到每台服务器上,适合服务器硬件相同的场景,服务请求数相同。

  3. 最少链接:将本次请求分配到请求数最少的服务上,这种可以根据服务器当前的请求处理情况,动态分配。

  4. Hash:根据 IP 地址进行 Hash 计算,得到 IP 地址,这种可以将来自同一 IP 地址的请求,同一会话期内,转发到同一服务器;实现会话粘滞。但目标服务器宕机后,会话也会随之丢失。

  5. 加权:在上面几种算法基础上,进行一定的加权比例分配。

  6. 重试:这种策略一般都会有,就是在调用失败后,进行二次重试机制。

 

当然,还有其他的动态的算法规则:最快模式、观察模式、动态性能分配等。

 

结束福利

 

开源基于 k8s 作微服务负载均衡、配置管理的架构设计代码:

https://github.com/damon008/spring-cloud-k8s

https://gitee.com/damon_one/spring-cloud-k8s

欢迎大家 star,多多指教。

 

关于作者

  笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合 docker、k8s 做微服务容器化,自动化部署等一站式项目部署、落地。Go 语言学习,k8s 研究,边缘计算框架 KubeEdge 等。公众号 程序猿Damon 发起人。个人微信 MrNull008,欢迎來撩。

 

个人博客:技术分享博客

 

欢迎关注 InfoQ: https://www.infoq.cn/profile/1905020/following/user

往期回顾

微服务自动化部署CI/CD

ArrayList、LinkedList&nbsp;你真的了解吗?

Oauth2的认证实战-HA篇

Oauth2的授权码模式《上》

微服务架构设计之解耦合

面试被问 Spring cloud 上下文,可以这样回答

Spring&nbsp;Cloud&nbsp;诸多形式组件,你都知道吗?

浅谈&nbsp;Java&nbsp;集合&nbsp;|&nbsp;底层源码解析

基于 Sentinel 作熔断 | 文末赠资料

基础设施服务k8s快速部署之HA篇

今天被问微服务,这几点,让面试官刮目相看

Spring cloud 之多种方式限流(实战)

Spring cloud 之熔断机制(实战)

面试被问finally 和 return,到底谁先执行?

Springcloud Oauth2 HA篇

Spring Cloud Kubernetes之实战一配置管理

Spring Cloud Kubernetes之实战二服务注册与发现

Spring Cloud Kubernetes之实战三网关Gateway

求关注

关注公众号,回复入群,获取更多惊喜!公众号(程序猿Damon)里回复 ES、Flink、Java、Kafka、MQ、ML、监控、大数据、k8s 等关键字可以查看更多关键字对应的文章。

如有收获,点个在看,谢谢

下载前必看:https://pan.quark.cn/s/a4b39357ea24 在本资料中,将阐述如何运用JavaScript达成单击下拉列表框选定选项后即时转向对应页面的功能。 此种技术适用于网页布局中用户需迅速选取并转向不同页面的情形,诸如网站导航栏或内容目录等场景。 达成此功能,能够显著改善用户交互体验,精简用户的操作流程。 我们须熟悉HTML里的`<select>`组件,该组件用于构建一个选择列表。 用户可从中选定一项,并可引发一个事件来响应用户的这一选择动作。 在本次实例中,我们借助`onchange`事件监听器来实现当用户在下拉列表框中选定某个选项时,页面能自动转向该选项关联的链接地址。 JavaScript里的`window.location`属性旨在获取或设定浏览器当前载入页面的网址,通过变更该属性的值,能够实现页面的转向。 在本次实例的实现方案里,运用了`eval()`函数来动态执行字符串表达式,这在现代的JavaScript开发实践中通常不被推荐使用,因为它可能诱发安全问题及难以排错的错误。 然而,为了本例的简化展示,我们暂时搁置这一问题,因为在更复杂的实际应用中,可选用其他方法,例如ES6中的模板字符串或其他函数来安全地构建执行字符串。 具体到本例的代码实现,`MM_jumpMenu`函数负责处理转向逻辑。 它接收三个参数:`targ`、`selObj``restore`。 其中`targ`代表要转向的页面,`selObj`是触发事件的下拉列表框对象,`restore`是标志位,用以指示是否需在转向后将下拉列表框的选项恢复至默认的提示项。 函数的实现通过获取`selObj`中当前选定的`selectedIndex`对应的`value`属性值,并将其赋予`...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值