ribbon简介
官网说明
Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.
大概意思是Ribbon是一个客户端负载均衡器,它可以有效的控制HTTP和TCP客户端的访问。Feign默认集成了Ribbon,也可以使用@FeignClient。
其中有个很关键的词“客户端负载均衡器”,我们常用的负载均衡模式就是服务端负载均衡,如nginx反向代理,这种模式并不知道服务究竟请求的具体是那台机器。 而客户端负载均衡是在发起请求时已确定明确的目标,请求将精确指向集群中的某台机器。
Ribbon的负载均衡默认是依靠服务注册中心来实现的,Ribbon通过注册客户端定期拉取注册服务,通过客户端的轮训、随机等算法来实现负载均衡。
创建服务提供者
使用前一篇文章的商品工程xmall-product作为服务提供者,启动双实例,供负载均衡使用。如何启动双实例,请参见另外一篇文章:Spring Boot工程如何在IDEA中启动多实例。
先启动8080端口的xmall-product工程,修改端口号为8081,并启动第二个实例。查看nacos,已有2个实例注册:
创建服务消费者
创建服务消费者工程xmall-product-clients-ribbon,作为服务消费者,调用商品服务。
pom
其父工程正是上一篇文章中创建的父工程java-boot-parent-2.1。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.luas.cloud</groupId>
<artifactId>java-boot-parent-2.1</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../java-boot-parent-2.1</relativePath>
</parent>
<groupId>com.luas.xmall</groupId>
<artifactId>xmall-product-clients-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>xmall-product-clients-ribbon</name>
<description>product service clients by ribbon</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos cloud -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml
依然注册到nacos,端口为8082。
server:
port: 8082
spring:
application:
name: xmall-product-clients-ribbon
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
注册RestTemplate
在启动类中注册RestTemplate,并添加@LoadBalanced注解,开启负载均衡。
在启动类中注册RestTemplate,也是懒省事,正常项目时要在配置类中注册,如SystemConfiguration。
至于为何不添加@EnableDiscoveryClient注解,前面已有说明,不在赘述。
@SpringBootApplication
public class XmallProductClientsRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(XmallProductClientsRibbonApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
创建客户端
创建SkuService,注入RestTemplate,访问xmall-product服务的“/sku/{skuId}”接口,在这里,因为服务都注册到了nacos,所以我们采用服务名来代替冗长的url地址。
package com.luas.xmall.product.clients.clients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class SkuService {
@Autowired
private RestTemplate restTemplate;
public Object info(String skuId) {
return this.restTemplate.getForObject("http://xmall-product/sku/{skuId}", Object.class, skuId);
}
}
创建测试入口
创建SkuController,注入上一步创建的SkuService客户端,来测试是否生效。
package com.luas.xmall.product.clients.controller;
import com.luas.xmall.product.clients.clients.SkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/sku")
public class SkuController {
@Autowired
private SkuService skuService;
@RequestMapping("/{skuId}")
public Object info(@PathVariable String skuId) {
return this.skuService.info(skuId);
}
}
浏览器访问http://localhost:8082/sku/1122,多次刷新页面,可发现负载均衡生效,商品信息来自于不同端口的实例。
源码
github
https://github.com/liuminglei/SpringCloudLearning/tree/master/03/
gitee
https://gitee.com/xbd521/SpringCloudLearning/tree/master/03/
正文完!
本文系【银河架构师】原创,如需转载请在文章明显处注明作者及出处。
微信搜索【银河架构师】,发现更多精彩内容。