1 前言
- 前面的章节中,我们已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式将信息注册到注册中心,并且可以通过SpringCloud提供的工具获取注册中心的服务列表。但是服务之间的调用还存在很多问题:如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均衡等等。
2 Ribbon基础
2.1 什么是Ribbon?
- Ribbon是Netflix公司发布的一个负载均衡器,有助于控制HTTP和TCP的客户端行为。在SpringCloud中,Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载均衡。
- 在SpringCloud中可以将注册中心Eureka和Ribbon配合使用,Ribbon自动的从注册中心获取服务提供者的列表新,并基于内置的负载均衡算法,请求服务。
2.2 Ribbon的作用
- 1️⃣服务调用:基于Ribbon实现服务调用,是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助于RestTemplate最终进行调用。
- 2️⃣负载均衡:当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址。
2.3 基于Ribbon实现订单微服务调用商品微服务
2.3.1 概述
- 不论是基于Eureka的注册中心还是基于Consul的注册中心,SpringCloud的Ribbon统一进行了封装,所以对于服务的调用,两者的方式是一样的。
2.3.2 改造步骤
在使用Eureka作为注册中心的时候,不需要再导入Ribbon的相关依赖,因为Eureka内部集成了Ribbon了。
- 1️⃣在创建RestTemplate的时候,声明@LoadBalanced注解。
- 2️⃣使用RestTemplate调用远程微服务的时候,不需要自己手动拼接远程微服务的URL,只需要用远程微服务的服务名替换IP地址即可。
2.3.3 实现
- 订单微服务:在创建RestTemplate的时候,声明@LoadBalanced注解
package com.sunxiaping.order.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;
@Configuration
public class SpringConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- 订单微服务:使用RestTemplate调用远程微服务的时候,不需要自己手动拼接远程微服务的URL,只需要用远程微服务的服务名替换IP地址即可
package com.sunxiaping.order.controller;
import com.sunxiaping.order.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
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;
@RestController
@RequestMapping(value = "/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
/**
* SpringCloud提供的获取元数据的工具类
* 调用方法获取服务的元数据
*/
@Autowired
private DiscoveryClient discoveryClient;
/**
* 基于Ribbon的形式调用远程的微服务
*
* @param id
* @return
*/
@GetMapping(value = "/buy/{id}")
public Product buy(@PathVariable(value = "id") Long id) {
Product product = restTemplate.getForObject("http://service-product/product/findById/" + id, Product.class);
return product;
}
}
- 代码测试:在浏览器请求http://192.168.31.198:9002/order/buy/1,查看展示效果如下,已经可以在订单微服务中通过服务名称的形式调用商品微服务获取数据了。