微服务学习-快速搭建

news2025/1/19 9:28:36

1. 速通版

1.1. git clone 拉取项目代码,导入 idea 中

git clone icoolkj-microservices-code: 致力于搭建微服务架构平台

1.2. git checkout v1.0.1版本

链接地址:icoolkj-microservices-code 标签 - Gitee.com

2. 项目服务结构

3. 实现重点步骤

3.1. 业务需求

实现用户下单,扣减库存,查询商品单价,扣减账户余额的功能。

3.2. 如何引入 Spring Cloud Alibaba 的依赖

3.2.1. 父工程 pom.xml 文件内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.icoolkj</groupId>
   <artifactId>icoolkj-microservices-code</artifactId>
   <version>1.0.1</version>
   <packaging>pom</packaging>
 
   <properties>
      <java.version>17</java.version>
      <!-- 微服务版本 -->
      <spring-boot.version>3.2.4</spring-boot.version>
      <spring-cloud.version>2023.0.1</spring-cloud.version>
      <spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>

   </properties>

   <dependencyManagement>
      <dependencies>

         <!-- Spring Boot Starter父依赖 -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>

         <!-- Spring Cloud依赖 -->
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>

         <!-- Spring Cloud Alibaba依赖 -->
         <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>

      </dependencies>
   </dependencyManagement>


</project>
3.2.2. <dependencyManagement> 和 <dependency> 的区别

Mave 使用 dependencyManagement 元素来提供一种管理依赖版本号的方式。

使用 pom.xml 中的 dependencyManagement 元素能让子项目中引用同一个版本依赖,而不用显示的列出版本号。

好处:如果多个子项目引用同一个依赖,可以避免每个子项目里面再声明版本号。

优势:当升级或切换项目中的某个依赖版本时,只需要再父 pom.xml 文件里面更新,子项目无需修改;如果某个子项目需要另外一个依赖的版本,只需要再子项目声明 version 即可。

注意:

  1. dependencyManagement 里面只是声明依赖,并不实现引入,因此子项目需要显示声明需要用的依赖;
  2. 如果不在子项目中声明依赖,是不会从父项目中继承下来的,只有在子项目中声明了依赖并且没有指定具体版本,才会从父项目继承该依赖项,且 version 和 scope 都读取父 pom;
  3. 如果子项目中指定了依赖项版本号,那么就会使用子项目指定的 jar 版本。

3.3. 环境准备

3.3.1. 在启动服务前,请先配置 Host 地址映射,确保服务能够正常启动
# 服务
127.0.0.1 icoolkj-mall-account
127.0.0.1 icoolkj-mall-order
127.0.0.1 icoolkj-mall-product
127.0.0.1 icoolkj-mall-inventory
127.0.0.1 icoolkj-mall-gateway
# 中间件
127.0.0.1 icoolkj-mall-mysql
127.0.0.1 icoolkj-mall-nacos-server
127.0.0.1 icoolkj-mall-seata-server
127.0.0.1 icoolkj-mall-sentinel-dashboard
127.0.0.1 icoolkj-mall-skywalking-server

Windows 系统路径:C:\Windows\System32\drivers\etc\hosts

macOS 系统路径:/etc/hosts

Linux 系统路径: /etc/hosts

3.3.2. 需要导入 MySQL 数据库脚本文件

脚本文件地址:spring-cloud-alibaba-examples/config/init.sql · icoolkj/icoolkj-microservices-code - Gitee.com

3.4. 项目演示

3.4.1. 启动所有服务,使用 Postman 进行测试

查询商品单价:localhost:8080/api/product/get-price-product?productId=1

查询商品库存:localhost:8081/api/inventory/get-inventory-quantity?productId=1

查询账户余额:localhost:8083/api/account/get-balance-account?userId=1

用户下单:localhost:8082/api/order/create-order

3.4.2. 发现问题
3.4.2.1. 用户正常下单,没有扣减库存,没有查询商品价格,没有扣减账户余额

微服务需要实现服务之间的调用,必须订单微服务 8082 如何调用库存微服务 8081,如何实现?

解决方案:利用 Spring 框架提供的 RestTemplate 实现服务间的调用

@Bean 的方式配置 RestTemplate

@Configuration
public class RestTemplateConfig {
    @Bean
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

 订单服务 OrderServiceImpl 引入RestTemplate

@Autowired
private RestTemplate restTemplate;

 通过 restTemplate.postForObject restTemplate.exchange 等发放调用 商品服务,库存服务,账户服务

//deduct inventory
InventoryRequest inventoryRequest = new InventoryRequest();
inventoryRequest.setProductId(productId);
inventoryRequest.setInventoryQuantity(orderQuantity);
//RestTemplate 远程调用
String inventoryUrl = "http://localhost:8081/api/inventory/reduce-inventory";
int inventoryCode = restTemplate.postForObject(inventoryUrl, inventoryRequest, Result.class).getCode();
if(inventoryCode == Result.FAIL){
    throw new BusinessException("inventory not enough.");
}

// 获取商品单价
String getPriceProductUrl = "http://localhost:8080/api/product/get-price-product?productId=" + productId;
// 使用泛型解析嵌套数据
ParameterizedTypeReference<Result<ProductResponse>> responseType =
        new ParameterizedTypeReference<Result<ProductResponse>>() {};
ResponseEntity<Result<ProductResponse>> responseEntity =
        restTemplate.exchange(getPriceProductUrl, HttpMethod.GET, null, responseType);

// 获取返回结果
Result<ProductResponse> result = responseEntity.getBody();
BigDecimal orderCost = null;
if(result.getCode() == Result.SUCCESS){
    ProductResponse productResponse = result.getData();
    if (productResponse != null && productResponse.getProductPrice() != null) {
        orderCost= productResponse.getProductPrice().multiply(new BigDecimal(orderQuantity));
    }
}
if(orderCost == null){
    throw new BusinessException("product price wrong, please check the product price.");
}
AccountRequest accountRequest = new AccountRequest();
accountRequest.setUserId(userId);
accountRequest.setOrderCost(orderCost);
//RestTemplate远程调用
String account_url = "http://localhost:8083/api/account/reduce-balance";
int accountCode = restTemplate.postForObject(account_url, accountRequest, Result.class).getCode();
// Integer accountCode = accountService.reduceBalance(accountDTO).getCode();
if (accountCode == Result.FAIL) {
    throw new BusinessException("balance not enough");
}
3.4.2.2. 微服务所在的 IP 地址和端口号都是硬编码,如果库存服务(服务提供者)的 IP 和端口发送变化,或者增加多个库存服务如何调用?

RestTemplate 远程调用

String inventoryUrl = "http://localhost:8081/api/inventory/reduce-inventory";
int inventoryCode = restTemplate.postForObject(inventoryUrl, inventoryRequest, Result.class).getCode();

需要实现服务发现功能,比如订单服务调用前能够获取到最新的库存、商品、账户等服务的列表

解决方案:引入注册中心 Nacos,实现服务的注册与发现,比如将库存、商品、账户等服务注册到 Nacos 中,订单服务调用之前从 Nacos 获取相应的服务列表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2278864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美最高法维持TikTok禁令,不卖就禁或有转机,TikTok直播专线助力企业在挑战中前行

一、TikTok 面临的危机与转机 最近&#xff0c;TikTok 在美国的命运可谓是波谲云诡。当地时间 1 月 17 日&#xff0c;美国联邦最高法院裁定 TikTok “不卖就禁” 的法律不违宪&#xff0c;这就意味着该法案将于 1 月 19 日生效 &#xff0c;TikTok 似乎已被逼至悬崖边缘。然而…

编写Wireshark的Lua脚本详解及示例解析

编写Wireshark的Lua脚本详解及示例解析 编写Wireshark Lua脚本的基本步骤SMGP.lua脚本解析脚本解析要点总结Wireshark是一个强大的网络协议分析工具,支持通过Lua脚本扩展其功能,以解析自定义或复杂的协议。下面将详细介绍如何编写Wireshark的Lua脚本,并通过解析一个具体的SM…

【20】Word:小许-质量管理-论文❗

目录 题目​ NO1.2.3.4.5 NO6.7 NO8 NO9 NO10.11 题目 NO1.2.3.4.5 另存为“Word.docx”文件在考生文件夹下&#xff0c;F12Fn是另存为的作用布局→页面设置对话框→纸张&#xff1a;大小A4→页边距&#xff1a;上下左右不连续ctrl选择除表格外的所有内容→开始→字体对…

【软件开发过程管理规范】需求管理,需求分析,设计开发管理,测试管理(Word)

一、需求管理规程 1 简介 2 过程总体描述 2.1 过程概述 2.2 过程流程图 3 过程元素描述 3.1 准备阶段 3.2 需求调研 3.3 需求分析 软件开发人员及用户往往容易忽略信息沟通&#xff0c;这导致软件开发出来后不能很好地满足用户的需要&#xff0c;从而造成返工。而返工不仅在技术…

RabbitMQ-消息可靠性以及延迟消息

目录 消息丢失 一、发送者的可靠性 1.1 生产者重试机制 1.2 生产者确认机制 1.3 实现生产者确认 &#xff08;1&#xff09;开启生产者确认 &#xff08;2&#xff09;定义ReturnCallback &#xff08;3&#xff09;定义ConfirmCallback 二、MQ的持久化 2.1 数据持久…

了解 .mgJSON 文件

.mgJSON &#xff08;Motion Graphics JSON&#xff09;是一个基于标准 JSON 格式的文件扩展名&#xff0c;专门用于存储和交换与动态图形、动画和多媒体应用相关的数据。该格式支持静态和动态数据流&#xff0c;能够精确描述动画、物体变换、图形效果等。 .mgJSON 文件通过层级…

小白爬虫——selenium入门超详细教程

目录 一、selenium简介 二、环境安装 2.1、安装Selenium 2.2、浏览器驱动安装 三、基本操作 3.1、对页面进行操作 3.1.1、初始化webdriver 3.1.2、打开网页 3.1.3、页面操作 3.1.4、页面数据提取 3.1.5、关闭页面 ?3.1.6、综合小案例 3.2、对页面元素进行操作 3…

pycharm+pyside6+desinger实现查询汉字笔顺GIF动图

一、引言 这学期儿子语文期末考试有一道这样的题目&#xff1a; 这道题答案是B&#xff0c;儿子做错了选了C。我告诉他“车字旁”和“车”的笔顺是不一样的&#xff0c;因为二者有一个笔画是不一样的&#xff0c;“车字旁”下边那笔是“提”&#xff0c;而“车”字是“横”&am…

快手极速版如何查找ip归属地?怎么关掉

在数字化时代&#xff0c;个人隐私的保护成为了广大用户关注的焦点。快手极速版作为一款备受欢迎的短视频应用&#xff0c;其IP归属地的显示与关闭功能自然也成了用户热议的话题。本文将详细介绍如何在快手极速版中查找IP归属地以及如何关闭IP属地显示&#xff0c;帮助用户更好…

C++ 模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

Go语言strings包与字符串操作:从基础到高级的全面解析

Go语言strings包与字符串操作:从基础到高级的全面解析 引言 Go语言以其简洁、高效和强大的标准库而闻名,其中strings包是处理字符串操作的核心工具。本文将深入探讨Go语言中strings包的功能及其在实际开发中的应用,帮助开发者更好地理解和使用这一工具。 1. strings包概述…

基于YOLOv4与Tkinter的口罩识别系统

往期精彩 基于YOLOv11的番茄成熟度实时检测系统设计与实现 用YOLOv11检测美国手语&#xff1a;挥动手腕的科技魔法 基于YOLOv11模型PyQt的实时鸡行为检测系统研究 OpenCV与YOLO在人脸识别中的应用研究(论文源码) 计算机视觉&#xff1a;农作物病虫害检测系统&#xff1a;基于Y…

电力场景红外测温图像绝缘套管分割数据集labelme格式2436张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2436 标注数量(json文件个数)&#xff1a;2436 标注类别数&#xff1a;1 标注类别名称:["arrester"] 每个类别标注的框数&am…

AI编程工具使用技巧——通义灵码

活动介绍通义灵码1. 理解通义灵码的基本概念示例代码生成 2. 使用明确的描述示例代码生成 3. 巧妙使用注释示例代码生成 4. 注意迭代与反馈原始代码反馈后生成优化代码 5. 结合生成的代码进行调试示例测试代码 其他功能定期优化生成的代码合作与分享结合其他工具 总结 活动介绍…

电梯系统的UML文档05

Dispatcher 不控制实际的电梯组件&#xff0c;但它在软件系统中是重要的。每一个电梯有一个ispatcher&#xff0c;主要功能是计算电梯的移动方向、移动目的地以及保持门的打开时间。它和系统中除灯控制器以外的几乎所有控制对象交互。 安全装置也是一个环境对象&#xff0c;它…

各种获取数据接口

各种获取数据免费接口 1.音频接口 代理配置 /music-api:{target:https://api.cenguigui.cn/,changeOrigin:true,rewrite:(path)>path.replace(/^\/music-api/,),secure:false}axios全局配置 import axios from axios;const MusicClient axios.create({baseURL: /music-a…

外包公司名单一览表(成都)

大家好&#xff0c;我是苍何。 之前写了一篇武汉的外包公司名单&#xff0c;评论区做了个简单统计&#xff0c;很多人说&#xff0c;在外包的日子很煎熬&#xff0c;不再想去了。 有小伙伴留言说有些外包会强制离职&#xff0c;不行就转岗&#xff0c;让人极度没有安全感。 这…

第十一章 图论

#include <iostream> #include <cstdio> #include <vector>using namespace std;const int MAXN 1000;vector<int> graph[MAXN]; //用向量存储邻接表中的每个点及其连接的的其他点int main(){return 0; } #include <iostream> #include &…

大数据中 TopK 问题的常用套路

大数据中 TopK 问题的常用套路 作者 Chunel Feng&#xff0c;编程爱好者&#xff0c;阿里巴巴搜索引擎开发工程师。开源项目&#xff1a;Caiss 智能相似搜索引擎 对于海量数据到处理经常会涉及到 topK 问题。在设计数据结构和算法的时候&#xff0c;主要需要考虑的应该是当前算…

RabbitMQ基础篇

文章目录 1 RabbitMQ概述1.1 消息队列1.2 RabbitMQ体系结构 2 RabbitMQ工作模式2.1 简单模式&#xff08;Simple Queue&#xff09;2.2 工作队列模式&#xff08;Work Queues&#xff09;2.3 发布/订阅模式&#xff08;Publish/Subscribe&#xff09;2.4 路由模式&#xff08;R…