当前位置: 首页 > ai >正文

微服务架构实战:从服务拆分到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.xdnf.cn/news/5336.html

相关文章:

  • DINOv2
  • Spring框架(一)
  • Spring AI(3)——Chat Memory
  • skopeo工具详解
  • 成功案例:塔能精准节能技术为核心的工厂节能
  • GitHub打开缓慢甚至失败的解决办法
  • RTOS优先级翻转
  • 论文解读:MP-SfM: Monocular Surface Priors for Robust Structure-from-Motion
  • 22.第二阶段x64游戏实战-分析周围对象类型
  • SHAP分析!Transformer-BiLSTM组合模型SHAP分析,模型可解释不在发愁!
  • 分享一个可以用GPT打标的傻瓜式SD图片打标工具——辣椒炒肉图片打标助手
  • 04.three官方示例+编辑器+AI快速学习webgl_animation_skinning_additive_blending
  • 基于VSCode+PlatformIO环境的ESP8266的HX1838红外模块
  • sql的性能分析
  • Linux | Uboot-Logo 修改文档(第十七天)
  • 【通讯录教程】如何将号码快速导入手机通讯录,支持苹果和安卓手机,一次性导入大量号码进入手机通讯录,基于WPF的解决方案
  • C语言中#include引用头文件的尖括号和双引号的区别
  • 情书大全v3.0.1
  • 【网络分析工具】网络工具wireshark、TCPdump、iperf使用详解
  • 招行数字金融挑战赛数据分析赛带赛题二
  • CSS Layer 详解
  • SAP学习笔记 - 开发08 - Eclipse连接到 BTP Cockpit实例
  • 20242817-李臻-课下作业:Qt和Sqlite
  • 【vue】计算属性和属性传值以及监听属性
  • 【数据结构】线性表
  • Linux 常用命令集合
  • 开源字体设计工具字玩 FontPlayer
  • 【Bluedroid】HID DEVICE 连接的源码分析
  • MIT XV6 - 1.5 Lab: Xv6 and Unix utilities - xargs
  • Qt—多线程基础