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

举报
小工匠 发表于 2021/09/10 23:14:51 2021/09/10
【摘要】 文章目录 概述Ribbon演示服务提供者微服务改造为使用MySql数据库新建服务消费者微服务,配置Ribbon注意事项 源码 概述 Spring Cloud-03将微服务注册到E...


在这里插入图片描述

概述

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

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

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

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

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

在这里插入图片描述


Ribbon演示

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

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

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

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

  
 
  • 1
  • 2
  • 3
  • 4

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

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

在这里插入图片描述

在这里插入图片描述


Step2: pom.xml引入ribbon依赖

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

  
 
  • 1
  • 2
  • 3
  • 4

Step3: 为RestTemplate添加@LoadBalanced注解

在这里插入图片描述

只需要为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();
  }  
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

我们把地址修改为了http://microservice-provider-user/user , 其中
microservice-provider-user用户微服务的虚拟主机名,是注册在Eureka Server上的名字,也是服务提供者微服务的配置文件中配置的spring.application.name在这里插入图片描述
当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

在这里插入图片描述

登录后,可以看到2个服务提供者,1个服务消费者都成功的注册到了Eureka Server上。
在这里插入图片描述

我们在服务消费者微服务,调用的地址为
在这里插入图片描述,对应两个服务提供者的地址。

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

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

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

在这里插入图片描述
在这里插入图片描述


注意事项

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

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

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


源码

https://github.com/yangshangwei/SpringCloudMaster

文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。

原文链接:artisan.blog.csdn.net/article/details/84900649

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。