Spring Cloud(Dalston.SR5)--Ribbon 中间层负载均衡
Spring Cloud 集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,使用 @LoadBalanced 修饰的 RestTemplate 类拥有了负载均衡功能,在 Spring 容器启动时,会为这些修饰过的 RestTemplate 添加拦截器,拦截器中使用 LoadBalancerClient 来处理请求,LoadBalancerClient 是 Spring 封装的负载均衡客户端,通过这样间接的处理,使得 RestTemplate 拥有了负载均衡的功能。下面我们在 Spring Cloud 中使用 Ribbon 示例如下:
- 创建项目
创建名称为 spring-cloud-ribbon-client 的 Spring Cloud 项目,修改 POM.xml 中增加以下依赖项:
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.lixue</groupId>
<artifactId>spring-cloud-ribbon-client</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-cloud-ribbon-client</name>
<description>spring-cloud-ribbon-client</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/><!--lookupparentfromrepository-->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 创建 Ribbon 配置类
Spring Cloud 中,可以将自定义的负载均衡规则以及自定义 Ping、ServerList 、ServerListFilter 和ServerListUpdater 等增加到服务器调用者,下面的 MyPing 和 MyServerListFilter 类为自定义类,注意,如果希望该 Ribbon 配置类只用于部分服务调用,则一定不能处于使用该 @ComponentScan 注解类的同一个包中,如果处于同一个包中,会被所有 Ribbon 使用。
package org.lixue.ribbon;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerListFilter;
import org.springframework.context.annotation.Bean;
public class MyRibbonConfig{
@Bean
public IPing getPing(){
return new MyPing();
}
@Bean
public ServerListFilter<Server> getServerListFilter(){
return new MyServerListFilter();
}
}
除了使用自定义配置类外,还可以使用配置文件的方式来配置定义各个属性,配置项和单独使用 Ribbon 一致,比如上面类的属性,定义到 application.yml 中,如下:
helloworld-provider:
ribbon:
# 配置 IPing 的实现类
NFLoadBalancerPingClassName:org.lixue.ribbon.MyPing
# 用于处理服务器列表拦截过滤
NIWSServerListFilterClassName:org.lixue.ribbon.MyServerListFilter
- 创建配置类
将 Rest 服务调用的 RestTemplate 增加 @LoadBalanced 和 @Bean 注解标注,表示该 RestTemplate 支持负载均衡。
package org.lixue.ribbonclient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestClientConfiguration{
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 创建客户端类
客户端类比较简单,使用 RestTemplate 实例,请求Rest 服务的 Url 即可,Url 的不是具体的地址,而是根据名称来调用服务,示例:http://helloworld-provider/speak ,表示调用 helloworld-provider 服务的 speak ,最终请求的的地址是通过解析 helloworld-provider 服务的注册 Eureka 的地址,通过负载均衡决定实际的 Url 地址。
package org.lixue.ribbonclient;
import org.lixue.ribbon.MyRibbonConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
// 如果使用配置文件,则无需使用 @RibbonClient 注解
@RibbonClient(name="helloworld-provider",configuration=MyRibbonConfig.class)
@Component
public class HelloWorldServiceClient{
@Autowired
private RestTemplate restTemplate;
public String speak(Stringbody) throws UnsupportedEncodingException{
StringencodeBody="";
if(body!=null){
encodeBody="?body="+URLEncoder.encode(body,"utf-8");
}
try{
return restTemplate.getForObject("http://helloworld-provider/speak"+encodeBody,String.class);
}catch(Exceptionex){
ex.printStackTrace();
System.out.println("Exceptionisclass"+ex.getClass().getName());
return ex.getMessage();
}
}
}
- 创建 REST 服务
package org.lixue.ribbonclient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
@RestController
public class InvokerController{
@Autowired
private HelloWorldServiceClient helloWorldServiceClient;
@RequestMapping(name="speak",method=RequestMethod.GET)
public String speak(@RequestParam(name="body",required=false) String body)throws UnsupportedEncodingException{
return helloWorldServiceClient.speak(body);
}
}
- 增加配置
调整
src/main/resources 目录中的 application.yml 配置文件,调整后配置如下:#配置应用名称
spring:
application:
name:spring-cloud-ribbon-client
#服务端口
server:
#设置eureka服务注册中心的地址,如果多个以逗号分割
eureka:
client:
service-url:
#defaultZone表示默认的区域的eureka服务地址,多个使用逗号分割
defaultZone:http://eurekaserver01:9000/eureka/,http://eurekaserver02:9000/eureka/
# 使用代码配置类无需配置
helloworld-provider:
ribbon:
NFLoadBalancerPingClassName:org.lixue.ribbon.MyPing
NIWSServerListFilterClassName:org.lixue.ribbon.MyServerListFilter
- 测试验证
启动 eureka-server 服务、启动多个 service-provider 服务(服务器地址或端口区分),启动该项目,访问地址 http://localhost:8085/speak ,多刷新几次可以看到分别访问了不同的 service-provider 服务,如下:
hello world port:8001
hello world port:8002
常用配置
<client> 表示的调用服务名称;<namespace> 为配置的命名空间,默认为 ribbon;如果是全局配置,则 <client>.<namespace>使用 ribbon 替换,例如,ribbon.listOfServers 表示全局的服务器列表;
设置连接服务超时时间(毫秒) |
||
<client>.<namespace>.ReadTimeout |
60000 |
设置读取服务超时时间(毫秒) |
<client>.<namespace>.OkToRetryOnAllOperations |
false |
对所有操作请求都进行重试 |
<client>.<namespace>.MaxAutoRetriesNextServer |
|
切换实例的重试次数 |
<client>.<namespace>.MaxAutoRetries |
|
对当前实例的重试次数 |
<client>.<namespace>.NFLoadBalancerRuleClassName |
|
配置负载均衡规则 IRule 的实现类 |
<client>.<namespace>.NFLoadBalancerClassName |
|
配置负载均衡实现类 |
<client>.<namespace>.NIWSServerListClassName |
|
服务器列表处理类,用来维护服务器列表,Ribbon 已经实现动态服务列表 |
<client>.<namespace>.NIWSServerListFilterClassName |
|
用于处理服务器列表拦截过滤 |
Spring Cloud(Dalston.SR5)--Ribbon 中间层负载均衡的更多相关文章
- Spring Cloud:使用Ribbon实现负载均衡详解(下)
在上一篇文章(Spring Cloud:使用Ribbon实现负载均衡详解(上))中,我对 Ribbon 做了一个介绍,Ribbon 可以实现直接通过服务名称对服务进行访问.这一篇文章我详细分析一下如何 ...
- Spring Cloud:使用Ribbon实现负载均衡详解(上)
1. 什么是 Ribbon? Spring Cloud Ribbon 是一套实现客户端负载均衡的工具.注意是客户端,当然也有服务端的负载均衡工具,我们后面再介绍.可以认为 Ribbon 就是一个负载均 ...
- 3.Spring Cloud初相识--------Ribbon客户端负载均衡
前言: 在生产环境中,未避免单点故障,每个微服务都会做高可用部署. 通白的说,就是每一个一模一样的服务会根据需求提供多分在多台机器上. 那么在大并发的情况下,如何分配服务可以快速得到响应,就成为了我们 ...
- Spring Cloud第四篇 | 客户端负载均衡Ribbon
本文是Spring Cloud专栏的第四篇文章,了解前三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...
- 史上最全Spring Cloud Alibaba--Nacos教程(涵盖负载均衡、配置管理、多环境切换、配置共享/刷新、灰度、集群)
能够实现Nacos安装 基于Nacos能实现应用负载均衡 能基于Nacos实现配置管理 配置管理 负载均衡 多环境切换 配置共享 配置刷新 灰度发布 掌握Nacos集群部署 1 Nacos安装 Nac ...
- Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群
通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...
- Spring Cloud(Dalston.SR5)--Feign 声明式REST客户端
Spring Cloud 对 Feign 进行了封装,集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,Spring Cloud 实现的 Feign 客户端类名为 LoadBala ...
- Spring Cloud(Dalston.SR5)--Eureka 服务消费
服务被注册.发布到 Eureka 服务器后,需要有程序去发现他,并且进行调用,称为服务消费,一个服务可能会部署多个实例,调用过程可能涉及负载均衡.服务器查找等问题,这些问题 Netflix 项目已经帮 ...
- Spring Cloud(Dalston.SR5)--Zuul 网关
我们使用 Spring Cloud Netflix 中的 Eureka 实现了服务注册中心以及服务注册与发现:而服务间通过 Ribbon 或 Feign 实现服务的消费以及均衡负载:使用Hystrix ...
随机推荐
- Java学习笔记9(面象对象9:多态)
多态概述 多态是继封装.继承后,面对对象的第三大特性. 现实事物经常会出现多态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一 ...
- python中闭包
闭包是指内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure). 闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变 ...
- mysqli扩展库的预处理
预处理的特点:1.效率高,执行速度快 2.安全性高,可以防止sql注入 $mysqli 中的函数 $stmt=$mysqli->prepare($sql); 预备一条s ...
- async/await学习笔记
async/await 的目的是简化使用 promises 的写法. 让我们来看看下面的例子: // 一个标准的 JavaScript 函数 function getNumber1() { r ...
- Ubuntu add sudo
为了安全起见,ubuntu中的普通用户一般没有root权限,因此即使知道管理员密码也无法使用sudo,但这个情况可以通过加入sudoer列表或者加入sudo组来改变. 拓展: 不管使用哪种方式,使得一 ...
- HSTS 与 307 状态码
最近线上产品突然在 Chrome 浏览器上出现 307 状态码,并跳转到 https 版.由于 https 尚未部署完毕,导致了相当严重的后果. 但是 307 代码是什么含义呢?页面又为何会出现 30 ...
- shell 脚本中将输出内容赋值给一个变量时的换行问题
for ((i=0; i<4; i++) do ....... done 如果使用 echo $a 输出变量,则变量中的 换行都会被忽略掉,所有内容输出到一行 而使用 echo "$a ...
- 洛谷 P4779 :【模板】单源最短路径(标准版)(Dijkstra+堆优化+链式前向星)
题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 100→60: Ag→Cu: 最终,他因此没能与理想 ...
- 自我复制的3D打印机
RepRap 是人类历史上第一部可以自我复制型的机器. https://reprap.org/wiki/RepRap RepRap 是一部可以生成塑料实物的免费桌面型 3D 打印机.由于 RepRap ...
- hdu4549 M斐波那契数列 矩阵快速幂+快速幂
M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的 ...