四、SpringCloud学习 -- Ribbon

代码地址:https://github.com/becauseoflife/CodeDemo/tree/main/SpringCloud/ribbon/springCloud

1、ribbon是什么?

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具

简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。Ribbon的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer(简称LB∶负载均衡)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法!

2、ribbon能干嘛?

  • LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。
  • 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。
  • 常见的负载均衡软件有Nginx,Lvs等等
  • dubbo、SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
  • 负载均衡简单分类:
    • 集中式LB
      • 即在服务的消费方和提供方之间使用独立的LB设施,如Nginx:反向代理服务器!,由该设施负责把访问请求通过某种策略转发至服务的提供方!
    • 进程式LB
      • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
      • Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!

3、客户端集成 Ribbon

子模块 springcloud-consumer-dept-80 导入 ribbon 依赖 (注:spring-cloud-starter-netflix-eureka-client 3.x.x 版自带有 ribbon,版本有冲突。不用导入ribbon依赖






<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    <version>3.1.1version>
dependency>

配置文件

server:
  port: 80

# Eureka 配置
eureka:
  client:
    register-with-eureka: false # 不向 Eureka 注册自己
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

主启动类开启注解

@EnableEurekaClient

配置负载均衡实现 RestTemplate

package com.example.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @desc
 * @auth llp
 * @date 2022年02月28日 17:44
 */
@Configuration
public class RestConfig {
    @Bean
    @LoadBalanced       // 配置负载均衡实现 RestTemplate
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

修改 contrller 微服务访问地址:

// Ribbon 这里的地址应该是一个变量,通过服务名来访问
private static final String REST_URL_PREFIX = "http://SPRING-PROVIDER-DEPT";    

总结: Ribbon 和 Eureka 整合以后,客户端可以直接调用,不用关心 IP 地址和端口号。即使用服务名即可。

4、使用Ribbon实现负载均衡

四、SpringCloud学习 -- Ribbon_第1张图片

新建数据库 db_02、db_03。新建服务提供者springcloud-provider-dept-8002、springcloud-provider-dept-8003。将springcloud-provider-dept-8001复制一份,修改配置文件中的端口、数据库url、以及Eureka上的描述信息配置文件中的配置。(注:复制文件记得修改 Mapper.xml 中的 SQL 语句中的数据库名称

启动测试

在这里插入图片描述

服务消费访问接口,可以看到以轮询的方式从数据库中查出数据。

5、自定义负载均衡算法

spring-cloud-starter-netflix-eureka-client3.0.x版本是包含对ribbon的依赖的,官方内置了随机和轮询负载均衡策略。

自定义实现负载均衡策略实现 ReactorServiceInstanceLoadBalancer 接口即可(相当于 IRule 接口)。

可以通过 @LoadBalancerClient 注解,指定服务级别的负载均衡策略。

@LoadBalancerClient(name = "SPRING-PROVIDER-DEPT", configuration = MyLoadBalance.class)

四、SpringCloud学习 -- Ribbon_第2张图片

6、Feign负载均衡

6.1、 简介

feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。

SpringCloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。

只需要创建一个接口,然后添加注解即可!

feign,主要是社区,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务访问两种方法

1.微服务名字【ribbon】

2.接口和注解【feign 】

Feign能做什么?

  • Feign旨在使编写Java Http客户端变得更容易
  • 前面在使用Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可。)即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon

  • 利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而且简单的实现了服务调用。
6.2、Feign的使用

模块使用的依赖



<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
    <version>3.1.1version>
dependency>

在 springcloud-api 新增 service 包和接口

package com.example.springcloud.service;

import com.example.springcloud.pojo.Dept;
import feign.Param;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Service
@FeignClient(value = "SPRING-PROVIDER-DEPT")
public interface DeptServiceClient {

    @PostMapping("/dept/add")
    boolean addDept(Dept dept);

    @GetMapping("/dept/get/{id}")
    Dept queryDept(@PathVariable("id") Long id);

    @GetMapping("/dept/list")
    List<Dept> queryAllDept();

}

新建 springcloud-consumer-dept-feign 模块,修改接口类

package com.example.springcloud.controller;

import com.example.springcloud.pojo.Dept;
import com.example.springcloud.service.DeptServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @desc
 * @auth llp
 * @date 2022年02月28日 17:39
 */
@RestController
public class DeptConsumerController {

    @Autowired
    private DeptServiceClient deptServiceClient;

    @RequestMapping("/consumer/dept/add")
    public boolean add(Dept dept){
        return this.deptServiceClient.addDept(dept);
    }

    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id")Long id){
        return this.deptServiceClient.queryDept(id);
    }

    @RequestMapping("/consumer/dept/list")
    public List<Dept> list(){
        return this.deptServiceClient.queryAllDept();
    }
}

主启动类加上注解

@EnableFeignClients(basePackages = {"com.example.springcloud"})

报错No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon or spring-cloud-starter-loadbalancer?

解决办法: 修改依赖版本



<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
    <version>2.2.9.RELEASEversion>
dependency>


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    <version>2.2.9.RELEASEversion>
dependency>

运行测试。

你可能感兴趣的:(SpringCloud,spring,cloud,ribbon,java)