由于在学习该项目的过程中发现了原讲义存在的一些问题,所以该笔记基于「学成在线」微服务项目 PDF 讲义进行编写,并且投入了时间去优化了笔记的格式、代码的高亮、重点的标记等。
以及一些原讲义中所描述的一些知识点使我无法理解的内容,我会对这些内容的表达方式进行修改或者提出一些问题,并且用我自己所理解的一些想法去重新的解释这个问题。
总结一下原 PDF 讲义中已知的一些问题:
PDF 中复制出来的代码,部分特殊符号的编码有问题,并且不易被发现,例如横杠 -,从PDF直接复制出来的话是无法运行的。PDF 编辑器复制出来的代码格式可能会变乱,且PDF中没有代码高亮,代码可阅读性差,并且复制出来时会有代码缩进错乱等问题。如有不足的地方,欢迎补充、填坑。
后端代码:https://gitee.com/codeyee/xuecheng-project-services
前端代码:https://gitee.com/codeyee/xuecheng-project-ui
完整的数据库文件以及 nginx 配置已上传至后端代码工程内一、学成在线是一个什么样的项目?
受互联网+概念的催化,当今中国在线教育市场的发展可谓是百花齐放、如火如荼。 按照市场领域细分为:学前教 育、K12教育、高等 育、留学教育、职业教育、语言教育、兴趣教育以及综合平台,其中,职业教育和语言教育 的市场优势突出。

学成在线借鉴了MOOC(大型开放式网络课程,即MOOC(massive open online courses))的设计思想,是一
个提供IT职业课程在线学习的平台,它为即将和已经加入IT领域的技术人才提供在线学习服务,用户通过在线学
习、在线练习、在线考试等学习内容,最终掌握所学的IT技能,并能在工作中熟练应用。
当前市场的在线教育模式多种多样,包括:B2C、C2C、B2B2C 等业务模式,学成在线采用 B2B2C 业务模式,即向企业或个人提供在线教育平台和学生完成教学活动,市场上类似的平台有:网易云课堂、腾讯课堂等,学成在线的特点是IT职业课程在线教学。
学成在线是一个在线教育平台,提供IT职业课程在线学习,平台包括:门户、学习中心、教学管理中心、系统管理 中心、社交系统等子系统。
项目的功能架构如下图:

门户是整个平台的入口,功能包括:
学习中心为用户提供在线学习服务,包括:
教学管理中心为教育机构或个人讲师提供教学管理功能,包括:
系统管理中心提供系统参数配置
项目采用前后端分离的技术架构,前端采用vue.js构建,服务端采用 Spring Cloud Netflix 微服务架构,系统分为用户层、CDN、负载均衡、前端UI、微服务层、数据层、接口层 及 DevOps 等部分组成,下图是完整的技术架构图:

业务流程举例:
1、用户可以通过pc、手机等客户端访问系统进行在线学习。
2、 系统应用 CDN 技术,对一些 图片、CSS样式文件、视频 等资源从 CDN 调度访问。
3、所有的请求全部经过负载均衡器。
4、对于PC、H5等客户端请求,首先请求UI层,渲染用户界面。
5、客户端UI请求服务层获取进行具体的业务操作。
6、服务层将数据持久化到数据库
下图是技术架构简图:

1、用户层,用户层描述了本系统所支持的客户端用户有哪些,本项目目前为各用户提供服务,包括H5、PC、Android和IOS等。
2、CDN 全称 Content Delivery Network,即内容分发网络,本系统所有静态资源全部通过 CDN 加速来提高访问速度。系统静态资源包括:html页面、js文件、css文件、image图片、pdf和ppt及doc教学文档、video视频等
3、负载均衡 系统的CDN层、UI层、服务层及数据层均设置了负载均衡服务,系统采用LVS+Nginx实现负载均衡均 衡。
4、UI 层 UI层描述了系统向pc用户、app用户、h5用户提供的产品界面。本项目在 PC 和 H5 端采用vue.js+elementUI 实现。
5、微服务层将系统服务分类三类:前端服务、后端服务及系统服务。 前端服务:主要为学习用户提供学习服务。 后端服务:主要为管理用户提供教学管理服务。 系统服务:公共服务,为系统的所有微服务提供公共服务功能
6、外部系统接口 包括如下接口:
OSS 存储7、DevOps 提供了本系统开发、运营、维护支撑的系统,包括如下内容:
Java 包依赖、项目工程打包服务。git 代码管理服务。所有微服务基于 Spring Boot、Spring Cloud Netflix构建
Spring MVC、Spring Security Oauth2 、Swagger
Spring
任务处理:Spring Task
数据缓存:Spring Data Redis
消息队列:Spring Rabbit Template
搜索: Elasticsearch
MyBatis、Druid 连接池、Spring Data JPA
操作MongoDB:Spring Data Mongodb
MySQL 和 MongoDb 存储数据,MySQL 存储用户、课程等系统核心信息,MongoDB 存储 cms、配置信息。等认证模块使用 redis 储存用户的令牌信息
项目架构设立接口层,接口层使用 swagger 注解描述接口的内容,接口定义规范如下:
请求
GET 请求时,前端请求 key/value 串,SpringMVC采用基本数据类型(String、Integer等)或自定义类型接收。POST 请求时,前端请 Form 表单数据(application/x-www-form-urlencoded)和 Json 数据(ContentType=application/json)、多部件类型数据(multipart/form-data),对于Json数据SpringMVC使用
@RequestBody 注解解析请求的 json 数据。响应
json。
两台 Eureka Server 互相注册,组成高可用。
微服务向 Eureka Server 注册自己,并在远程调用时从微服务发现目标服务地址。

微服务远程调用采用客户端负载均衡技术,使用 Feign Client。

网关的作用是负载均衡、路由转发、请求过虑等。
项目中网关与 Nginx 配合使用。

该项目是基于 Spring 进行构建的
1、所有的微服务开发采用 Spring Boot 开发
3、数据层使用Spring Data JPA、Spring Data MongoDB、Spring Data redis。
4、业务层使用Spring来控制本地事务,还使用了 Spring Task 任务调度框架、Spring AMQP 组件等。
5、控制层使用 SpringMVC、Sprnig Security Oauth2。
6、微服务管理使用Spring Cloud的Eureka注册中心,微服务之间调用使用 Ribbon 和 Feign Client 完成。
7、使用 Zuul网关完成微服务安全验证
此问题通常是在回答了项目的技术架构后被问及,根据具体的使用Spring Cloud完成微服务开发的步骤来回答即可。
1、每个微服务使用 Spring Boot 开发,每个微服务工程包括了web、service、dao三层,这和开发一般的项目没有区别:
Spring Data JPA 和 Mybatis,访问 mongodb使用 Spring data mongodb。
2、微服务开发完成要向 Eureka 注册中心注册,以便被其它微服务查找和访问。
3、微服务与微服务之间使用 feign 来调用,feign Client具有负载均衡的作用。只需要在接口上声明@FeignClient 注,Spring 底层会产生动态代理对象,使用 ribbon 客户端完成调用。
4、前端访问微服务需要通过网关,网关使用Nginx 和 Zuul 来实现,Nginx 是最前边的负载均衡,通过 Nginx 之后便到达了 Zuul,项目中 Zuul 的功能是过虑用户请求,判断用户身份,对于一些对外公开的微服务则需要经过 Zuul,直接通过 Nginx 负载均衡即可访问
此问题是考察对数据访问接口的使用程度。
项目中使用 Spring Data JPA 和 MyBatis 都是用来访问 MySQL,但是它们的分工不同:
Spring Data JPA 是 Spring 提供的一套JPA接口,使用 Spring Data JPA 主要完成一些简单的增、删、改、查功能。
对于复杂的查询功能会使用 MyBatis 编写SQL语言来实现,因为使用 Spring Data JPA 来做一些复杂的查询是没有 MyBatis 方便的,Spring Data JPA 是面向的对象,而 MyBatis 直接面向 SQL 语句,并且复杂的 sql 操作使用原生的 sql 实现的话也便于后续的优化。
容错保护是指微服务在执行过程中出现错误并从错误中恢复的能力。微服务容错性不好很容易导致雪崩效应,什么 是雪崩效应

微服务的雪崩效应表现在服务与服务之间调用,当其中一个服务无法提供服务可能导致其它服务也死掉,比如:单 点登录服务调用用户信息服务查询用户信息,由于用户信息服务无法提供服务导致单点登录服务一直等待,从而导 致用户登录、用户退出功能无法使用,像这样由一个服务所引起的一连串的多个服务无法提供服务即是微服务的雪 崩效应。

Spring Cloud Hystrix 是基于 Netflix 的开源框架 Hystrix 的整合,它实现了断路保护、线程隔离、信号隔离等容错功能。
什么是断路保护?
断路保护就类似家庭电路中的保险丝,当电路过载时保险丝会自动切断,保护整个电路的安全。微服务的断路保护 的工作原理是当请求微服务失败的数量达到一定比例时会切换为开路状态,当请求微服务时就直接返回结果不再请 求微服务,当保持开路状态一段时间后判断微服务是否可以正常请求,如果正常则切换到半开路状态,最后切换到 哪闭路状态。

具体的操作方法可以采用 Fallback,会每个FeignClient方法调用Fallback,当出现开路则调用Fallback方法返回错 误结果。
什么是线程隔离?
调用微服务使用不同的线程池,线程池之间互不影响,即使某个服务不可用也不影响其它服务的调用,比如:对商 品服务的调用使用一个线程池,对用户服务的调用使用另一个线程池,即使用户服务不可用也不影响商品服务的调 用。
此问题问的较模糊,没有问是客户端的视图还是服务端的视图,所以此问题不光是视图技术还是考察我们对前后端分离的理解。
1、视图层在前端和服务端都存在。
2、前端视图采用 vue.js + elementUI 产品界面。
3、服务端都是暴露的 rest 接口,统一用 json 展示数据。
本问题考察前后端分离开发中接口定义技能。
1、接口定义
使用 SpringMVC 编写Controller 方法,对外暴露 Http 接口,在 Controller 方法上使用RequestMapping、PostMapping、GetMapping 等注解定义 Http 接口。
2、采用什么数据格式?
GET 请求时:前端请求 key/value 串,SpringMVC 采用基本数据类型(String、Integer等)或自定义类型接收。
POST 请求时:前端请 Form 表单数据(application/x-www-form-urlencoded)和Json数据(ContentType=application/json)、多部件类型数据(multipart/form-data),对于 Json 数据SpringMVC使用 @RequestBody 注解解析请求的json数据。
json 格式,json 格式数据 SpringMVC 采用 FastJson 解析为对象。
非 json 格式数据 SpringMVC 提供参数绑定的方法,将 key/value 或 Form-Data 数据转换为对象或基本数据类型的变量。
前后端分离开发模式在互联网公司最常见,特别是一些大型的互联网公司,但是一些传统的软件开发企业仍然是采用传统开发模式,此问题被问及是考察你有没有真正体会前端开发的好处。
1、前端与后端开发人员讨论确定接口。
接口讨论通过,形成接口文档 。
本项目专门设立一个 api 工程,在此工程定义接口,Spring Boot 集成 Swagger,生成 Swagger 接口,前后端开发人员通过 html 查看接口文档的内容。
2、前端与后端开发人员按照接口文档进行开发。
开发过程中各自进行单元测试。
前端人员怎么进行单元测试?
前端人员可以通过一些工具生成一些模拟数据,比如:EasyMock。
3、双方功能开发完成进行前后端联调。
阅读:https://github.com/phodal/fe/blob/master/chapters/chapter-13.md
前端工程大多为单页面应用(SPA),采用 vue.js 框架开发,搜索功能前端采用 nuxt.js 服务端渲染(SSR)框架开发。
技术栈包括:
名称 | 说明 |
|---|---|
node.js | Node.js是一个事件驱动I/O服务端 JavaScript 环境,基于Google的 V8 引擎,V8引擎执行 Javascript 的速度非常快,性能非常好。 |
vue.js | 一套构建用户界面的渐进式框架。Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 |
npm/cnpm | NPM是随同 NodeJS 一起安装的包管理工具,能解决NodeJS代码部署上的很多问题 |
webpack | Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。 |
axios | Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。 |
nuxt.js | Nuxt.js 是一个通过 Vue 用于服务端渲染的简单框架,灵感来自 Next.js |
element-ui | 一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 |
CMS(Content Management System)即内容管理系统,本项目对 CMS 系统的定位是对各各网站(子站点)页面的管理,本项目的CMS系统不去管理每个子网站的全部资源,比如:图片、CSS、html 页面等,主要管理由于运营需要而经常变动的页面,从而满足根据运营需要快速开发、上线的需求。
功能包括:
freemarker 引擎技术,所以需要定义模板。
是什么?为什么?怎么用?
GridFS 是 MongoDB 提供的用于持久化存储文件的模块,它可以作为分布式文件系统使用,CMS 子系统将页面文件、模板文件存储到 GridFS 中,由于本项目使用 MongoDB,选用 GridFS 可以快速集成开发。
它的工作原理是:
在 GridFS 存储文件是将文件分块存储,文件会按照 256KB 的大小分割成多个块进行存储,GridFS 使用两个集合(collection)存储文件,一个集合是 chunks, 用于存储文件的二进制数据;一个集合是 files,用于存储文件的元数据信息(文件名称、块大小、上传时间等信息)。
从 GridFS 中读取文件要对文件的各个块进行组装、合并。

使用方法是:
使用 Spring data mongodb 包下提供的 GridFsTemplate 访问 GirdFS。
gridFsTemplate.findone() 查询文件
gridFsTemplate.delete() 删除文件
gridFsTemplate.store()存储文件
1、平台包括多个站点,页面归属不同的站点,需求是发布一个页面应将该页面发布到所属站点的服务器上。
2、每个站点服务部署 CMS Client 程序,并与交换机绑定,绑定时指定站点 Id 为 routingKey。指定站点id 为routingKey 就可以实现 cms client 只能接收到所属站点的页面发布消息。
3、页面发布程序向 MQ 发布消息时指定页面所属站点 Id 为 routingKey,根据 routingKey 将消息发给指定的 CMS Client。
每次发布会在数据库记录发布日志,每个 CMS Client 完成页面发布会上报发布结果。
1、在站点管理中配置了每个站点的服务器信息
2、在每次发布页面时会记录发布日志(服务器ID、页面ID、页面名称、发布结果)
3、CMS Client 完成页面发布后会向数据库记录发布结果。
4、用户通过查询发布日志表的信息就可以知道每一次的发布结果(哪些服务器页面发布成功,哪些发布失败)

1、课程信息比较复杂,为了方便教学机构按步骤管理课程信息,并且也可以划分权限管理课程信息,将课程信息 管理功能分为多个表,如下
2、将课程信息分开也是为了系统扩展需要,如果将课程所有信息存储在一张表中将不利于系统扩展。
每个教学机构都可以在媒资系统管理自己的教学资源,包括:视频、教案等文件。
媒资管理的主要管理对象是课程录播视频,包括:媒资文件的查询、视频上传、视频删除、视频处理等。
前端使用 WebUploader 将文件分块,调用服务端分块上传接口来上传分块文件,分块上传完毕前端请求服务端进行合并,当上传过程中断再次进行上传时服务端判断分块是否已经上传,已经上传的分块不再重新上传。

如上图所示,Java 程序调用 ffmpeg 及流媒体程序员提供的视频处理类库(C程序)完成 avi、mp4 视频转成 m3u8 格式的视频。
Java 程序使用Jdk提供的 Process Builder 调用 ffmpeg 及 C 程序进行视频处理。
Process Builder 可以调用第三方程序,在 java 程序运行时启动第三方程序进程。
视频处理完成,Java 程序捕获第三方程序的输出日志,解析出视频处理完成标记,更新视频处理状态为已完成。
视频处理完成会在中心媒体服务器保存一份,另外通过 CDN 程序将视频发布到边缘媒体服务器,用户点播视频通
过 CDN 请求边缘媒体服务器中的视频,提高了视频播放速度。
具体使用的是第三方公司的 CDN 服务。
本项目中未实现CDN内容分发
项目中课程搜索采用 ElasticSearch 来完成。
实现方法是:
1、使用 Logstash(logstash是ES下的一款开源软件,它能够同时 从多个来源采集数据、转换数据)将MySQL中的课程信息读取到 ES 中创建索引,使用IK分词器进行分词。
2、使用 Java High Level REST Client 完成搜索。
3、生产环境使用 ES 部署为集群。

本项目采用 FastDFS 分布式系统作为图片服务器。
FastDFS 是用 c 语言编写的一款开源的分布式文件系统,适合小文件的存储。
FastDFS 包括 Tracker server 和 Storage server 。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度向 Storage server 完成文件上传和下载。
使用 FastDFS 官方提供的 Java API 实现。
图片服务使用 Nginx 作为代理服务器,对 Storage上部署的 Nginx 完成负载均衡请求。

FastDFS 相比其它的分布式文件系统它适用小文件存储,它不对文件进行分块存储,也不用对文件进行合并处理,所以性能比 GFS、HDFS 等通用文件系统的性能要高。
时序图如下

执行流程如下:
1、管理员进入教学管理前端,点击上传图片
2、图片上传至文件系统服务,文件系统请求 fastDFS 上传文件
3、文件系统将文件信息入库,将文件信息存储到文件系统服务数据库中。
4、文件系统服务向前端返回文件上传结果,如果成功则包括文件的 Url 路径。
5、课程管理前端请求课程管理,进行保存课程图片信息到课程数据库。
6、课程管理服务将课程图片信息保存在课程数据库。
FastDFS 支付断点续传,在 Api 中有 append_file1 方法就是用来实现断点续传的,本项目没有使用 FastDFS 的断点续传功能。
本项目采用 HLS 技术实现视频点播。
1、使用 FFmpeg 对视频进行编码处理,生成 m3u8 文件及 ts 文件。
2、使用 Nginx 作为媒体服务器。
3、客户端使用 video.js 播放视频。
本项目采用 Spring security + Oauth2 完成用户认证及用户授权。认证授权流程如下:
1、用户请求认证服务完成身份认证。
2、认证服务下发用户 JTI (身份令牌)和 JWT 令牌,拥有身份令牌表示身份合法,Jwt 令牌用于完成授权。
3、用户携带 jwt 令牌请求资源服务。
4、网关校验用户身份令牌的合法,不合法表示用户没有登录,如果合法则放行继续访问。
5、资源服务获取 jwt 令牌,根据 jwt 令牌完成授权,并放行用户访问指定的资源。

此问题考察对事务的理解和应用程度。
1、在微服务中使用 Spring 声明式事务控制方式进行控制,在 Service 方法上添加 @Transctional 注解即可实现事务控制,它控制的是 MySQL 的本地事务。
2、项目中大量存在分布式事务控制,比如下单支付、课程发布等地址都用到了分布式事务。本项目实现分布式事务控制实现最终数据一致性,做法是:
a、将分布式事务拆分为多个本地事务。
b、提交事务前每个参与者要通过数据校验,和资源预留。
c、由消息队列去通知多个事务参与者完成本地事务的提交。
d、提交失败的本地事务会重试。

1、接口的开发需要前端和服务端共同调试,要仔细阅读测试人员反映的 bug 信息,判断这个 bug 是服务端的bug 还是前端的 bug。通常服务接口开发完成会使用 postman 工具进行测试,测试没有问题再提交到 Git或SVN 。
2、找到 bug 的出错点就可以根据 bug 信息进行修改。
3、修改完成需要前后端再次连调测试,按照测试人员提交的测试流程重新进行测试,测试通过将此 bug 置为已解决。
1、系统中收费的课程需要用户在线支付,支付接口采用微信的扫码支付。
2、拿到需求后,确定使用微信支付,首先去阅读微信的接口文档,这里重点阅读统一下单、支付结果通知、支付 结果查询三个接口。
3、下载官方提供的 sdk 编写单元测试用例测试每个接口。测试时没有使用微信的沙箱测试,直接使用正式接口,我们将金额改的小一些进行测试。
4、单元测试通过后开发整个支付功能,最终集成测试通过。
接口参数的签名问题,当时是因为自己没有仔细看接口文档导致少写一个必填参数一直报签名失败,随后将所有必填参数填写完成,最终解决问题。
本项目中还未实现在线支付功能,这里仅是提供一些实现的思路,需要后续自己完善
系统对异常的处理使用统一的异常处理流程。
1、自定义异常类型。
2、自定义错误代码及错误信息。
3、对于可预知的异常由程序员在代码中主动抛出自定义异常类型的异常,抛出异常时需要指定错误代码。
4、对于不可预知的异常(运行时异常)由 SpringMVC 统一捕获 Exception 类型的异常,由统一的异常捕获类来解析处理,并转换为与自定义异常类型一致的信息格式(错误代码+错误信息)。
5、可预知的异常及不可预知的运行时异常最终会采用统一的信息格式(错误代码+错误信息)来表示,最终也会随请求响应给客户端。

项目使用 RabbitMQ 消息队列。
RabbitMQ 提供很多的工作模式,如下:
项目主要使用了 Routing 模式。
Routing 模式即路由模式,使用方法是:
1、每个消费者监听自己的队列,并且设置 routingkey。
2、生产者将消息发给交换机,由交换机根据 routingkey 来转发消息到指定的队列。
有哪些应用场景?
1、任务异步处理。
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
2、应用程序解耦合
MQ 相当于一个中介,生产方通过 MQ 与消费方交互,它将应用程序进行解耦合。
此问题考察开发人员的问题描述及问题解决能力,可列举开发中实际的技术问题。
回答此问题要从两个方面来回答:
1、问题的描述
2、问题的解决方案
例子:
在处理订单时要用到定时任务,当时采用的是 Spring Task 来完成,由于一个订单服务会部署多个,多个订单服务同时去处理任务会造成任务被重复处理的情况,如何解决任务的重复处理。
解决:
采用乐观锁解决,在任务表中设置一个 version 字段记录版本号,取出任务记录同时拿到任务的版本号,执行前对任务进行锁定,具体的做法是执行 update 根据当前版本号将版本号加 1,update 成功表示锁定任务成功,即可开始执行任务。
ElasticSearch 和 Logstash 使用windows 批处理启动(开发环境)其他服务均使用 windows 服务启动,启动效果如下

ES启动脚本
@echo off
setlocal enabledelayedexpansion
setlocal enableextensions
SET params='%*'
:loop
FOR /F "usebackq tokens=1* delims= " %%A IN (!params!) DO (
SET current=%%A
SET params='%%B'
SET silent=N
IF "!current!" == "-s" (
SET silent=Y
)
IF "!current!" == "--silent" (
SET silent=Y
)
IF "!silent!" == "Y" (
SET nopauseonerror=Y
) ELSE (
IF "x!newparams!" NEQ "x" (
SET newparams=!newparams! !current!
) ELSE (
SET newparams=!current!
)
)
IF "x!params!" NEQ "x" (
GOTO loop
)
)
CALL "%~dp0elasticsearch-env.bat" || exit /b 1
IF ERRORLEVEL 1 (
IF NOT DEFINED nopauseonerror (
PAUSE
)
EXIT /B %ERRORLEVEL%
)
set ES_JVM_OPTIONS=%ES_PATH_CONF%\jvm.options
@setlocal
for /F "usebackq delims=" %%a in (`CALL %JAVA% -cp "!ES_CLASSPATH!" "org.elasticsearch.tools.launchers.JvmOptionsParser" "!ES_JVM_OPTIONS!" ^|^| echo jvm_options_parser_failed`) do set JVM_OPTIONS=%%a
@endlocal & set "MAYBE_JVM_OPTIONS_PARSER_FAILED=%JVM_OPTIONS%" & set ES_JAVA_OPTS=%JVM_OPTIONS:${ES_TMPDIR}=!ES_TMPDIR!% %ES_JAVA_OPTS%
if "%MAYBE_JVM_OPTIONS_PARSER_FAILED%" == "jvm_options_parser_failed" (
exit /b 1
)
cd /d "%ES_HOME%"
%JAVA% %ES_JAVA_OPTS% -Delasticsearch -Des.path.home="%ES_HOME%" -Des.path.conf="%ES_PATH_CONF%" -Des.distribution.flavor="%ES_DISTRIBUTION_FLAVOR%" -Des.distribution.type="%ES_DISTRIBUTION_TYPE%" -cp "%ES_CLASSPATH%" "org.elasticsearch.bootstrap.Elasticsearch" !newparams!
endlocal
endlocal
exit /b %ERRORLEVEL%Logstash 启动脚本
@title logstash i n teachplan_media_pub
logstash.bat -f ../config/mysql_course_media.conf --path.data=../data/teachplan_media/Application | 服务描述 |
|---|---|
XC-GOVERN-CENTER | Eureka服务注册中心,本项目中启动两个实例作为一主一从 |
XC-GOVERN-GATEWAY | Zuul网关 |
XC-SERVICE-BASE-FILESYSTEM | 文件系统服务,本项目中主要提供图片服务上传下载功能 |
XC-SERVICE-LEARNING | 学习中心服务,提供中心相关的API接口 |
XC-SERVICE-MANAGE-CMS | 站点CMS,提供网站页面静态化、制作、发布等相关API接口 |
XC-SERVICE-MANAGE-CMS-CLIENT | 站点CMS客户端,通过MQ接收页面发布的通知, |
XC-SERVICE-MANAGE-COURSE | 课程管理服务,提供课程管理相关的API |
XC-SERVICE-MANAGE-MEDIA | 课程媒资管理服务,提供课程媒体文件相关的API |
XC-SERVICE-MANAGE-MEDIA-PROCESSOR | 媒资处理服务,通过MQ接收视频处理通知,再调用第三方API来对媒资文件进行转码、分块等。 |
XC-SERVICE-MANAGE-ORDER | 订单管理服务,提供订单处理相关的API |
XC-SERVICE-SEARCH | 搜索服务,提供搜索相关的API |
XC-SERVICE-UCENTER | 用户中心服务,提供用户相关的API |
XC-SERVICE-UCENTER-AUTH | 统一认证中心服务,提供认证、授权相关操作的API |
在IDEA中启动服务,启动效果如下

所有服务成功的注册到
所有服务成功的注册到 eureka 中

启动效果如下

访问cms前端 http://cms.xuecheng.com/#/cms/page/list
cms.xuecheng.com在hosts文件中指向本地,并且配置nginx虚拟主机

找到一个以往的页面,点击预览,效果如下

新增页面,填写页面数据,填写数据模型url,用于结合模板渲染页面

添加成功

预览效果如下

编辑页面信息测试

删除测试

删除成功

window.open() 来访问预览页面,无法向 header 传递认证信息
解决方案:在 cms 服务和 course 服务的 ResourceServerConfig 分别放心 /cms/preview/*,/cms/config/getmodel/* 和 /course/preview/model/* 的鉴权
访问学成主站 http://www.xuecheng.com/
点击右上角登录,进入到登录页面

登录成功,主站右上角显示用户信息

登录成功后,用户的认证令牌信息储存到 redis 中

点击右上方的 “教学提供方” 进入到课程管理前端,点击我的课程,页面初始化前会访问 /course/list 接口获取该用户所属的所有课程信息,并且渲染到页面当中,效果如下

点击管理课程,测试更新课程信息

测试更换课程图片,删除原有图片并且上传

营销信息修改

添加课程计划测试

预览课程
点击课程预览,生成预览链接

访问预览链接,效果如下
从效果图中可以看到,成功将我们的课程数据与课程模板相结合进行静态化渲染,得到最终的课程详情页面效果

课程发布
点击课程发布按钮

点击查看课程详情页面,会自动跳转到该课程的正式发布页面,跳转到的链接如下
http://www.xuecheng.com/course/detail/4028e58161bcf7f40161bcf8b77c0000.html
页面效果如下

课程重新发布后,课程发布信息的时间戳会被更新,logstash也会重新采集我们发布的课程数据并且添加到 ElasticSearch 的索引库当中

更新的 ES 索引库数据如下

上传视频文件测试,效果如下图

访问我的媒资,可以看到我们刚才上传的视频文件的相关信息,如下图

访问搜索门户页面 http://www.xuecheng.com/course/search 为了显示分页的效果,我们设置为每页显示两个结果

输入 cloud 关键字进行搜索,并且实现关键字高亮,效果如下

课程图片随意上传的,别较真哈哈
点击搜索结果进入该课程的课程详情页面

在课程的课程计划管理中,为某个课程计划关联我们刚才上传的视频,操作示例如下

关联成功后,重新发布该课程信息

课程信息重新发布后,会更新该课程的时间戳,logstash 检索到时间戳的变化后会自动将更新后的课程信息到 ElasticSearch 的索引库中,如下图所示

自动更新课程计划信息

来到该课程的课程详情页面,点击 马上学习

进入到在线学习页面,点击目录中的课程计划,将会自动切换到课程计划节点对应的媒资内容

播放测试,推动进度条

已分散到每个章节的最后总结中,待整理汇总至此
欢迎各位小伙伴进行补充
平均每天投入3小时左右进行知识点的学习,练习,笔记总结等,坚持下来大概需要花费2个月左右可以将该项目完整的学习下来,该项目还留下了一些需求需要自己去补充完善。