Ribbon和RestTemplate负载均衡
  jmWSp8RIQOBK 2023年11月02日 34 0


Ribbon实现负载均衡



官方文档:​​https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.2.0.M3/reference/html/#spring-cloud-ribbon​

文章目录


    • ​​项目结构​​
    • ​​父级依赖​​
    • ​​服务提供者​​
    • ​​依赖​​
    • ​​配置文件​​
    • ​​User​​
    • ​​主程序​​
    • ​​Controller​​
    • ​​服务消费者​​
    • ​​依赖​​
    • ​​User​​
    • ​​Controller​​
    • ​​主程序​​
    • ​​测试​​
    • ​​随机策略​​
    • ​​轮询策略​​

    概述

    下面是截取官方文档的两段话,我们可以大概看一下:

    Ribbon是什么:Ribbon是一个客户端负载均衡器。提供了大量的Http和Tcp客户端行为。Feign已经使用了Ribbon,所以,如果使用​​@FeignClient​​ ,这一部分也被采用。Feign后面也会介绍到。

    Ribbon和RestTemplate负载均衡_SpringCloudAlibaba

    这一部分使用到了Nacos服务注册中心,所以需要先准备好注册中心,前面有介绍。

    项目结构

    Ribbon和RestTemplate负载均衡_spring_02

    父级依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="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.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.9.RELEASE</version>
    <relativePath/>
    </parent>
    <groupId>com.ooyhao</groupId>
    <artifactId>nacos-feign-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
    <java.version>1.8</java.version>
    </properties>

    <modules>
    <module>nacos-feign-service-provider-1</module>
    <module>nacos-feign-service-provider-2</module>
    <module>nacos-feign-service-provider-3</module>
    <module>nacos-feign-service-consumer</module>
    </modules>

    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>0.9.0.RELEASE</version>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>

    负载均衡是面向同一服务的集群使用的,所以我们一般都是将同一服务部署到不同的主机上,即拥有不同Ip、相同或不同端口,本地测试,用端口来标识不同的服务。

    服务提供者

    依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="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.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.ooyhao</groupId>
    <artifactId>nacos-feign-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
    </parent>
    <groupId>com.ooyhao</groupId>
    <artifactId>nacos-feign-service-provider-1</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
    <java.version>1.8</java.version>
    </properties>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>

    配置文件

    下面是三个服务的不同的配置文件:

    1. 配置文件一
    server:
    # 服务端口
    port: 8071
    spring:
    # 项目/服务 名
    application:
    name: feign-service-provider
    cloud:
    nacos:
    discovery:
    # 注册中心地址:端口
    server-addr: 127.0.0.1:8848
    1. 配置文件二
    server:
    # 服务端口
    port: 8072
    spring:
    # 项目/服务 名
    application:
    name: feign-service-provider
    cloud:
    nacos:
    discovery:
    # 注册中心地址:端口
    server-addr: 127.0.0.1:8848
    1. 配置文件三
    server:
    # 服务端口
    port: 8073
    spring:
    # 项目/服务 名
    application:
    name: feign-service-provider
    cloud:
    nacos:
    discovery:
    # 注册中心地址:端口
    server-addr: 127.0.0.1:8848

    其实就是指定相同的服务名,不同的端口,并且配置到注册中心,即可。

    User

    package com.ooyhao.nacosfeignserviceprovider.pojo;

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import java.io.Serializable;

    @Data
    @AllArgsConstructor
    public class User implements Serializable {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    }

    主程序

    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosFeignServiceProvider1Application {
    public static void main(String[] args) {
    SpringApplication.run(NacosFeignServiceProvider1Application.class, args);
    }
    }

    说明:这里会发现一个问题,如果没有写​​@enableDiscoveryClient​​ 注解,也是可以将自身注册到注册中心去的,在网上看到,从Spring Cloud Edgware开始,@EnableDiscoveryClient 或@EnableEurekaClient 可省略,测试结果也是如此,于是我翻阅了一下Spring官方文档,看到了下面这段话,即:​​@EnableDiscoveryClient​​ 不再是必须的了,你可以将DiscoveryClient的实现类置于SpringBoot项目的ClassPath中就可以注册服务。也就是说,我们只需要在POM文件中添加相关依赖,在配置文件中配置相应的配置,就可以自动实现服务注册于发现了。

    Ribbon和RestTemplate负载均衡_ide_03

    ​https://cloud.spring.io/spring-cloud-static/spring-cloud-commons/2.2.0.M3/reference/html/#enablediscoveryclient​

    Controller

    @RestController
    public class IndexController {

    private static Map<Integer,User> users = new HashMap<>();

    static {
    users.put(1,new User(1,"张三","provider-1",18));
    users.put(2,new User(2,"李四","provider-1",19));
    users.put(3,new User(3,"王五","provider-1",20));
    }

    @GetMapping("/user/{id}")
    public User user(@PathVariable("id") Integer id){
    System.out.println("provider 1 rec");
    return users.get(id);
    }
    }

    这里需要修改下不同的服务的password,用于后续观察负载均衡的效果。

    服务消费者

    依赖

    server:
    port: 8080
    spring:
    application:
    name: feign-service-consumer
    cloud:
    nacos:
    discovery:
    server-addr: 127.0.0.1:8848

    # 配置负载均衡策略
    #feign-service-provider:
    # ribbon:
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

    User

    User对象就不再赘述了。将服务提供方的User对象复制过来即可。这里测试发现,服务提供方的User类和服务消费方的User类可以不需要放在相同的包下,这点与RabbitMQ的自动序列化和反序列化要求不同 。

    Controller

    /**
    * 描述:
    * 类【IndexController】
    *
    * @author ouYangHao
    * @create 2019-10-15 9:57
    */
    @RestController
    public class IndexController {

    @Autowired
    private RestTemplate restTemplate;


    @GetMapping("/user/{id}")
    public User user(@PathVariable("id") Integer id){
    User user = restTemplate.getForObject("http://feign-service-provider/user/" + id, User.class);
    System.out.println(user);
    return user;
    }

    }

    这里可以发现,使用RestTemplate进行Http接口调用的时候,使用的是服务名​​feign-service-provider​​ ,而不是IP加端口的形式,这样就把IP地址与服务名的映射关系的任务交给注册中心去维护了。我们只需要知道服务名就可以,至于服务在世界何处不用关心。

    主程序

    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosFeignServiceConsumerApplication {


    @Bean
    public IRule iRule(){
    return new RandomRule();//随机策略
    // return new RoundRobinRule();//轮询策略
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }

    public static void main(String[] args) {
    SpringApplication.run(NacosFeignServiceConsumerApplication.class, args);
    }
    }

    测试

    随机策略

    这里我们先试用随机策略来测试:连续多次刷新访问下面路径:

    ​​http://localhost:8080/user/1​​

    Ribbon和RestTemplate负载均衡_ide_04

    可以看出,当前测试结果符合预定随机策略结果。

    轮询策略

    我们将​​iRule​​方法换成轮询方式,重新启动:

    @Bean
    public IRule iRule(){
    return new RoundRobinRule();//随机策略
    }

    测试结果:

    Ribbon和RestTemplate负载均衡_SpringCloudAlibaba_05


    测试结果符合轮询规则!


    【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

    1. 分享:
    最后一次编辑于 2023年11月08日 0

    暂无评论

    推荐阅读
      Fo7woytj0C0D   2023年12月23日   31   0   0 pythonsedidepythonidesed
    jmWSp8RIQOBK