第5步: 服务远程调用(OpenFeign LoadBalance) - YuHaiQing233/explore-cloud-alibaba GitHub Wiki

1. 添加相关依赖

<!-- 远程调用,负载均衡依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

2. 编写Feign接口

package com.explore.order.feign;

import com.explore.user.domain.User;
import com.explore.user.dto.UserReductionRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * 调用三方接口类
 *
 * @author: HaiQing.Yu
 * @time: 2022/2/4 10:04
 */
@FeignClient(value = "cloud-user",path = "/api/user")
public interface IUserFeign {

    @GetMapping("/info")
    String info();

    @GetMapping("/find/{userId}")
    User getById(@PathVariable("userId") Long userId);

     @PostMapping("/reduction")
    Boolean reduction(@RequestBody UserReductionRequest request);
}

该接口类是为了调用外部服务定义的接口

3. 配置启用OpenFeign注解

package com.explore.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * 订单服务 启动类
 *
 * @author: YuHaiQing
 * @time: 2022/2/1 18:56
 */
@EnableFeignClients     // 添加该注解,表示启用Feign
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}

4. 使用Feign接口实现远程调用

package com.explore.order.controller;

import com.explore.base.ResultResponse;
import com.explore.order.domain.Order;
import com.explore.order.feign.IProductFeign;
import com.explore.order.feign.IUserFeign;
import com.explore.order.service.IOrderService;
import com.explore.product.dto.ProductReductionRequest;
import com.explore.user.dto.UserReductionRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单 控制器类
 *
 * @author: YuHaiQing
 * @time: 2022/2/1 18:57
 */
@RestController
@RequestMapping("/api/order")
public class OrderController {

    @Value("${server.port}")
    private Integer port;

    @Autowired
    private IOrderService orderService;
    @Resource
    private IUserFeign userFeign;
    @Resource
    private IProductFeign productFeign;


    @GetMapping("/info")
    public String Info(){
        return "服务名称: cloud-order, 服务端口: " + port;
    }


    /**
     * 下单业务
     *
     * @author: HaiQing.Yu
     * @time: 2022/2/1 22:25
     */
    @PostMapping("/placeOrder")
    public ResultResponse<Boolean> placeOrder(@RequestBody Order order){

        // 1. 创建订单
        order.setOrderNo("ECA" + System.currentTimeMillis());
        order.setCreateTime(LocalDateTime.now());
        Boolean createFlag = orderService.createOrder(order);
        if(!createFlag){
            return ResultResponse.error(444,"订单创建失败");
        }

        // 2. 用户扣款
        UserReductionRequest request = new UserReductionRequest();
        request.setUserId(order.getUserId());
        request.setMoney(order.getPrice().multiply(new BigDecimal(order.getQuantity())));
        Boolean reduction = userFeign.reduction(request);
        if(!reduction){
            return ResultResponse.error(444,"用户扣款失败");
        }

        // 3. 产品减库存
        ProductReductionRequest productRequest = new ProductReductionRequest();
        productRequest.setProductId(order.getProductId());
        productRequest.setQuantity(order.getQuantity());
        final Boolean pFlag = productFeign.reduction(productRequest);
        if(!pFlag){
            return ResultResponse.error(444,"产品减库存失败");
        }

        // 4. 更新订单状态
        final Boolean aBoolean = orderService.updateOrderStatus(order.getId(), Order.OrderStatus.complete.getStatus());
        if(!aBoolean){
            return ResultResponse.error(444,"更新订单状态失败");
        }

        return ResultResponse.success(Boolean.TRUE);
    }

}

5. 调用结果

6. 关于负载均衡

OpenFeign 3.1.0版本,只需要引入LoadBalancer依赖,IUserFeign接口类中配置了服务名称即可,调用时会自动进行负载均衡,如需修改负载均衡策略,需额外配置。
⚠️ **GitHub.com Fallback** ⚠️