Spring Cloud_6_负载均衡框架Ribbon
负载均衡框架Ribbon认识Ribbon[ˈrɪbən]第一个Ribbon程序负载均衡是分布式架构的重点,负载均衡机制将决定着整个服务集群的性能与稳定根据Spring Cloud_4_Eureka集群搭建可知,Eureka服务实例可以进行集群部署,每个实例都均衡处理服务请求,那么这些请求是如何被分摊到各个服务实例中的?讲解Netflix的负载均衡项目Ribbon1、Ribb...
·
负载均衡框架Ribbon
- 认识Ribbon[ˈrɪbən]
- 第一个Ribbon程序
- 负载均衡是分布式架构的重点,负载均衡机制将决定着整个服务集群的性能与稳定
- 根据Spring Cloud_4_Eureka集群搭建可知,Eureka服务实例可以进行集群部署,每个实例都均衡处理服务请求,那么这些请求是如何被分摊到各个服务实例中的?
- 讲解Netflix的负载均衡项目Ribbon
1、Ribbon介绍
1.1、Ribbon简介
- Ribbon是Netflix下的负载均衡项目
- 在集群中为各个客户端的通信提供了支持
- 主要实现中间层应用程序的负载均衡
- Ribbon提供了以下特性:
- 负载均衡器,可支持拔插式的负载均衡规则
- 对多种协议提供支持,HTTP,TCP,UDP
- 集成了负载均衡功能的客户端
1.2、Ribbon子模块
- Ribbon主要有以下三大子模块:
- ribbon-core:该模块为Ribbon项目的核心,主要包括负载均衡的接口定义、客户端接口定义,内置的负载均衡实现等API
- ribbon-eureka:为Eureka客户端提供的负载均衡实现类
- ribbon-httpclient:对Apache的HttpClient进行封装,该模块提供了含有负载均衡功能的REST客户端
1.3、负载均衡组件
- Ribbon的负载均衡器主要与集群中的各个服务器进行通讯
负载均衡器主要提供以下基础功能:
- 维护服务器的IP、DNS名称等信息
- 根据特定的逻辑在服务器列表中循环
为实现负载均衡的基础功能,Ribbon的负载均衡器有以下三大子模块:
- Rule:一个逻辑组件,这些逻辑将会决定,从服务器列表中返回哪个服务器实例
- Ping:该组件主要使用定时器,来确保服务器网络可以连接
- ServerList:服务器列表,可以通过静态的配置确定负载的服务器,也可以动态指定服务器列表。如果动态指定服务器列表,则会有后台的线程来刷新该列表
2、Ribbon程序入门
- 关于Ribbon的知识,主要围绕负载均衡器组件进行
- 接下来,编写一个Ribbon程序,进行初步入门认识
- 先写一个简单的Hello World程序
- 看看本案例的程序结构图
2.1、编写服务
- 为了能查看负载均衡的效果,先编写一个简单的REST服务,通过指定不同的端口,让服务可以启动多个实例
- 本列的请求服务器,仅仅是一个基于SpringBoot的Web应用
2.1.1、引入依赖
- 创建新的Maven项目:atm_ribbon_server
- 引入spring-boot-start-web依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atm.cloud</groupId>
<artifactId>atm_ribbon_server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>atm_ribbon_server Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Spring Cloud -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>atm_ribbon_server</finalName>
</build>
</project>
2.1.2、编写启动类
- 建立启动类
package com.atm.cloud;
import java.util.Scanner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class MyRibbonServer {
public static void main(String[] args) {
//读取控制台输入作为端口参数
Scanner scanner=new Scanner(System.in);
String port=scanner.nextLine();
//设置启动的服务端口
new SpringApplicationBuilder(MyRibbonServer.class).properties(
"server.port=" + port).run(args);
}
}
- 运行main方法,并在控制台输入端口号,即可启动web服务器
- 接下来编写控制器,添加一个REST服务
2.1.3、编写控制器
package com.atm.cloud;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@RequestMapping(value="/person/{personId}",method= RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public Person findPerson(@PathVariable("personId")Integer personId,
HttpServletRequest request){
Person person=new Person();
person.setId(personId);
person.setName(request.getRequestURL().toString());
person.setAge(18);
return person;
}
@GetMapping("/hello")
public String hello(){
return "Hello Ribbon";
}
}
- 在控制器中,发布了两个REST服务。
2.2、编写请求客户端
- 新建Maven项目:atm_ribbon_client
2.2.1、引入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atm.cloud</groupId>
<artifactId>atm_ribbon_client</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>atm_ribbon_client Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Spring Cloud -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- ribbon -->
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
<build>
<finalName>atm_ribbon_client</finalName>
</build>
</project>
2.2.2、测试类编写
package com.atm.cloud;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.client.http.RestClient;
public class MyRESTClient {
public static void main(String[] args) {
// 设置请求的服务器
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.listOfServers",
"localhost:8080,localhost:8081");
// 获取REST请求客户端
RestClient client = (RestClient) ClientFactory
.getNamedClient("my-client");
// 创建请求实例
HttpRequest request = HttpRequest.newBuilder().uri("/person/1").build();
//发送6次请求到服务器中
for (int i = 0; i < 6; i++) {
try {
HttpResponse response=client.executeWithLoadBalancer(request);
String result=response.getEntity(String.class);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
- 使用了ConfigurationManager来配置了请求的服务器列表
- 为“localhos:8080”和”localhost:8081”,再使用RestClient对象,向“/person/1”地址发送6次请求
- 分别以8080端口和8081端口启动MyRibbonServer(atm_ribbon_server)
- 根据输入我们可以知道,RestClient轮流向8080与8081端口发送请求
- 可见,RestClient已经帮我们实现了负载均衡的功能
2.3、Ribbon配置
- 在编写客户端时,使用了ConfigurationManager来配置,除了在代码中指定配置项外,还可以将配置放到”.properties”文件中,ConfigurationManager的loadPropertiesFromResource方法可以指定properties文件的位置,配置格式如下:
<client>.<nameSpace>.<property>=<value>
- 其中client为客户的名称,声明该配置属于哪一个客户端,在使用ClientFactory时可以传入客户端的名称,即可返回对应的“请求客户端”实例
- nameSpace为该配置的命名空间,默认为“ribbon”
- property为属性名
- value为属性值
- 如果想对全部的客户端生效,可以将客户端名称去掉,直接以“< nameSpace >.< property >”的格式进行配置
- 以下的配置,为客户端指定服务器生效
my-client.ribbon.listOfServers=localhost:8080,localhost:8081
- Ribbon的配置,同样可以使用SpringCloud的配置文件(application.yml)
更多推荐
已为社区贡献8条内容
所有评论(0)