【Spring Cloud】环境和工程基本搭建

【Spring Cloud】环境和工程基本搭建

系列文章目录

文章目录

在这里插入图片描述

一、开发环境安装

1.1、JDK

1.1.1、JDK版本介绍

Oracle从JDK9开始每半年发布⼀个新版本, 新版本发布后, ⽼版本就不再进⾏维护. 但是会有⼏个长期维护的版本.
目前长期维护的版本有: JDK8, JDK11, JDK17, JDK21,在JDK版本的选择上,尽量选择长期维护的版本.
为什么选择JDK17?
Spring Cloud 是基于 SpringBoot 进行开发的, SpringBoot 3.X以下的版本, Spring官方已不再进行维护(还可以继续使用), SpringBoot 3.X的版本, 使用的JDK版本基线为JDK17. 所以本文选择使用JDK17

2、案例介绍

2.1、需求

实现⼀个电商平台(不真实实现, 仅为演示)。一个电商平台包含的内容非常多, 以京东为例, 仅从首页上就可以看到巨多的功能

在这里插入图片描述


我们该如何实现呢? 如果把这些功能全部写在⼀个服务⾥, 这个服务将是巨大的.巨多的会员, 巨大的流量, 微服务架构是最好的选择.
微服务应用开发的第⼀步, 就是服务拆分. 拆分后才能进行"各自开发

2.2、服务拆分

服务拆分原则:
微服务到底多小才算"微", 这个在业界并没有明确的标准. 微服务并不是越⼩越好, 服务越⼩, 微服务架构的优点和缺点都会越来越明显.
服务越小, 微服务的独立性就会越来越⾼, 但同时, 微服务的数量也会越多, 管理这些微服务的难度也会提高. 所以服务拆分也要考虑场景.
.

还是以企业管理为例
企业中一个员工的工作内容与企业规模, 项⽬规模等都有关系.
在小公司, ⼀个员工可能需要负责很多部门的事情, 大公司的话, ⼀个部门的工作可能需要多个员工来处理.

拆分微服务—般遵循如下原则:

  1. 单⼀职责原则
    单⼀职责原则原本是面向对象设计中的⼀个基本原则, 它指的是⼀个类应该专注于单⼀功能. 不要存在多于⼀个导致类变更的原因. 在微服务架构中,一个微服务也应该只负责⼀个功能或业务领域, 每个服务应该有清晰的定义和边界, 只关注自己的特定业务领域
  2. 服务自治
    服务自治是指每个微服务都应该具备高度自治的能力, 即每个服务要能做到独立开发, 独立测试, 独立构建, 独立部署, 独立运行.
    以上面的电商系统为例,每⼀个微服务应该有自己的存储, 配置,在进行开发, 构建, 部署, 运行和测试时,并不需要过多关注其他微服务的状态和数据。
  3. 单向依赖
    微服务之间需要做到单向依赖, 严禁循环依赖, 双向依赖
    循环依赖: A -> B -> C ->A
    双向依赖: A -> B, B -> A
微服务架构并无标准架构, 合适的就是最好的, 不然架构师大会也不会各个系统架构百花齐放了.
在架构设计的过程中, 坚持 “合适优于业界领先”, 避免"过度设计"(为了设计而设计). 很多业界领先方案并不是⼀群天才在某个时期一下子做出来的, 而是经过数年的发展逐步完善. 业界领先的方案⼤多是"逼"出来的, 随着业务的发展, 量变导致质变,新的问题出现了, 当前的⽅案⽆法满⾜需求, 需要用新的方案来解决. 通过不断的创新和尝试,业界领先的方案才得以形成。

服务拆分示例:
⼀个完整的电商系统是庞大的, 咱们课程中重点关注如何使用SpringCloud解决微服务架构中遇到的问题.
以订单列表为例:订单列表需要包含的主要信息有:
1.订单列表
2. 商品信息

根据服务的单⼀职责原则, 我们把服务进行拆分为: 订单服务, 商品服务
订单服务: 提供订单ID, 获取订单详细信息
商品服务: 根据商品ID, 返回商品详细信息.

在这里插入图片描述

3.数据准备

根据服务自治原则, 每个服务都应有自己独立的数据库
订单服务:

-- 建库 create database if not exists cloud_order charset utf8mb4;-- 订单表 DROP TABLE IF EXISTS order_detail; CREATE TABLE order_detail ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '订单id', `user_id` BIGINT (20) NOT NULL COMMENT '⽤⼾ID', `product_id` BIGINT (20) NULL COMMENT '产品id', `num` INT (10) NULL DEFAULT 0 COMMENT '下单数量', `price` BIGINT (20) NOT NULL COMMENT '实付款', `delete_flag` TINYINT (4) NULL DEFAULT0, `create_time` DATETIME DEFAULTnow(), `update_time` DATETIME DEFAULTnow(),PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT ='订单表';-- 数据初始化 insert into order_detail (user_id,product_id,num,price)values(2001,1001,1,99),(2002,1002,1,30),(2001,1003,1,40),(2003,1004,3,58),(2004,1005,7,85),(2005,1006,7,94); create database if not exists cloud_product charset utf8mb4;-- 产品表 DROP TABLE IF EXISTS product_detail; CREATE TABLE product_detail ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '产品id', `product_name` varchar (128) NULL COMMENT '产品名称', `product_price` BIGINT (20) NOT NULL COMMENT '产品价格', `state` TINYINT (4) NULL DEFAULT 0 COMMENT '产品状态 0-有效 1-下架', `create_time` DATETIME DEFAULTnow(), `update_time` DATETIME DEFAULTnow(),PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT ='产品表';-- 数据初始化 insert into product_detail (id, product_name,product_price,state) values (1001,"T恤",101,0),(1002,"短袖",30,0),(1003,"短裤",44,0),(1004,"卫⾐",58,0),(1005,"⻢甲",98,0),(1006,"⽻绒服",101,0),(1007,"冲锋⾐",30,0),(1008,"袜⼦",44,0),(1009,"鞋⼦",58,0),(10010,"⽑⾐",98,0)

4.工程搭建

4.1、构建父子工程

4.1.1、创建父工程

1.创建⼀个空的Maven项⽬, 删除所有代码, 只保留pom.xml
2.目录结构:

在这里插入图片描述


2. 完善pom文件
使用properties来进行版本号的统一管理, 使用dependencyManagement来管理依赖, 声明父工程的打包方式为pom

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version><relativePath/><!-- lookup parent from repository --></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><mybatis.version>3.0.3</mybatis.version><mysql.version>8.0.33</mysql.version><spring-cloud.version>2022.0.3</spring-cloud.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><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>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>${mybatis.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement></project>

DependencyManagement 和 Dependencies:

1 . dependencies :将所依赖的jar直接加到项目中. 子项目也会继承该依赖.
2 . dependencyManagement :只是声明依赖, 并不实现Jar包引入. 如果子项目需要用到相关依赖,需要显式声明. 如果子项目没有指定具体版本, 会从⽗项⽬中读取version. 如果子项目中指定了版本号,就会使用子项目中指定的jar版本. 此外父⼯程的打包方式应该是pom,不是jar, 这里需要手动使用 packaging 来声明

4.1.2、创建子项目-订单服务

做如下操作:

在这里插入图片描述


声明项目依赖 和 项目构建插件:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

4.1.3、创建子项目-商品服务

创建模块部分同上

下面声明项目依赖和项目构建插件

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

4.2、完善订单服务

4.2.1、完善启动类, 配置文件

启动类:

@SpringBootApplicationpublicclassOrderServiceApplication{publicstaticvoidmain(String[] args){SpringApplication.run(OrderServiceApplication.class, args);}}

配置文件:

server: port:8080 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=false username: root password: root driver-class-name:com.mysql.cj.jdbc.Driver mybatis: configuration: # 配置打印 MyBatis⽇志 log-impl:org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case:true #配置驼峰⾃动转换 

4.2.2 业务代码

  1. 实体类:
@DatapublicclassOrderInfo{privateInteger id;privateInteger userId;privateInteger productId;privateInteger num;privateInteger price;privateInteger deleteFlag;privateDate createTime;privateDate updateTime;}
  1. Controller
@RequestMapping("/order")@RestControllerpublicclassOrderController{@AutowiredprivateOrderService orderService;@RequestMapping("/{orderId}")publicOrderInfogetOrderById(@PathVariable("orderId")Integer orderId){return orderService.selectOrderById(orderId);}}
  1. Service
@ServicepublicclassOrderService{@AutowiredprivateOrderMapper orderMapper;publicOrderInfoselectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);return orderInfo;}}
  1. Mapper
@MapperpublicinterfaceOrderMapper{@Select("select * from order_detail where id=#{orderId}")OrderInfoselectOrderById(Integer orderId);}

完善商品服务类似,故代码不展示。

4.4、远程调用

4.4.1、需求

根据订单查询订单信息时, 根据订单里产品ID, 获取产品的详细信息.

在这里插入图片描述

4.4.2、实现

实现思路:: order-service服务向product-service服务发送⼀个http请求, 把得到的返回结果, 和订单结果融合在⼀起, 返回给调用方.
实现方式: 采用Spring 提供的RestTemplate

1 . 定义RestTemplate:

@ConfigurationpublicclassBeanConfig{@BeanpublicRestTemplaterestTemplate(){returnnewRestTemplate();}}
  1. 修改order-service中的 OrderService
@ServicepublicclassOrderService{@AutowiredprivateOrderMapper orderMapper;@AutowiredprivateRestTemplate restTemplate;publicOrderInfoselectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);String url ="http://127.0.0.1:9090/product/"+ orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class); orderInfo.setProductInfo(productInfo);return orderInfo;}}

5.RestTemplate

RestTemplate 是从 Spring3.0 开始支持的⼀个 HTTP 请求⼯具, 它是⼀个同步的 REST API 客户端, 提供了常见的REST请求方案的模版

什么是REST?
REST(Representational State Transfer), 表现层资源状态转移.
REST是由HTTP的主要设计者提出来的⼀种软件架构风格.这里面主要有三个概念:

1 . 资源: 网络上的所有事物都可以抽象为资源, 每个资源都有⼀个唯⼀的资源标识符(URI)
2 . 表现层: 资源的表现形式, 比如文本作为资源, 可以用txt格式表现, 也可以通过HTML, XML, JSON等格式来表现, 甚至以二进制的格式表现.
3 . 状态转移: 访问URI, 也就是客⼾端和服务器的交互过程. 客户端用到的手段,只能是HTTP协议. 这个过程中, 可能会涉及到数据状态的变化. 比如对数据的增删改查, 都是状态的转移

REST 是一种设计风格, 指资源在网络中以某种表现形式进行状态转移.
简单来说: REST描述的是在网络中Client和Server的⼀种交互形式, REST本身不实用,实用的是如何设计RESTful API(REST风格的网络接口)

什么是RESTful?
REST 是⼀种设计风格, 并没有⼀个明确的标准. 满足这种设计风格的程序或接口我们称之为RESTful(从单词字面来看就是⼀个形容词). 所以RESTful API 就是满足REST架构风格的接口.

RESTful风格大致有以下几个主要特征:

资源: 资源可以是⼀个图片, 音频, 视频或者JSON格式等网络上的⼀个实体, 除了⼀些⼆进制的资源外普通的文本资源更多以JSON为载体、面向用户的⼀组数据(通常从数据库中查询而得到)
2 . 统⼀接口: 对资源的操作. 比如获取, 创建, 修改和删除. 这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法. 换言而知,如果使用RESTful风格的接口, 从接⼝上你可能只能定位其资源,但是无法知晓它具体进行了什么操作,需要具体了解其发⽣了什么操作动作要从其HTTP请求方法类型上进行判断
比如同⼀个的URL:
GET /blog/{blogId}:查询博客
DELETE /blog/{blogId}:删除博客
这些内容都是通过HTTP协议来呈现的. 所以RESTful是基于HTTP协议的.
RestTemplate 是Spring提供, 封装HTTP调用, 并强制使用RESTful风格. 它会处理HTTP连接和关闭,只需要使用者提供资源的地址和参数即可

RESTful实践
RESTful风格的API 固然很好很规范, 但⼤多数互联网公司并没有按照其规则来设计, 因为REST是⼀种风格,而不是⼀种约束或规则, 过于理想的RESTful API 会付出太多的成本.
RESTful API 缺点:

  1. 操作方式繁琐, RESTful API通常根据GET, POST, PUT, DELETE 来区分对资源的操作动作. 但是HTTP Method 并不可直接见到, 需要通过抓包等⼯具才能观察. 如果把动作放在URL上反而更加直观, 更利于团队的理解和交流.
  2. ⼀些浏览器对GET, POST之外的请求支持不太友好, 需要额外处理.
  3. 过分强调资源. 而实际业务需求可能比较复杂, 并不能单纯使用增删改查就能满足需求, 强行使用RESTful API会增加开发难度和成本.
    所以, 在实际开发中, 如果业务需求和RESTful API不太匹配或者很麻烦时, 也可以不用RESTful API. 如果使用场景和REST风格比较匹配, 就可以采用RESTful API.
    总之: 无论哪种风格的API, 都是为了方便团队开发, 协商以及管理, 不能墨守成规. 尽信规范不如无规范.

6.项目存在问题

• 远程调用时, URL的IP和端口号是写死的(http://127.0.0.1:9090/product/), 如果更换IP, 需要修改代码
◦ 调用方如何可以不依赖服务提供⽅的IP?
• 多机部署, 如何分摊压力?
• 远程调用时, URL非常容易写错, 而且复用性不高, 如何优雅的实现远程调用
• 所有的服务都可以调用该接口, 是否有风险?
除此之外, 微服务架构还面临很多问题, 我会在本系列后续文章一一为大家介绍学习如何使用Spring Cloud 来解决这些问题.

二、总结

以上就是本文全部内容,主要主要搭建了后续Spring Cloud后续组件使用的基本工程环境,以及引出了相关spring cloud可以解决的实际工程问题。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持

Read more

Flutter for OpenHarmony: Flutter 三方库 husky 守卫鸿蒙项目的 Git 提交规范(前端工程化必备)

Flutter for OpenHarmony: Flutter 三方库 husky 守卫鸿蒙项目的 Git 提交规范(前端工程化必备)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在 OpenHarmony 项目的团队协作中,我们最怕遇到“带病提交”的代码。比如:某位开发者提交的代码没经过 dart format 美化、或是包含明显的 lint 警告,甚至导致整个鸿蒙工程编译失败。如果在 CI(持续集成)阶段才发现,修复成本就太高了。 husky 是从前端生态圈引进的 Git Hooks 管理神器。它能让你极简地配置 Git 的各个钩子(如 pre-commit),在代码真正提交到远端(AtomGit)之前,强制执行格式化或单元测试,确保入库的代码永远是高质量的。 一、Git Hook 工作流模型 husky 在本地提交阶段建立了一道自动化的“安检门”。 通过 失败

By Ne0inhk
2026最新|GitHub 启用双因素身份验证 2FA 教程:TOTP.app 一键生成动态验证码(新手小白图文实操)

2026最新|GitHub 启用双因素身份验证 2FA 教程:TOTP.app 一键生成动态验证码(新手小白图文实操)

2026最新|GitHub 启用双因素身份验证 2FA 教程:TOTP.app 一键生成动态验证码(新手小白图文实操) 如果你最近登录 GitHub 时被提示“启用双因素身份验证(2FA)”,别慌——这就是在你输入密码后,再增加一道“动态验证码”的安全锁。本文用TOTP.app(可下载/可在线) 带你从 0 到 1 完成 GitHub 的 2FA 配置,全程保留原图与链接,按步骤照做就能成功。 关键词:GitHub 2FA、GitHub 双因素身份验证、GitHub 启用 2FA、GitHub TOTP、GitHub 动态验证码、GitHub 账号安全、GitHub 登录保护、

By Ne0inhk
最新版 Kimi K2.5 进阶实战全攻略:从开源部署到 Agent 集群搭建(视频理解 + 多模态开发 + 高并发调优)

最新版 Kimi K2.5 进阶实战全攻略:从开源部署到 Agent 集群搭建(视频理解 + 多模态开发 + 高并发调优)

1 技术背景与核心架构原理 1.1 技术定位与版本说明 Kimi K2.5 是月之暗面于2026年初发布的开源多模态大语言模型,聚焦长上下文理解、原生多模态交互、Agent 原生支持三大核心能力,针对工业级落地场景完成了全链路优化。本次实战覆盖的开源版本包括: * kimi-k2.5-chat-70b:基础对话版,支持2000K token 上下文窗口,原生适配工具调用 * kimi-k2.5-multimodal-70b:多模态完整版,新增图像、长视频时序理解能力,支持最长10小时连续视频输入 * kimi-k2.5-agent-70b:Agent 优化版,强化多轮工具链执行、分布式状态同步能力,适配集群化部署 * 量化衍生版本:AWQ 4bit/8bit、FP8 量化版,适配低显存硬件环境,精度损失控制在1%以内 1.2 核心架构与技术亮点 1.2.1

By Ne0inhk

VS Code 中 Git 的使用:从零到一保姆级菜鸟教程

VS Code 中 Git 的使用:从零到一保姆级菜鸟教程 前言 在现代软件开发中,版本控制是必不可少的技能。VS Code 作为目前最流行的代码编辑器,其内置的 Git 可视化工具让代码管理变得极其直观和简单。 本文将带你从零开始,跑通“下载安装 -> 环境配置 -> GitHub 关联 -> 提交推送 -> 冲突解决”的全流程。告别繁琐的命令行,用可视化的方式优雅地管理代码! 1. 软件下载与基础配置 1.1 下载地址 * VS Code 官方下载:https://code.visualstudio.com/Download * Git 官方下载 (Windows

By Ne0inhk