Ribbon
基础Ribbon
引入项目改造
一般来说,提到负载均衡,大家一般很容易想到浏览器 -> NGINX
-> 反向代理多个 Tomcat
这样的架构图——业界管这种负载均衡模式叫”服务器端负载均衡”
,因为此种模式下,负载均衡算法是 NGINX
提供的,而 NGINX
部署在服务器端。
Ribbon
则是一个客户端侧
负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。
Ribbon
是 Netflix
发布的负载均衡器,它可以帮我们控制 HTTP
和 TCP
客户端的行为。只需为 Ribbon
配置服务提供者地址列表,Ribbon
就可基于负载均衡算法计算出要请求的目标服务地址。
Ribbon
默认为我们提供了很多的负载均衡算法,例如轮询、随机、响应时间加权等——当然,为 Ribbon
自定义负载均衡算法也非常容易,只需实现IRule
接口即可。
TIPS Ribbon
的仓库地址(Github): https://github.com/Netflix/ribbon
在 Spring Cloud
中,当 Ribbon
与 Eureka
配合使用时,Ribbon
可自动从 Eureka Server
获取服务提供者地址列表,并基于负载均衡算法,选择其中一个服务提供者实例。下图展示了 Ribbon
与 Eureka
配合使用时的大致架构。
创建ribon服务,microservice-consumer-movie-ribbon
pom.xml
Maven
引入依赖:由于 spring-cloud-starter-netflix-eureka-client
已经包含 spring-cloud-starter-netfilx-ribbon
,故而无需额外添加依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.lzj1234</groupId> <artifactId>microservice-consumer-movie-ribbon</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> <!-- <maven.compiler.source>8</maven.compiler.source>--> <!-- <maven.compiler.target>8</maven.compiler.target>--> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- <version>2.4.2</version>--> </dependency> <!-- 引入H2数据库,一种内嵌的数据库,语法类似MySQL --> <!-- https://mvnrepository.com/artifact/com.h2database/h2 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.200</version> <!-- <scope>test</scope>--> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.18</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <!-- <version>2.4.2</version>--> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-clean-plugin --> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <version>2.5</version> </dependency> <!-- 新增依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <!-- 引入spring cloud的依赖,不能少,主要用来管理Spring Cloud生态各组件的版本 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
org.springframework.boot:spring-boot-maven-plugin:2.0.7.RELEASE:repackage failed: Unable to find mai
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
这是因为springboot默认没有启动类,需要手动添加启动类:springboot
创建启动类,App.java
package com.lzj1234;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
// 只需在RestTemplate
上添加LoadBalanced
注解,即可让RestTemplate
整合Ribbon
!
}
再次执行mvn install 命令,安装依赖包,就不会出错了
MovieController
package com.lzj1234; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.loadbalancer.LoadBalanced; 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; @RequestMapping("/movies") @RestController public class MovieController { @Autowired RestTemplate restTemplate; @GetMapping("/users/{id}") public User findById(@PathVariable Long id){ // 这里用到了RestTemplate的占位符能力 microservice-provider-user User user=this.restTemplate.getForObject("http://microservice-provider-user/users/{id}",User.class,id); return user; } }
配置文件
server: port: 8010 spring: application: name: microservice-consumer-movie-ribbon logging: level: root: INFO # 配置日志级别,让hibernate打印出执行的SQL参数 org.hibernate: INFO org.hibernate.type.descriptor.sql.BasicBinder: TRACE org.hibernate.type.descriptor.sql.BasicExtractor: TRACE # 新增配置 eureka: client: serviceUrl: defaultZone: http://localhost:8080/eureka/ instance: prefer-ip-address: true
mvn spring-boot:run
在项目中引用 Ribbon
来实现了客户端的负载均衡。Ribbon
是一个客户端侧
负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。