业务场景
订单服务调用商品服务集群,进行伪下单功能开发,使用Ribbon实现订单调用商品服务。
思路:
1.创建订单服务
2.编写伪下单接口
a.调用商品服务获取商品信息(Ribbon调用服务)
b.根据商品信息,订单接口返回订单详情信息
调用逻辑图如下:
实现订单服务项目
订单服务项目通过Spring Initializr搭建项目,选择Web 和 Eureka Discovery。跟前一篇博客写的Product-Service是一样的。我们把Product-Service实例端口也获取到放入到产品信息中,验证Ribbon的客户端负载均衡。
order-service入口:
分析:
服用的调用就是通过RestTemplate实现,而RestTemplate是通过Ribbon实现的。@LoadBalanced是客户端负载均衡的注解。
服务调用:
package com.ckmike.order_service.service.impl; import com.ckmike.order_service.domain.ProductOrder; import com.ckmike.order_service.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.Date; import java.util.Map; import java.util.UUID; /** * OrderServiceImpl 简要描述 * <p> TODO:描述该类职责 </p> * * @author ckmike * @version 1.0 * @date 18-11-7 下午11:55 * @copyright ckmike **/ @Service public class OrderServiceImpl implements OrderService { @Autowired private RestTemplate restTemplate; @Override public ProductOrder save(int userId, int productId) { // 获取商品信息 Map<String,Object> obj = restTemplate.getForObject("http://product-service/api/v1/product/find?id="+productId,Map.class); ProductOrder productOrder = new ProductOrder(); productOrder.setCreateTime(new Date()); productOrder.setUserId(userId); productOrder.setTradeNo(UUID.randomUUID().toString()); productOrder.setPrice(Double.parseDouble(obj.get("price").toString())); productOrder.setProductName(obj.get("name").toString()); return productOrder; } }
我们把EurekaServer、Product-Service(3个实例)、Order-Service三个项目启动起来,eureka控制台,如下图:
通过调用order-service的save接口:
随着订单接口的调用,我们可以看到ProductName的商品服务实例的接口每次都是不一样的,这里就是客户端负载均衡策略的体现。
总结:
默认情况下,RestTemplate客户端负债均衡采用的是轮巡策略进行客户端服务调用。我们可以通过配置修改负载均衡策略。如下:
该策略采用随机调用策略,更多的策略可参考com.netflix.loadbalancer下的源码或者看文档查询。