Spring Cloud微服務架構從入門到會用(三)—服務間調用Feign

微服務最重要的一個功能是服務間調用,各個服務互相依賴。比如電商系統有訂單服務,有庫存服務。在我們購買一件商品的時候,需要生成訂單和減庫存。這裏我們就要用到服務間調用Feign。

Feign是一個http請求調用的輕量級框架,可以以Java接口註解的方式調用Http請求,而不用像Java中通過封裝HTTP請求報文的方式直接調用。

接下來我們新建兩個module,一個app-order,一個app-storage;app-order作爲調用方,app-storage作爲被調用方。使用mybatis-plus作爲數據處理框架。使用lombok簡化代碼(idea需要按照lombok插件,否則會報錯)

1. 創建app-storage

1.1 修改app-storage下的pom.xml文件
<properties>
   <java.version>1.8</java.version>
   <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>

<dependencies>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
    <!-- eureka-client -->
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
   </dependency>
   <!-- feign -->
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-openfeign</artifactId>
   </dependency>

   <!--    mybatis-plus    -->
   <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.3.1.tmp</version>
   </dependency>
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <scope>runtime</scope>
   </dependency>
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <optional>true</optional>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
       <exclusions>
           <exclusion>
               <groupId>org.junit.vintage</groupId>
               <artifactId>junit-vintage-engine</artifactId>
           </exclusion>
       </exclusions>
   </dependency>
</dependencies>

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>${spring-cloud.version}</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>
1.2 修改配置
# 設置端口號
server.port=9920
# 設置服務名稱
spring.application.name=app-storage
# 設置eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}

# 數據源配置
spring.datasource.url=jdbc:mysql://localhost:3306/storage?allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
1.3 創建表,預製數據
CREATE TABLE `tb_storage` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

預製數據

INSERT INTO `storage`(`id`, `commodity_code`, `count`) VALUES (1, 'product-1', 9999999);
1.4 修改啓動類
@SpringBootApplication
@EnableEurekaClient  // 開啓eureka客戶端模式
@MapperScan("com.ipp.springcloud.appstorage.mapper") // mybatis掃描
public class AppOrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(AppOrderApplication.class, args);
    }
}
1.5 創建storage表對應的entity,mapper,service,controller

可以用mybatis-plus代碼生成插件去生成以上代碼,篇幅問題不在此處做詳細展示,詳細內容請查看git倉庫。

1.6 創建一個供app-order調用的減庫存接口

controller

/**
     * 減庫存
     * @param commodityCode 商品代碼
     * @param count 數量
     * @return
     */
    @RequestMapping(path = "/deduct")
    public Boolean deduct(String commodityCode, Integer count) {
        storageService.deduct(commodityCode, count);
        return true;
    }

service

@Override
    public void deduct(String commodityCode, int count) {
        QueryWrapper<Storage> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new Storage().setCommodityCode(commodityCode));
        Storage storage = baseMapper.selectOne(wrapper);
        storage.setCount(storage.getCount() - count);
        baseMapper.updateById(storage);
    }

2. 創建app-order

2.1 修改app-order下的pom.xml文件

內容與app-storage一致

2.2 修改配置
# 設置端口號
server.port=9910
# 設置服務名稱
spring.application.name=app-order
# 設置eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}

# 數據源配置
spring.datasource.url=jdbc:mysql://localhost:3306/order?allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
2.3 創建表
CREATE TABLE `tb_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.4 修改啓動類
@SpringBootApplication
@EnableEurekaClient  // 開啓eureka客戶端模式
@EnableFeignClients //開啓feign請求
@MapperScan("com.ipp.springcloud.apporder.mapper") // mybatis掃描
public class AppOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(AppOrderApplication.class, args);
    }

}
2.5 創建表order表對應的entity,mapper,service,controller

可以用mybatis-plus代碼生成插件去生成以上代碼,篇幅問題不在此處做詳細展示,詳細內容請查看git倉庫。

2.6 創建feign調用接口
@FeignClient(name = "APP-STORAGE")
public interface StorageFeignService {
    /**
     * 減庫存
     * @param commodityCode
     * @param count
     * @return
     */
    @GetMapping("storage/deduct")
    Boolean deduct(@RequestParam("commodityCode") String commodityCode, @RequestParam("count") Integer count);
}

這裏的@FeignClient 中的name寫的是app-storage服務的服務名稱(也就是註冊到eureka中的服務名稱)

下面聲明的deduct方法對應app-storage服務中的deduct接口

2.7 創建下訂單的接口

controller

 @RequestMapping("/placeOrder/commit")
    public Boolean placeOrderCommit() {
        orderServiceImpl.placeOrder("1", "product-1", 1);
        return true;
    }

service

@Autowired
private StorageFeignService storageFeignService;

@Override
public void placeOrder(String userId, String commodityCode, Integer count) {
     BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
     Order order = new Order()
             .setUserId(userId)
             .setCommodityCode(commodityCode)
             .setCount(count)
             .setMoney(orderMoney);
     baseMapper.insert(order);
     storageFeignService.deduct(commodityCode, count);
}

3. 啓動服務驗證

依次啓動server-eureka,app-storage,app-order

4. 驗證接口

在瀏覽器中訪問 http://127.0.0.1:9910/order/placeOrder/commit , 分別查看order表和storage表。是否生成了訂單和減了庫存

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章