八、服务调用Ribbon入门
前面我们已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式将信息注册到注册中心,并且可以通过Spring Cloud提供的工具获取注册中心的服务列表。
但是服务之间的调用还存在很多的问题,如:如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均衡等等。
8.1 Ribbon概述
Ribbon是 Netflixfa发布的一个负载均衡器,有助于控制 HTTP 和TCP客户端行为。在SpringCloud 中,Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。
在Spring Cloud中可以将注册中心和Ribbon配合使用,Ribbon自动的从注册中心中获取服务提供者的列表信息,并基于内置的负载均衡算法,请求服务。
8.2 Ribbon的主要作用
8.3 基于Ribbon实现订单调用商品服务
前面我们配置了Eureka Server高可用集群,但是如何均衡的调用服务还并未实现,也就是说,在此基础上添加负载均衡策略即可实现。
服务提供者ebuy-product
ProductController.java
package cn.ebuy.product.controller;
import cn.ebuy.product.pojo.EasybuyProduct;
import cn.ebuy.product.service.EasybuyProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/product")
@SuppressWarnings("all")
public class ProductController {
@Value("${spring.cloud.client.ip-address}")
String ip;
@Value("${server.port}")
int port;
@Autowired
private EasybuyProductService productService;
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public EasybuyProduct findById(@PathVariable Long id) {
EasybuyProduct product = productService.selectByPrimaryKey(id);
product.setEpDescription("调用ebuy-product服务,ip:"+ip+",服务提供者端口:"+port);
return product;
}
}
服务调用者ebuy-order(需要配置负载均衡)
application.yml
ebuy-product:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
启动类OrderApplication.java
package cn.ebuy.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class OrderApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate()
{
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
注意:服务消费者方在RestTemplate上的@LoadBalanced注解一定不能少,否则在调用时不能实现负载均衡!!!
Controller层实现:
package cn.ebuy.order.controller;
import cn.ebuy.order.pojo.EasybuyProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/order")
@SuppressWarnings("all")
public class OrderController {
@Autowired
RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public EasybuyProduct findById(@PathVariable Long id) {
EasybuyProduct easybuyProduct=new EasybuyProduct();
easybuyProduct = restTemplate.getForObject("http://ebuy-product/product/"+id,EasybuyProduct.class);
return easybuyProduct;
}
到此为止,一个简单的基于Eureka Server集群的服务之间的调用就完成了,如有不对,欢迎大家指正。
|