# zhl-cloud **Repository Path**: l-cloud/zhl-cloud ## Basic Information - **Project Name**: zhl-cloud - **Description**: springcloud项目的快速脚手架demo项目 技术选型:springboot2.x+mybatisplus+spring-cloud-alibaba组件 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2020-08-04 - **Last Updated**: 2025-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zhl-cloud #### 介绍 ## 简介 基于`SpringCloud(Hoxton.RELEASE)` + `SpringBoot(2.2.2.RELEASE)` 的 快速开发平台,可以作为后端服务的开发脚手架。代码简洁,架构清晰,非常适合学习使用。核心技术采用SpringCloud(Nacos、Fegin、Ribbon、Gateway、Hystrix)、SpringBoot、Mybatis Plus、Seata、Sentinel、Redis、RabbitMQ、FastDFS等主要技术。 希望能努力打造一套从 `基础框架` - `微服务架构` - `持续集成` - `系统监测` 的解决方案。 ``` 本项目旨在通过约定表结构设计规范、代码编写规范、模块拆分规范,实现系统的代码生成功能、基础功能、常用功能、通用功能。 ``` #### 软件架构 所涉及的相关的技术有: JSON序列化:Jackson 消息队列:RabbitMQ/rocketmq/activemq 数据库: MySQL 5.7.9 或者 MySQL 8.0.19 定时器:quartz (准备使用xxl-jobs) 推送:websocket 持久层框架: Mybatis-plus 代码生成器:基于Mybatis-plus-generator自定义 API网关:Gateway 服务注册发现&配置中心:Nacos 服务消费:OpenFeign 负载均衡:Ribbon 服务熔断:Hystrix 项目构建:Maven 3.5 分布式事务: Seata 分布式系统的流量防卫兵: Sentinel 文件服务器:FastDFS 5.0.5/阿里云OSS/七牛/本地存储 Nginx 部署方面: 服务器:CentOS Jenkins Docker 18.09 Kubernetes 1.12 #### 软件架构 1. **服务注册&发现与调用:** 基于Nacos来实现的服务注册与发现,使用使用Feign来实现服务互调, 可以做到使用HTTP请求远程调用时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。 2. **服务鉴权:** 通过JWT的方式来加强服务之间调度的权限验证,保证内部服务的安全性。 3. **负载均衡:** 将服务保留的rest进行代理和网关控制,除了平常经常使用的node.js、nginx外,Spring Cloud系列的zuul和ribbon,可以帮我们进行正常的网关管控和负载均衡。其中扩展和借鉴国外项目的扩展基于JWT的Zuul限流插件,方面进行限流。 4. **熔断机制:** 因为采取了服务的分布,为了避免服务之间的调用“雪崩”,采用了Hystrix的作为熔断器,避免了服务之间的“雪崩”。 5. **监控:** 利用Spring Boot Admin 来监控各个独立Service的运行状态;利用turbine来实时查看接口的运行状态和调用频率;通过Zipkin来查看各个服务之间的调用链等。 6. **链路调用监控:** 利用Zipkin实现微服务的全链路性能监控, 从整体维度到局部维度展示各项指标,将跨应用的所有调用链性能信息集中展现,可方便度量整体和局部性能,并且方便找到故障产生的源头,生产上可极大缩短故障排除时间。有了它,我们能做到: \> 请求链路追踪,故障快速定位:可以通过调用链结合业务日志快速定位错误信息。 \> 可视化:各个阶段耗时,进行性能分析。 \>依赖优化:各个调用环节的可用性、梳理服务依赖关系以及优化。 \>数据分析,优化链路:可以得到用户的行为路径,汇总分析应用在很多业务场景。 7. **数据权限** 利用基于Mybatis的DataScopeInterceptor拦截器实现了简单的数据权限 8. **SaaS(多租户)的无感解决方案** 使用Mybatis拦截器实现对所有SQL的拦截,修改默认的Schema,从而实现多租户数据隔离的目的。 并且支持可插拔。 9. **二级缓存** 采用J2Cache操作缓存,第一级缓存使用内存(Caffeine),第二级缓存使用 Redis。 由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。 该缓存框架主要用于集群环境中。单机也可使用,用于避免应用重启导致的缓存冷启动后对后端业务的冲击。 10. **优雅的Bean转换** 采用Dozer组件来对 DTO、DO、PO等对象的优化转换 11. **前后端统一表单验证** 严谨的表单验证通常需要 前端+后端同时验证, 但传统的项目,均只能前后端各做一次检验, 后期规则变更,又得前后端同时修改。 故在`hibernate-validator`的基础上封装了`zuihou-validator-starter`起步依赖,提供一个通用接口,可以获取需要校验表单的规则,然后前端使用后端返回的规则, 以后若规则改变,只需要后端修改即可。 12. **防跨站脚本攻击(XSS)** - 通过过滤器对所有请求中的 表单参数 进行过滤 - 通过Json反序列化器实现对所有 application/json 类型的参数 进行过滤 13. **当前登录用户信息注入器** - 通过注解实现用户身份注入 14. **在线API** 由于原生swagger-ui某些功能支持不够友好,故采用了国内开源的`swagger-bootstrap-ui`,并制作了stater,方便springboot用户使用。 15. **代码生成器** 基于Mybatis-plus-generator自定义了一套代码生成器, 通过配置数据库字段的注释,自动生成枚举类、数据字典注解、SaveDTO、UpdateDTO、表单验证规则注解、Swagger注解等。 16. **定时任务调度器**: 基于xxl-jobs进行了功能增强。(如:指定时间发送任务、执行器和调度器合并项目、多数据源) 17. **大文件/断点/分片续传** 前端采用webupload.js、后端采用NIO实现了大文件断点分片续传,启动Eureka、Zuul、File服务后,直接打开docs/chunkUploadDemo/demo.html即可进行测试。 经测试,本地限制堆栈最大内存128M启动File服务,5分钟内能成功上传4.6G+的大文件,正式服耗时则会受到用户带宽和服务器带宽的影响,时间比较长。 18. **分布式事务** 集成了阿里的分布式事务中间件:seata,以 **高效** 并且对业务 **0侵入** 的方式,解决 微服务 场景下面临的分布式事务问题。 19. **跨表、跨库、跨服务的关联数据自动注入器** 用于解决跨表、跨库、跨服务分页数据的属性或单个对象的属性 回显关联数据之痛, 支持对静态数据属性(数据字典)、动态主键数据进行自动注入。 20. **灰度发布** 为了解决频繁的服务更新上线,版本回退,快速迭代,公司内部协同开发,本项目采用修改ribbon的负载均衡策略来实现来灰度发布。 #### 项目架构图 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1018/181332_12b418c3_1791572.png "系统架构图.png") #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### docker安装rocketmq教程  **{RmHome}** 要替换成你的宿主机想保存 MQ 的日志与数据的地方, 通过 docker 的 -v 参数使用 volume 功能,把你本地的目录映射到容器内的目录上。 否则所有数据都默认保存在容器运行时的内存中,重启之后就又回到最初的起点。 1、安装 Namesrv 拉取镜像:docker pull rocketmqinc/rocketmq:4.4.0 启动容器:docker run -d -p 9876:9876 -v {RmHome}/data/namesrv/logs:/root/logs -v {RmHome}/data/namesrv/store:/root/store --name rmqnamesrv -e "MAX_POSSIBLE_HEAP=100000000" rocketmqinc/rocketmq sh mqnamesrv 2、安装 broker 服务器 与上步是同一个镜像,如果上步完成,此步无需拉取 创建 broker.conf 文件 在 broker.conf 中写入如下内容 brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 brokerRole = ASYNC_MASTER flushDiskType = ASYNC_FLUSH brokerIP1 = {本地外网 IP} brokerIP1 要修改成你自己宿主机的 IP 启动容器:docker run -d -p 10911:10911 -p 10909:10909 -v {RmHome}/data/broker/logs:/root/logs -v {RmHome}/rocketmq/data/broker/store:/root/store -v {RmHome}/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -e "MAX_POSSIBLE_HEAP=200000000" rocketmqinc/rocketmq sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf 3、安装 rocketmq 控制台 拉取镜像:docker pull pangliang/rocketmq-console-ng 启动容器:docker run -e "JAVA_OPTS=-Drocketmq.config.namesrvAddr=192.168.17.6:9876 -Drocketmq.config.isVIPChannel=false" -p 8080:8080 -t styletang/rocketmq-console-ng #### docker安装rabbitmq教程 1、安装 包含web管理页面rabbitmq 拉取镜像:docker pull rabbitmq:3.7.7-management 启动容器:docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin df80af9ca0c9 -d 后台运行容器; --name 指定容器名; -p 指定服务运行的端口(5672:应用访问端口;15672:控制台Web端口号); -v 映射目录或文件; --hostname  主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名); -e 指定环境变量;(RABBITMQ_DEFAULT_VHOST:默认虚拟机名;RABBITMQ_DEFAULT_USER:默认的用户名;RABBITMQ_DEFAULT_PASS:默认用户名的密码) #### 使用说明 1. xxxx 2. xxxx 3. xxxx #### Flyway使用说明 1、Flyway 可以用来管理数据库版本 如果是在一个全新的项目中使用 Flyway,那么在新建一个 Spring Boot 项目时,就有 Flyway 的选项 项目创建成功后,resources目录下也会多出来一个db/migration目录,这个目录用来存放数据库脚本, 如下: 这个如果创建项目时就选择了 Flyway 依赖,就会有这个目录。现在我要在已经做好的微人事中加入 Flyway,这个目录就需要我手动创建了 然后在 vhr-web 模块下的 resources 目录下,手动创建 db/migration 目录, 然后在该目录下创建数据库脚本,数据库脚本的命名方式如下 Flyway不限定脚本里面的内容,但是对脚本文件的名称有一定的要求 版本号可以使用小版本,如V1.1 具体要求: 1、版本号和版本描述之间,使用两个下划线分隔。 2、版本描述之间,使用一个下划线分隔单词。 3、版本号唯一:不允许多个脚本文件有相同的版本号。 命名规则:V__.sql 首先是大写字母 V,然后是版本号,要是有小版本可以用下划线隔开,例如 2_1,版本号后面是两个下划线, 然后是脚本名称,文件后缀是 .sql。 使用Flyway升级,flyway会自动创建一张历史记录表:flyway_schema_history 这张表记录了每一次升级的记录,包括已经执行了哪些脚本,脚本的文件名,内容校验和,执行的时间和结果: flyway在升级数据库的时候,会检查已经执行过的版本对应的脚本是否发生变化,包括脚本文件名,以及脚本内容。如果flyway检测到发生了变化,则抛出错误,并终止升级。 如果已经执行过的脚本没有发生变化,flyway会跳过这些脚本,依次执行后续版本的脚本,并在记录表中插入对应的升级记录。 所以,flyway总是幂等的,而且可以支持跨版本的升级 所有的脚本,一旦执行了,就会在 flyway_schema_history 表中有记录,如果你不小心搞错了,可以手动从 flyway_schema_history 表中删除记录, 然后修改 SQL 脚本后再重新启动(生产环境不建议) prefix:前缀,不同的类型采用不同的前缀, 版本迁移使用 V 最常见的迁移就是就是版本化迁移,每次迁移都会对应的迁移版本,迁移的版本必须全局唯一,版本迁移最大的特点就是依次只被执行依次 撤销迁移使用 U 每个撤销迁移都对应的一个版本迁移,也就是说撤销迁移是针对版本迁移所存在的,每一个撤销迁移与版本迁移都是一一对应的,而且对应的版本号必须一致 可重复迁移使用 R,当然这些都是可配置的 可重复迁移有描述和校验码,但是没有版本号,程序在每次启动的时候,如果发现脚本文件有变化就会执行 Suffix:后缀,一般都是 .sql #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)