负载均衡Ribbon
1. Feign 默认集成了 Ribbon
Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单。使用 Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解。Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,默认实现了负载均衡的效果
。所以使用Feign无需任何操作就已经附带了Ribbon负载均衡。
2. 概述
负载均衡是分布式架构的重点,负载均衡机制决定着整个服务集群的性能与稳定。
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行
。
负载均衡解决的是将一个客户端的流量以某种符合最大化资源利用率的方式均摊到服务端所提供的所有实例上
的问题。在这个问题的场景中,后端服务的实例是通过水平扩展的方式来提供高可用的。
3. 负载均衡分类
在微服务架构中,负载均衡是必须使用的技术,通过它来实现系统的高可用、集群扩容等功能。负载均衡可以分为两种:服务端负载均衡和客户端负载均衡。
1、服务器负载均衡
通常所说的负载均衡指服务器负载均衡,由服务端来决定调用哪个节点
,可通过硬件设备或软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx
等,类似的架构图如下:
原理:
通过硬件或软件实现负载均衡均会
维护一个服务端清单
,利用心跳检测等手段进行清单维护,保证清单中都是可以正常访问的服务节点
。当用户发送请求时,会先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法(轮训、随机、加权轮训)从可用的服务端列表中取出一台服务端的地址,接着进行转发,降低系统的压力
。
2、客户端负载均衡
客户端实际上是指服务调用者。在 SpringCloud 中调用者本身集成负载均衡,由调用者决定来调用哪个节点的服务
,这就是客户端负载均衡。
SpringCloud Ribbon是基于客户端的负载均衡工具,它可以将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用。
原理:
Ribbon 维护了一个服务列表,如果服务实例注销或死掉,Ribbon 能够自行将其剔除
。Ribbon 提供了客户端负载均衡的功能,Ribbon 利用从注册中心中读取到的服务信息列表(存储在本地即客户端中),在调用某个服务时,根据负载均衡算法直接请求到具体的微服务实例,常用的负载均衡算法有:轮循、随机、加权轮循、加权随机、地址哈希等方法
。如下图是Ribbon负载均衡的流程图:
3、客户端和服务端负载均衡的区别
两者主要区分点在于服务清单的存放位置:
在客户端负载均衡中,客户端会存储一份服务端清单,它是通过从注册中心进行抓取得到的,同时也需要对此进行维护;而在服务端负载均衡中,服务端自己会维护一份服务端清单
。
4. Ribbon 简介
Spring Cloud Ribbon是一个
基于 HTTP 和 TCP 协议
的客户端负载均衡
工具,它基于Netflix Ribbon实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用
。
Spring Cloud Hoxton.SR6版本不需要引入spring-cloud-starter-netflix-ribbon,已经默认集成
5. 负载均衡@LoadBalanced
Ribbon负载均衡实现,RestTemplate 要加上@LoadBalanced
package com.example.springcloud.ribbon.configuration;
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;
/**
* <pre>
* RestConfiguration
* </pre>
*
* <pre>
* @author mazq
* 修改记录
* 修改后版本: 修改人: 修改日期: 2020/07/31 09:43 修改内容:
* </pre>
*/
@Configuration
public class RestConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
yaml配置:
server:
port: 8082
spring:
application:
name: eureka-service-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
register-with-eureka: false
healthcheck:
enabled: false
instance:
status-page-url-path: http://localhost:8761/actuator/info
health-check-url-path: http://localhost:8761/actuator//health
prefer-ip-address: true
instance-id: eureka-service-consumer8082
image.png
关键点,使用SpringCloud的@LoadBalanced,才能调http://EUREKA-SERVICE-PROVIDER/api/users/? 接口的数据,浏览器是不能直接调的
import com.example.springcloud.ribbon.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
@SpringBootApplication
@EnableEurekaClient
@RestController
@Slf4j
public class SpringcloudRibbonApplication {
@Autowired
RestTemplate restTemplate;
public static void main(String[] args) {
SpringApplication.run(SpringcloudRibbonApplication.class, args);
}
@GetMapping("/findUser/{username}")
public User index(@PathVariable("username")String username){
return restTemplate.getForObject("http://EUREKA-SERVICE-PROVIDER/api/users/"+username,User.class);
}
}
还没有评论,来说两句吧...