从零搭建微服务项目Pro(第0章——微服务项目脚手架搭建)
前言:
在本专栏Base第0章曾介绍一种入门级的微服务项目搭建,尽管后续基于此框架上实现了Nacos、Eureka服务注册发现、配置管理、Feign调用、网关模块、OSS文件存储、JSR参数校验、LogBack日志配置,鉴权模块、定时任务模块等,但由于之前的博客更侧重于功能的实现而非整体架构的和谐统一,随着模块和功能的增多,原先框架设计层面上的不足也逐渐暴露出来,代码层面比如实体类存放位置、Exception处理方式难以统一,各层级耦合度高等,依赖方面如循环依赖、依赖冲突等问题也时有发生。因此,笔者通过参考实习公司代码,使用企业级的脚手架搭建方式,最终重构了原有项目,并实现了绝大部分功能。本章将结合代码以及一些个人见解具体介绍,并会介绍一些微服务相关知识帮助快速上手。
最终实现完整项目代码链接如下,后续会逐步迭代并最终完成完整的后端代码,(可能还会包括Vue网页端和OpenHarmony手机端的前端代码),以及详尽的配置文档方便快速入手以及设计文档方便快速了解业务,欢迎Star和Follow。
wlf728050719/BitGoPlus
https://github.com/wlf728050719/BitGoPlus如果没有接触过微服务项目或者对上述功能模块感兴趣的小伙伴可收藏下面专栏目录链接,专栏主要内容为笔者从0接触微服务的全部学习心得和记录。以及建议按时间顺序看循序渐进。
从零搭建微服务项目(全)-CSDN博客
https://blog.csdn.net/wlf2030/article/details/145799620?spm=1001.2014.3001.5501

一、前置知识:
为降低本章门槛还是做一些前置知识讲解。如果有一定微服务项目开发基础这部分就可以直接跳过。以及笔者有误的地方也欢迎评论区指出。
1.前端、后端、数据库

前端(客户端):B/S架构下前端主要指网页,C/S架构下主要指手机或电脑上的应用程序,当然也有微信小程序这种混合架构下的前端,前端主要用于和用户交互,并将用户指定通过http请求发送给后端。并展示后端返回数据
后端(服务器):接收前端请求,处理业务逻辑(如验证、计算),并与数据库交互,并将数据作为响应返回前端。
数据库:结构化存储数据(如用户信息、订单记录)。
这里拿BS架构举例,当搜索一次4399后按f12抓包能够看见其发起了一次http请求,请求地址是www.baidu.com以及将输入的值4399和编码格式utf8以及上次搜索的值43999一并发送(请求)给了对应域名的服务器,并成功获取了其返回的数据xml形式数据(响应)。


(注意不是有服务器就是后端,笔者大二学数据库时曾以为安装了数据库的云服务器就是后端,做的课设实际前端既负责处理远程服务器传来的数据又展示界面,当时信誓旦旦的和老师说是CS架构项目,现在看来可能叫CD结构更合适)
2.后端分层架构

(学习过Servlet开发或者Spring MVC/Spring Boot的小伙伴应该对这张图不会陌生。个人所有编程语言最喜欢Java很大程度上在于它把分层解耦的思想发挥到了极致。)
后端按照各自负责功能划分为五层,可以选择将Manager层合并到Service层,笔者更倾向五层架构。图中默认上层依赖于下层,箭头关系表示可直接依赖,如:开放接口层可以依赖于 Web 层,也可以直接依赖于 Service 层,依此类推:
UserManagerImpl属于Manager层,其作用在于对插入数据库的主键进行处理,而非使用数据库生成主键。(个人倾向五层架构的原因也在于如果使用了mybatis plus,在遇到需要对与数据库直接交互数据特殊处理时,放dto中需要手写本来已经实现的crud操作费时费力,放service中与其他业务函数相比比如register、login忽然出现一个insert,update显得不伦不类)
UserServiceImpl属于Service层,能够看到其一个业务函数中使用了多个Manager层数据对象,实现了功能的复用。

UserController属于Web层,其将service层提供的功能封装为一个个接口,供前端访问。比如登录功能,前端只需要发送https://ip地址:port号/user/register并附带上注册所需要的数据即可在数据库中新增一个用户。

终端显示层负责将后端返回的数据(如JSON、XML)转换为用户可理解的界面(如表格、图表、文字),其实理解为前端也行,但一般都采用前后端分离的方式,所以一般不会直接在后端返回一个html页面。
3.微服务架构

服务调用:
微服务架构是一种 将单体应用拆分为多个小型、独立服务 的架构风格,每个服务负责不同的业务功能,比如A服务负责用户,B服务负责订单,各个服务内部可以相互调用,比如订单表中只有用户id,但订单服务需要返回用户完整信息,此时B服务就需要远程调用(RPC)A服务,传给它用户id,并拿取其返回信息拼装返回给前端。
服务调用可参考下面链接:从零搭建微服务项目Base(第1章——微服务模块间调用接口)_搭建一个微服务项目-CSDN博客
从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)_springboot feign 日志-CSDN博客
从零搭建微服务项目Base(第6章——Feign性能优化以及模块抽取)-CSDN博客
服务注册、网关路由:
当服务从单体拆分成多个后,前端人员编写接口时需要把哪个服务对应哪个ip端口写入程序中,然后每次发请求均需要查询对应接口,这显然不切实际,一旦接口增加,岂不是用户还得升级以下前端配置,注册中心加网关即可很好解决这个问题,每个服务启动时,将自己的服务名和ip端口注册到注册中心,前端只需要记住网关服务的地址即可,所有请求都发向网关,网关中配置哪些请求路径匹配哪些服务,并从注册中心拿到这些服务的地址,网关进行转发即可。同时注册中心会告诉网关哪些服务实例挂了,或者哪些服务现在很忙,通过负载均衡决定到底路由到哪个服务。
服务注册可参考下面链接:
从零搭建微服务项目Base(第2章——Eureka服务注册和发现)_微服务开发实例 服务发现与注册-CSDN博客
从零搭建微服务项目Base(第3章——Nacos服务注册和发现)_nacos服务从零搭建-CSDN博客
网关路由可参考下面链接:
从零搭建微服务项目Base(第7章——微服务网关模块基础实现)-CSDN博客
鉴权:
但此时又出现一个问题,要是我知道你某个服务真实地址,我直接访问它不过你的网关,我直接访问敏感接口猛猛爬用户数据该怎么办,此时就需要为每个服务引入鉴权,你绕过我网关没关系,但你只要访问我的敏感接口就必须提供身份证明(jwt生成的token),同时为了让其他服务能够正常相互调用也需要进一步处理,这里不再细讲。
鉴权可参考下面链接:
从零搭建微服务项目Pro(第6-1章——Spring Security+JWT实现用户鉴权访问与token刷新)_微服务springboot+security+jwt实现刷新token-CSDN博客
配置管理:
既然服务名和ip对应关系已经存放在注册中心,不如多存点,将各服务配置也同样存储,这样就不用将配置也打包,否则一旦配置发生变化岂不是还得重新打包上线。因此nacos,eureka等(注册中心)顺便也做了配置管理。
配置管理可参考下面链接:
从零搭建微服务项目Base(第4章——Nacos环境隔离和配置拉取)_微服务项目搭建 nacos-CSDN博客
分库分表:
既然服务都拆分了,那自然数据库也得拆,否则相当于把热点从服务器转移到了数据库上。分库显然能够减轻单个数据库压力,那分表呢?垂直分表将热点数据集中减小每次数据吞吐量,水平分布则能通过主键id定位使用哪张表,如果分了100张表,则单表的数据量除以100,查询表的速率显然会涨一大截。当然由于分布式系统加分表后如何确保主键唯一以及具体如何使用也需要解决。
分库分表可参考下面链接:
从零搭建微服务项目Pro(第7-1章——分布式雪花算法)_如果当前时间戳对于用例来说是异常的,那么深入到指标,找出时间戳中有高度异-CSDN博客
从零搭建微服务项目Pro(第8-1章——Sharding-Jdbc+MybatisPlus)_mybatis-plus 整合 sharding-jdbc-CSDN博客
缓存:
学习过计组的小伙伴都知道cache的速度远大于磁盘,当然此cache非彼cache,单拿最常用的缓存redis举例,其会将数据以key-value的形式存储,搜索效率远快于数据库逐条查询,因此一般常将不那么频繁变动的数据存在缓存,后端优先使用缓存数据。当然如果sql数据变动一定要及时更改缓存,否则就会出现经典面试题目,数据库和缓存不一致怎么办(延迟双删)。
缓存可参考下面链接:
(-----------------------占位符----------------------还没做------------------------后续更新------------------------)
二、代码约定:
对于代码的某种实现,不同时间可能会有不同的做法,为了统一代码,做了以下约定(其实只是单纯怕自己忘记变成左右手互博),该部分内容在项目readme.md中,会随着项目推进不断迭代(可能会吃书,仅供参考)
(1)表现层业务成功返回R.ok,可预见错误返回R.failed。用户异常操作时(如未授权访问/参数校验错误)均抛出异常(前后端统一)
(2)返回R中不带额外数据时,使用R<Boolean>,需要明确设置true,失败使用false(前后端统一)
(3)除了业务异常以及继承类msg使用中文,其余使用英文(用户友好)
(4)持久层类均与PO或DictItem结尾,对应同名Manager类(统一命名规范)
(5)Manager层负责可复用业务,Service层实现具体业务,原则上每个服务只能有一个service,且其函数与对应接口同名(分层解耦)
(6)所有接口传入对象只能为dto中定义对象,且只有dto中对象添加jsr校验(使参数校验部分统一由Controller负责)
(7)所有dto对象转po对象方法必须定义在dto对象中,且方法固定为newXX明确为两个不同对象(使po专注于与数据库交互)
(8)manager层不对mapper的异常进行特殊处理,抛出统一捕获(便于Service层回滚)
(9)每个服务RPC接口均命名为APIController且统一以/api路径开头(安全配置开放为内部端点,统一鉴权)
(10)通过@Cacheable注解value为命名空间,统一使用KeyGenerator进行管理。使用RedisTemplate则需要统一使用定义在RedisKey文件中的String.format/String形式(防止魔法值,且相同类型缓存使用类似键生成方式方便查询)
(11)所有service层涉及操作manager的方法均需要添加@Transactional(防止数据库脏数据)
(12)各模块内部exception定义在各自模块中,继承BizException或SysException(方便ExceptionHandler统一处理)
(13) 所有实体类必须定义在common-core模块中(否则容易出现循环依赖问题)
三、项目结构

.sql存储建库sql文件
.style存储代码风格规范文件(可参考下面链接)Java静态代码分析工具安装及使用(FindBugs、SpotBugs、SonarQube)以及使用CheckStyle规范阿里代码风格_spotbugs怎么用-CSDN博客
.yaml存储放在nacos上的配置文件,方便配置文件版本管理
auth-service鉴权服务模块
common公共模块定义
common-bom约定依赖版本
common-cache缓存相关模块
common-core存放所有模块pojo,异常声明处理,以及jsr参数校验(可参考下面链接)
从零搭建微服务项目Pro(第2-1章——JSR303自定义参数校验+异常处理)-CSDN博客
从零搭建微服务项目Pro(第2-2章——JSR303自定义文件校验+整合至微服务公共模块)-CSDN博客
common-data数据库模块,上文提到分库分表在此配置
common-feign服务调用模块,上文提到服务调用在此配置
common-security鉴权模块,上文提到鉴权在此配置
gateway网关模块,上文提到网关模块在此配置
order-service订单服务
task-service定时任务服务(可参考下面链接)
从零搭建微服务项目Pro(第1-1章——Quartz实现定时任务模块)_微服务如何处理定时任务-CSDN博客
从零搭建微服务项目Pro(第1-2章——Quartz实现定时任务模块优化)_springcloud quartz模块-CSDN博客
从零搭建微服务项目Pro(第1-3章——Quartz定时任务模块整合)_创建quarz服务和原有服务的交互逻辑-CSDN博客
user-service用户服务
四、Pom文件
虽然此处会展示,但仍然建议在项目文件中查看。
根
<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>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version><name>${project.artifactId}</name><packaging>pom</packaging><properties><spring-boot.version>2.3.9.RELEASE</spring-boot.version><spring-cloud.version>2.2.5.RELEASE</spring-cloud.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.version>3.8.1</maven.compiler.version><checkstyle.skip>false</checkstyle.skip></properties><modules><module>user-service</module><module>order-service</module><module>common</module><module>gateway</module><module>task-service</module><module>auth-service</module></modules><dependencyManagement><dependencies><!-- 公共版本定义 --><dependency><groupId>cn.bit</groupId><artifactId>common-bom</artifactId><version>${project.version}</version><type>pom</type><scope>import</scope></dependency><!-- spring boot --><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>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>compile</scope><version>1.18.20</version><optional>true</optional></dependency></dependencies><build><resources><!--允许src/main/resources下配置文件读取pom中配置--><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources><pluginManagement><plugins><!--checkstyle插件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-checkstyle-plugin</artifactId><version>3.6.0</version><dependencies><dependency><groupId>com.puppycrawl.tools</groupId><artifactId>checkstyle</artifactId><version>9.3</version></dependency></dependencies><configuration><outputEncoding>UTF-8</outputEncoding><skip>${checkstyle.skip}</skip><configLocation>.style/alibaba.xml</configLocation><consoleOutput>true</consoleOutput><failsOnError>false</failsOnError><linkXRef>false</linkXRef><includeTestSourceDirectory>false</includeTestSourceDirectory><sourceDirectories>${project.build.sourceDirectory}</sourceDirectories></configuration><executions><execution><id>validate</id><phase>validate</phase><goals><goal>check</goal></goals></execution></executions></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven.compiler.version}</version><configuration><target>${maven.compiler.target}</target><source>${maven.compiler.source}</source><encoding>UTF-8</encoding><skip>true</skip></configuration></plugin></plugins></build><!--多环境配置--><profiles><profile><id>dev</id><properties><profile.active>dev</profile.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server-addr>192.168.200.1:8848</nacos.server-addr><nacos.cluster-name>BJ</nacos.cluster-name><nacos.namespace>5dadfe94-237d-4367-998e-b13d172ddcfc</nacos.namespace><profiles.auth-service.port>1232</profiles.auth-service.port><profiles.gateway.port>1233</profiles.gateway.port><profiles.user-service.port>1234</profiles.user-service.port><profiles.order-service.port>1235</profiles.order-service.port><profiles.quartz-service.port>1236</profiles.quartz-service.port></properties></profile><profile><id>test</id><properties><profile.active>test</profile.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server-addr>192.168.200.1:8848</nacos.server-addr><nacos.cluster-name>BJ</nacos.cluster-name><nacos.namespace>5dadfe94-237d-4367-998e-b13d172ddcfc</nacos.namespace><profiles.auth-service.port>2232</profiles.auth-service.port><profiles.gateway.port>2233</profiles.gateway.port><profiles.user-service.port>2234</profiles.user-service.port><profiles.order-service.port>2235</profiles.order-service.port><profiles.quartz-service.port>2236</profiles.quartz-service.port></properties></profile><profile><id>prod</id><properties><profile.active>prod</profile.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server-addr>192.168.200.1:8848</nacos.server-addr><nacos.cluster-name>BJ</nacos.cluster-name><nacos.namespace>5dadfe94-237d-4367-998e-b13d172ddcfc</nacos.namespace><profiles.auth-service.port>3232</profiles.auth-service.port><profiles.gateway.port>3233</profiles.gateway.port><profiles.user-service.port>3234</profiles.user-service.port><profiles.order-service.port>3235</profiles.order-service.port><profiles.quartz-service.port>3236</profiles.quartz-service.port></properties></profile></profiles></project>
common
<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><parent><groupId>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version></parent><artifactId>common</artifactId><packaging>pom</packaging><name>common</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><modules><module>common-bom</module><module>common-core</module><module>common-cache</module><module>common-feign</module><module>common-data</module><module>common-security</module></modules>
</project>
common-bom
<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>cn.bit</groupId><artifactId>common-bom</artifactId><version>1.0.0</version><packaging>pom</packaging><name>common-bom</name><url>http://maven.apache.org</url><properties><bitgo.version>1.0.0</bitgo.version><mybatis-plus.version>3.5.1</mybatis-plus.version><sharding-jdbc.version>4.1.1</sharding-jdbc.version><jjwt.version>0.9.1</jjwt.version><jaxb.version>2.3.1</jaxb.version><mysql.connector.version>8.0.28</mysql.connector.version><openfeign.version>2.2.5.RELEASE</openfeign.version><gateway.version>2.2.5.RELEASE</gateway.version></properties><dependencyManagement><dependencies><!-- jwt --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>${jaxb.version}</version></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>${jaxb.version}</version></dependency><!-- sharding jdbc --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>${sharding-jdbc.version}</version></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.connector.version}</version></dependency><!-- open feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version></dependency><!-- gateway --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><version>${gateway.version}</version></dependency><!-- =============内部依赖版本号============== --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId><version>${bitgo.version}</version></dependency><dependency><groupId>cn.bit</groupId><artifactId>common-cache</artifactId><version>${bitgo.version}</version></dependency><dependency><groupId>cn.bit</groupId><artifactId>common-feign</artifactId><version>${bitgo.version}</version></dependency><dependency><groupId>cn.bit</groupId><artifactId>common-data</artifactId><version>${bitgo.version}</version></dependency><dependency><groupId>cn.bit</groupId><artifactId>common-security</artifactId><version>${bitgo.version}</version></dependency></dependencies></dependencyManagement>
</project>
common-cache
<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><parent><groupId>cn.bit</groupId><artifactId>common</artifactId><version>1.0.0</version></parent><artifactId>common-cache</artifactId><packaging>jar</packaging><name>common-redis</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- cache --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency></dependencies>
</project>
common-core
<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><parent><groupId>cn.bit</groupId><artifactId>common</artifactId><version>1.0.0</version></parent><artifactId>common-core</artifactId><packaging>jar</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- validation --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- security --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId></dependency></dependencies>
</project>
common-data
<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><parent><groupId>cn.bit</groupId><artifactId>common</artifactId><version>1.0.0</version></parent><artifactId>common-data</artifactId><packaging>jar</packaging><name>common-mybatis</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- =======内部依赖======= --><!-- common cache --><dependency><groupId>cn.bit</groupId><artifactId>common-cache</artifactId></dependency></dependencies>
</project>
common-feign
<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><parent><groupId>cn.bit</groupId><artifactId>common</artifactId><version>1.0.0</version></parent><artifactId>common-feign</artifactId><packaging>jar</packaging><name>common-feign</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- open feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- =======内部依赖======= --><!-- common-core --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId></dependency></dependencies>
</project>
common-security
<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><parent><groupId>cn.bit</groupId><artifactId>common</artifactId><version>1.0.0</version></parent><artifactId>common-security</artifactId><packaging>jar</packaging><name>common-security</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- jwt --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId></dependency><!-- =======内部依赖======= --><!-- common-core --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId></dependency><!-- common-feign --><dependency><groupId>cn.bit</groupId><artifactId>common-feign</artifactId></dependency><!-- =======内部依赖======= --></dependencies>
</project>
gateway
<?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>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version></parent><artifactId>gateway</artifactId><name>gateway</name><description>gateway</description><dependencies><!-- gateway --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- =======公共依赖======= --><!-- nacos discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- =======内部依赖======= --></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
order-service
<?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>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version></parent><artifactId>order-service</artifactId><name>order-service</name><description>order-service</description><dependencies><!-- =======公共依赖======= --><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacos discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- open feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- sharding jdbc --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- =======内部依赖======= --><!-- common-core --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId></dependency><!-- common-data --><dependency><groupId>cn.bit</groupId><artifactId>common-data</artifactId></dependency><!-- common-cache --><dependency><groupId>cn.bit</groupId><artifactId>common-cache</artifactId></dependency><!-- common-feign --><dependency><groupId>cn.bit</groupId><artifactId>common-feign</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
task-service
<?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>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version></parent><artifactId>task-service</artifactId><name>task-service</name><description>task-service</description><dependencies><!-- quartz--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><!-- =======公共依赖======= --><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacos discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- open feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- sharding jdbc --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- =======内部依赖======= --><!-- common-core --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId></dependency><!-- common-data --><dependency><groupId>cn.bit</groupId><artifactId>common-data</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
user-service
<?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>cn.bit</groupId><artifactId>BitGoPlus</artifactId><version>1.0.0</version></parent><artifactId>user-service</artifactId><name>user-service</name><description>user-service</description><dependencies><!-- =======公共依赖======= --><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacos discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- open feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- sharding jdbc --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- =======内部依赖======= --><!-- common-core --><dependency><groupId>cn.bit</groupId><artifactId>common-core</artifactId></dependency><!-- common-data --><dependency><groupId>cn.bit</groupId><artifactId>common-data</artifactId></dependency><!-- common-security --><dependency><groupId>cn.bit</groupId><artifactId>common-security</artifactId></dependency><!-- common-cache --><dependency><groupId>cn.bit</groupId><artifactId>common-cache</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
核心为将配置文件定义在根pom中更具不同开发环境选择不同配置,比如nacos地址和各服务端口,并用common-bom统一管理用到所有依赖以及内部common模块的版本信息,再由根pom将其导入通过<dependencyManagement>进而实现对整个项目所用依赖统一管理。
五、服务bootstrap配置文件
server:port: @profiles.order-service.port@spring:profiles:active: @profile.active@application:name: @project.artifactId@cloud:nacos:server-addr: @nacos.server-addr@username: @nacos.username@password: @nacos.password@discovery:cluster-name: @nacos.cluster-name@namespace: @nacos.namespace@group: ${spring.profiles.active}config:cluster-name: ${spring.cloud.nacos.discovery.cluster-name}namespace: ${spring.cloud.nacos.discovery.namespace}group: ${spring.cloud.nacos.discovery.group}file-extension: yamlshared-configs:- data-id: application.yamlgroup: ${spring.profiles.active}refresh: true
snowflake:service-name: ${spring.application.name}
所有服务均使用此bootstrap.yaml文件,不同的配置使用在nacos服务器上的yaml文件,同时各服务公共配置文件为application.yaml。
总结:
理论上使用项目提供的所有配置文件和sql以及代码是能够运行所有服务的,不过由于本章重点在于微服务脚手架的搭建,所以不再具体讲解如何正确配置,后续发布release版本代码会同步更新博客,感兴趣可以start或者follow,基本每周都会有较大新增和改动,当然能自己正确配置的是这个(大拇指)
相关文章:
从零搭建微服务项目Pro(第0章——微服务项目脚手架搭建)
前言: 在本专栏Base第0章曾介绍一种入门级的微服务项目搭建,尽管后续基于此框架上实现了Nacos、Eureka服务注册发现、配置管理、Feign调用、网关模块、OSS文件存储、JSR参数校验、LogBack日志配置,鉴权模块、定时任务模块等,但由于…...
dolphinscheduler创建文件夹显示存储未启用的问题--已解决
只要修改api-server/comf/common.properties和standalone-server/conf/common.properties里面的内容就可以了,应为你要靠standalone-server这个服务启动dolphinscheduler-web,其他就算怎么改你重启dolphinscheduler的时候系统也不会识别新的common.prope…...
C++线段树详解与实现技巧
📚 C++线段树详解与实现技巧 线段树(Segment Tree)是一种高效处理 区间查询 和 区间更新 的数据结构,时间复杂度为 O(log n)。本文结合代码实例,详解其核心原理与实现细节。 🌳 线段树结构特点 完全二叉树:使用数组存储,父子节点关系通过下标计算。区间划分:每个节…...
聊一聊原子操作和弱内存序
1、原子操作概念 在并发编程中,原子操作(Atomic Operation)是实现线程安全的基础机制之一。从宏观上看,原子操作是“不可中断”的单元,但若深入微观层面,其本质是由底层处理器提供的一组特殊指令来保证其原…...
VIRT, RES,SHR之间的关系
VIRT、RES 和 SHR 是进程内存使用的三个关键指标,它们之间的关系反映了进程的内存分配和使用情况。以下是它们的定义和关系: VIRT(虚拟内存):表示进程分配的虚拟内存总量,包括所有代码、数据、共享库、堆栈…...
Ubuntu中部署MeloTTS
0. 环境 ubuntu server 22.04 cuda version 12.4 python version 3.9 1. 安装python依赖 git clone https://github.com/myshell-ai/MeloTTS.git cd MeloTTS注意不是执行 pip install melotts 如果国内服务器无法从github中下载源码,那么可以把github改为gitc…...
2024年React最新高频面试题及核心考点解析,涵盖基础、进阶和新特性,助你高效备战
以下是2024年React最新高频面试题及核心考点解析,涵盖基础、进阶和新特性,助你高效备战: 一、基础篇 React虚拟DOM原理及Diff算法优化策略 • 必考点:虚拟DOM树对比(同级比较、Key的作用、组件类型判断) •…...
Adobe After Effects的插件--------Optical Flares之Options概述
Optical Flares插件的Options是对整个效果的组装和设置。点击该按钮会弹出一个组装室弹窗。 Options组装室就是对每个【镜头对象】进行加工处理,再将其组装在一起,拼凑成完整的光效。 接下来是我对组装室的探索: 面板 面板中有预览、堆栈、编辑和浏览按钮,其作用是调节窗…...
深入解读 React 纯组件(PureComponent)
什么是纯组件? React 的纯组件(PureComponent)是 React.Component 的一个变体,它通过浅比较(shallow comparison)props 和 state 来自动实现 shouldComponentUpdate() 方法,从而优化性能。 核心特点 1. 自动浅比较: PureCompon…...
微信小程序事件详解
微信小程序中的事件绑定是实现交互功能的核心机制之一。通过事件绑定,开发者可以监听用户的操作行为(如点击、输入、滑动等),并根据需要执行相应的逻辑处理。 以下是关于微信小程序事件绑定的详细说明: 一、事件绑定的…...
字符串与相应函数(上)
字符串处理函数分类 求字符串长度:strlen长度不受限制的字符串函数:strcpy,strcat,strcmp长度受限制的字符串函数:strncpy,strncat,strncmp字符串查找:strstr,strtok错误信息报告:strerror字符操作,内存操作函数&…...
Laravel源码进阶
Laravel源码进阶 版本 laravel5.8 生成服务容器 public index.php //compose必要操作 require __DIR__./../vendor/autoload.php; //容器文件 $app require_once __DIR__./../bootstrap/app.php;-bootstrap/app.php //初始化容器 构造函数中执行这个几个方法 //$this->…...
镜舟科技亮相 2025 中国移动云智算大会,展示数据湖仓一体创新方案
4月10-11日,2025 中国移动云智算大会在苏州金鸡湖国际会议中心成功举办。大会以“由云向智,共绘算网新生态”为主题,汇聚了众多行业领袖与技术专家,共同探讨了算力网络与人工智能的深度融合与未来发展趋势。 作为中国领先的企业级…...
2025蓝桥杯省赛C/C++研究生组游记
前言 至少半年没写算法题了,手生了不少,由于python写太多导致行末老是忘记打分号,printf老是忘记写f,for和if的括号也老是忘写,差点连&&和||都忘记了。 题目都是回忆版本,可能有不准确的地方。 …...
重读《人件》Peopleware -(6)Ⅰ管理人力资源Ⅴ-帕金森定律重探 Parkinson’s Law Revisited
1954年,英国作家C. Northcote Parkinson引入了一个概念:工作会膨胀以填满分配给它的时间,这个概念现在被熟知为帕金森定律。如果你不知道很少有管理者接受过任何管理培训的话,你可能会以为他们都参加过一个关于帕金森定律及其影响…...
Linux-内核驱动-led
登记设备号(后面可以动态分配) 自己定义内核函数 登记设备名字和功能 exit和init在内核启动自动执行 这样定义直接操作物理地址 ioctl 定义了设备文件的各种操作,并准备将其注册到内核中。 代码中声明了一个cdev结构体变量cdev,这…...
记录一次因ASM磁盘组空间不足,导致MAP进程无法启动
生产中 ADG 库出现告警,检查发现 map 进程异常: 检查 alter 日志,出现: ORA-19504:failed to create file "DATAC1/casarch/2_162186_1067953047.arc" ORA-17502:ksfdcre:4 Failed to create file ... ORA-15041:diskgroup "DATAC1" space exhausted OR…...
可能存在特殊情况,比如控制台显示有延迟、缓冲问题等影响了显示顺序。
从控制台输出看,正常逻辑应是先执行 System.out.println(" 未处理异常演示 "); 输出对应文本,再因 arr 为 null 访问 length 触发 NullPointerException 输出异常信息。可能存在特殊情况,比如控制台显示有延迟、缓冲问题等影响…...
使用DaemonSet部署集群守护进程集
使用DaemonSet部署集群守护进程集 文章目录 使用DaemonSet部署集群守护进程集[toc]一、使用DaemonSet部署日志收集守护进程集二、管理DaemonSet部署的集群守护进程集1.对DaemonSet执行滚动更新操作2.对DaemonSet执行回滚操作3.删除DaemonSet 一、使用DaemonSet部署日志收集守护…...
c++中继承方面的知识点
继承的概念及定义 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保 持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象 程序设计的层次结…...
PyTorch 学习笔记
环境:python3.8 PyTorch2.4.1cpu PyCharm 参考链接: 快速入门 — PyTorch 教程 2.6.0cu124 文档 PyTorch 文档 — PyTorch 2.4 文档 快速入门 导入库 import torch from torch import nn from torch.utils.data import DataLoader from torchvision …...
Spring AI 结构化输出详解
一、Spring AI 结构化输出的定义与核心概念 Spring AI 提供了一种强大的功能,允许开发者将大型语言模型(LLM)的输出从字符串转换为结构化格式,如 JSON、XML 或 Java 对象。这种结构化输出能力对于依赖可靠解析输出值的下游应用程…...
spring security oauth2.0的四种模式
OAuth 2.0 定义了 4 种授权模式(Grant Type),用于不同场景下的令牌获取。以下是每种模式的详细说明、适用场景和对比: 一、授权码模式(Authorization Code Grant) 适用场景 • Web 应用(有后端…...
从零开始的C++编程 2(类和对象下)
目录 1.构造函数初始化列表 2.类型转换 3.static成员 4.友元 5.内部类 6.匿名对象 1.构造函数初始化列表 ①之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,初始化…...
Vue 项目中 package.json 文件的深度解析
Vue 项目中 package.json 文件的深度解析 在 Vue 项目中,package.json 文件是项目配置的核心,它管理着项目的依赖关系、脚本命令、版本信息等重要内容。正确理解和配置 package.json 文件,对于项目的开发、构建、测试和部署都至关重要。本文…...
将三维非平面点集拆分为平面面片的MATLAB实现
将三维非平面点集拆分为平面面片的MATLAB实现 要将三维空间中不在同一平面上的点集拆分为多个平面面片,可以采用以下几种方法: 1. 三角剖分法 (Delaunay Triangulation) 最简单的方法是将点集进行三角剖分,因为三个点总是共面的࿱…...
AI结合VBA提升EXCEL办公效率尝试
文章目录 前言一、开始VBA编程二、主要代码三、添加到所有EXCEL四、运行效果五、AI扩展 前言 EXCEL右击菜单添加一个选项,点击执行自己逻辑的功能。 然后让DeepSeek帮我把我的想法生成VBA代码 一、开始VBA编程 我的excel主菜单没有’开发工具‘ 选项,…...
基于单片机的电梯智能识别电动车阻车系统设计与实现
标题:基于单片机的电梯智能识别电动车阻车系统设计与实现 内容:1.摘要 随着电动车在日常生活中的普及,将电动车带入电梯带来的安全隐患日益凸显,如引发火灾等。本研究的目的是设计并实现一种基于单片机的电梯智能识别电动车阻车系统。方法上,…...
Python快速入门指南:从零开始掌握Python编程
文章目录 前言一、Python环境搭建🥏1.1 安装Python1.2 验证安装1.3 选择开发工具 二、Python基础语法📖2.1 第一个Python程序2.2 变量与数据类型2.3 基本运算 三、Python流程控制🌈3.1 条件语句3.2 循环结构 四、Python数据结构🎋…...
Java——数据类型与变量
文章目录 字面常量Java数据类型变量定义变量的方式整形变量长整型变量短整型变量字节型变量浮点型变量双精度浮点型单精度浮点型 字符型变量布尔型变量 类型转换自动类型转换(隐式)强制类型转换(显式) 类型提升byte与byte的运算 字…...
