Spring Cloud 笔记(三)Netflix Ribbon(负载均衡)

快来打我* 2023-10-08 11:36 81阅读 0赞

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

1.简介

Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供着地址列表后,Ribbon就可以基于某种负载均衡算法,自动的帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询,随机等。当然,我们也可以为Ribbon实现自定义的负载均衡算法。

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

Ribbon 子模块

Ribbon 主要有以下三大子模块:

  • ribbon-core:该项目为Ribbon项目的核心,主要包括负载均衡接口定义、客户端接口定义、内置负载均衡实现等API。
  • ribbon-eureka:为Eureka提供的负载均衡实现类。
  • ribbon-httpclient:对Apache的HttpClient进行封装,该模块提供了含有负载均衡功能的REST客户端。
负载均衡器组件

Ribbon的负载均衡器主要与集群中的各个服务器进行通信,负载均衡器需要提供以下功能:

  • 维护服务的IP、DNS名称等信息
  • 根据特定的逻辑在服务器列表中循环。

为了实现负载均衡的基础功能,Ribbon 的负载均衡器有以下三大子模块:

  • Rule:一个逻辑组件,这些逻辑将会决定,从服务器中返回哪个服务器实例
  • Ping:该组件主要使用定时器,来确保服务器网络可以连接
  • ServerList:服务器列表,可以通过静态的配置确定负载的服务器,也可以动态指定服务器列表。如果动态指定服务器列表,则会有后台线程来刷新该列表

本次关于Ribbon的学习,主要围绕负载均衡器组件进行,下面搞个demo:

首先创建一个springboot项目,添加web依赖,用作服务器端,并以不同的端口启动,修改入口类函数,代码如下:

  1. import java.util.Scanner;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.boot.builder.SpringApplicationBuilder;
  4. @SpringBootApplication
  5. public class FirstRibbonServerApplication {
  6. public static void main(String[] args) {
  7. Scanner scan = new Scanner(System.in);
  8. String port = scan.nextLine();
  9. new SpringApplicationBuilder(FirstRibbonServerApplication.class).properties("server.port="+port).run(args);
  10. //SpringApplication.run(FirstRibbonServerApplication.class, args);
  11. }
  12. }

并随意创建一个controller,编写一个方法,用于返回Json/字符串,之后:
分别用8080/8081端口启动程序,之后使用Ribbon编写客户端调用两个服务,代码如下:

  1. import org.springframework.boot.autoconfigure.SpringBootApplication;
  2. import com.netflix.client.ClientFactory;
  3. import com.netflix.client.http.HttpRequest;
  4. import com.netflix.client.http.HttpResponse;
  5. import com.netflix.config.ConfigurationManager;
  6. import com.netflix.niws.client.http.RestClient;
  7. @SpringBootApplication
  8. public class FirstRibbonClientApplication {
  9. public static void main(String[] args) throws Exception {
  10. //SpringApplication.run(FirstRibbonClientApplication.class, args);
  11. ConfigurationManager.getConfigInstance().setProperty("my-client.ribbon.listOfServers", "localhost:8080,localhost:8081");
  12. @SuppressWarnings("deprecation")
  13. RestClient client=(RestClient) ClientFactory.getNamedClient("my-client");
  14. HttpRequest request = HttpRequest.newBuilder().uri("/hello/jackshen").build();
  15. for (int i = 0; i < 6; i++) {
  16. HttpResponse response = client.executeWithLoadBalancer(request);
  17. String result = response.getEntity(String.class);
  18. System.out.println("+++++++++++++++++++++++++++++++++++"+result);
  19. }
  20. }
  21. }

最终在客户端会返回如下信息:

  1. http://localhost:8080/hello/jackshen
  2. http://localhost:8081/hello/jackshen
  3. http://localhost:8080/hello/jackshen
  4. http://localhost:8081/hello/jackshen
  5. http://localhost:8080/hello/jackshen
  6. http://localhost:8081/hello/jackshen

以上是:Ribbon原生API使用方式

Ribbon配置

在编写客户端时,使用了 ConfigurationManager 来设置配置项,除了在代码中指定配置 项 外 , 还 可 以 将 配 置 放 到 “ .properties ” 文 件 中 , ConfigurationManager 的loadPropertiesFromResources 方法可以指定 properties 文件的位置,配置格式如下:

  1. <client>.<nameSpace>.<property>=<value>

其中为客户的名称,声明该配置属于哪一个客户端,在使用 ClientFactory 时可传入客户端的名称,即可返回对应的“请求客户端”实例。为该配置的命名空间,默认为“ribbon”,为属性名,为属性值。如果想对全部的客户端生效,可以将客户端名称去掉,直接以“.”的格式进行配置。以下的配置,为客户端指定服务器列表:

  1. my-client.ribbon.listOfServers=localhost:8080,localhost:8081

Ribbon 的配置,同样可以使用在 Spring Cloud 的配置文件(即 application.yml)中使
用。

spring 的application.yml 中配置自定义规则和ping类,配置内容如下:
  1. cloud-provider:
  2. ribbon:
  3. NFLoadBalancerRuleClassName: org.crazyit.cloud.MyRule
  4. NFLoadBalancerPingClassName: org.crazyit.cloud.MyPing
  5. listOfServers: http://localhost:8080/,http://localhost:8081/
springboot类配置方法如下:
  1. package com.panku.conf;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import com.netflix.loadbalancer.IPing;
  5. import com.netflix.loadbalancer.IRule;
  6. import com.panku.domain.MyPing;
  7. import com.panku.domain.MyRule;
  8. @Configuration
  9. public class MyConf {
  10. @Bean
  11. public IRule getRule() {
  12. return new MyRule();
  13. }
  14. @Bean
  15. public IPing getPing() {
  16. return new MyPing();
  17. }
  18. }
  19. package com.panku.conf;
  20. import org.springframework.cloud.netflix.ribbon.RibbonClient;
  21. @RibbonClient(name="cloud-provider",configuration=MyConf.class)
  22. public class CloudProviderConfig {
  23. }

调用方法如下:

  1. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.bind.annotation.PathVariable;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import org.springframework.web.client.RestTemplate;
  8. @RestController
  9. @Configuration
  10. public class InvokerController {
  11. @Bean
  12. @LoadBalanced
  13. public RestTemplate getRestTpl() {
  14. return new RestTemplate();
  15. }
  16. @RequestMapping("/hello/{name}")
  17. public String hello(@PathVariable("name")String name) {
  18. RestTemplate restTpl = getRestTpl();
  19. String json = restTpl.getForObject("http://cloud-provider/hello/"+name, String.class);
  20. return json;
  21. }
  22. }
RestTemplate 负载均衡原理
@LoadBalanced 注解概述

RestTemplate 本是 spring-web 项目中的一个 REST 客户端访问类,它遵循 REST 的设计原则,提供简单的 API 让调用去访问 HTTP 服务器。RestTemplate 本身不具有负载均衡的功能,该类也与 Spring Cloud 没有关系,但为何加入@LoadBalanced 注解后,一个RestTemplate 实例就具有负载均衡的功能呢?实际上这要得益于 RestTemplate 的拦截器功能。
在 Spring Cloud 中,使用@LoadBalanced 修饰的 RestTemplate,在 Spring 容器启动时,会为这些被修饰过的 RestTemplate 添加拦截器,拦截器中使用了 LoadBalancerClient来处理请求,LoadBalancerClient 本来就是 Spring 封装的负载均衡客户端,通过这样间接处理,使得 RestTemplate 就拥有了负载均衡的功能

REST 客户端 Feign 介绍

Feign 是一个 Github 上一个开源项目,目的是为了简化 Web Service 客户端的开发。在使用 Feign 时,可以使用注解来修饰接口,被注解修饰的接口具有访问 Web Service 的能力,这些注解中既包括了 Feign 自带的注解,也支持使用第三方的注解。除此之外,Feign还支持插件式的编码器和解码器,使用者可以通过该特性,对请求和响应进行不同的封装与解析。
Spring Cloud 将 Feign 集成到 netflix 项目中,当与 Eureka、Ribbon 集成时,Feign 就
具有负载均衡的功能。Feign 本身在使用上的简便性,加上与 Spring Cloud 的高度整合,使
用该框架在 Spring Cloud 中调用集群服务,将会大大降低开发的工作量

调用方法:
1.在入口类添加注解:@EnableFeignClients
2.编写接口类:内容如下:

  1. package com.panku.icloud;
  2. import org.springframework.cloud.openfeign.FeignClient;
  3. import org.springframework.web.bind.annotation.PathVariable;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. @FeignClient("cloud-provider")
  6. public interface HelloClient {
  7. @RequestMapping("/hello/{name}")
  8. String hello(@PathVariable("name")String name);
  9. }

3.编写调用控制器,内容如下:

  1. package com.panku.controller;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import org.springframework.web.client.RestTemplate;
  10. import com.panku.icloud.HelloClient;
  11. @RestController
  12. public class InvokerController {
  13. @Autowired
  14. private HelloClient helloClient;
  15. @RequestMapping("/simhello/{name}")
  16. public String simHello(@PathVariable("name")String name) {
  17. return helloClient.hello(name);
  18. }
  19. }

注意:springboot2.0之后所feign的starter名称变为:spring-cloud-starter-openfeign

关注公众号【程序员每日一学】让我们每天一起学习进步~

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,81人围观)

还没有评论,来说两句吧...

相关阅读