小白的學習筆記——服務拆分和遠端呼叫

superNeumann發表於2024-03-17

很久沒寫隨筆了,這些東西早就該寫了。

一、服務拆分和遠端呼叫

(一)服務拆分

任何分散式架構都離不開服務的拆分,微服務也是一樣。
微服務拆分時有這樣幾個原則:

  • 不同微服務,不要重複開發相同業務
  • 微服務資料獨立,不要訪問其它微服務的資料庫
  • 微服務可以將自己的業務暴露為介面,供其它微服務呼叫

比如現在有一個Demo工程,它結構下有兩個子工程:

  • Order-Service:訂單微服務,負責訂單相關業務
  • User-Service:使用者微服務,負責使用者相關業務

那麼它們兩個應該滿足以下要求:

  • 訂單微服務和使用者微服務都必須有各自的資料庫,相互獨立
  • 訂單服務和使用者服務都對外暴露Restful的介面
  • 訂單服務如果需要查詢使用者資訊,只能呼叫使用者服務的Restful介面,不能直接查詢使用者資料庫

透過例子,我覺得服務拆分的概念與SpringBoot中分層解耦的三層架構的概念有一定相似度。微服務架構將應用程式拆分為多個獨立的服務,每個服務都是一個獨立的模組,具有自己的功能和資料。同樣,Spring Boot的三層架構也將應用程式的不同部分劃分為獨立的層次,每個層次負責不同的任務,具有相對獨立性。(歡迎討論)

二、遠端呼叫

在Order-Service服務中,有一個根據id查詢訂單的介面:

點選檢視程式碼


@RestController
@RequestMapping("order")
public class OrderController {

   @Autowired
   private OrderService orderService;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根據id查詢訂單並返回
        return orderService.queryOrderById(orderId);
    }
}

根據id查詢訂單,返回值是Order物件,如圖:

image

其中的user為null

在User-Service中有一個根據id查詢使用者的介面:

image

查詢結果:

image

我們需要修改Order-Service中的根據id查詢訂單業務,要求在查詢訂單的同時,根據訂單中包含的userId查詢出使用者資訊,一起返回。
我們需要在Order-Service中 向User-Service發起一個http的請求,呼叫http://localhost:8081/user/{userId}這個介面

首先,註冊RestTemplate
我們在order-service服務中建立配置類,註冊RestTemplate例項:

點選檢視程式碼


@Configuration
public class RestTemplateConfig {

    /*
    * 建立RestTemplate物件並注入到SpringIOC容器中
    * */
    @Bean
    @LoadBalanced   //標識次方法發起的http請求會被Ribbon攔截
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

然後,實現遠端呼叫
修改order-service服務中的OrderService類中的queryOrderById方法:

點選檢視程式碼

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查詢訂單
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate發起http請求,查詢使用者
        //url路徑
        String url = "http://userservice/user/" +  order.getUserId();
        //傳送http請求,實現遠端呼叫
        User user = restTemplate.getForObject(url, User.class);  //反序列化
        // 3.封裝user資訊
        order.setUser(user);
        // 4.返回
        return order;
    }
}

相關文章