代码地址:https://github.com/becauseoflife/CodeDemo/tree/main/SpringCloud/ribbon/springCloud
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。Ribbon的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer(简称LB∶负载均衡)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等等)去连接这些机器。我们也很容易使用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 地址和端口号。即使用服务名即可。
新建数据库 db_02、db_03。新建服务提供者springcloud-provider-dept-8002、springcloud-provider-dept-8003。将springcloud-provider-dept-8001复制一份,修改配置文件中的端口、数据库url、以及Eureka上的描述信息配置文件中的配置。(注:复制文件记得修改 Mapper.xml 中的 SQL 语句中的数据库名称)
启动测试
服务消费访问接口,可以看到以轮询的方式从数据库中查出数据。
spring-cloud-starter-netflix-eureka-client3.0.x版本是包含对ribbon的依赖的,官方内置了随机和轮询负载均衡策略。
自定义实现负载均衡策略实现 ReactorServiceInstanceLoadBalancer
接口即可(相当于 IRule
接口)。
可以通过 @LoadBalancerClient
注解,指定服务级别的负载均衡策略。
@LoadBalancerClient(name = "SPRING-PROVIDER-DEPT", configuration = MyLoadBalance.class)
feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。
SpringCloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。
只需要创建一个接口,然后添加注解即可!
feign,主要是社区,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务访问两种方法
1.微服务名字【ribbon】
2.接口和注解【feign 】
Feign能做什么?
Feign集成了Ribbon
模块使用的依赖
<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>
运行测试。