SpringCloud——使用Ribbon做负载均衡
Ribbon负载均衡
一、简介
1:什么是负载均衡
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。以上内容来自于百度百科
个人理解而言,负载均衡,是弥补了单体架构或者单个服务的负载能力不足而导致的整体性能瓶颈,因此,可以通过将一个服务部署多台服务器,然后将一台机器原来的压力分摊到多个执行单元上,这样就提升了原有架构的性能瓶颈。可以理解为 “将负载均衡到多个服务中”。常见的负载均衡有两种策略:
- Nginx独立进程做负载均衡,通过负载均衡策略,将请求转发到不同的执行单元上
- 客户端负载均衡策略,通过在客户端保存服务列表信息,然后自己调用负载均衡策略,分摊调用不同的执行单元。
2:什么是Ribbon
Ribbon是Netflix公司开源的一个负载均衡的组件,它属于上述负载均衡方式中的第二种。将负载均衡的逻辑封装在了客户端中,并且运行在客户端。Ribbon经过了非常严格的测试,可以更好的控制Http和Tcp客户端的负载均衡行为。
Ribbon的负载均衡有两种方式
- 和RestTemplate结合
- 和Feign结合
Ribbon的核心子模块
- ribbon-loadbalancer:可以独立使用或者和其他模块一起使用的负载均衡API
- ribbon-eureka:结合Eureka作客户端的API
- ribbon-core:Ribbon的核心API
3:什么是RestTemplate
RestTemplate是SpringResource中一个访问第三方RESTful API接口的网络通讯框架。其主要方法都与REST的HTTP协议的方法紧密关联。 RestTemplate支持常见的HTTP请求方式,例如GET、POST、PUT、DELETE等,所以RestTemplate很容易构建RESTful API 调用方式例如
restTemplate.getForObject("http://common-service/hello", String.class)
二、开始使用Ribbon
Ⅰ.代码编写
- ribbon-test父项目
- pom.xml
<groupId>com.calvin.ribbon</groupId> <artifactId>ribbon-test</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>common-service</module> <module>eureka-server</module> <module>ribbon-service</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
- eureka-server
- pom.xml
<parent> <groupId>com.calvin.ribbon</groupId> <artifactId>ribbon-test</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>eureka-server</artifactId> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
application.yml
server: port: 8080 eureka: instance: hostname: localhost client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
- ServerApplication.java
@EnableEurekaServer @SpringBootApplication public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class); } }
- commons-service
- pom.xml
<parent> <artifactId>ribbon-test</artifactId> <groupId>com.calvin.ribbon</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>common-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
- application.yml
spring: application: name: common-service eureka: client: service-url: defaultZone: http://localhost:8080/eureka/
此处没有指定server.port,是因为我们在启动此服务的是时候做点手脚,需要以不同端口在本地启动, 即配置两个Name不同的启动类,给分别指定不同的Environment variables,内容为server.port=8083, server.port=8084 具体教程是在Idea下的EditConfiguration中做如下操作:
- CommonServiceApplication.java
@SpringBootApplication @EnableEurekaClient public class CommonServiceApplication { public static void main(String[] args) { SpringApplication.run(CommonServiceApplication.class); } }
- HelloController.java
@RestController public class HelloController { @Value("${server.port}") private String port; /** * 接口测试 * @return */ @GetMapping("/hello") public String sayHello(){ return "port : " + port ; } }
- ribbon-service
- pom.xml
<parent> <artifactId>ribbon-test</artifactId> <groupId>com.calvin.ribbon</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ribbon-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
- application.yml
server: port: 8082 spring: application: name: ribbon-service eureka: client: service-url: defaultZone: http://localhost:8080/eureka/
- RibbonClientApplication.java
@EnableEurekaClient @SpringBootApplication public class RibbonServerApplication { public static void main(String[] args) { SpringApplication.run(RibbonServerApplication.class); } /** * 配置LoadBalance和RestTemplate * @return RestTemplate */ @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
接下来就是调用的关键代码
- RemoteCommonService.java
/** * <p> * CommonService服务远程调用类 * </p> * @author Calvin * @date 2019/10/09 * @since 1.0 */ @Service public class RemoteCommonService { /** * 注入RestTemplate */ @Autowired private RestTemplate restTemplate; /** * 远程调用common-service/hello * @return */ public String sayHi(){ return restTemplate.getForObject("http://common-service/hello", String.class); } }
- SayHiController.java
@RestController public class SayHiController { @Autowired private RemoteCommonService remoteCommonService; @GetMapping("hi") public String sayHi(){ return remoteCommonService.sayHi() + ", this is ribbon service"; } }
Ⅱ.配置启动
最终配置四个启动类,如图所示:
启动顺序:
- step1. EurekaSeverApplicaton
- step2. CommonServiceApplication
- step3. CommonServiceApplication2
- step4. RibbonServerApplication
Ⅲ.结果验证
Eureka管理界面 http://localhost:8080/
刷新页面
三、核心剖析——LoadBalancerClient
负载均衡的核心类是LoadBalanceClient,此类可以获取负载均衡的服务提供者的实例信息,当然这些实例信息是通过EurekaClient获取的,并且缓存了一份服务实例信息。
@Autowired private LoadBalancerClient loanBalanceClient; /** * 远程调用common-service/hello * @return */ public String sayHi(){ ServiceInstance serviceInstance = loanBalanceClient.choose("common-service"); logger.info("current service info is {} : {}", serviceInstance.getHost(), serviceInstance.getPort()); return restTemplate.getForObject("http://common-service/hello", String.class); }
此时不断刷接口,同样可以看到LoadBalancerClient在不断的改变请求的实例信息。
四、小结
- 认识了关于Ribbon以及常用负载均衡的概念
- 动手实践了一下Ribbon进行负载均衡的调用
- 认识Ribbon的一个核心类
五、总结
- 本文首次实践Ribbon做负载均衡,缺乏原理剖析
- 文章中代码相对简单,但是基本可以表达Ribbon所做的事情
- 需要在以后,对整个Ribbon的源码进行解析(算是插眼)
- 关于RestTemplate还有很多用法,后续可以专门出文章进行深入理解

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何设计高扩展的在线网页制作平台
如何设计高扩展的在线网页制作平台 本文主要介绍如何设计一个高扩展的在线网页制作平台,会交代一些背景和最终的效果以及核心设计方案。 背景 2018年3月份开始,随着运满满的快速发展,开始在频繁的迭代各种活动,那时最快的方式就是拷贝老的活动项目,然后按需求修改,接着上线,然而这种方式很快就遇到了瓶颈,迫使运营团队也会去寻找一些第三方平台去满足自己的运营要求,不过由于定制化弱和用户信息没打通导致没办法大量使用,还是只能等待前端资源排期,两个比较突出的问题。 产品每个活动都需要前端人员介入,甚至替换一个简单的图标和简单的布局,都需要排期等待,吃掉了50%的前端资源。 市面上可使用的一些在线制作推广平台制作的页面又不能很好地结合到自己的业务流程里面。 转盘抽奖,如果使用第三方平台需要在活动结束后把抽奖名单导出,然后导入自己的平台里面去做匹配,然后在筛选中奖名单,很不方便。 拉新送红包,使用第三方的平台如果用户提交了拉新的手机号。需要定期去同步数据然后送红包,不能对接自己的平台做到实时。 针对这些问题团队迫切需要一个平台来提供运营快速创建活动,开发也能在这平台做一些功能扩展。最好能满足已下几个要求...
- 下一篇
设计模式 - 单例模式之多线程调试与破坏单例
前言 在之前的 设计模式 - 单例模式(详解)看看和你理解的是否一样? 一文中,我们提到了通过Idea 开发工具进行多线程调试、单例模式的暴力破坏的问题;由于篇幅原因,现在单独开一篇文章进行演示:线程不安全的单例在多线程情况下为何被创建多个、如何破坏单例。 如果还不知道如何使用IDEA工具进行线程模式的调试,请先阅读我之前发的一篇文章: 你不知道的 IDEA Debug调试小技巧 一、线程不安全的单例在多线程情况下为何被创建多个 首先回顾简单线程不安全的懒汉式单例的代码以及测试程序代码: /** * @author eamon.zhang * @date 2019-09-30 上午10:55 */ public class LazySimpleSingleton { private LazySimpleSingleton(){} private static LazySimpleSingleton instance = null; public static LazySimpleSingleton getInstance(){ if (instance == null) { insta...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7,8上快速安装Gitea,搭建Git服务器