微服務架構實戰:從服務拆分到RestTemplate遠程調用

微服務架構實戰:從服務拆分到RestTemplate遠程調用

  • 一 . 服務拆分
    • 1.1 服務拆分注意事項
    • 1.2 導入服務拆分 Demo
    • 1.3 小結
  • 二 . 服務間調用
    • 2.1 注冊 RestTemplate
    • 2.2 實現遠程調用
    • 2.3 小結
  • 三 . 提供方和消費方

在分布式系統設計中,微服務架構因其靈活性、可擴展性成為主流方案。然而,如何合理拆分服務、實現高效服務間通信,是開發者面臨的核心挑戰。本文通過一個電商場景的訂單-用戶服務案例,演示如何基于單一職責原則拆分微服務,并通過RestTemplate實現服務間HTTP調用。讀者將學習到:

  1. 服務拆分的三大核心原則(單一職責、數據獨立、面向服務);
  2. 獨立數據庫設計與多服務協同開發;
  3. 使用Spring Boot的RestTemplate組件完成跨服務數據聚合。
    在這里插入圖片描述

    本專欄的內容均來自于 B 站 UP 主黑馬程序員的教學視頻,感謝你們提供了優質的學習資料,讓編程不再難懂。

    專欄地址 : https://blog.csdn.net/m0_53117341/category_12835102.html

一 . 服務拆分

1.1 服務拆分注意事項

  1. 單一職責 : 不同微服務之間不要重復的開發相同業務
  2. 數據獨立 : 不能訪問其他微服務的數據庫
  3. 面向服務 : 將自己的業務暴露出接口 , 供其他微服務調用

1.2 導入服務拆分 Demo

第一步 : 導入提供給大家的項目模板

cloud-demo.zip

那在父工程的 <dependencyManagement> 下 , 只負責版本的鎖定 , 不負責版本的導入

然后我們來修改一下兩個微服務的 application.yml 信息

第二步 : 了解項目架構

  1. order-service : 根據 ID 查詢訂單
  2. user-service : 根據 ID 查詢用戶

那這兩個就是不同的微服務 , 也需要有自己獨立的數據庫

第三步 : 將兩個微服務的 SQL 進行導入

-- 創建數據庫
create database `cloud_user` character set utf8mb4;-- 使用數據庫
use `cloud_user`;SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人',`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, '柳巖', '湖南省衡陽市');
INSERT INTO `tb_user` VALUES (2, '文二狗', '陜西省西安市');
INSERT INTO `tb_user` VALUES (3, '華沉魚', '湖北省十堰市');
INSERT INTO `tb_user` VALUES (4, '張必沉', '天津市');
INSERT INTO `tb_user` VALUES (5, '鄭爽爽', '遼寧省沈陽市大東區');
INSERT INTO `tb_user` VALUES (6, '范兵兵', '山東省青島市');SET FOREIGN_KEY_CHECKS = 1;
-- 創建數據庫
create database `cloud_order` character set utf8mb4;-- 使用數據庫
use `cloud_order`;SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '訂單id',`user_id` bigint(20) NOT NULL COMMENT '用戶id',`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名稱',`price` bigint(20) NOT NULL COMMENT '商品價格',`num` int(10) NULL DEFAULT 0 COMMENT '商品數量',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of tb_order
-- ----------------------------
INSERT INTO `tb_order` VALUES (101, 1, 'Apple 蘋果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新國標電動車', 209900, 1);
INSERT INTO `tb_order` VALUES (103, 3, '駱駝(CAMEL)休閑運動鞋女', 43900, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 雙模5G 驍龍865', 359900, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 雙模5G 視頻雙防抖', 299900, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷靜星II ', 544900, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人體工學電腦椅子', 79900, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休閑男鞋', 31900, 1);SET FOREIGN_KEY_CHECKS = 1;

那將來微服務的模塊有可能會很多 , 啟動起來會很麻煩 , 就給大家介紹一種新的啟動方式

之后我們想要啟動誰 , 選中誰即可

1.3 小結

  1. 微服務需要根據業務模塊拆分 , 做到單一職責 , 不要重復開發相同業務
  2. 微服務可以將業務暴漏為接口 , 供其他微服務使用
  3. 不同微服務都應該有自己獨立的數據庫

二 . 服務間調用

我們先訪問這兩個服務

訪問 http://127.0.0.1:8081/user/1 就可以獲取到 ID 為 1 的用戶信息

訪問 http://127.0.0.1:8080/order/101 就可以獲取到 ID 為 101 的訂單信息

那接下來 , 我們想實現一個案例 : 根據訂單 ID 查詢訂單的同時 , 把訂單所屬的用戶信息一起返回

那這樣的話 , 我們就需要將上面兩個 URL 所獲取的內容合并 , 然后進行返回

那我們用戶是通過 URL 來獲取到數據的 , 所以我們也可以通過代碼的方式來去模擬 URL 來去獲取數據

那接下來 , 我們就在 order-service 中向 user-service 發起一個 HTTP 請求 , 調用 http://127.0.0.1:8081/user/{userId} 這個接口

2.1 注冊 RestTemplate

我們在 order-service 的啟動類中創建一個模板對象

package com.example.order;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@MapperScan("com.example.order.mapper")
@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

2.2 實現遠程調用

那接下來 , 我們就需要組裝出要發送的 URL 地址了

首先 , 我們需要獲取到 userId , 而正好 order 表中也存儲了 userId , 所以我們可以直接獲取

那接下來就需要拼接 URL 了

接下來 , 我們就可以調用 RestTemplate 來去發起請求獲取用戶信息

首先需要注入 RestTemplate 對象

然后我們調用它的 getForObject 方法 , 他有兩個參數

  1. 要發起請求的 URL 地址
  2. 獲取到的消息應該轉化成哪種對象

最后我們把獲取到的內容添加到 order 的 user 字段中

package com.example.order.service;import com.example.order.mapper.OrderMapper;
import com.example.order.pojo.Order;
import com.example.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public Order queryOrderById(Long orderId) {// 1. 查詢訂單Order order = orderMapper.findById(orderId);// 2. 查詢用戶 IDLong userId = order.getUserId();// 3. 拼接 URLString url = "http://127.0.0.1:8081/user/" + userId;// 4. 調用 RestTemplate 發起請求獲取用戶信息// 第一個參數: 要請求的 URL 地址// 第二個參數: 獲取到的數據要轉換成哪種對象User user = restTemplate.getForObject(url, User.class);// 5. 將獲取到的用戶信息添加到 order 實體類的 user 字段中order.setUser(user);// 6. 返回return order;}
}

接下來 , 我們重啟 order-service 服務 , 來觀察一下前后變化

2.3 小結

微服務調用方式

  • 基于 RestTemplate 發起的 HTTP 請求實現遠程調用
  • HTTP 請求做遠程調用是與語言無關的調用 , 只需要知道對方的 IP、端口、接口路徑、請求參數即可 .

三 . 提供方和消費方

服務提供方 : 被其他微服務調用的服務 (提供接口給其他微服務)

服務消費方 : 調用其他微服務的服務 (調用其他微服務提供的接口)

那我們之前的案例中 , user-service 就是服務提供方 , order-service 就是服務消費方

那提供方與消費方的角色其實是相對來說的 , 一個服務既可以是服務提供者 , 又可以是服務消費者


小結 :

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82626.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82626.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82626.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 索引與事務詳解

目錄 一、索引&#xff08;Index&#xff09; 二、事務&#xff08;Transaction&#xff09; 三、總結 一、索引&#xff08;Index&#xff09; 索引的本質&#xff1a;一種數據結構&#xff08;如 BTree、Hash&#xff09;&#xff0c;用于快速定位數據&#xff0c;避免全…

macOS Python 環境配置指南

1. 檢查現有 Python 環境 python3 --version # 檢查 Python 3 版本 pip3 --version # 檢查 pip 版本 2. 安裝 pyenv&#xff08;Python 版本管理工具&#xff09; # 使用 Homebrew 安裝 pyenvbrew install pyenv# 配置 pyenv 環境變量&#xff08;添加到 ~/.zshrc&#…

游戲引擎學習第272天:顯式移動轉換

回顧并為今天的內容鋪墊背景 我們剛開始為游戲主角編寫一些程序邏輯&#xff0c;因為我們之前已經完成了大部分引擎方面的開發&#xff0c;現在可以專注在角色身上。這個角色的移動方式會有些特別&#xff0c;與大多數游戲角色的運動機制不太一樣。我們當前正在實現的控制方式…

軟件測試都有什么???

文章目錄 一、白盒測試&#xff08;結構測試&#xff09;二、黑盒測試&#xff08;功能測試&#xff09;三、灰盒測試四、其他測試類型五、覆蓋準則對比六、應用場景 軟件測試主要根據測試目標、技術手段和覆蓋準則進行分類。分為白盒測試、黑盒測試、灰盒測試及其他補充類型 一…

very_easy_sql(SSRF+SQL注入)

題目有一行提示&#xff1a; you are not an inner user, so we can not let you have identify~&#xff08;你不是內部用戶&#xff0c;所以我們不能讓你進行身份驗證&#xff09;聯想到可能存在SSRF漏洞&#xff0c;一般情況下&#xff0c;SSRF攻擊的目標是外網無法訪問的內…

國內外主流AI編程工具全方位對比分析(截至2025年5月)

一、國際主流工具對比 1. Windsurf&#xff08;Codeium公司&#xff09; 核心功能&#xff1a;代理型AI編程&#xff08;代碼導航/修改/命令執行&#xff09;、瀏覽器DOM訪問、網頁研究功能語言支持&#xff1a;70語言&#xff0c;包括Python/Java/JavaScript/Rust等[[22-23]…

ARP協議的工作原理

文章目錄 ARP協議的工作原理ARP報文&#xff08;以太網&#xff09;ARP高速緩存 ARP協議的工作原理 ARP協議的作用是實現任意網絡層地址到任意物理地址轉換。工作原理是&#xff1a; 主機向自己所在網絡廣播一個ARP請求&#xff0c;該請求包含目標機器的網絡地址。處于該網絡…

【小知識酷】《Matlab》考點精簡

在線編譯器 https://matlab.mathworks.com/?elqsidumic49viv8wu5r6fckew 第1章 matlab基礎知識 第1節 輸出函數 1. 使用disp函數 disp函數可用于輸出變量的值或者字符串。 % 輸出字符串 disp(Hello, MATLAB!); %顯示Hello, MATLAB!% 輸出變量 x 10; disp(x); %顯示10% 輸出數…

碼蹄集——中庸之道(三個數比較)

MT1112 中庸之道 請編寫一個簡單程序&#xff0c;輸入3個整數&#xff0c;比較他們的大小&#xff0c;輸出中間的那個數 格式 輸入格式&#xff1a; 輸入整型&#xff0c;空格分隔 輸出格式&#xff1a;輸出整型 樣例 1 輸入&#xff1a;1 5 3 輸出&#xff1a;3 比較…

快速搭建一個vue前端工程

一、環境準備 1、安裝node.js 下載地址&#xff1a;Node.js 推薦版本如下&#xff1a; 2、檢查node.js版本 node -v npm -v 二、安裝Vue腳手架 Vue腳手架是Vue官方提供的標準化開發工具。vue官網&#xff1a;https://cn.vuejs.org/ 全局安裝vue/cli &#xff08;僅第一次…

React Native基礎環境配置

React Native基礎環境配置 1.引言2.React-Native簡介3.項目基礎環境搭建1.引言 感覺自己掌握的知識面還是有點太窄了,于是決定看看移動端的框架,搞個react搭一個后端管理項目,然后拿react-native寫個小的軟件,試著找個三方上架一下應用市場玩玩。畢竟不可能一直在簡歷上掛一…

PHP和Composer 安裝

Composer 是 PHP 的 依賴管理工具&#xff0c;就像&#xff1a; Node.js 用 npm Python 用 pip Java 用 maven 用來安裝和管理 PHP 項目中需要用到的第三方庫 安裝PHP可以理解成 Java解釋器 安裝PHP PHP For Windows: Binaries and sources Releaseshttps://windows.php.n…

API請求參數有哪些?

通用參數 app_key&#xff1a;應用的唯一標識&#xff0c;用于驗證應用身份&#xff0c;調用API時必須提供。 timestamp&#xff1a;請求時間戳&#xff0c;通常為當前時間的毫秒級時間戳&#xff0c;用于防止請求被重放攻擊。 format&#xff1a;返回數據的格式&#xff0c;…

并發筆記-條件變量(三)

文章目錄 背景與動機30.1 條件變量的定義與基本操作 (Definition and Routines)30.2 生產者/消費者問題 (Bounded Buffer Problem)30.3 覆蓋條件 (Covering Conditions) 與 pthread_cond_broadcast30.4 總結 背景與動機 到目前為止&#xff0c;我們已經學習了鎖 (Locks) 作為并…

stm32實戰項目:無刷驅動

目錄 系統時鐘配置 PWM模塊初始化 ADC模塊配置 霍爾接口配置 速度環定時器 換相邏輯實現 主控制循環 系統時鐘配置 啟用72MHz主頻&#xff1a;RCC_Configuration()設置PLL外設時鐘使能&#xff1a;TIM1/ADC/GPIO時鐘 #include "stm32f10x.h"void RCC_Configu…

LC-3 中常見指令

當然可以&#xff01;以下是 LC-3 中常見指令&#xff08;匯編格式&#xff09;與對應的二進制編碼格式 的總結表&#xff0c;通俗易懂地介紹每條指令的用途、操作碼&#xff08;opcode&#xff09;以及格式結構。 ? 常見 LC-3 指令與對應的二進制格式 指令名稱操作碼&#x…

深入解析Docker:核心架構與最佳實踐

文章目錄 前言一、Docker 解決了什么問題&#xff1f;二、Docker 底層核心架構2.1 Docker 引擎的分層架構2.2 鏡像的奧秘&#xff1a;聯合文件系統&#xff08;UnionFS&#xff09;2.3 容器隔離的核心技術2.3.1 命名空間2.3.2 控制組&#xff08;Cgroups&#xff09;2.3.3 內核…

從零打造企業級Android木馬:數據竊取與遠程控制實戰

簡介 木馬病毒已從簡單的惡意軟件演變為復雜的攻擊工具,尤其在2025年企業級攻擊中,木馬病毒正成為黑客組織的主要武器之一。 本文將深入探討如何制作具備數據竊取和遠程控制功能的Android木馬,從基礎原理到企業級防御繞過技術,同時提供詳細的代碼實現,幫助開發者理解木馬…

ES常識5:主分詞器、子字段分詞器

文章目錄 一、主分詞器&#xff1a;最基礎的文本處理單元主分詞器的作用典型主分詞器示例 二、其他類型的分詞器&#xff1a;解決主分詞器的局限性1. 子字段分詞器&#xff08;Multi-fields&#xff09;2. 搜索分詞器&#xff08;Search Analyzer&#xff09;3. 自定義分詞器&a…

【第三十五周】Janus-pro 技術報告閱讀筆記

Janus-Pro 摘要Abstract文章信息引言方法Janus 架構Janus 訓練Janus-Pro 的改進 實驗結果總結 摘要 本篇博客介紹了Janus-Pro&#xff0c;這是一個突破性的多模態理解與生成統一模型&#xff0c;其核心思想是通過解耦雙路徑視覺編碼架構解決傳統方法中語義理解與像素生成的任務…