分分28官网|分分28开奖网

原理:一文详解,Spring Cloud Ribbon负载均衡
作者:强官涛   类型:Python开发    类别:原理   日期:2019-09-03    阅读:1388 次   消耗积分:0 分




今天的这篇文章来自蜗牛学院重庆校区刘颖聪老师。

蜗牛学院资深导师,重庆邮电大学计算机专业学士学位,12年软件开发、管理及培训经验。精通开发和逆向编译技术。曾在天收网络技术有限公司担任逆向编译工程师,腾讯,盛大驱动保护项目合作。叁壹伍捌网络文化公司研发部项目经理,参与站群建设,SEO,反黑技术等工作。国内某IT培训机构资深项目经理,教学幽默风趣,注重案例与生活的结合,着重培养学员独立解决问题的思想及技术层次的扩展。

·  正  ·  文  ·  来  ·  啦  ·


Spring Cloud是pivotal公司(Spring母公司)开源的一套微服务解决方案,也是当前最为流行的微服务落地解决方案。其中众多的组件主要是由国外知名视频点播公司NetFliex所贡献,这意味着,这些组件是经过生产环境考验,非常成熟。


今天我们要谈到的Spring Cloud中的负载均衡组件Ribbon,也是由NetFliex贡献的久经沙场的成熟产品。但在开始之前,我们先来了解下负载均衡的概念。


负载均衡

负载均衡,英文名称为Load Balance,其含义就是指将工作任务(负载)进行平衡、分摊到多个操作单元上进行运行,从而协同完成工作任务。(引自百度百科)


一种常见的负载均衡模式,是在执行工作任务的多台服务器前,加设一个负载均衡器。其结构如下:


20190903_111547_527.jpg


这里看到,从用户发送的三个请求a\b\c被分别发送到服务器1,服务器2,服务器3。这样如果一台服务器的负载能力为100,那么三台服务器的负载能力就是300,有效提高了系统的整体负载。我们把这种模式称为集中式负载均衡。


另一种模式则是将负载均衡的逻辑写在调用者的代码中。如下图


20190903_111602_478.jpg


同样的,a/b/c三个请求到达服务器1 时,服务器1中执行一段代码选出合适的服务器执行,最简单的情况下第1次选择了服务器4,第二次选择了服务器5,第三次选择了服务器6。同样也实现了负载均衡。这里没有用专门的负载均衡设备,而是使用代码逻辑实现,称为软负载,又称为进程内的负载均衡模式。


上图中,我们将服务器1称为调用者,服务器4、5、6称为提供者。而我们今天的主角,Ribbon就是使用了后一种,进程内的负载均衡模式。它作为负载均衡组件,被加入调用者的代码逻辑中,负责选出合适的提供者服务来执行,进而实现负载均衡。


负载均衡案例

这里我们用一个例子来说明ribbon的作用。我们假设有一个电影网站movie,用户可以通过这个网站查看电影信息并且可以发表评论。这样我们开发了两个应用movie(电影网站)和review(评论服务),movie应用将会调用review服务来获取到某个电影的评论。为了提升负载能力,我们将review部署了三台服务器,最终的结构如下:显然,这里movie是调用者,review的三个服务是提供者,ribbon应该加入到movie中来选择具体调用哪个review服务。


20190903_111613_807.jpg


关于consul


这里我们需要用到consul来作服务发现,或许你没有听过consul,但没关系,我们只需要启动它,其他的事情就可以不管了。


下载合适你的版本的consul :


解压后,在consul.exe 目录下执行 consul.exe agent -dev 启动consul。启动后,可以通过浏览器访问localhost:8500 查看consul的界面


20190903_111629_974.png


开发review


接下来我们使用idea来开发spring-cloud应用 review。


第一步,使用idea的spring initializar创建项目。选择如下review需要的依赖


- spring-web-starter   用于使用SpringMVC开发web应用

- spring-cloud-consul-discovery  用于consul服务发现

- spring-boot-actuator  【可选】用于暴露应用健康状况


具体操作见下图:


20190903_111702_308.png


第二步,接下来我们修改配置文件application.properties。

#项目的名字,重要,

spring.application.name=review

# tomcat的端口,使用随机端口

server.port=${random.int[8600,8900]}

# 当前系统的注册到consul,可以被调用

spring.cloud.consul.discovery.register=true


server.port的配置我们使用了一个8600-8900之间的随机端口,以便于在本地部署多个review服务的时候,不会发生端口冲突。具体语法就是${random.int[开始数值,结束数值]}。


第三步,我们来开发一个Web服务,暴露给movie项目调用。如果你有SpringMVC的开发经验,那么这一步也是易如反掌。


20190903_111731_487.jpg

稍加解释,@RestController意味着该Controller的所有方法都是返回Json对象的。


我们定义了一个sayHello的方法处理请求路径为say的请求,返回的是一个从 Environment对象中获取到的本地端口路径(还记得我们的随机端口吗?这里就是返回它)。Environment是Spring Boot提供的一个对象,可以从中获取环境相关的信息。


这样,Review就开发好了。不过问题来了,我们如何启动多个review的实例呢?大家回看我们的效果图,我们必须部署多个review实例才可以测试负载均衡。


这就到了最后一步, spring boot的maven插件支持从命令行运行spring boot项目。具体操作是在review项目根目录下执行 mvn spring-boot:run 。但需要先启动consul,否则启动会失败。


启动日志概略如下:


20190903_111750_147.jpg

多开几个命令行窗口,执行多次以上命令后,就实现了多个review实例。在consul上可以看到部署多个实例后的效果。下图是部署两个实例后的样子。


20190903_111758_649.png


开发Movie


movie应用跟review最大区别在于,它是调用方。所以这边需要编写调用代码。


第一步,仍然使用idea的spring initializar创建项目。选择如下movie需要的依赖:

- spring-web-starter   用于使用SpringMVC开发web应用

- spring-cloud-consul-discovery  用于consul服务发现

- spring-cloud -netflix-ribbon  负载均衡组件ribbon


大家一定留意到了今天的主角ribbon,ribbon将在movie项目中负责选择合适的review服务来执行调用。


完整步骤如下图:


20190903_111809_856.png


第二步增加application.properties配置

# 这里是纯服务调用方,不需要向consul注册服务,但是可以调用服务

spring.cloud.consul.discovery.register=false

# 项目名称

spring.application.name=movie


第三步编写代码。这里我们开发一个程序来调用并显示review的say服务。


我们使用RestTemplate这个组件来请求review的服务。RestTemplate是Spring Web封装的一种请求Http服务的组件,简单好用。它可以自动发送请求、接受结果并自动封装返回结果为Java对象。


首先我们在MovieApplication使用Java配置的方式声明一个RestTemplate的Spring Bean。并且将Ribbon加入到调用逻辑中。


20190903_111837_403.jpg


为了简单起见我们将配置写在MovieApplication中,@SpringBootApplication 注解本身是包含了@Configuration注解的,因此可以声明SpringBean。@Bean标记的方法返回值将会作为SpringBean处理,所以这里我们就声明了一个SpringBean。而@LoadBalanced注解则会启用Ribbon的功能,凡是通过这个RestTemplate实例调用的服务都会自动进行负载均衡。(对于Spring的Java配置风格不熟悉的可以参考这篇。)


接下来,我们来编写调用的代码,与review相仿,仍然是SpringMVC风格。代码如下


20190903_111846_791.jpg


我们使用了restTemplate调用review服务。通常的Http请求是需要指定网页地址的,比如“http://www.baidu.com/s?wd=123”, 理论上我们应该填写review的地址,但是review并不是一个应用而是由三个相同实例组成的一个服务,我们的目标就是将请求均衡的分发给这三个实例。所以填写的地址就有讲究了,这里的地址填写的需要调用服务的名字,我们的开发review的时候配置了 spring.application.name 就是服务名了。根据目前配置,调用地址就是“http://review/say”了。这样,我们所有的开发工作都结束了。


测试最终效果


movie使用的是默认端口8080 ,所以当我们启动movie后,可以通过浏览器访问地址localhost:8080/show  就可以看见页面上显示一个端口,当你刷新端口就会改变,但当你刷新超过3次就会回到第1个端口,如此往复。


背后的故事就是,我们访问movie,movie通过ribbon依次选择了review的三个实例中的一个来执行,所以端口各不相同。


20190903_111903_901.gif



总结及思考

Spring Cloud 选择了ribbon作为负载均衡器,实现方式是将ribbon加入到调用方的调用逻辑中。但为何要如此设计呢?


回到微服务的实际场景,服务一定是非常多的,互相调用关系也非常复杂。那么就要求服务间的负载均衡应该是低成本、低消耗、透明化的,如果选用前文提到的集中式负载均衡,那么设置独立的负载均衡器成本会很高,消耗也会大,而且新部署的服务都需要配备新的负载均衡器。一方面运维成本倍增,另一方面增加了部署结构的复杂度,维护成本几何级增长。


反之,通过良好的设计和编码,ribbon的使用成本几乎为0,仅仅在代码中加入@LoadBalanced注解,如果更进一步使用配套的Feign客户端则内置了ribbon,完全将负载均衡透明化了。ribbon本身只是一段代码逻辑,运行时消耗也非常少。低成本、低消耗、透明化,ribbon是微服务界,负载均衡的不二之选。


为了答谢大家对蜗牛学院的支持,蜗牛学院将会定期对大家免费发放干货,敬请关注蜗牛学院的官方微信。


20190320_095757_834.jpg





版权所有,转载本站文章请注明出处:蜗牛学院在线课堂, http://www.mountsinaibaptistchurch.org/note/371
上一篇: 访谈:他两次考研成功后放弃入学,现转行Java开发,入职月薪7.5K
下一篇: 资讯:程序员是如何把女朋友气走的
提示:登录后添加有效评论可享受积分哦!