Ribbon是客户端的负载均衡,在微服务调用,API网关的请求转发等,都离不开Ribbon。因此理解和使用Spring-cloud-Ribbon 是非常重要的。我们先来看一下如何使用Ribbon进行负载均衡。
我们将使用4个服务来实现。
- 服务注册
- 服务提供1
- 服务提供2
- 客户端
具体的架构流程图如下
![](https://img.haomeiwen.com/i13837765/a265eafca457cf26.png)
项目搭建
具体搭建方法参照Spring Cloud系列-- 服务治理简单搭建 ,我们使用IDEA简单搭建一下4个服务。这里只给出主要的截图和代码。
注册中心
新建项目
![](https://img.haomeiwen.com/i13837765/98ece01a1fadc10e.png)
![](https://img.haomeiwen.com/i13837765/1f44709982441913.png)
![](https://img.haomeiwen.com/i13837765/65e2af6b7fbfc68d.png)
启动配置
application.properties
#服务ID
spring.application.name=eureka-server
#端口
server.port=1111
#实例主机名
eureka.instance.hostname=localhost
#是否注册自己
eureka.client.register-with-eureka=false
#是否需要检索服务
eureka.client.fetch-registry=false
#是否开启自我保护
eureka.server.enable-self-preservation=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.register</groupId>
<artifactId>spring-cloud-test-register</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-test-register</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringCloudTestRegisterApplication
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudTestRegisterApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudTestRegisterApplication.class, args);
}
}
直接启动测试
![](https://img.haomeiwen.com/i13837765/104b23044345c4cb.png)
服务提供
新建项目
![](https://img.haomeiwen.com/i13837765/e64f2a903c564ade.png)
![](https://img.haomeiwen.com/i13837765/048f5c5e2e45dc46.png)
![](https://img.haomeiwen.com/i13837765/8ed29e27610f0554.png)
启动配置
这里我们参考之前的服务治理搭建,搞出两个外部化配置文件,通过IDEA的启动配置来启动两个服务,如果不知道怎么配置,可以参考之前那篇文章。
application-provider1.properties
spring.application.name=ribbon-service
#端口
server.port=1112
#指向注册中心
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
application-provider2.properties
spring.application.name=ribbon-service
#端口
server.port=1113
#指向注册中心
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ribbonprovider</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
com.ribbonprovider.provider.HelloWorldController
@RestController
public class HelloWorldController {
//获取当前端口配置
@Value("${server.port}")
private String port;
@GetMapping("/hello")
public String helloWorld() {
return "Hello World from port:" + port;
}
}
com.ribbonprovider.provider.ProviderApplication
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
启动查看注册结果
![](https://img.haomeiwen.com/i13837765/33ca8b32552c7c59.png)
我们可以看到两个服务已经注册到了注册中心上。
服务消费(客户端)
新建项目
![](https://img.haomeiwen.com/i13837765/d7415b69a96c3f81.png)
![](https://img.haomeiwen.com/i13837765/12662ddf28375be9.png)
这里就新加入了 ribbon依赖。
启动配置
application-consumer.properties
spring.application.name=ribbon-consumer
server.port=1114
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.consumer</groupId>
<artifactId>myribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>myribbon</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
com.consumer.myribbon.HelloConsumerController
@RestController
public class HelloConsumerController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/helloworld")
public String helloWorld() {
return restTemplate.getForEntity("http://RIBBON-SERVICE/hello",String.class).getBody();
}
}
com.consumer.myribbon.MyribbonApplication
@EnableEurekaClient
@SpringBootApplication
public class MyribbonApplication {
public static void main(String[] args) {
SpringApplication.run(MyribbonApplication.class, args);
}
@Bean
//负载均衡注解
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
启动查看注册结果
![](https://img.haomeiwen.com/i13837765/c3e5c985cdc8e6c6.png)
请求服务查看负载均衡结果
我们直接请求本地路径
http://localhost:1114/helloworld
来查看返回信息中的值
![](https://img.haomeiwen.com/i13837765/cffea110442e0e46.png)
![](https://img.haomeiwen.com/i13837765/d46e2c9633c34ee2.png)
可以看到端口的变化情况。
总结
在Spring强大的生态下,一切都变得很简单,希望大家不要局限于表面,尽量明白Ribbon的原理
网友评论