概述:实战电商项目 订单服务 调用商品服务获取商品信息
对实战二product进行改进,会有负载均衡策略,对商品服务分两个节点,进行轮询策略。可看上一章文章
1.ProductController修改
//将配置文件里的值注入
@Value("${server.port}")
private String port;
@RequestMapping("find")
public Object findById(@RequestParam("id") int id){
Product product = productService.findById(id);
Product result = new Product();
//将原来的product的值 克隆拷贝到product里
BeanUtils.copyProperties(product,result);
//重新赋值 便于观察端口号
result.setName(result.getName()+"data from port="+port);
return result;
}
2.启动多个实例
不会启动多实例的可以看上一章实战二
一:创建order_service项目
可看上一章实战三,这里不再做图片展示
选择依赖 Web-SpringWeb SpringCloudRoutin-Ribbon Spring Cloud Discovery>Eureka DisCovert Client
二:开发伪下单接口,不保存数据库
1.实体类 注意添加get、set方法
public class ProductOrder implements Serializable {
private int id;//主键id
/**
* 商品名称
*/
private String productName;
/**
* 订单流水号
*/
private String tradeNo;
/**
* 价格
*/
private int prict;
private Date createTime;//订单时间
private int userId;//下单用户id
private String userName;//下单用户名称
}
2.订单service接口
/**
* 订单业务类
*/
public interface ProductOrderService {
/**
* 下单接口
* @return
*/
ProductOrder save(int userId,int productId);
}
3.订单实现类 使用负载均衡
@Service
public class ProdctOrderServiceImpl implements ProductOrderService {
@Autowired
private RestTemplate restTemplate;
@Override
public ProductOrder save(int userId, int productId) {
//获取商品详情 调商品服务
//因为使用的是负载均衡策略,不能指定固定路径 使用服务名路径名的方式
Object obj = restTemplate.getForObject("http://product-service//api/v1/product/find?id="+productId,Object.class);
//打印展示当前调用的是哪一个节点的服务 8771或8772
System.out.println(obj);
//伪下单操作 这里只做下单后信息 没有商品服务数据的传输 下一章会讲到
ProductOrder productOrder = new ProductOrder();
//因为没有连接数据库 这里直接设置值
productOrder.setCreateTime(new Date());
productOrder.setUserId(userId);
productOrder.setTradeNo(UUID.randomUUID().toString());
return productOrder;
}
}
4.控制层
@RestController
@RequestMapping("/api/v1/order")
public class OrderController {
@Autowired
private ProductOrderService productOrderService;
@RequestMapping("save")
public Object save(@RequestParam("user_id")int userId,@RequestParam("product_id")int productId){
return productOrderService.save(userId,productId);
}
}
三:使用Ribbon(类似httpClient,URLConnection)
负载均衡策略
ribbon包装 底层httpClient,URLConnection 原有的调用不能调用集群或者负载均衡策略
启动类添加
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
四:测试
在客户端做负载均衡随机轮询 多次访问可发现 打印的商品服务调用了不同节点服务 OK了!
}
再启动一个product节点,此时为三个,但不会立即调用到第三个节点,会过一段时间刷新从服务列表里拿到,动态刷新,不断去拿,不断去续约