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/
正文完!
微信搜索【银河架构师】,发现更多精彩内容。