【SpringCloud Alibaba】(二)微服务环境搭建

1. 项目流程搭建

整个项目主要分为 用户微服务、商品微服务和订单微服务,整个过程模拟的是用户下单扣减库存的操作。这里,为了简化整个流程,将商品的库存信息保存到了商品数据表,同时,使用商品微服务来扣减库存。小伙伴们在实现时,也可以将商品库存信息单独开发一个微服务模块,主体逻辑和将库存信息放在商品微服务进行管理是一样的。各服务之间的调用流程如下:
在这里插入图片描述
用户微服务、商品微服务和订单微服务的整体流程为:用户通过客户端调用订单微服务的提交订单的接口后,订单微服务会分别调用用户微服务和商品微服务的接口来查询用户信息和商品信息,并校验商品库存是否充足,如果商品库存充足的话,就会保存订单。并且会调用商品微服务的扣减库存的接口来扣减库存

2. 技术选型

整个项目采用 SpringCloud Alibaba 技术栈实现,主要的技术选型如下所示:

  • 持久层框架:MyBatis、MyBatis-Plus
  • 微服务框架:SpringCloud Alibaba
  • 消息中间件:RocketMQ
  • 服务治理与服务配置:Nacos
  • 负载均衡组件:Ribbon
  • 远程服务调用:Fegin
  • 服务限流与容错:Sentinel
  • 服务网关:SpringCloud-Gateway
  • 服务链路追踪:Sleuth + ZipKin
  • 分布式事务:Seata
  • 数据存储:MySQL+ElasticSearch

3. 模块划分

为了方便开发和维护,同时为了模块的复用性,整体项目在搭建时,会将用户微服务、商品微服务和订单微服务放在同一个 Maven 父工程下,作为父工程的子模块,同时,将用户微服务、商品微服务和订单微服务都会使用的 JavaBean 单独作为一个 Maven 模块,以及各服务都会使用的工具类单独作为一个 Maven 模块

在这里插入图片描述
其中各模块的说明如下所示:

  • shop-springcloud-alibaba:Maven 父工程。
  • shop-bean:各服务都会使用的 JavaBean 模块,包含实体类、Dto、Vo 等 JavaBean。
  • shop-utils:各服务都会使用的工具类模块。
  • shop-order:订单微服务。
  • shop-product:商品微服务。
  • shop-user:用户微服务

4. 代码地址

代码码云地址

其中,数据库文件位于 db 文件夹下。

5. 模块开发

代码已托管到码云,这里只贴部分代码。

5.1 创建 maven 父工程

在IDEA中创建 Maven 工程,名称为 shop-springcloud-alibaba,创建后在项目的 pom.xml 文件中添加
StringBoot 与 SpringCloud alibaba 相关的配置,如下所示:

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath/></parent><packaging>pom</packaging><groupId>com.zzc</groupId><artifactId>shop-springcloud-alibaba</artifactId><version>0.0.1-SNAPSHOT</version><name>shop-springcloud-alibaba</name><description>shop-springcloud-alibaba</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-cloud.version>Greenwich.RELEASE</spring-cloud.version><spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version><logback.version>1.1.7</logback.version><slf4j.version>1.7.21</slf4j.version><common.logging>1.2</common.logging><fastjson.version>1.2.51</fastjson.version><mybatis.version>3.4.6</mybatis.version><mybatis.plus.version>3.4.1</mybatis.plus.version><mysql.jdbc.version>8.0.19</mysql.jdbc.version><druid.version>1.1.10</druid.version></properties><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><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>

5.2 创建工具类模块

在父工程下创建工具类模块 shop-utils,作为整个项目的通用工具类模块。工具类模块的总体结构如下所示:
在这里插入图片描述
代码结构说明:

  1. HttpCode:HTTP 状态码封装类
  2. RestCtrlExceptionHandler:全局异常捕获类
  3. md5 包:通用 MD5 与密码加密类
  4. Result:数据响应类
  5. id 包:使用雪花算法生成 Id

5.3 创建其它微服务模块

5.3.1 创建实体类模块

在父工程下创建实体类模块 shop-bean,作为整个项目的通用实体类模块

shop-bean 模块的依赖相对来说就比较简单了,只需要依赖 shop-utils 模块即可。在 shop-bean 模块的 pom.xml 文件中添加如下配置:

<dependency><groupId>com.zzc</groupId><artifactId>shop-utils</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>

5.3.2 创建三大微服务并完成交互

对于用户微服务、商品微服务和订单微服务来说,每个服务占用的端口和访问的基础路径是不同的,这里就将每个服务占用的端口和访问的基础路径整理成下表所示:

服务名称项目名称占用端口访问的基础路径备注
用户微服务shop-user8060/user用户的增删改查
商品微服务shop-product8070/product商品的增删改查
订单微服务shop-order8080/order订单的增删改查

创建微服务

创建名称为 shop-user 的 Maven 项目,由于我们在前面的文章中,已经完成了对项目整体结构的搭建,所以,在 shop-user 的 pom.xml 文件里添加如下依赖即可:

<dependency><groupId>com.zzc</groupId><artifactId>shop-bean</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>

shop-productshop-order 微服务与 shop-user 类似,只是配置文件 application.yml 配置端口、访问路径不同。

6. 订单微服务下单接口

这里重点看看 shop-order 的下单接口:

@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrder(OrderParamVo orderParamVo) {if (orderParamVo.isEmpty()){throw new RuntimeException("参数异常: " + JSONObject.toJSONString(orderParamVo));}User user = restTemplate.getForObject("http://localhost:8060/user/get/" + orderParamVo.getUserId(), User.class);if (user == null){throw new RuntimeException("未获取到用户信息: " + JSONObject.toJSONString(orderParamVo));}Product product = restTemplate.getForObject("http://localhost:8070/product/get/" + orderParamVo.getProductId(), Product.class);if (product == null){throw new RuntimeException("未获取到商品信息: " + JSONObject.toJSONString(orderParamVo));}if (product.getProStock() < orderParamVo.getCount()){throw new RuntimeException("商品库存不足: " + JSONObject.toJSONString(orderParamVo));}Order order = new Order();order.setAddress(user.getAddress());order.setPhone(user.getPhone());order.setUserId(user.getId());order.setUsername(user.getUsername());order.setTotalPrice(product.getProPrice().multiply(BigDecimal.valueOf(orderParamVo.getCount())));baseMapper.insert(order);OrderItem orderItem = new OrderItem();orderItem.setNumber(orderParamVo.getCount());orderItem.setOrderId(order.getId());orderItem.setProId(product.getId());orderItem.setProName(product.getProName());orderItem.setProPrice(product.getProPrice());orderItemMapper.insert(orderItem);Result<Integer> result = restTemplate.getForObject("http://localhost:8070/product/update_count/" + orderParamVo.getProductId() + "/" + orderParamVo.getCount(), Result.class);if (result.getCode() != HttpCode.SUCCESS){throw new RuntimeException("库存扣减失败");}log.info("库存扣减成功");
}

saveOrder() 方法的实现中,实现的主要逻辑如下:

  1. 判断 orderParams 封装的参数是否为空,如果参数为空,则抛出参数异常。
  2. 通过 RestTemplate 调用用户微服务获取用户的基本信息,如果获取的用户信息为空,则抛出未获
    取到用户信息的异常。
  3. 通过 RestTemplate 调用商品微服务获取商品的基本信息,如果获取的商品信息为空,则抛出未获
    取到商品信息的异常。
  4. 判断商品的库存是否小于待扣减的商品数量,如果商品的库存小于待扣减的商品数量,则抛出商品
    库存不足的异常。
  5. 如果 orderParams 封装的参数不为空,并且获取的用户信息和商品信息不为空,同时商品的库存
    充足,则创建订单对象保存订单信息,创建订单条目对象,保存订单条目信息。
  6. 调用商品微服务的接口扣减商品库存

在上述实现的过程中,存在一个很明显的问题:那就是将用户微服务所在的IP和端口,以及商品微服务所在的IP和端口硬编码到订单微服务的代码中了。这样的做法存在着非常多的问题

硬编码的问题

如果将用户微服务和商品微服务所在的IP地址和端口号硬编码到订单微服务中,会存在非常多的问题,其中,最明显的问题有三个,如下所示。

  1. 如果用户微服务和商品微服务的IP地址或者端口号发生了变化,则订单微服务将变得不可用,需要
    对同步修改订单微服务中调用用户微服务和商品微服务的IP地址和端口号。
  2. 如果系统中提供了多个用户微服务和商品微服务,则无法实现微服务的负载均衡功能。
  3. 如果系统需要支持更高的并发,需要部署更多的用户微服务和商品微服务以及订单微服务,如果将用户微服务和商品微服务的IP地址和端口硬编码到订单微服务,则后续的维护会变得异常复杂。

所以,在微服务开发的过程中,需要引入服务治理功能,实现微服务之间的动态注册与发现。

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

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

相关文章

「苹果安卓」手机搜狗输入法怎么调整字体大小及键盘高度?

手机搜狗输入法怎么调整字体大小及键盘高度&#xff1f; 1、在手机上准备输入文字&#xff0c;调起使用的搜狗输入法手机键盘&#xff1b; 2、点击搜狗输入法键盘左侧的图标&#xff0c;进入更多功能管理&#xff1b; 3、在搜狗输入法更多功能管理内找到定制工具栏&#xff0c…

[数据结构 -- C语言] 二叉树(BinaryTree)

目录 1、树的概念及结构 1.1 树的概念 1.2 树的相关概念&#xff08;很重要&#xff09; 1.3 树的表示 2、二叉树的概念及结构 2.1 概念 2.2 特殊二叉树 2.3 二叉树的性质&#xff08;很重要&#xff09; 2.4 练习题 2.5 二叉树的存储结构 2.5.1 顺序存储 2.5.2 链…

Jenkins报警机制的配置与Linux的使用总结

先在钉钉中添加一个机器人 在Configure System中找到机器人选项&#xff0c;并且复制webhook到网络钩子&#xff0c;然后添加机器人的编号、名称和关键词&#xff0c;然后点击测试&#xff0c;如果显示测试成功则表示配置成功&#xff0c;最后保存 再到配置中勾选顶顶机器人的定…

【CMU15-445 FALL 2022】Project #1 - Buffer Pool

About 实验官网 Project #1 - Buffer Pool在线评测网站 gradescope Lab Task #1 - Extendible Hash Table 详见——【CMU15-445 FALL 2022】Project #1 - Extendable Hashing 如果链接失效&#xff0c;请查看当前平台我之前发布的文章。 Task #2 - LRU-K Replacement Polic…

YOLOv5基础知识

定位和检测: 定位是找到检测图像中带有一个给定标签的单个目标 检测是找到图像中带有给定标签的所有目标 图像分割和目标检测的区别&#xff1a; 图像分割即为检测出物体的完整轮廓&#xff0c;而目标检测则是检测出对应的目标。&#xff08;使用框框把物体框出来&#xff…

SAP客制化区域菜单和IMG配置清单

1. 自定义区域菜单 事务代码 SE43&#xff0c;操作如下 添加菜单对象 展示效果 输入区域菜单名称并回车&#xff0c;效果如下 2. 自定义IMG配置 事务代码 SIMGH IMG structure 示例-事务代码入口 示例-表格维护入口 示例-自定义代码控制对象 需要创建dummy表并设置表维护 页面设…

Progressive Dual-Branch Network for Low-Light Image Enhancement 论文阅读笔记

这是22年中科院2区期刊的一篇有监督暗图增强的论文 网络结构如下图所示&#xff1a; ARM模块如下图所示&#xff1a; CAB模块如下图所示&#xff1a; LKA模块其实就是放进去了一些大卷积核&#xff1a; AFB模块如下图所示&#xff1a; 这些网络结构没什么特别的&#xf…

分布式光伏监控系统运维系统实时查看数据分布式光伏电站监控管理

光伏电站是一种利用太阳能发电的设施&#xff0c;随着人们对可再生能源的需求不断增加&#xff0c;光伏电站的建设也越来越普遍。但是&#xff0c;光伏电站的运营和管理需要高质量的监控系统来确保其正常运行。本文将介绍光伏电站监控系统的组成及其原理。 详细软件具体需求可…

【二等奖方案】基于人工智能的漏洞数据分类赛题「道可道,非常道」团队解题思路

2022 CCF BDCI 大赛 数字安全公开赛「基于人工智能的漏洞数据分类」赛题二等奖团队「道可道&#xff0c;非常道」战队获奖方案&#xff0c;赛题地址&#xff1a; http://go.datafountain.cn/s57 团队简介 本团队具有丰富的比赛和项目经验。在AI大赛上多次拿到Top成绩&#xf…

线性表之链表

1、链表概述 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 顺序表的存储位置可以用一个简单直观的公式表示&#xff0c;它可以随机存取表中任意一个元素&#xff0c;但插入和删除需要移动大量元素。链式…

深入理解 PostgreSQL 的架构和内部工作原理

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Postman怎么做接口测试-以简单的登录接口为例

我们就以登录某测试系统为例子&#xff0c;实现在Postman上做接口测试 一、首先打开系统首页首页&#xff0c;做一个登录操作&#xff08;目的是获取接口url及参数&#xff09;&#xff1a;一般在公司做接口测试的时候页面还没有出来&#xff0c;我们需要根据接口文档进行接口…

kafka第三课-可视化工具、生产环境问题总结以及性能优化

一、可视化工具 https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 下载解压之后&#xff0c;编辑该文件&#xff0c;修改zookeeper地址&#xff0c;也就是kafka注册的zookeeper的地址&#xff0c;如果是zookeeper集群&#xff0c;以逗号分开 vi conf/application.conf 启…

Python 逻辑回归:理论与实践

文章目录 1. 介绍1.1 什么是逻辑回归&#xff1f;1.2 逻辑回归的应用领域 2. 逻辑回归的原理2.1 Sigmoid 函数2.2 决策边界2.3 损失函数 3. 逻辑回归的实现3.1 数据准备3.2 创建逻辑回归模型3.3 模型训练3.4 模型预测3.5 模型评估 4. 可视化决策边界4.1 绘制散点图4.2 绘制决策…

基于SaaS模式的Java基层卫生健康云HIS系统源码【运维管理+运营管理+综合监管】

云HIS综合管理平台 一、模板管理 模板分为两种&#xff1a;病历模板和报表模板。模板管理是运营管理的核心组成部分&#xff0c;是基层卫生健康云中各医疗机构定制电子病历和报表的地方&#xff0c;各医疗机构可根据自身特点特色定制电子病历和报表&#xff0c;制作的电子病历…

Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

代码随想录| 图论04 查并集 ●查并集理论知识 ●1971.寻找图中是否存在路径 ●684.冗余连接 ●685.冗余连接II

#查并集理论知识 并查集用处&#xff1a;解决连通性问题 将两个元素添加到一个集合中。判断两个元素在不在同一个集合 思路&#xff1a;将三个元素A&#xff0c;B&#xff0c;C &#xff08;分别是数字&#xff09;放在同一个集合&#xff0c;其实就是将三个元素连通在一起&a…

Python 算法基础篇:插入排序和希尔排序

Python 算法基础篇&#xff1a;插入排序和希尔排序 引言 1. 插入排序算法概述2. 插入排序算法实现实例1&#xff1a;插入排序 3. 希尔排序算法概述4. 希尔排序算法实现实例2&#xff1a;希尔排序 5. 插入排序与希尔排序的对比总结 引言 插入排序和希尔排序是两种常用的排序算法…

017-从零搭建微服务-系统服务(四)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

【NLP】如何使用Hugging-Face-Pipelines?

一、说明 随着最近开发的库&#xff0c;执行深度学习分析变得更加容易。其中一个库是拥抱脸。Hugging Face 是一个平台&#xff0c;可为 NLP 任务&#xff08;如文本分类、情感分析等&#xff09;提供预先训练的语言模型。 本博客将引导您了解如何使用拥抱面部管道执行 NLP 任务…