餐掌柜之——1、项目概述及环境搭建、Dubbo入门
个人笔记
什么是SaaS平台?它的特点是什么?
SaaS:软件即服务,通过网络提供软件服务,供应商将软件统一部署在服务器上,客户可以根据自己的需求向供应商购买
SaaS典型代表:用友,他主要通过子域名提供OA服务(办公自动化)
特点:
- 互联网特性:通过SaaS提供在线服务, 这都是基于网络的,客户就不用投入成本在硬件、维护等等之上。
- 多重租赁特性:通过一套标准软件系统给成百上千客户提供不同服务,用户可以根据自己需求购买软件服务。这要求SaaS服务能够支持不同租户之间数据和配置的隔离(软件共享,数据隔离)
- 服务特性:SaaS使软件以互联网为载体的服务形式给客户使用
- 可扩展性:可以最大限度地提高系统的并发性,用户也可以定制服务
餐掌柜各个平台的作用是什么?
客人点餐平台: 负责实体店线下开桌、点餐、追加菜品等
商家业务管理平台:管理点餐平台,提供员工、店铺、桌台、菜品、订单、结算等功能
运营商平台:运营商管理基础数据模块, 管理商家、统一权限、日志、图片、数字字典等
餐掌柜的通用服务、核心业务、系统架构作用是社么?分别用到了什么技术?
通用服务的作用:
- 通用的模块抽离出来以后,开发其他项目以及新增的业务时可以直接复用,可以提高项目开发的效率
- 随着业务的增加,系统模块之间会越来越复杂,把通用模块抽离出来,可以减少各个模块之间的耦合度,使项目更好维护
核心业务的作用:
- 客人点餐平台: 负责实体店线下开桌、点餐、追加菜品等
- 商家业务管理平台:管理点餐平台,提供员工、店铺、桌台、菜品、订单、结算等功能
- 运营商平台:运营商管理基础数据模块, 管理商家、统一权限、日志、图片、数字字典等
系统架构:
- 代理 与 数据展现:根据域名的不同,通过Nginx集群反向代理到相应服务的Gateway网关,实现统一的业务数据访问
- 权限控制:使用JWT + Spring Security实现权限控制
- 服务治理与配置中心:使用Nacos实现注册中心与配置中心
- 服务调用:使用Dubbo实现服务与服务之间的调用
- 流量控制:使用Sentinel完成对各个服务的 流量控制、降级熔断、负载保护等
- 缓冲层:使用Spring Cache + Redis实现无侵入的业务数据缓冲,提高系统性能
- 基础业务支撑:基于Spring Boot脚手架,集成OSS图片存储、Sharding-JDBC分库分表、Mybatis-Plus、Swagger2接口文档、Seata分布式事务、Mysql数据库、RabbitMQ消息队列,当然也少不了Docker容器化的使用
项目模块 及 核心项目模块 职责是什么?
餐掌柜中采用了Maven的分层架构,来维护整体的项目结构,各个模块相互独立,这样可以更好的实现功能及组件的复用,从而减少开发成本。
核心项目模块的作用:主要对各种中间件进行集成,例如:MQ消息队列、Seata分布式事务、Redis缓存等
项目数据库结构设计、分库设计是怎么样的?
餐掌柜的数据库遵循领域模型设计(DDD),把数据库根据功能模块垂直划分为5个库,分别对应各个服务(一个服务对应一个数据库):
- 基础模块库
- 权限模块库
- 商家模块库
- 交易模块库
- 报表模块库
优点:
- 解决业务层面的耦合,让业务看起来更清晰,在对不同业务的数据进行维护时不会影响到其他业务
- 一个库分成了多个库,这样对并发高的业务数据库进行集群时能够不浪费资源
- 它是搭建微服务的基石,让每个微服务都是独立的。
什么是微服务?微服务的特点是什么?
微服务是一种基础的架构设计风格,把一个大项目分成很多个小的微服务可以减少各个模块之间的耦合,使其更好开发与维护。再然后,“微” 字顾名思义,每个微服务只做单一的一件事,一个小团队就能完成,这样可以更加好的协同工作,并且每个微服务都能独立运行,这样可以根据需求更好的做集群以应对高并发场景,而不会浪费资源。
微服务的特点:
- 单一职责:每个服务只做一件事。
- 微:微服务的服务拆分的粒度很小,麻雀虽小但五脏俱全。
- 面向服务:通过REST风格的接口调用服务,而不管它的实现。
- 自治:服务间互相独立,互不干扰,当然开发服务的团队也是,可以更好的协同工作。
Dubbo服务执行流程是怎么样的?
- 服务者把自己注册到注册中心
- 消费者向注册中心订阅某个服务
- 注册中心通过异步的方式把服务对应的ip和端口同步到消费者
- 消费者把服务列表缓存本地,并且通过同步的方式访问服务者
Dubbo的调用方式是什么?基于什么协议实现的?
调用方式:RPC远程过程调用
协议:Dubbo协议
与Spring Cloud的Feign的区别:Feign基于Http协议,而Dubbo基于自己的RPC协议
Dubbo与Feign对比的优缺点:
- 优点:性能更好
- 缺点:只支持Java语言,不过后续支持的语言会越来越多;Feign因为基于Http协议,所以只要能使用Http协议那么都能使用它
老师讲义
项目概述及环境搭建
学习目标:
- 能够说出什么是saas平台及其特点
- 能够说出餐掌柜核心架构、项目模块功能、数据库结构
- 了解微服务平台中工作协调相关事宜
- 掌握基础组件安装及项目启动
- 掌握餐掌柜项目的开发规范
- 掌握Dubbo基础使用
第一章 餐掌柜项目概述
1、SaaS平台
SaaS平台:供应商将应用软件统一部署在自己的服务器上,客户可以根据工作实际需求,通过互联网向厂商定购所需的应用软件服务,按定购的服务多少和时间长短向厂商支付费用,并通过互联网获得Saas平台供应商提供的服务
互联网特性
SaaS软件行业知名产品NetSuite所提供的在线ERP、在线CRM等模块产品都是基于网络的,这样的优势在于不必投入任何硬件费用,也不用请专业的系统维护人员就能上网,有浏览器就可以进行ERP、CRM系统的使用。快速的实施、便捷的使用、低廉的价格都有赖于SaaS产品的互联网特性。
多重租赁(Multi-tenancy)特性
SaaS服务通常基于一套标准软件系统为成百上千的不同客户(又称为租户)提供服务。这要求SaaS服务能够支持不同租户之间数据和配置的隔离,从而保证每个租户数据的安全与隐私,以及用户对诸如界面、业务逻辑、数据结构等的个性化需求。由于SaaS同时支持多个租户,每个租户又有很多用户,这对支撑软件的基础设施平台的性能、稳定性和扩展性提出很大挑战。SaaS作为一种基于互联网的软件交付模式,优化软件大规模应用后的性能和运营成本是架构师的核心任务。
服务(Service)特性
SaaS使软件以互联网为载体的服务形式被客户使用,所以很多服务合约的签订、服务使用的计量、在线服务质量的保证和服务费用的收取等问题都必须加以考虑。而这些问题通常是传统软件没有考虑到的。
可扩展(Scalable)特性
可扩展性意味着最大限度地提高系统的并发性,更有效地使用系统资源。比如应用:优化资源锁的持久性,使用无状态的进程,使用资源池来共享线和数据库连接等关键资源,缓存参考数据,为大型数据库分区。
2、业务概述
餐饮SaaS管理系统就是【运营商】将餐饮管理系统部署到云端,商家只需要进行付费申请使用,而无需对技术、硬件、运维等各个方面再次投入,平台一般具有下列模块:
- 运营平台:运营商管理基础数据模块【统一权限、日志、图片、数字字典】以及商家管理的平台
- 商家平台:点餐后台核心业务,提供员工、店铺、桌台、菜品、订单、结算等功能
- 点餐平台:H5点餐平台,客户实现开桌、点餐、追加菜品等功能
相对传统餐饮行业来说:连锁店数据还不能共享,老板管理店铺不方便,而SaaS餐饮管理软件,具有餐饮O2O应用场景所有功能,如自助点餐、线上外卖、自动收银等,既节约了顾客的用餐时间又节省了成本,还方便了店铺之间的管理,更提高了店铺线上与线下的数据实时更新。
3、核心架构
3.1、通用服务
对于一个公司架构设计来说,必须思考的问题是,这个功能在现在或者将来能满足多少业务场景?如果将来有新的业务出现,是不是能够复用?或者说,需要做多大的调整才可以复用?甚至于,这个功能有没有可能对外输出,提供SaaS化的服务建立通用服务业务为了业务的敏捷,创新!有下面三个特征:
- 敏捷 业务需求变化快,变更以天甚至更短的频率计算,一个单体大型应用,庞大的开发团队对单一应用的变更变得越来越困难。将大应用变为多个小的应用组合,才能适应外部的快速变化,实现业务的敏捷。
- 解耦 随着业务的发展,业务系统之间的交互通常会变得越来越复杂。一个功能的修改可能会影响很多方面。只有将需要大量交互的功能独立,从应用中拆解出来,这样可以使得应用之间耦合度大幅下降。
- 复用 一些公共的能力通过复用,大大提高了开发效率,避免了重复建设。同时使得数据和流程可以集中得以管理和优化。
餐掌柜项目中提供的通用服务:
3.2、核心业务
请求接入:
H5:客户点餐接入
运营商:运营管理接入
商家:商家主业务接入
阿里云:OSS、ECS、部署平台接入
网关:
Nginx:反向代理,路由承压力
Gateway:第二代网关服务,路由分发、权限鉴定
核心业务:
点餐平台:负责客户点餐业务,为Android、IOS、H5提供统一服务接口
商家平台:负责基础数据配置,同时提供店员及交易结算服务
运营平台:负责商家管理及运营报表系统
通用业务:
通用非业务系统的中台系统:权限、支付、图片、数字自动、日志中心、报表等
3.3、系统架构
餐掌柜项目是基于spring-cloud-alibaba的架构体系,关于spring-cloud-alibaba,其核心组件如下:
Sentinel
阿里巴巴开源产品,把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性.
Nacos
阿里巴巴开源产品,一个更易于构建云原生应用的动态服务发现,配置管理和服务管理平台.
RocketMQ
Apache RocketMQ基于Java的高性能,高吞吐量的分布式消息和流计算平台.
Dubbo
Apache Dubbo是一款高性能的Java RPC框架.
Seata
阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案.
Alibaba Cloud OSS
阿里云对象存储服务器(Object Storage Service,简称OSS),是阿里云提供的海量,安全,低成本,高可靠的云存储服务.
Alibaba Cloud Schedulerx
阿里中间件团队开发的一款分布式调度产品,支持周期性的任务与固定时间点触发任务.
展现层:负载与用户的交互,分为Android、IOS、web应用,他们都是通过访问统一的gateway网关来实现业务数据的访问
代理层:选用高性能的nginx服务,通过域名与不同servrce的绑定,通过gateway路由到不同的服务器组
权限控制层:使用无状态的JWT认证,结合Spring Security实现统一的权限控制
服务治理:使用nacos注册中心,配置中心实现服务的治理
服务调用:使用Spring Cloud alibaba 的核心组件dubbo进行服务之间的调用
流量控制:使用 Sentinel把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性
缓冲层:spring cache 配合redis轻松无侵入的实现业务数据的缓冲
基础业务支撑:基于spring boot脚手架,轻松集成OSS图片存储、sharding-jdbc分库分表、mybatis-plus、docker、接口文档swagger2、分布式事务seata、MySQL、RocketMQ/RabbitMQ等组件
4、项目模块
在餐掌柜项目中采用maven的分层构架,来维护整体的项目架构,各个模块相对独立,达到功能及组件的复用,从而减少开发成本的投入,避免反复造轮子的现象,整体的分层构建如下图所示:
主项目结构说明:
1 | |——restkeeper-super 负责整个项目的模块定义,依赖和插件管理 |
5、数据库结构
5.1、数据库概述
遵循领域模型设计【DDD】,我们按照功能模块领域垂直把数据库分为5个库,具体库的职能以及内部所含有的表详细情况如下图所示:
带来的提升:
解决业务层面的耦合,业务清晰
能对不同业务的数据进行分级管理、维护、监控、扩展等
高并发场景下,垂直分库一定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈
关于==【垂直分库、水平分库、垂直分表、水平分表】==在后续的项目中我们会使用sharding-jdbc来实现
微服务处理业务搭建一个基石
5.2、表数据冗余
根据数据库设计的第三范式:在数据库设计过程中,应该尽量消除冗余。即设计数据库时,某一个字段属于一张表,但它同时出现在另一个或多个表,且完全等同于它在其本来所属表的意义表示,那么这个字段就是一个冗余字段。
问题:随着企业数据量与并发量不断的增加,冗余字段的存在到底是好还是坏呢?
创建一个关系型数据库设计,我们有两种选择:
尽量遵循范式理论的规约,尽可能少的冗余字段,让数据库设计看起来精致、优雅、让人心醉。
合理的加入冗余字段这个润滑剂,减少join,让数据库执行性能更高更快。
所有问题出现必然因为场景问题,针对冗余字段问题,分为两个场景:
快照场景(副本场景):交易场景大部分是数据快照,而不是冗余,用户下单时候的用户名、地址、商品名称、商品描述等,若采用关联,商品在下单后发生了更新的话再去关联查询就会导致和用户操作时的数据不一致,从而产生纠纷,例如我们在项目中的设计:
冗余场景:一般数据改动的可能性少,而查询多的场景会使用冗余,例如淘宝的店铺名称,淘宝商家中心会有这个字段,可能里面的商家论坛也有,再假设聚划算这种独立的大业务自己也存一份,再来个垂直频道电器城的后台管理也独立存一份,这种场景是由于对查询性能要求高产生的,所以必须要冗余,在业务的取舍上,肯定是对让用户更快看到信息,那么不可避免的是带来维护成本的增加,对于数据一致性问题,只要做到最终一致就可以了,分布式的CAP原则的实际应用基本都是通过牺牲数据一致性(C)来保证高可用(A)和高可靠(P), 因为这种场景大部分都是可以接受短暂的数据不一致的,对业务的影响及其微小。
在餐掌柜的项目我们遵循的原则:
- 项目全部采用逻辑关联,没有采用主外键约束
- 尽可能少使用多表关联查询。冗余是为了效率,减少join
- 尽可能服务独立化,查询单表化,例如:查询用户信息又需要用户的头像,处理的原则是调用【用户服务】和【附件服务】在dubbo层组装数据
5.3、数据库导入
我们使用docker-compose第一次安装mysql的时候,会自动执行初始化脚本,具体会在【第二章-基础组件安装】中演示
6、工作协调
6.1、团队组织及分工
微服务,顾名思义,微服务得从两个方面去理解,什么是”微”、什么是”服务”, 微狭义来讲就是体积小、著名的”2 pizza 团队”很好的诠释了这一解释【2 pizza 团队最早是亚马逊 CEO Bezos提出来的,意思是说单个服务的设计,所有参与人从设计、开发、测试、运维所有人加起来 只需要2个披萨就够了】,而做为微服务,具备有下列四个要素:
- 小:微服务体积小,2 pizza 团队。
- 独:能够独立的部署和运行。
- 轻:使用轻量级的通信机制和架构。
- 松:为服务之间是松耦合的。
微服务的特点:
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
- 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
- 面向服务:面向服务是说每个服务都要对外暴露Rest风格服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
- 自治:自治是说服务间互相独立,互不干扰
- 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
- 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
- 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不同接口
- 数据库分离:每个服务都使用自己的数据源
- 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
6.2、gitee/gitlab代码管理
为了方便开发小组的成员们进行代码共享,我们使用给Git来管理小组内的代码,Git是目前世界上最先进的分布式文件版本控制系统(没有之一)。对于我们java程序员而言,管理的就是代码文件版本,其主体架构图下:
这里我们使用gitee平台来管理代码,同学们可用访问【https://gitee.com】进行代码管理
6.2.1、创建组织
登录自己的gitee账号后,在左侧选择【组织】点击【+】号
6.2.2、创建仓库
选择【仓库】—>【所有的】然后点击【+】号
点击【创建】,完成创建
6.2.3、升级账号
主页面选择【企业版】
点击【开始免费使用】
点击【马上升级】
点击【组织升级企业】—>选择刚刚建立的组织点击【升级】
填写验证码,点击【升级】
完成升级,在【我参与的仓库】中含有刚刚升级的项目
6.2.4、项目上传
在【资料\基础代码\restkeeper-super】中有为各位提供的基础代码,这里我们需要把项目代码上传到gitee上:
拷贝【资料\基础代码\restkeeper-super】到你自己的硬盘上,这里我拷贝到【F:\restkeeper\restkeeper-super】盘下
使用IDEA打开【F:\restkeeper\restkeeper-super】项目
下面,我们需要先创建本地仓库
初始化完成后,进行第一次本地提交,提交时间比较长,请耐心等待
关联远程仓库
点击复制,填写入上一步中的URL
先拉取远程仓库代码
==如果出现以下异常==
点击右下角【Git:master】,做合并代码操作
合并完成
提交代码
提交完成
查看远程gitee,可用看见刚刚上传的代码
第二章 项目快速启动
1、基础组件安装
首先想启动餐掌柜SaaS平台,则需要安装下列三方组件:
- 缓存服务:redis组件
- 注册配置中心:nacos平台
- 数据库:Mysql
- 消息中间件:RabbitMQ/RocketMQ
- 分布式事务:seata-server
- 分布式调度中心:xxl-job-admin
- 反向服务器:nginx
这里我们采用docker-compose来进行安装,需要特别注意的:
宿主机地址请设置为:192.168.200.129, 【宿主机地址设置见课程资料】
1.1、docker安装
卸载老版本docker
1
2
3
4
5
6
7
8
9
10
11yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce设置仓库
1
yum install -y yum-utils device-mapper-persistent-data lvm2
更新本地镜像库
1
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新镜像源缓存
1
2
3sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast安装docker
1
yum install -y docker-ce
关闭防火墙
1
2systemctl stop firewalld
systemctl disable firewalld启动docker
1
systemctl start docker
开机自启动docker
1
systemctl enable docker
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了:
之前还有 Docker 官方加速器 https://registry.docker-cn.com ,现在好像已经不能使用了,我们可以多添加几个国内的镜像,如果有不能使用的,会切换到可以使用个的镜像来拉取。
修改配置:
1 | mkdir -p /etc/docker |
1.2、docker-compose安装
安装docker-compose
注意: 安装时去官网下载最新版本
1
curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
修改docker-compose权限
1
2chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
执行docker-compose version 查看安装情况
docker-compose –help 仓库其命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43[root@localhost docker-demo]# docker-compose --help
利用Docker来定义和构建一个多容器的应用
使用方式:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE 指定一个 compose 文件,
(默认: docker-compose.yml)
-p, --project-name NAME 指定project名字
(默认: 目录名称)
--verbose 显示更多日志
--log-level LEVEL 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
-v, --version 打印版本并退出
-H, --host HOST Daemon socket to connect to
Commands:
build 构建多个service
config 校验 Compose 文件,格式是否正确,若正确则显示配置,
若格式错误显示错误原因
down 停止并删除 容器, 网络, 镜像, 和 数据卷
exec 进入一个指定的容器
help Get help on a command
images 列出该Compose中包含的各个镜像
kill 通过发送 SIGKILL 信号来强制停止服务容器
格式为 docker-compose kill [options] [SERVICE...]
logs 查看服务容器的输出日志
格式为 docker-compose logs [options] [SERVICE...]。
pause 暂停一个容器
port 打印某个容器端口所映射的公共端口
ps 列出项目中目前的所有容器
pull 拉取服务依赖的镜像
push 推送服务依赖的镜像到 Docker 镜像仓库
restart 重启项目中的服务
rm 删除停止的容器(要先停止容器)
run 在某个服务上运行指令
scale 设定某个容器的运行个数
start 启动多个 services
stop 停止多个 services
top 查看各个服务容器内运行的进程。
unpause 恢复处于暂停状态中的服务。
up 创建并启动多个service的容器
version Show the Docker-Compose version information
1.3、初始化组件
上面我们完成docker和docker-compose的安装,下面我们来安装基础组件,首先把【资料\环境搭建\docker】的文件上传到你centos中的/opt目录:
并且为rocketmq文件目录授权:chmod -R 777 rocketmq/
在opt
目录下运行下列命令,整个创建过程需要一定的时间【5分钟左右】,启动完成执行命令:
1 | docker-compose up -d |
查看启动情况:
1 | docker-compose ps -a |
1.3.1、MySQL服务
校验mysql数据库
同步mysql时间
1 | docker cp /usr/share/zoneinfo/Asia/Shanghai mysql:/etc/localtime |
==账号:root 密码:pass==
1.3.2、Nacos注册中心服务
地址:http://192.168.200.129:8848/nacos
账号:nacos 密码:nacos
1.3.3、消息服务RocketMQ
地址:http://192.168.200.129:8180/#/cluster
1.3.4、xxl-job定时任务平台
地址:http://192.168.200.129:8280/xxl-job-admin/
账号:admin 密码:123456
1.3.5、分布式事务Seata服务
seata-server我们使用的是nacos,只需要在服务列表中看见seata-server
1.3.6、Redis服务
使用RedisDesktopManager连接192.168.200.129端口6379
至此我们的基本组件安装完成
2、运营平台启动
2.1、调用链路
上图为运营平台的调用链路,从中我们可用看到:
- 用户发起请求访问restkeeper-vue-operator,在vue中有网关设置
- vue中网关会调用restkeeper-gateway-operator网关,然后由restkeeper-gateway-operator网关路由对应业务系统web项目
- model-basic-job-listen模块主要负责日志的收集【后面分析】
- 运营平台中有2个核心web模块:model-security-web【统一权限】、model-basic-web【基础服务】的服务消费方模块
- 运营平台中有2个核心producer模块:model-security-producer【统一权限】、model-basic-producer【基础服务】的服务提供方模块
我们需要启动上述的6个模块才可把运营平台启动
2.2、服务启动
2.2.1、后端服务启动
找到需要启动的模块下com.itheima.restkeeper包下以***Start
结尾的启动类,直接启动即可,例如:
启动后端服务,包含下列6个模块,按下列顺序启动:
- restkeeper-gateway-operator
- model-basic-job-listen
- model-security-producer
- model-basic-producer
- model-security-web
- model-basic-web
为防止内存不够使用可以启动时设置JVM参数:
1 -Xms128M -Xmx128M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M
启动完成访问:http://192.168.200.129:8848/nacos,注意:model-basic-job-listen模块不需要注册到nacos中
2.2.2、运营平台前端项目启动
2.2.2.1、依赖前端环境
前端依赖的环境分别为:nodeJS、cnpm、webpack
安装node.js:https://nodejs.org/zh-cn/,这里我下载的版本为v12.21版本,课程资料中有对应的安装包
安装直接全部点击下一步最后完成安装
安装结束后打开cmd命令窗口 输入以下命令验证是否安装成功,如出现版本号则安装成功
1 | 查看node版本 |
安装cnpm:在cmd命令窗口使用如下命令安装npm的国内镜像cnpm
1 | npm install -g cnpm --registry=http://registry.npm.taobao.org |
安装webpack:
1 | cnpm webpack -g |
下载项目依赖js包:
第一次运行项目之前我们需要执行下列命令,安装项目
1 | npm install |
在cmd窗口中切换到restkeeper-vue-operator项目所在模块:
==【非必须执行】==如果安装中有失败,这边可用在host
中做如下配置,这里是让github更快加载
1 | 140.82.114.4 github.com |
2.2.2.2、 启动项目
Vscode打开项目,使用下列命令启动项目:
1 | npm run dev |
注意:这里默认打开的访问路径为:http://localhost/#/login,但是我们的系统是基于saas系统,这里需要绑定域名,但是我们没有域名,所以这里需要设置hosts,再次找到hosts
添加如下配置:
1 | 127.0.0.1 www.eehp.cn |
账号:hm@itcast.cn 密码:pass
第三章 项目开发规范
在项目开发过程中,如果开发人员过多又没有一个开发统一规范,在后期的维护、迭代升级的过程中会相当痛苦,也不利于新人接手项目,项目规范是为了统一一个开发标准,让代码易懂便于维护升级,下面我们为整个系统指定规范。
1、基础父类定义
1.1、BasicPojo
各个模块中POJO对象继承的基础父类
隶属模块:framework-mybatis-plus
包路径:com.itheima.restkeeper.basic
作用:所有实体类公共字段的定义
其中结构如下:
1 | package com.itheima.restkeeper.basic; |
1.2、BasicVo
各个模块中VO对象继承的基础父类
隶属模块:framework-vo
包路径:com.itheima.restkeeper.basic
作用:所有VO对象公共字段的定义
其中结构如下:
1 | package com.itheima.restkeeper.basic; |
1.3、IBasicEnum
各个模块中枚举对象实现的基础父接口
隶属模块:framework-vo
包路径:com.itheima.restkeeper.basic
作用:枚举对象实现的基础方法定义
其中结构如下:
1 | package com.itheima.restkeeper.basic; |
2、统一返回数据
2.1、ResponseWrap
所有对前端接口的返回对象
隶属模块:framework-vo
包路径:com.itheima.restkeeper.basic
作用:定义返回对象的包装
其中结构如下:
1 | package com.itheima.restkeeper.basic; |
2.2、ResponseWrapBuild
构造ResponseWrap工具
隶属模块:framework-commons
包路径:com.itheima.restkeeper.utils
作用:构造ResponseWrap工具,并且从UserVoContext上下文中获取当前登录对象作为操作人信息填入
其中结构如下:
1 | package com.itheima.restkeeper.utils; |
3、vo与pojo
VO :value object 值对象 / view object 表现层对象,
主要职能作用:
- 对应页面显示的数据对象
- 页面请求参数封装
- dubbo层调用多个服务,服务返回结果封装
例如:
- 用户信息 —>【用户服务】返回VO +【附件服务】返回图片Vo
POJO :plain ordinary java object 无规则简单java对象,在餐掌柜中严格遵循POJO的实体类结构使用【驼峰规则】映射数据库字段
3.1、作用范围
以restkeeper-model-security模块为例,一个标准的模块其模块结构如下
1 | |——restkeeper-model-security 统一权限模块 |
VO和POJO的负责区域入下图所示:
其中model-security-producer是VO与POJO对象转换层
3.2、对象转换工具
VO对象与POJO对象属成员变量拷贝工具
隶属模块:framework-mybatis-plus
包路径:com.itheima.restkeeper.basic
作用:VO对象与POJO对象属成员变量拷贝工具
注意:VO对象与POJO对象属成员变量【类型】和【成员变量名称】必须保持一致,支持父类属性拷贝
1 | package com.itheima.restkeeper.utils; |
单个对象拷贝:
List对象拷贝:
4、异常处理
4.1、统一异常处理
在项目开发过程中,异常是需要统一,如图所示,service—>producer—>interface—>web逐层向上抛出:
首先,自定义异常类ProjectException
隶属模块:framework-web
包路径:com.itheima.restkeeper.exception
作用:统一异常处理自定义异常类
1 | package com.itheima.restkeeper.exception; |
再定义BaseController类采用SpringMVC的统一异常处理,使用@ControllerAdvice、@ExceptionHandler注解,优雅的处理异常
隶属模块:framework-web
包路径:com.itheima.restkeeper.web
作用:统一异常处理
1 | package com.itheima.restkeeper.web; |
4.2、异常枚举
为了规范异常处理后返回的信息,我们为每一个模块定义了异常处理枚举:
隶属模块:framework-vo
包路径:com.itheima.restkeeper.enums
作用:各模块的异常枚举
需要注意,每个enum都需要实现IBasicEnum接口,以UserEnum为例:
1 | package com.itheima.restkeeper.enums; |
第四章 springcloud-alibaba-dubbo
1、架构演进概述
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
2、Dubbo架构
下面我们看下dubbo架构
名词解释
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向添加中心添加自己提供的服务。
- 服务服务消费方在启动时,向添加中心订阅自己所需的服务。
- 添加中心返回服务提供者地址列表给服务消费方,如果有变更,添加中心将基于长连接推送变更数据给服务消费方。
- 服务服务消费方,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务服务消费方和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
3、dubbo快速入门
上面我们介绍了dubbo的架构,下面我们来使用dubbo来进行开发,在开发之前,我们先看下面的图解:
从上图我们可用看出在一个标准的dubbo服务调用中,他分为3个部分
dubbo-interface:
负责接口的定义,这里我们通常定义***Face
结构的接口类,例如:UserFace
dubbo-producer:
【服务提供方】负责接口的实现,这里我们通常用==@DubboService==定义***FaceImpl
结构的接口类,例如:UserFaceImpl
dubbo-web:
【服务消费方】负责调用接口,通常我们在web层使用==@DubboReference==调用接口
下面我们来构建第一个dubbo服务,我们需要在dubbo-parent中pom.xml引入下列依赖:
1 | <dependencies> |
在dubbo-producer和dubbo-web中pom.xml导入:
1 | <dependencies> |
3.1、定义接口
1 | package com.itheima.dubbo; |
3.2、服务提供方实现
服务提供方:dubbo-producer负责服务的提供,我们需要把他添加到nacos添加中心中
(1)application.yml添加:
1 | #服务配置 |
(2)实现dubbo-interface的Userface接口:
1 | package com.itheima.dubbo.service; |
3.3、服务消费方实现
服务消费方:dubbo-web负责服务的接口消费,我们需要把他添加到nacos添加中心中
(1)application.yml配置文件:
1 | #服务配置 |
(2)调用dubbo-interface的Userface接口:
1 | package com.itheima.dubbo.web; |
3.4、测试
访问Nacos地址:http://192.168.200.129:8848/nacos/
可以点击 详情 查看服务注册的详细内容:
启动dubbo-producer和dubbo-web模块,访问:http://127.0.0.1:8081/user/itheima
4、业务模块开发流程初识
4.1、业务调用链路
在开始业务开发之前,我们首先看一下系统的调用链路,以 restkeeper-model-shop
模块为例,其调用的时序图如下所示:
以restkeeper-model-shop模块为例,一个标准的模块其模块结构如下
1 | |——restkeeper-model-shop 商家服务平台 |
4.2、服务提供方分析
在restkeeper-model-shop模块中有3个【提供者】模块:
- model-shop-applet
- model-shop-producer
- model-shop-user
这里以model-shop-producer为例,首先查看模块依赖关系:
其中 model-shop-producer 模块他有以下职能:
1 | - dubbo微服务【提供方】 |
==注意:餐掌柜中为避免模块职能混乱,禁止服务提供方模块调用服务提供方模块,当产生跨服务接口调用,例如一个接口需要多个接口来支持,我们会放到web层进行服务调用然后业务组装,如果牵涉分布式事务问题,我们会采用seata方式来解决==
下面我们对model-shop-producer进行dubbo的集成,首先在model-shop-producer的pom.xml导入下列依赖:
1 | <!-- Dubbo Spring Cloud Starter --> |
再在model-shop-producer的application.yml添加定义如下:
1 | dubbo: |
4.3、服务消费方分析
在restkeeper-model-shop模块中有1个【服务消费方】模块:model-shop-web,这里以model-shop-web为例,首先查看模块依赖关系:
其中model-shop-web模块他有以下职能:
1 | - 传入参数的接收及校验工作 |
下面我们对model-shop-web进行dubbo的集成,首先在model-shop-producer的pom.xml导入下列依赖:
1 | <!-- Dubbo Spring Cloud Starter --> |
再在model-shop-web的application.yml添加定义如下:
1 | dubbo: |
相比【服务提供方】来说【服务消费方】就多subscribed-services属性配置,此属性为订阅服务的服务名
4.4、服务接口定义
可能在以往的开发中我们只是知道三层架构【mapper、service、web】,那这里的face层是什么意思呢?大家都知道dubbo服务的调用逻辑,【服务消费方】调用【提供方】,那他们直接能调用的集成也就是声明统一的接口定义,在餐掌柜系统中dubbo层接口就起到此作用:
1 | - 定义dubbo服务接口 |
首先我们需要定义一个dubbo接口,那我们在哪里写能?从餐掌柜maven分层构建中我们可用发现,每个以restkeeper-model-***
开头的项目都是一个二级模块,并且模块中都有一个model-***-interface
的模块,例如:
没有错,这里就是我们定义face接口的三级模块,在定义dubbo接口的时,都需要找到类似:model-***-interface
的模块去书写
4.5、service核心业务
上面我们再介绍【dubbo层接口实现】提到dubbo层接口实现会调用核心业务,这个核心也就是这里的service层,还是以restkeeper-model-shop为例:
如果模块以model-***-service的格式出现,则表示此模块为核心模块,职能:
1 | - pojo、mapper、service层定义 |
商家平台启动依赖: