基于grpc从零开始搭建一个准生产分布式应用 - 工程构建

贵有恒,何必三更起、五更眠、最无益,只怕一日曝、十日寒。这篇文章主要讲述基于grpc从零开始搭建一个准生产分布式应用 - 工程构建相关的知识,希望能为你提供帮助。

开始本章之前默认读者已经配置好了以下环境:Intellij IDEA 2022.1.2、JDK 1.8.0_144、Maven 3,另外也建议大家在一些免费代码托管平台开个帐号,这样就可以免费使用git做版本处理了,笔者自己私人使用的是阿里云的云效平台。因为此专题涉及到代码,所以笔者暂时把工程名称定为【base-grpc-framework】。
本章代码任务:1、构建工程目录;2、完成springboot集成模块;
一、为什么工程结构需要设计?工程的构建工作一般很容易被忽略,通常认为只是创建几个目录存储代码用而已。其实不然,工程目录结构合理与否除了直接会影响工程打包和上线流程,还会影响开发效率以及重构。
工程目录设计除了符合系统架构外,还要符合小组成员的开发习惯。所以在开发新项目或是优化祖传代码时一定要把这件事做为一件非常重要的事来对待,否则过程中重构工程结构的代价会非常大,想想N多代码需要迁移、多个分支在开发、还要大量的回归测试等等。
二、两种典型的工程目录结构2.1、普通的分布式工程结构
大多数项目组都会采用这种格式(在这个系列专题中笔者用到的是这种结构),这种结构一般比较适用单体应用或是不太复杂的分布式应用,其特点是把API定义和API实现隔离开。其它模块都可看成是辅助模块被包装或是被引用,其结构如下:
其调用关系大致如下,比较简单不再详细描述了,同学们理解下就可以:

2.2、组件化的分布式工程结构
这种应用比较复杂,一般是为了满足一套代码多地部署而设计的。其特点是多地部署时其核心代码在逻辑上存在差别。比如电商中的结算流程,在不同国家都有法律上的明确要求。
结算流程在中国需要遵守二分帐期的法规要求,但这个法规只局限于中国,比如在泰国就没有。在用同一套代码实现时就需要在部署泰国时把二分这个逻辑拿掉,一般有两种方案:1、维护两套源码;2、把差异点隔离出来,按需打包;在综合考虑成本时一般在维护大型系统时一般都会采用第2套方案。下同给出两个例子,这两个例子可以组合使用以适应更多场景。
  这种方式不在本专题内容范畴内,所以只简单介绍下,感觉举的读者可在笔者写的《DDD领域驱动设计》专题中了解。

上图红框内的模块区分了国别,承载了不同国家的定制化业务代码,cn-中国,id-印尼,th-泰国。

上图红框内的模块区分了业务,承载了不同业务方的定制化代码,比如虚拟商品区别于实物商品的物流和仓储流程。

综上:如果在建设中台系统或是跨国系统时可以采用2.2节中的工程设计,建设普通的业务类系统或单体应用时可采用2.1节中的工程设计。
三、工程详细3.1、总体结构
为了有个全局视角,笔者把后续需要用到的模块一次性全创建了,如下图所示,这里只需了解下全貌即可,后续章节笔者会带着大家一点点填内容:

  • pom.xml:项目主maven文件,主要定义公共的配置以及版本控制;
  • .gitignore:用git时忽略的提供文件配置;
  • base-grpc-framework-common:项目工具包;
  • base-grpc-framework-api:项目接口定义;
  • base-grpc-framework-core:接口业务实现;
  • base-grpc-framework-dao:数据库存储实现;
  • base-grpc-framework-application:项目启动包装应用;
  • base-grpc-framework-client:web客户端;
四、创建过程本节中我们要实现上一节中提到的工程结构,在特殊的地方笔者会详细说明,通用的地方大家按图示自行创建即可在后续实现代码时再完善其内容。因此专题的代码笔者一直在写,部分源码已早于文档内容并可能存在错误,所以暂时先不共享了,在此专题结束时会统一放出来。实在有需要的同学可以私信笔者,不过笔者强烈建议大家随着笔者一起来动手。
笔者用的是IDE是idea,建议大家使用2022的版本,优化了很多便捷的操作。必要的插件可参考笔者的  ??https://blog.51cto.com/arch/5277533?? 一文,先安装即可后续应该全会用到了。完整的工程目录下如:

4.1、创建root工程
root工程,只有一个pom.xml文件,主要为了控制版本和一些公共的配置(可查看下面的源码注释),打包为pom类型。文档中所有的代码都是经过笔者测试过的,可复制后直接使用,完整代码如下:
【基于grpc从零开始搭建一个准生产分布式应用 - 工程构建】
< ?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> com.zd< /groupId>
< artifactId> base-grpc-framework-parent< /artifactId>
< packaging> pom< /packaging>
< version> 1.0-SNAPSHOT< /version>

< !--引入springboot框架-->
< parent>
< artifactId> spring-boot-starter-parent< /artifactId>
< groupId> org.springframework.boot< /groupId>
< version> 2.2.2.RELEASE< /version>
< /parent>

< !--版本定义:插件相关、配置相关、工具框架、grpc、数据库、其它杂项-->
< properties>
< java.version> 14< /java.version>
< maven.compile.source> 1.8< /maven.compile.source>
< maven.compile.target> 1.8< /maven.compile.target>
< project.build.sourceEncoding> UTF-8< /project.build.sourceEncoding>

< maven.kr.motd> 1.6.2< /maven.kr.motd>
< maven.org.xolstice> 0.6.1< /maven.org.xolstice>

< nacos.version> 0.2.8< /nacos.version>
< junit.test.version> 4.12< /junit.test.version>

< hutool.version> 5.7.21< /hutool.version>
< lombok.version> 1.18.20< /lombok.version>
< guava.version> 30.1-jre< /guava.version>
< mapstruct.version> 1.4.2.Final< /mapstruct.version>

< grpc.version> 2.13.0.RELEASE< /grpc.version>
< io.grpc.version> 1.42.1< /io.grpc.version>
< protobuf.java.version> 3.19.1< /protobuf.java.version>

< mybatisplus.version> 3.4.1< /mybatisplus.version>
< mysql.version> 8.0.23< /mysql.version>
< druid.version> 1.1.22< /druid.version>

< commons-lang3.version> 3.9< /commons-lang3.version>
< /properties>

< dependencyManagement>
< dependencies>
< !--nacos应用配置-->
< dependency>
< groupId> com.alibaba.boot< /groupId>
< artifactId> nacos-config-spring-boot-starter< /artifactId>
< version> $nacos.version< /version>
< /dependency>

< !--公共的工具类-->
< dependency>
< groupId> cn.hutool< /groupId>
< artifactId> hutool-all< /artifactId>
< version> $hutool.version< /version>
< /dependency>

< dependency>
< groupId> com.google.guava< /groupId>
< artifactId> guava< /artifactId>
< version> $guava.version< /version>
< /dependency>

< dependency>
< groupId> org.projectlombok< /groupId>
< artifactId> lombok

    推荐阅读