项目介绍
市场规模
2021年7月,国务院颁布《关于进一步减轻义务教育阶段学生作业负担和校外培训负担的意见》,简称"双减"政策。在该政策影响下,多年来占据我国教育培训行业半壁江山的课外辅导培训遭到毁灭性打击。相对的,职业教育培训的市场规模持续增长。

线上职业教育
随着互联网发展,传统行业也逐渐网络化发展。再加上疫情的影响,很多职业技能培训企业都开始发展在线教育。相比于传统线下培训,在线教育有成本更低,学习时间碎片化,教育资源能充分利用。因此,在线教育市场规模不断增长,前景巨大。

功能演示
天机学堂是一个基于微服务架构的生产级在线教育项目



项目亮点

技术架构

环境搭建
企业发开模式
微服务项目与传统项目相比,包含项目模块非常多,每个模块都要独立部署,因此在开发模式上有很大差别:
- 开发人员成倍增多,分组分别开发不同的微服务模块
- 微服务模块之间有业务关联,需要相互协作

我们开发时,是否能把所有的项目代码都拉取到本地,然后在本地部署运行、开发测试?

- 大型微服务项目显然不能,原因如下:
- 我们可能没有其它模块的代码拉取权限
- 微服务运行环境过于复杂,本地部署成本较高微服务模块较多,本地计算机性能难以支撑
在开发的不同阶段,往往有不同的测试手段:

- 单元测试: 测试最小的可测试单元
- 集成测试: 验证某个功能接口
- 组件测试: 验证微服务组件
- 端对端联调: 验证整个系统
模拟企业环境
为了模拟企业中的开发环境,我们利用虚拟机搭建了一套开发环境,其中部署了开发常用的组件

- Git私服(gogs):代码全部提交带了自己的Git私服,模拟企业开发的代码管理,大家也需要自行到私服拉取代码
- jenkins:持续集成,目前已经添加了所有部署脚本和Git钩子,代码推送会自动编译,可以根据需求手动部署
- nacos:服务注册中心、统一配置管理,大多数共享的配置都已经交给nacos处理
- seata:分布式事务管理
- xxl-job:分布式任务系统
- es:索引库
- redis:缓存库
- mysql:数据库
- kibana:es控制台
参考虚拟机运行说明, 运行准备好的虚拟机
- 配置VMware网络
首先,在VMware中选择编辑,虚拟网络编辑器:

这里需要管理员权限,因此要点击更改设置:

接下来,就可以修改虚拟网卡的IP地址了,流程如图:


注意:一定要严格按照标号顺序修改,并且IP地址也要保持一致!
点击确定后,等待一段时间,VMware会重置你的虚拟网卡。完成后,可以在windows的网络控制面板看到:

选中该网卡,右键点击,在菜单中选择状态,并在弹出的状态窗口中选择详细信息:

在详细信息中,查看IPv4地址是否是 192.168.150.1:

如果与我一致,则证明配置成功!
- 导入虚拟机
打开VMware,选择文件 ,然后打开:

找到提供的虚拟机文件夹,进入文件夹后,选中*.vmx文件,然后点击打开:

导入成功:

启动虚拟机,选择【我已复制该虚拟机】:

虚拟机登入信息如下:
# 用户名
root
# 密码
123321
-
测试网络
ping baidu.com
为保持网络畅通请关闭代理
-
远程连接

- 查看容器
使用docker ps查看容器的详细信息

使用dps查看容器的简易信息, 该命令需自定义

访问服务
http://192.168.150.101:8848/nacos/
- 配置域名解析
为了模拟使用域名访问,我们需要在本地配置hosts:

当我们访问上述域名时,请求实际是发送到了虚拟机,而虚拟机中的Nginx会对这些域名做反向代理,这样我们就能请求到对应的组件了:

nginx的配置已经配置好了, 在/usr/local/src/nginx/conf中查看

验证访问http://nacos.tianji.com/ 和 http://mq.tianji.com/
持续集成环境
持续集成的好处: 降低开发和部署的边界成本

持续集成的流程:

我们在虚拟机中已经基于jenkins实现了持续集成,访问 http://jenkins.tianji.com (账号:root/123)即可查看控制台

基本使用
- 我们可以在Git仓库模拟代码push操作:
- 首先,访问http://git.tianji.com(tjxt/123321),找到tianji这个仓库,点击仓库设置按钮:

- 然后,点击《管理Web钩子》菜单,进入页面后点击钩子后面的修改按钮:

- 进入页面后,向下滚动,点击测试推送按钮:

- 然后回到jenkins页面,会发现已经触发了
tjxt-dev-build的自动编译:

- 编译完成后, 点击对应微服务后面的运行按钮, 才会部署 (实际上可以实现一键编译+部署, 出于教学方便, 这里独立部署就行了)

- 构建过程中,可以在页面左侧看到构建进度,如果没有说明构建已经结束了(你的机器速度太快了!):

- 完成后,点击对应的微服务名称【例如tj-gateway】,即可进入构建任务的详情页面,在页面左侧可以看到构建历史:

- 其中#1代表第一次构建,点击前面的√即可查看构建日志:

- 看到上面的日志,说明构建已经成功,容器也成功运行了。
- 验证一下服务, 通过查看容器和日志验证


验证已有服务
- 我们需要分别启动几个开发完成的微服务:
- tj-user
- tj-auth
- tj-gateway
- tj-course
- tj-media
- tj-search
- tj-exam
- tj-data
- 此时访问Nacos控制台,可以看到微服务都成功注册了:

- 此时访问 http://www.tianji.com (jack/123 rose/123456)即可看到用户端页面:

- 此时访问 http://manage.tianji.com 即可看到管理端页面:

- 如果想要知道微服务具备哪些API接口,可以访问网关中的swagger页面,路径如下:http://api.tianji.com/doc.html

本地开发部署
对于需要开发功能的微服务,则需要在本地部署,不过首先我们要把代码拉取下来。
- 查看Git私服的代码:http://git.tianji.com/tjxt/tianji (tjxt/123321)

- 将代码克隆到自己的IDEA工作空间中,master分支是完整项目代码,上课要从lesson-init分支开发:

- 以lesson-init分支为起点,创建一个dev分支,完成项目开发:

- 然后用IDEA打开项目即可

- 我们的微服务都支持多环境部署,因此配置文件有多个

- 部署到虚拟机中会使用dev环境配置,而在本地应该使用local环境配置。
我们可以利用IDEA来配置微服务启动时要激活的环境,例如:

可以在本地启动ExamApplication,然后我们去Nacos控制台查看exam-service,可以看到有两个实例,分别是虚拟机IP和宿主机IP:

启动ExamApplication服务报错:
"Error creating bean with name 'globalTransactionScanner' defined in class path resource"
该报错的根本原因是 Java 11+ 的模块化系统(Jigsaw) 导致 cglib 库无法访问 ClassLoader.defineClass 方法,从而引发 java.lang.reflect.InaccessibleObjectException。
解决方案:
<seata-version>1.5.1</seata-version>改成<seata-version>1.7.0</seata-version>
如果存在多个实例, 可能会造成服务调用混乱, 可以通过配置禁止服务注册, 避免本地运行的服务影响其他人
spring:
cloud:
nacos:
server-addr: 192.168.150.101:8848 # nacos注册中心
discovery:
namespace: f923fb34-cb0a-4c06-8fca-ad61ea61a3f0
group: DEFAULT_GROUP
ip: 192.168.150.1
register-enabled: false # 不做服务注册, 只做服务发现