SpringCloud五大神兽02-Ribbon/Feign负载均衡

1.简介

  • Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。使用Ribbon的时候,只要服务提供者的名称相同,就自动形成了集群,并且有默认负载均衡策略(轮询)。
  • Feign是对Ribbon的封装,简化了服务的调用方式,即调用服务的时候,不再需要拼接需要传递的参数到访问地址上,而是采用定义接口(遵循Feign提供的模板)的方式去实现,Feign会完全代理HTTP请求。

2.使用

创建两个微服务,一个叫Consumer,一个叫Provider,用Consumer去调用Provider。当然,Eureka也是必不可少的。这三个微服务作为子模块,它们的父模块的pom.xml还是采用依赖版本管理的方式。

<properties>
      <spring.cloud-version>Finchley.SR4</spring.cloud-version>
      <spring.boot-version>2.0.5.RELEASE</spring.boot-version>
</properties>
<dependencyManagement>
      <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-dependencies</artifactId>
              <version>${spring.boot-version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>${spring.cloud-version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
      </dependencies>
</dependencyManagement>

2.1.Ribbon

2.1.1.导入依赖

  • 服务消费者Consumer:Eureka客户端、Ribbon场景启动器
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

        <!-- Ribbon场景启动器 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
   </dependency>
</dependencies>
  • 服务提供者Provider:Eureka客户端(不需要Ribbon依赖)
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2.1.2.写启动类

  • 服务消费者Consumer:配置RestTemplate、配置负载均衡策略
@SpringBootApplication
@EnableEurekaClient //可写可不写
public class RibbonConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApp.class,args);
    }
    /**
     * @LoadBalanced: 开启负载均衡策略,默认是轮询
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    /**
     * 修改负载均衡策略(IRule是一个接口,只能new它的实现类)
     *      new RandomRule():随机策略
     *      new WeightedResponseTimeRule():权重策略
     *      new RoundRobinRule():轮询策略--默认
     * @return
     */
    @Bean
    public IRule iRule(){
        return new RoundRobinRule();
    }
}
  • 服务提供者Provider:正常写即可
@SpringBootApplication
@EnableEurekaClient //可写可不写
public class Provider8082App {
    public static void main(String[] args) {
        SpringApplication.run(Provider8082App.class,args);
    }
}

2.1.3.写yml配置

  • 服务消费者Consumer:配置端口和服务名称、注册服务到Eureka注册中心
server:
  port: 9090

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    instance-id: ribbon-consumer:9090    #自定义一个服务id名称,否则就默认使用当前计算机名称作为服务的id

spring:
  application:
    name:  RIBBON-CONSUMER   #服务名称标识 如果不配置,则默认是UNKNOWN
  • 服务提供者Provider:配置端口和服务名称、注册服务到Eureka注册中心
server:
  port: 8082

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    instance-id: service-provider-ribbon:8082    #自定义一个服务id名称,否则就默认使用当前计算机名称作为服务的id

spring:
  application:
    name:  SERVICE-PROVIDER-RIBBON   #服务名称标识 如果不配置,则默认是UNKNOWN

2.1.4.写Controller

仅做一个简单的测试,在浏览器访问服务消费者,服务消费者调用服务提供者的服务,返回一个字符串在浏览器上展示

  • 服务消费者Consumer:用RestTemplate来发HTTP请求,调用Provider
@RestController
public class RibbonConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/ribbon/consumer")
    public String consumer(){
        System.out.println("consumer...................");
        //发送get请求,访问另一个provider服务
        //如果需要传递参数,需要拼接到URL上
        String s = restTemplate.getForObject("http://SERVICE-PROVIDER-RIBBON/ribbon/provider", String.class);

        return s;
    }
}
  • 服务提供者Provider:返回一个字符串
@RestController
public class ProviderController8082 {
    /**
     * @return
     */
    @GetMapping("/ribbon/provider")
    public String provider(){
        System.out.println("provider..............");
        return "*****8082*****";
    }
}

2.1.5.浏览器访问测试

浏览器访问测试

2.2.Feign

Ribbon和Feign都是配置在服务消费者上,服务提供者的配置是一样的

2.2.1.导入依赖

  • 服务消费者Consumer:Eureka客户端、Feign场景启动器(注意:依赖的名字叫openfeign
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- feign场景启动器 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>

2.2.2.写启动类

  • 服务消费者Consumer:
    注意:一定要加@EnableFeignClients注解
/**
 * @EnableFeignClients 这个注解表示开启动态代理
 *  会自动递归扫描当前启动类所在的包【扫描所有添加了@FeignClient注解的接口,然后采用动态代理技术生成实现类,
 *  创建对象保存到Spring容器中】
 */
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
public class FeignConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(FeignConsumerApp.class,args);
    }

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

2.2.3.写yml配置

  • 服务消费者Consumer:端口和服务名称配置、服务注册到Eureka服务中心
server:
  port: 9091

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    instance-id: feign-consumer:9091    #自定义一个服务id名称,否则就默认使用当前计算机名称作为服务的id

spring:
  application:
    name:  FEIGN-CONSUMER   #服务名称标识 如果不配置,则默认是UNKNOWN

2.2.4.写Feign客户端接口

Feign客户端接口写在服务消费者方,它是一个接口,接口上需要添加@FeignClient注解
接口中的方法参数、返回值、请求地址必须和对应的服务提供者Controller中的方法定义的一致。
为方便起见,可以直接把服务提供者中对应的方法copy过来,删除方法体即可。

/**
 * @FeignClient 表明当前接口是Feign的客户端接口,并在value属性中指定所调用的服务名称
 */
@FeignClient(value = "SERVICE-PROVIDER")
@Component
public interface ProviderClient {
    @GetMapping("/feign/provider")
    String provider();
}

2.2.5.写Controller

  • 服务消费者Consumer:依赖注入Client对象,调用方法即可(使用方式类似于mapper层接口)
@RestController
public class FeignConsumerController {
    @Autowired
    private ProviderClient providerClient;

    @GetMapping("/feign/consumer")
    public String feignConsumer(){
        System.out.println("feignConsumer.....................");
        String s = providerClient.provider();
        return s;
    }
}

2.2.6.浏览器访问测试

浏览器访问

3.Ribbon和Feign的区别

Feign是通过定义FeignClient接口的方式调用(类似于mapper层接口的使用方式),我们只需要定义好接口,在接口上加@FeignClient注解并指定要调用的服务名称或者服务集群名称,在启动类上加@EnableFeignClients注解,Feign底层就会动态代理生成FeignClient接口的实现类,实现类中重写接口的方法,内部还是采用的Ribbon的方式去调用(用RestTemplate发送HTTP请求)。
由于Feign是对Ribbon进行的封装,所以Feign也有Ribbon的负载均衡。
另外,Feign内部也集成了Hystrix,所以我们一般会使用Feign。

4.总结

简单理解,Ribbon是SpringCloud中微服务之间的调用方式,有了它,我们可以通过微服务的名称去调用对应的微服务,如果多个微服务有相同的名称,就自动形成了集群,并且Ribbon会自动对集群进行负载均衡,默认的策略是轮询,也可以自己定义负载均衡策略。
Feign是对Ribbon进行的封装,拥有Ribbon的所有功能,优化的地方在于采用了定义FeignClient接口的方式去调用微服务,发送HTTP请求的步骤封装到了底层自动实现,使用更方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值