Spring Cloud【Finchley】-04使用Ribbon实现客户端负载均衡

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
网络型负载均衡 NLB,每月750个小时 15LCU
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Spring Cloud【Finchley】-04使用Ribbon实现客户端负载均衡

20190806093230928.jpg


概述


Spring Cloud-03将微服务注册到Eureka Server上 + 为Eureka Server添加用户认证中遗留的问题还记得吧 ,对,服务消费者调用服务提供者是硬编码的方式,虽然把地址配置到了application.yml中,但是一旦服务端的地址发生改变,那肯定是要修改配置文件的。


如何解决呢? Spring Cloud整合了Ribbon.


Ribbon是Nextflix发布的负载均衡器,为Ribbon配置服务提供者地址后,Ribbon就可以基于某种负载均衡的算法,自动帮助服务消费者请求。


Ribbon支持轮询、随机等负载均衡算法,当然也支持实现自定义的负载均衡算法。


在Spring Cloud中,当Ribbon和Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者的地址列表,并基于某种负载均衡算法,请求其中一个服务提供者实例。


20181208230245273.png

Ribbon演示

服务提供者微服务改造为使用MySql数据库


当然了,这一步不是必须的。

Step1 修改pom.xml增加mysql的依赖


<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
</dependency>


Step2: applicaiton.yml中关于数据库的部分调整为

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/artisan?useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver


新建服务消费者微服务,配置Ribbon


Step1: 在maven父工程上右键新建maven module ,名称为:micorservice-consumer-movie-ribbon


20181209130835569.png


20181208231214137.png

Step2: pom.xml引入ribbon依赖

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>


Step3: 为RestTemplate添加@LoadBalanced注解


20181208231422424.png


只需要为RestTemplate添加@LoadBalanced注解,就可以为RestTemlate整合Ribbon,使其具备负载均衡的能力


Step4: 修改Controller层代码,将地址调整为注册在Eureka上的虚拟主机名

package com.artisan.microservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.artisan.microservice.model.User;
import lombok.extern.slf4j.Slf4j;
@RestController
@Slf4j
public class MovieController {
  @Autowired
  private RestTemplate restTemplate;
  @Autowired
  LoadBalancerClient loadBalancerClient;
  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
   // 调用注册在Eureka上的服务端的地址
    return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);
  }
  @GetMapping("/callProvider")
  public String callUserInstance() {
    ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
    // 打印当前选择的哪个节点
    log.info("serviceId: {} , host: {} ,port: {} ,uri: {}" ,serviceInstance.getServiceId() , serviceInstance.getHost(), serviceInstance.getPort(),serviceInstance.getUri());
    return serviceInstance.getUri().toString();
  }  
}


我们把地址修改为了http://microservice-provider-user/user , 其中

microservice-provider-user用户微服务的虚拟主机名,是注册在Eureka Server上的名字,也是服务提供者微服务的配置文件中配置的spring.application.name


20181208233812854.png

当Ribbon和Eureka同时使用时,会自动将虚拟主机名映射为微服务的网络地址。

同时为了更加直观的获取当前选择的用户微服务节点,我们新增加了个方法callProvider,待会测试就可以看到效果了。


Step5: 验证Ribbon提供的能力


1.启动Eureka Server

2.启动两个 microservice-provider-user实例 。(在STS中启动一个后,修改下application.yml的端口,再次run as spring boot app 即可启动第二个实例,以此类推)

3.启动microservice-provider-movie-ribbon

4.访问Eureka Server的页面,查看是否注册成功


http://localhost:8761/login

20181208235738913.png


登录后,可以看到2个服务提供者,1个服务消费者都成功的注册到了Eureka Server上。


20181208235823822.png

我们在服务消费者微服务,调用的地址为



20181209000259294.png

,对应两个服务提供者的地址。


同时我们在服务消费者微服务工程中,为RestTemplate标注了@LoadBalanced注解,所以会使用Ribbon的负载均衡算法来分发到不同的服务提供者地址


多次访问 http://localhost:7902/movie/1 ,观察控制台每个节点的日志输出情况。


同时访问http://localhost:7902/callProvider


20181209000955263.png

20181209001010286.png

注意事项


默认情况下,虚拟主机名和服务名称是一致的,也可以通过eureka.instance.virtual-host-name或者eureka.instance.secure-virtual-host-name指定虚拟主机名


不能将restTemplate.getForObject()和loadBalancerClient写在同一个方法中,两者会冲突,因为RestTemplate实际上是一个Ribbon客户端,本身已经包含了choose的行为


虚拟主机名不能包含"_"之类的字符,否则Ribbon再调用的时候会抛出异常


源码


https://github.com/yangshangwei/SpringCloudMaster



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
10月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
855 61
|
9月前
|
负载均衡 Java Nacos
常见的Ribbon/Spring LoadBalancer的负载均衡策略
自SpringCloud 2020版起,Ribbon被弃用,转而使用Spring Cloud LoadBalancer。Ribbon支持轮询、随机、加权响应时间和重试等负载均衡策略;而Spring Cloud LoadBalancer则提供轮询、随机及Nacos负载均衡策略,基于Reactor实现,更高效灵活。
599 0
|
12月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
缓存 负载均衡 Java
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
文章标题为“OpenFeign的Ribbon负载均衡详解”,是继OpenFeign十大可扩展组件讨论之后,深入探讨了Ribbon如何为OpenFeign提供负载均衡能力的详解。
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
|
12月前
|
负载均衡 Java 开发者
Ribbon框架实现客户端负载均衡的方法与技巧
Ribbon框架为微服务架构中的客户端负载均衡提供了强大的支持。通过简单的配置和集成,开发者可以轻松地在应用中实现服务的发现、选择和负载均衡。适当地使用Ribbon,配合其他Spring Cloud组件,可以有效提升微服务架构的可用性和性能。
166 0
|
4月前
|
负载均衡 前端开发 应用服务中间件
Tomcat的负载均衡和动静分离(与nginx联动)
总的来说,负载均衡和动静分离是提高Web应用性能的两个重要手段。通过合理的配置和使用,我们可以让Web应用更好地服务于用户。
145 21
|
缓存 负载均衡 算法
解读 Nginx:构建高效反向代理和负载均衡的秘密
解读 Nginx:构建高效反向代理和负载均衡的秘密
229 2
|
9月前
|
负载均衡 前端开发 应用服务中间件
负载均衡指南:Nginx与HAProxy的配置与优化
负载均衡指南:Nginx与HAProxy的配置与优化
584 3
|
负载均衡 算法 应用服务中间件
nginx自定义负载均衡及根据cpu运行自定义负载均衡
nginx自定义负载均衡及根据cpu运行自定义负载均衡
299 1
|
运维 负载均衡 算法
SLB与NGINX的异同是什么
SLB与NGINX的异同是什么
1511 2