赞
踩
大家好,今天给大家介绍基于Vue+SpringCloud+Mysql的博客系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴,可以进入我的博客主页查看左侧最下面栏目中的自助下载方法哦
文章目录:
项目难度:中等难度
适用场景:相关题目的毕业设计
配套论文字数:30851个字99页
包含内容:全套源码+配整论文
开题报告、论文答辩、课题报告等ppt模板推荐下载方式:
提示:以下为毕业论文的简略介绍,项目完整源码及完整毕业论文下载地址见文末。
绪论
1.1 研究的背景
近些年,微服务开始在软件系统设计中开始流行,它是一种与往系统架构设计不同的风格,它完整地拆分了单体应用的功能,并分配到指定的模块中,这种模块化方式已经成为企业主流的设计方式。
Vue这几年在前端大放异彩,因为Vue是一个国产的可组件化JavaScrtipt库,所以Vue的上手程度相比其它JavaScript框架更容易些。Vue 的组件库使用了最新的MVVM设计模式,因此Vue只关注前端视图的变化,把控制层分离来模块化前端的设计,完全符合主流的软件设计方式。
SpringCloud是微服务其中一个代言词,能与SpringCloud抗衡也只有Dubbo,但是如今的SpringCloud更新速度是相当地快,它已经在微服务开发中的占据了显著地位。SpringCloud是基于SpringBoot快速构建的一个工具集,并且它们俩都是Spring家族的子集,因此,它们也都是基于Java语言实现的,而Java是一种跨平台、适合于分布式计算机环境的面向对象编程语言。
如上所述Vue与SpringCloud都顺应了主流的趋势,所以这个组合在JavaWeb开发中变成了“香饽饽”,同样它们也推动了软件开发技术的进步。
1.2 研究的目的
在校大学生想要快速融入到企业当中都必须花一定的时间自学,或者不满足于个人所学,参加一些比赛或者自己动手写几个项目。大学生就业困难也是一个愈来愈显著的问题,在校学习的东西不够,不愿意花时间学习等。
因此设计本次博客的目的在于强化对Java和JavaScript的理解,增强个人的JavaWeb能力,提高对于系统架构的理解,写一个完整的Web对自己的提升是巨大的,除了提高个人技术外还会增强个人的毅力,对以后的工作都是有积极意义的。
2 博客的相关理论与技术
2.1 博客系统理论分析
本次设计使用的是JavaWeb开发中主流的微服务架构方式,微服务一定会涉及分布式,一般提到微服务大多在系统逻辑与物理结构设计上,而分布式则涉及到的都是一些机器或者实现技术,阅读本章可以理解整个博客用到的理论及其技术。
2.1.1 博客的微服务分析
目前来说,微服务(SpringCloud)是软件开发中的一个主流的热门技术,而SpringCloud只是微服务的一个重要子集。微服务的概念可以这样被定义:微服务之间通过HTTP等一些轻量通信进行交互数据,而每一个微服务都存在自己的进程中,独立承担着某些业务功能,最终所有微服务聚合共同架起整个系统。
设计一个微服务系统需要遵守以下原则:
1.微服务的单一原则:一般指的是一个类中只负责一个完整的功能,与其相关性不大的功能最好不要放进去,对以后的功能扩展不太友好。
2.微服务的隔离原则:指每一个微服务中心的功能代码块独立地运行在一个模块包中,多个微服务则有多个模块包,它们一起独立运行,并且不会发生互相干扰,从微服务的逻辑设计到开发设计都是独立在一个包中。
3.微服务的通信原则:当多个微服务发生数据交互时,它们之间应该使用轻量的通信服务来进行交互,轻量通信需要具备跨语言,跨平台的特点。
4.微服务的控制原则:每一个微服务都需要把控服务的代码量,在设计逻辑结构时要考虑周当,并不是一味地把代码量减少,使微服务变小容易控制。因为每个微服务的功能特性不同,所要要编写的代码量也不同。因此在逻辑结构设计时,就需要应该确定业务的边界,保持相对独立且松耦的关系。
5.微服务修复原则:微服务最好编写完整且稳定的高可用组件,除了微服务组件的高可用,还需要考虑“熔断”微服务的业务来保护系统。
2.1.2 博客的分布式分析
博客系统除了会涉及到微服务,还会涉及到分布式,分布式系统的定义大多从程序来看的,可以是相同的程序,例如“集群”方式。也可以不是相同的程序,通过远程调用来完成交互,分布式可以认为是一种对机器的有效管理方式。
关于分布式需要了解五个重要的特性:
1.内聚和透明性:分布式系统是利用计算机网络构建的协作系统,所以分布式系统通常都具备内聚性与透明性的特性。
2.独立扩展性:其一是垂直扩展即优化服务器的性能或者升级服务器硬件;其二,增加服务器水平扩展,即增加服务器的数量。
3.可靠性与可用性:可靠性是在指定的时间内,系统无错误和障碍的平均运行时间,可用性则是某个时间段内无错误和障碍的总运行时间。
4.高性能:对于高并发的平均处理时间越少越好,单位时间内处理的人物越多越好,利用更多的机器来实现更高的计算与存储能力。
5.一致性:多节点部署下,保证计算与存储的数据只有一份。
由于分布式与微服务涉及到的面会有一些相似,但是两者的核心本质是不一样的,在此需要详细说明一下微服务与分布式两者的具体区别:
微服务是架构设计方式,例如:博客的逻辑设计需要涉及到某些功能,功能要怎么划分,需要考虑到“高并发”的问题,最终系统该如何拆分,功能如何划分比较合理,再为以后的系统扩展打下基础,而分布式是系统部署方式,系统拆分后,把功能放到某个机器上,若是采用了微服务的架构方式,利用的是分布式部署。若不是微服务架构方式则可以采用“集群部署”或者分布式部署,“集群部署”相当于同一个业务,部署在多个服务器上。
不管微服务还是分布式都有两个共同的缺点,第一个就是网络的的问题,例如:网路延迟,丢包和信息丢失,所以需要编写补偿机制来保护用户的体验。第二个就是节点故障,微服务节点故障或者分布式系统的某个节点故障,节点故障不一定可以完全避免,但是可以人为的操作干预,相比第一个缺点产生的网络通信还是有可操作性,但是动手起来有不小的挑战难度,需要仔细打磨每一个细节。
2.1.3 关于分布式锁分析
关于分布式锁的详解可以自行查找了解,在此只介绍分布式锁的概念和博客采用的分布式锁。简而言之,对Java分布式锁来说,对于不同的机器产生的不同JVM虚拟机之间需要资源共享,这个时候就需要用到分布式锁来进行控制。
如果程序中使用了Synchronized关键字,Lock并发接口,并发工具类或并发集合,这些操作也可以完成多线程的“共享资源”,但这只是单体应用的服务实例,对于分布式系统来说,独立的JDK和主机Host,两者区别就是在于单体并发控制到分布式跨JVM之间的差别,分布式锁也是基于跨JVM来进行“共享资源”的控制。
对于分布式锁有五点要求:
1.排他性:一个资源只允许在一个时间段被一个JVM上的一个线程执行。
2.避免死锁:需要人为释放锁,可以设置锁的失效时间。
3.公平锁:不同机器争夺资源时的几率是一样的,但不是必要的。
4.高可用锁:获取与释放锁的机制需要保证性能符合设计。
5.可重入锁:设置锁的可重入次数或者时间,若是发生获取失败,则可以等待一个时间段或者设置一个时间段获取锁的次数。
博客使用了基于Redis实现的分布式锁(关于Redis的分析可看标题2-7,在此只提一下Redis的分布式锁的要点),Redis提供了原子操作SETNX与EXPIRE,SETNX表示当key在Redis中不存在时才能设置成功,key间接当作“锁”,并用EXPIRE来释放获取的锁,Redisson可以看作内置了这些特性,封装好给我们使用。
由上可知,重要的操作就是SETNX,关于SETNX的操作有三个要点:
1.使用SETNX操作获取锁,如果返回0则说明已经存在且被其它线程获取,出现了1则说明获取成功。
2.需要为锁设置合理的失效时间,若是发生了程序异常,锁不释放就会导致死锁,时间需要合理且符合程序的流程。
3.与多线程操作的理念相似,执行完锁后需要释放获取到的锁。
2.1.4 博客的高可用分析
高可用是微服务架构中一个重要的设计元素,一般指的是系统减少微服务不能提供的时间。博客的高可用的需要做到服务自治,当一个微服务出现无法响应,而另一个微服务就可以替代它,所以在设计博客高可用系统时,需要从许多方面去考虑,远不止一个高可用,最重要的就是自我修复避免系统的无法响应。
博客中一共涉及到Eureka,Zuul的高可用,后续标题中会提到,在此不做介绍,高可用的分布式系统需要遵守微服务的开发准则,也需要遵守以下微服务运行机制(括号中是博客使用到的技术,会在后续的标题中一一详细介绍,在此作为理解):
1.扩展机制:水平与垂直扩展,与分布式的扩展相似
2.隔离机制:避免博客的一个业务占用太多资源导致服务的无法响应,会对其他博客业务造成影响,添加容错机制即可。
3.解耦原则:尽可能地使用合成复用原则来代替继承关系。
4.限流机制(Zuul):限流可以在路由网关上面体现出来,根据不同的算法可以实现不同的负载均衡。
5.降级机制:在核心业务运行时,牺牲一部分非核心的业务保证核心业务功能
稳定运行,当系统不可用时,需要给予用户一些提示。
6.熔断机制(Hystrix):在调用微服务请求时,添加回退保护即可。
7.跟踪机制(Zipkin):博客API会产生数据指标,产生的数据需要用来观测,然后再做数据分析,对系统做个深度分析以便以后的功能扩充。
8.维护机制:博客的系统维护比较需要方便,压力与微服务的数量成正比。
9.补偿机制:如果发生网络问题导致博客业务数据不一致性的问题,需要补偿机制弥补用户。例如:RabbitMQ异步消息,补偿表和定时任务检测。
10.监控机制(Hystrix+Turbine):更多的是通过Hystrix监控各个微服务的运行指标,通过HTTP转递给开发者观看。
11.演练机制:算是一种未雨绸缪,在测试博客功能时,适当关闭个微服务中心,把博客的异常或者补偿都要测试一下,防止在真实情况下出现业务炸裂情况,尽可能的在某个机器或某个微服务挂掉时,尽量不影响博客系统整体的高可用性。
2.2 前端的搭建
2.2.1 Node-Npm简介
Node.js是服务端的Javascript解释器,是一种服务端语言,可以被看作是一个基于JavaScript运行环境的平台。
Npm则是属于node.js里面的一个网络下载包的管理工具,博客前端需要用到的一些UI组件均存在npm中。前端Npm与后端“maven”相似,都可以下载需要用到的组件包。
对于Vue的安装可以采用原始的Npm安装也可以采用IDE直接创建Vue的脚手架,因为时间飞速的发展,前端也发展迅速,当项目过大时前端也必须分工协作所以模块化与组件化也是非常重要的部分,因此前端的自动化部署也应运而生。
前端的工程化与webpack离不开,在npm中即可下载webpack,webpack的模块化的运行原理如图2-1所示:
图2-1 webpack模块化示意图
Webpack是将所有的文件都最后统一生成静态资源文件,每一相同类地资源文件相当于都是一个moudle。Webpack模块化了前端,增强了前端的协作性。
2.2.2 采用的UI框架
UI(界面设计)框架是博客的美观的体现,可以由开发者自行根据HTML,CSS,JavaScript开发美观组件,也可以节省时间使用他人封装好的UI框架,UI框架需要做到拿来即用,使用者可以做一些代码实际性的修改来结合业务的实现。
关于本次博客的开发一共采用了三种UI库:
1.Bootstrap:Bootstarp是过去几年中web开发中受欢迎的前端组件库,不过现在的Bootstarp组件库却不是很常用, 由于Bootstarp在布局上面占据显著的优势,所以Bootstarp非常适合博客的开发,
2.Element-UI: Element-UI是一个利用原生JavaScript编写的UI组件库,当前是与vue配合开发的一个比较好的UI框架。
3.View-UI:View- UI是一套基于 Vue 的 UI 组件库,博客的开发采用了Vue框架,所以使用这个UI框架上手十分简单,对每一个开发者学习时会非常的友好,除此之外View-UI的组件漂亮又整洁,非常适合博客的开发。
这三个UI库在设计中都有体现,Bootstarp的组件趋于整洁,View-UI与element-UI的常用组件趋于漂亮实用化,并且View-UI本次博客采用的组件与Element-UI相差不大,但是npm上View-UI的下载量趋于快速上升的趋势,并且view-UI 的api 更加简洁,View-UI现在保持一种热门的趋势。
View UI具备以下友好的特性:
Ⅰ. 丰富的组件和功能,满足绝大部分网站场景,也可以自己自定义组件开发
Ⅱ. 提供开箱即用的 Admin 系统 和 高阶组件库,需要付费才可以使用
Ⅲ. Vue.js生态环境友好,有问题可以解答,对于学习者方便快捷。
Ⅳ. 友好的 API ,自由灵活地使用空间。
Ⅴ. 细致、漂亮的 UI可节省开发者的时间,也可以重构组件。
Ⅵ. 事无巨细的文档,官网的文档非常适合初学者学习。
Ⅶ. 可自定义主题,直接导入使用。
2.2.3 v-charts图表
博客的开发少不了图表,图表可以增强用户的体验,例如开发中的常用功能会有消费记录,访问记录等。每一个网页界面中可以创建多个echarts图表实例,但是每一个 echarts 实例都会独立占有一个对象节点,除此之外还需要做一些繁琐的数据的类型转换,修改图表的基础配置,这对于开发者比较棘手,所以v-charts 的出现正是为了解决这个痛点。v-charts是居于 vue 与 echarts 封装好的图表组件,只需要更改图表的参数就可以完成图表的显示与遍历,非常适合vue的整合开发。
可以自行配置局部的图表组件,也可以按照以下全局导入的方式:
//npm下载v-charts图表组件
npm i v-charts echarts -S
// main.js的全局导入
import Vue from 'vue'
import VCharts from 'v-charts'
import App from './App.vue'
//全局使用图表组件
Vue.use(VCharts)
new Vue({
el: '#app',
render: h => h(App)
})
2.3 Vue架构
2.3.1 关于MVVM模式
MVVM(Model-View-ViewModel)模式是基于原来 Model–View–Controller(MVC)模式改进而来的,MVVM 的核心是 ViewModel (V)层,这个V作用就是替代了controller层。原先的MVC模式是View与Controller直接交互,而这个V直接负责与 Model 层交互,这就完全分离了 View 层和 Model 层,可以把V是看作是一个数据中转站,它是实现前后端分离的最重要一环,同样MVVM模式也是Vue的数据绑定系统的设计核心,MVVM模式的用例图如图2-2所示:
图2-2 MVVM模式
2.3.2 关于Vue的生命周期
每一个运行框架都会有比较完整的生命周期,设计出一个稳定的生命周期可以保障框架有序地运行。Vue的生命周期含有运行生命周期函数,数据data,模板template,挂载el、方法函数methods,。Vue的生命周期也可以认为是Vue的运行的流程图,这个说法虽然不够严谨,但是可以加强对Vue框架的理解与控制。
图2-3是Vue 2.0的生命周期的活动图:
图2-3 Vue的生命周期
对于上图需要解释一下常用的三个函数:
1.created函数:完成创建vue实例后调用created函数来完成data数据的初始化任务,不过$el不可用,因为el尚未挂载。create函数适合初始化数据。
2.mouthed函数:el挂载到实例上,还可以完成data数据的更新。mounted函数如果完成业务逻辑改变,可以改变data再挂载el。
3.beforeDestroy函数:解除事件的监听,例如addEventListener监听。
2.3.3 Ajax运行原理分析
异步的JavaScript和Xml(Ajax)是一种利用异步方式来快速创建动态的网页技术,它不是一种常见的编程或者脚本语言。使用Ajax的好处就在于可以不用重新刷新整个网页,就可以对网页进行异步更新,而一般的传统网页(不采用 Ajax)若是要更新网页中的内容,需要重新刷新整个页面,可以认为是同步刷新。Ajax 的核心对象就是XMLHttpRequest(XHR),属于原生JavaScript的范畴。
关于Ajax的运行原理可以分为以下几个部分,图解如图2-4所示:
1.首先创建一个异步XHR调用对象来进行交互。
2.其次XHR定义HTTP请求与配置信息,使用XHR.open()函数。
3.然后发送HTTP请求,使用XHR.send()函数。
4.之后通过XHR的onreadystatechange事件获取异步调用返回的数据。
5.最后利用JavaScript和DOM实现网页的局部刷新。
2.3.4 使用Axios的原因
前些年比较火的是JQuery,JQuery包中 ajax 也是对原生XHR对象封装,在前端慢速的时代有着卓越的影响,但现在却有几个明显的缺点:
1.JQuery是基于MVC规范,不符合现在前端的MVVM规范。
2.JQuery是基于最初的XHR进行整合,不符合前端的ES语法规范。
3.JQuery完整包过于庞大,要用一个组件却要导入整个包,不合理。
不符合关注分离的原则,封装过于密封,维护压力比较大。
4.JQuery的配置与其调用时的方式非常混乱,基于事件的异步不友好。
5.Axios其实也是对最初XHR的封装,因为它是基于Promise API实现,比较符合现在前端的ES规范,例如常用的POST,GET请求,Axios也可以自定义配置这些请求函数,自定义的方便在于可以请求体Headers附带Token或者指定的数据,也可以定制数据的转换方式,比较合理化,符合编程的艺术思维。
前端自定义Axios的POST函数的详解如以下所示:
post(url, data) {
return axios({
method: 'post', //请求的方式
url: url, //请求的地址
baseURL: host, //host
data: Qs.stringify(data), //字符串转换data
timeout: 30000, //请求响应时间
headers: {
'X-Requested-With': 'XMLHttpRequest', //请求的对象与类型
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'TOKEN': window.localStorage.getItem('token'), //携带元数据Token
}
})
}
2.4 SpringCloud架构
2.4.1 SpringCloud框架
SpringCloud 是基于SpringBoot基础上构建的,用于快速构建系统的工具框架集合,SpringBoot有自动装配Spring MVC和内置Tomcat的优势。SpringBoot有四个特性。例如:编码相对简单,简化了配置,部署更加便捷,监控更加方便。总的来说,就是“习惯大于配置”。目前应用项目的搭建规范是基于Maven构建多模块的方式,这种方式搭建的各个模块各司其职,负责不同的功能,同时每个模块采用层级依赖的方式最终构成一个聚合型的Maven项目。
把SpringCloud比喻成一栋楼的话,SpringBoot就相当于地基,随着版本的发展,两者的版本会发生兼容冲突
SpringCloud的版本名只是官方定义的地铁站名字,从首字母A开始更新利用人们方便记忆,版本在一般情况下是向下兼容,向上不兼容,所以版本需要装配一致,否则项目无法运行。由于微服务的体系并不完全成熟,所以向下兼容也会出问题,包会有BUG和缺少部分类,新学者都直接使用最新的稳定包即可。
2.4.2 Zuul路由网关
微服务的网关Zuul是客户端与服务端的通信中转站,用户的API请求会经网关到指定的微服务,Zuul同样也是一种“过滤器”。用户的流量成千上万的点击,所以需要高可用的Zuul来保证不会发生单点故障。博客采用的是Zuul注册到服务中心上的一种方式,未采用外部Nginx负载均衡,所以Zuul的高可用如图2-6所示:
图2-6 Zuul高可用架构图
Zuul路由网关的核心配置是过滤器,它起到的作用是“拦截”信息,关于Zuul路由网关官方一共定义了四种不同过滤器类型,允许自定义过滤器:
1.pre类型:before拦截,请求前被调用,可以用来做Token的验证。
2.routing类型:拦截过后会把API请求转发分配到指定的微服务中心。
3.post类型:响应API请求,收集API指标,把响应结果发送给用户。
4.error类型:任执行发生错误时,会使用该过滤器执行报错。
省略
2.5 Mysql数据库
数据库是根据数据的存储结构来存储、管理和操纵数据的存储库,每种数据库都有多个封装好的不同调用方式,可以直接用于增删改查存储库中的数据。
Mysql是一种关系型SQL数据库,Mysql数据库开源,使⽤范围⼴,跨平台⽀持性好,还提供了多种语⾔的调⽤API,所谓关系型数据库就是在存储库中建立了一个关系模型,然后再利用数学等集合关系来操纵存储库中的数据。
Mysql作为一种常规的后端存储库,其性能虽然比Oracle弱,也被Oracle收购,但是Mysql是免费的,所以用来学习非常适合。
2.6 Mybatis框架
Mybatis的前身是IBatis。Ibatis是一个基于Java的持久层框架,2010年改名Mybatis,现由GitHub提供维护。Mybatis的优势在于定制SQL,由于Mybatis底层采用大量的反射,所以Mybatis会提供自动映射,动态SQL等。因此Mybtais的DAO层是不需要实现类的,只需要一个接口和XML配置类就可以启动。如今主流Mybatis编程是Mapper接口编程,所以本次博客采用的是国人开发的MyBatisCodeHelperPro插件,插件可以直接生成简单的SQL增删改查,节省简单SQL代码的时间。
Mybatis的核心组件一共分为四个部分:
1.SqlSessionFactoryBuilder:生成SqlSessionFactory,相当于一种构造器。
2.SqlSessionFactory:采用的是工厂模式生成SqlSession。
3.SqlSession:执行Sql与返回Sql结果。
4.SQL Mapper:Sql的Mapper映射器,采用主流的Mapper编程。
可以用一张图来解释Mybatis的4个核心组件的联系,如图2-13所示:
图2-13 Mybatis的核心组件
图2-13可以理解为传递“钥匙”,通过Java构造来实现SQL的执行流程。其底层是基于Java拦截器反射实现,若想学习可自行去了解。
2.6.1 Mybatis分页插件
在开发博客时,用到了许多分页操作,原生的分页类操作起来又比较麻烦,所以在使用MyBatis框架时,可以使用开源Mybatis的PageHelper分页插件。当然也可以采用原生的Mybatis分页插件,不过没有开源的Mybatis分页插件pageHelper好用。使用开源的插件比较危险,使用的时候需要仔细控制好每个环节。
SpringBoot整合pageHelper分页插件可以导入Maven以下配置:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
pageHelper调用的方式有许多种,但是个人建议使用以下的代码方式调用:
//Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10); //第几页多少数据
List<Country> list = countryMapper.selectIf(1); //数据库中的数据
PageInfo pageInfo=new PageInfo(list); //进行数据分页
关于pageHelper的yml配置信息如以下所示:
//这只是pageHelper的配置,完整需要配置Mybatis,Mapper和Entity位置。
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
2.7 Redis缓存中间件
Redis是Nosql缓存数据库。Redis的优势有三点。第一,它是基于ANSI C语言编写的,接近机器语言,运行速度快。其次,Redis基于内存的读写,相比于数据库的磁盘读写要快的多。最后,相比SQL而言,本身的数据结构类型比较简单。但是Redis同样也有弊端,内存相比磁盘来说存储较小,所以需要考虑系统的数据所需的存储量和数据存在的时间。在早期互联网产品面对“高并发”响应时会发生“响应慢”等情况,原因是用户的读请求远大于写请求,造成数据库的整体压力上升,所以引入了Redis中间件来把用户的读请求放到缓存中。随着微服务、分布式架构时代的到来,Redis得到了一席施展之地。
省略
3 博客的需求分析
3.1 博客的微服务功能分析
博客是互联网的一种分享类型的技术产物,但是如何留着用户才是重要的,并不都是所有的功能都会涉及到“高并发”,博客的功能多样性会增强用户的体验,让用户对博客的使用产生依赖性,利用从众心态合理地开发增值功能。
本次系统的开发采用了主流的微服务架构方式,所以把控每个微服务的功能相互独立和完整是“微服务”系统的关键。由于博客的实现比较简单,所以只有涉及到“高并发”的时候需要断点分析即可,下面将介绍博客系统的一些功能。
博客基本的功都具备,例如博客的核心功能:博客的发表,删除,浏览,评论,点赞等。除了这些,还可以每天定时签到提升博客的等级,充值会员提升使用体验。个人的安全信息也非常重要,所以我单独划分一个微服务中心来实现。同样我在每行重要的代码上都增加了明显的注释,这对于我以后的维护和扩充博客功能可以打下坚实的基础,尽可能地符合软件设计开发原则。
关于博客的功能一共涉及到8个微服务中心:
1.用户的个人中心:包含登录、注册、智能验证。
2.用户的安全中心:安全信息、手机与邮箱的基本功能和安全认证的接口。
3.用户的博客中心:发表和管理个人的博客,游客可以浏览公开的博客。
4.用户的文件中心:发表博客需要用到的图片和个人用户的头像。
5.用户的签到中心:博客的签到累计的经验值和签到奖励。
6.用户的会员中心:包含普通会员和超级会员。
7.用户的支付中心:VIP的充值功能,个人钱包功能,账单等。
8.用户的搜索中心:根据摘要或者文章标题的关键字搜索指定的博客。
3.2 本章总结
本章写的大多是要实现的博客需求,下一章会具体提到博客的架构设计。
4 博客的设计分析
4.1 博客的架构设计
划分完需求后,博客的微服务架构涉及如图4-1所示:
图4-1 博客的微服务架构图
从宏观设计来说,各个微服务中心都是一个moudle,需要注册到一个高可用的微服务注册中心上保证机器信息的正确性。
从微观运行来说,用户的请求API都经过Zuul,再由Zuul负载均衡分配给需要的微服务中心,所以Zuul也需要高可用保证用户流量可以得到回应。通过zuul网关后,请求通过Feign实现微服务之间数据的交互。
当发生错误运行时,利用Hystrix的回退机制保护系统的稳定运行,不会发生级联占用效应,保证每一个请求API都可以得到响应。当发生网络不可用的情况下,需要触发用户的补偿机制,当出现不可知的错误时,也可以直接管理机器的集群来维护系统的稳定运行。
4.2 博客的数据库设计
对于用户来说,需要输入账号和密码,若是不存在可以注册自己的账号和密码。注册的时候提供30分钟填写博客信息的有效时间,不填写则直接登录。需要设置个人的手机和邮箱来绑定安全认证,若想要开通我的钱包则需要实名注册,同样也包含校园认证。丢失了个人信息,则可以用身份证申诉。每天凌晨开始可以开始签到,根据会员的不同增益不同,签到的持续天数不同经验值累加也不同。会员的开通只包含支付宝,账单是每笔消费的记录。核心表是用户博客之类的表,文章均存在数据库,不过ElasticSearch也保存了文章的标题和摘要。每个用户可以评论他人的文章,私密的文章不会出现,会员的文章会出现在会员专区。
博客一共含有8个主功能,所以一共涉及用户表,用户信息表,安全表,头像表,签到表,签到奖励表(两种奖励),会员表,钱包表,订单表,博客表,博客分类表,博客标签表,博客图片表,博客的评论表,点赞表和收藏表17个表。
4.2 本章总结
本章涉及到只有架构设计,而博客总体的功能实现会在下一章中提及。
5 博客的设计实现
5.1 博客总体架构的实现
博客的各个功能均已实现,从前端到后端都会有详解的实现,本章是对前4章的一个实现总结,前文涉及到高可用与分布式时候都会有所提及但未有详解的解答,阅读本章就会明白微服务到底是怎么运行的。
5.1.1 Vue架构的实现
前端IDE采用的是WebStorm,博客的Vue主要分布如图5-1所示
Alert.js是自定义重构代码的漂亮提示框。axios.js是封装好的axios请求HTTP函数,components是Vue文件存储位置,也是Vue的组件,index.js是管理前端路由url的跳转,利用components组件与url的控制。store.js是组件状态管理的文件,由于采用的LocalStorage本地存储所以并不是主用。main.js是全局文件也是最重要的文件,管理Vue的全局配置。static/img中保存的是博客所用的图片。
5.1.1.1 package.json文件
不管是用IDE创建的项目还是采用常规脚手架创建的vue项目,其项目都会在根目录生成一个package.json文件,这个文件与后端的“pom”相似,这个文件包含所需要的各种包,还包含项目的配置的名称与版本对应。
博客项目中的package的完整dependencies代码如以下所示:
"dependencies": { "axios": "^0.19.0", "bootstrap": "^3.3.7", "echarts": "^4.6.0", "element-ui": "^2.12.0", "font-awesome": "^4.7.0", "github-markdown-css": "^4.0.0", "highlight.js": "^9.18.1", "jquery": "^3.4.1", "marked": "^0.8.0", "mavon-editor": "^2.7.7", "popper.js": "^1.12.5", "showdown": "^1.9.1", "v-charts": "^1.19.0", "view-design": "^4.0.2", "vue": "^2.5.2", "vue-drag-verify": "^1.0.6", "vue-nocaptcha": "^0.2.8", "vue-puzzle-vcode": "^1.1.2", "vue-qr": "^2.2.1", "vue-router": "^3.0.1", "vue-schart": "^2.0.0", "vue-splitpane": "^1.0.6", "vuex": "^3.1.2" }
5.1.2 SpringCloud架构的实现
博客Maven的整体微服务中心实现的结构图如图5-2所示:
图5-2 SpringCloud后端图
SpringCloud是基于Java语言的工具集,SpringCloud具备拿来就用的特性,可以节省开发的配置时间,它可以在Docker等云环境中开发和部署。SpringCloud的组件比较丰富,博客使用了Eureka,Zuul,Feign,Htsrrix,trubine,Zipkin微服务组件。组件可以自由地选择,不过需要解决SpringBoot与SpringCloud之间的版本依赖才能使用。博客涉及到的Java的JDK版本是1.8,SpringBoot的版本是Spring Boot 1.5.9.RELEASE,SpringCloud的版本是Edgware SR4。后端的IDE采用的是IDEA,Maven的版本为3.6.1,任何一个版本的更改都可能会导致兼容不一致。
5.1.3 博客的高可用的实现
博客使用了两个Zuul并且注册到高可用的服务发现中心来构造Zuul高可用集群。Eureka是所有微服务的注册中心,并且自己本身也是微服务不过需要禁止自我注册。Eureka注册中心包含每个微服务的名称,IP,端口等,由于因为的单个节点的微服务可能会发生不可用的情况下导致系统发生停机,所以采用高可用的微服务注册中心。让两个(多个)服务发现组件相互注册以达到可以保持其它微服务的调用,维持整个系统的高可用性
DS Replicas代表两个模块加载模拟单机代替高可用的实现,不过需要修改本地Host来模拟真实多机高可用的效果。每个微服务都具有自己的虚拟主机名以及状态来描绘微服务的显示情况。每个微服务之间通过与服务注册中心每30S心跳传递保证服务可用性。默认90S没有收到心跳则会注销该微服务。EurekaServerOne与EurekaServerTwo为两个微服务注册中心,两者相互注册到对方的服务中心上来保证Eureka的高可用稳定,从而使每一个博客的请求都可以得到响应。
5.2 用户的个人中心
用户的个人中心相当于博客的大门,用户的首次流量都经过此处,首次负载均衡调用也是基于这个中心开始,主要涉及到用户的登录与注册的基本功能,在登录上排除恶意的攻击与干扰,保证博客登录的稳定,从而保证系统的稳定。这个中心核心功能就是权限验证,保持登录的标志,它是保持业务稳定的重要因素,后续的实现会在以上所述的三个重要功能展开来讲。
5.2.1 登录的智能验证
Vue整合阿里云智能验证时,需要注册布局组件来动态加载JavaScript文件,不然无法使用阿里云的智能组件,前端登录智能验证的核心代码如以下所示:
//动态加载阿里云的JavaScript文件 <remote-js src="//g.alicdn.com/sd/nvc/1.1.112/guide.js" @loaded="initCaptcha"> </remote-js> //注册局部组件来加载阿里云的JavaScript文件 components: { "remote-js": { render(createElement) { const self = this; return createElement("script", { attrs: { type: "text/javascript", src: this.src }, on: { load() { self.$emit("loaded"); } } }); }, props: { src: { type: String, required: true } } } }, //点击智能验证的封装函数 initCaptcha() { let _this=this; let ic = new smartCaptcha({ renderTo: '#sc', width: 350, height: 42, default_txt: "请点击验证按钮", success_txt: "博客登录验证成功", fail_txt: "点击按钮重新刷新登录验证", scaning_txt: "智能检测中", success: function (data) { console.log(NVC_Opt.token); console.log(data.sessionId); console.log(data.sig); _this.aliToken=NVC_Opt.token; _this.sessionId=data.sessionId; _this.sig=data.sig; }, }); ic.init(); },
5.2.2 博客的登录注册
登录是一个系统的重要的功能,也是个人隐私的重要体现,拿常见的登录有邮箱,手机,账号或,语音或者二维码登录,不过不管通过哪种登录,个人信息的安全都应该得到保护,保护个人隐私重要的是从个人做起,拒绝非法点击与输入。
拿本次博客的登录来说只需要验证账号和密码就行,个人登录是不会进行权限验证。注册成功会保持30分钟的权限验证,关于权限验证会在标题5-2-3中提到,以便后面的博客信息的操作,超过则需要重新登录去博客的个人中心填写博客信息。
博客的登录与注册的页面如图5-4所示:
图5-4 登录与注册的页面
博客登录的用户名需要以英文子母开头,用户名和密码均不可以超过16位,
注册保证两次登录密码正确就可,在此不再贴出图片累述。
5.2.3 登录的权限验证
登陆权限控制是每个系统都应必备的功能,是保持登录状态的重要实现。微服务所有的权限验证均在一个module上,Token消时则直接回退给前端status 404失败码,成功则是执行对应的业务逻辑,注意登录的博客是不需要权限验证。
博客使用了前后端拦截器拦截Token(登录成功的认证码),所以后端需要定义一个token验证注解,用拦截器拦截系统的url请求,再进行拦截用户的API请求,最后再验证传过来的token与Redis中token值是否一致,效验通过才可以正常访问。当用户登录成功博客后,后端返回token数据。token具有存在时间,如果用户一段时间后不在线或者操作的话,则token会失效,用户保持登录时,则不会过期。
Redis中会以用户的登录账号作为与token关联的认证,有效的token码可以取出用户的账号,然后再进行业务逻辑。这些redis中的key都可以自行设置一些时间,不过前端只保存token值,二次登录会覆盖Redis中的token值。
权限验证保持登录状态如图5-5所示:
图5-5 权限验证
权限验证相当于系统的第一道大门,如今的安全框架越来越丰富,例如SpringSecurity,Shiro,OAuth等,shiro->security->oauth的上手难度逐渐提升。若是需要对密码加密的,可以需根据个人开发自行配置使用对应的安全框架。
登录验证的前端钩子与拦截器实现前端的Token的检测的代码如以下所示:
省略
5.3 用户的安全中心
5.3.1 用户的安全布局
安全中心包含邮箱,手机,身份证,校园认证和其它微服务中心需要用到的认证接口。邮箱采用QQ邮箱,开启SMTP 587端口发送邮箱验证码。手机采用阿里云短信API服务。两者的验证码存在的时间均为1次失效且存在10分钟。身份证需要手机号的验证。校园认证的名字需要和身份证的名字一致。除了绑定一些安全的服务,还包括三种修改密码的方式,原始密码修改新密码,邮箱重置密码,手机重置密码,身份证重置密码。个人申述包括手机号重置邮箱,旧手机更换新手机,身份证重置手机。安全中心前端图如图5-6所示:
图5-6 安全中心前端图
安全中心包括用户的规则规章,博客旨在分享自己的动态和经验给他人,不可以辱骂他人,以及不遵守国家的法律法规。本次博客的其它微服务中心所需要的手机认证接口均由这个微服务中心提供。
5.3.2 用户的邮箱注册
博客采用的是免费的QQ邮箱,邮箱的yml配置如下:
省略
5.3.4 用户的安全认证
提供安全的认证有身份认证与校园认证,当然只是表单的提交,真实的认证需要有关部门的配合,在此只是用来模拟,校园认证需要与身份证的名字保持一致,否则无法通过。实名认证与图5-7所示,校园认证由图5-8所示。
图5-7 实名认证
图5-8校园认证
5.3.5 用户的密码安全
当个人安全账号发生异常,可以提供修改密码,也可以重置密码。
如图5-9修改个人密码与图5-10重置个人密码所示:
图5-9 修改个人密码
5.3.6 用户的账号申诉
可以使用手机号重置邮箱,也可以使用旧手机号更换新手机号。如果个人博客的手机号安全信息被盗取,手机号也可以被重置,但是需要借助身份证申诉,不过一天只可以成功申诉一次。如图5-11所示:
图5-11 安全申诉
对于安全申诉的一天时效使用Redis中间件:
//设置一天的限时
jedis.set(resetName,username);
jedis.expire(resetName,86400);
5.4 用户的文件中心
5.4.1 用户的头像存储
当用户注册的时会需要选择个人的头像,上传的头像只能是JPG格式且大小不能超过2MB,且上传前会先查询数据库中的头像图片名是否已经存在,存在的话直接会先删除OSS中旧图片,再插入新图片,如果不存在的话,直接插入到OSS文件服务器中。头像的存储流程由前端发起file传给后端,后端接受file头像,利用二进制传给OSS文件服务器。服务器再传过来头像的外网URL地址,此时修改显示时间为10年再返还给用户,最后把头像外网URL地址保存到自己的LocalStorage本地。用户头像上传到OSS对象文件服务器如图5-12所示:
省略
5.6 用户的会员中心
5.6.1 会员的流程控制
由于会员中心与支付中心联系比较密切,所以两者的中心可以结合起来看作一个中心来观看。用户的会员中心包括普通会员和超级会员,每种方式存在三种收益方式,年费季费和月费,支付成功后均由负载均衡执行业务逻辑。由于支付不属于这个module中,所以这个module只是由其它微服务调用直接完成业务逻辑。
5.7 用户的支付中心
5.7.1 用户的支付中心
未完成实名认证时页面会转到实名认证中,当完成实名认证时,首次进入我的钱包中心会触发设置支付密码,当设置成功后,支付以及绑定个人银行卡均需要用到支付密码。可以用旧支付密码修改新密码,也可以手机重置手机密码。还可以绑定自己的银行卡,需要有关部门的配合。本次博客只允许建设银行,工商银行和中国银行,且每张银行卡只允许绑定一张。利用v-charts组件把个人的时间段的消费情况以条形图展现给用户观看。博客支付中心的前端图如图5-15所示:
图5-15 前端支付中心
用户设置个人支付密码由5-16所示:
图5-16 设置支付密码
5.7.2 用户的账户钱包
5.7.2.1 我的账户余额
当用户开通了我的钱包后,可以选择是否进行余额充值,账户余额暂时只可以用支付宝充值。所有关于金额的操作均需要在后端安全操作,前端只用来显示数据,必须使用数据库中的金额。
我的钱包如图5-17所示:
图5-17 我的钱包
充值账户余额如图5-18所示:
图5-18 充值
5.7.2.2 我的支付密码
密码为6位有效数字,可以使用原密码更换新支付密码,如图5-19所示:
图5-19 更换支付密码
丢失忘记,可以使用手机号重置支付密码,如图5-20所示:
图5-20 重置支付密码
5.7.2.3 我的账户银行卡
银行卡姓名需要与实名认证的姓名一致。主页如图5-21所示,绑定银行卡如图5-22所示,解绑银行卡如图5-23所示:
5.7.3 用户的会员支付
支付中心包含普通会员和超级会员,由于普通会员采用支付宝原始的方式,而超级会员采用支付宝的二维码方式,所以两者会在调用的时候会有所不用。
超级会员的支付页面由图5-24所示:
图5-24 超级会员
5.7.3.1 普通会员支付的发起
由开通普通会员为例,结果以图2-19中的异步发送支付通知为准,成功与失败均由这个通知为基准,判定进行什么样的业务逻辑。开通普通会员的同步支付的后端原代码如以下所示:
省略
5.8 用户的博客中心
5.8.1 用户的访问主页
编写博客是一个展示自我的机会,通过这个机会,可以增强个人的表达能力,还会结识一些五湖四海的博友。通过他人文章的学习,我们还可以增强个人的知识度和眼界。综上所述,用户的博客中心是博客系统的最核心功能。
用户可以分享自己的博客动态,博客旨在分享自己所学所知给他人,或者解决他人的困难。博客中心包含发表博客,查看个人博客,删除博客,更新个人博客。非本人也可以观看他人的博客,也可以评论他人的博客,所以需要用到分页功能和轮滑加载功能配合前端展示不是私密的博客给他人观看。每个用户所看到的博客都是最新发的博客,可以与他人进行学习交流。每个发表者要尊重他人的知识劳动成果,切勿抄袭并且发表不适当的文章,做一名合格的博友。
当用户输入账号密码登录后,可以看到博客的主页如图5-32所示,主页面可以看到发表人和发表的文章,点击文章可以进入文章的主页面进行学习交流。
图5-32 博客主页
5.8.2 用户的文章中心
用户的文章微服务中心的功能包含发表,查看,修改,删除,用户可以控制自己发表过的每一篇文章。
个人的博客中心如图5-33所示:
图5-33 个人博客中心
关于文章的增删改会在后续标题中得到详解,在此只放出用户的个人文章中心由图可以看出是用户发表过的全部文章,后端利用的是先分页后List方式,最终传送前端进行ListItem遍历显示即可。
由于也使用了Elasticsearch把文章分类作为存储索引,但是重要的文章信息均放在数据库中,在此只提一下,到后续的分类搜索中会详细说明。
5.8.2.1 发表个人的博客
文章的的发布有许多选择,自己可以选择文章的分类和文章的标签,同样也可以设置文章的可见性。用户可以设置文章的标签,标签用来显示给游客看,用来文章的标识认证,还可以设置文章的分类,类型和保密性,每种文章的分类会发布到那个分类的专区。文章类型有三种,若是转载和翻译他人的文章需要著名地址,保护他人的知识劳动成果。只有具备会员资格才可以发送到会员专区,但是转载的文章不可以发送到会员专区,发表文章时可参考红字注意事项。
博客发表的页面如图5-34所示:
图5-34 确认发表文章
博客的发表的核心原代码如以下所示:
省略
5.8.2.2 修改个人的博客
若是需要修改个人的博客,需要进入图5-33的个人博客中心,查看发表的指定文章进入到指定文章的页面,点击编辑按钮,不是本人的文章不会出现编辑按钮,博客的编辑按钮效果图如图5-34所示:
可以修改文章的所有的条件与内容,如图5-35所示:
图5-35 修改个人博客
文章的发表与修改的源码不同在于要删除之前的原属文章的分类Id与标签Id的关联,再进入文章的插入,不过文章的修改也会触发在搜索引擎上的文章信息修改,搜索引擎上的文章信息也会跟着更新,保持搜索到最新的数据。
5.8.2.3 删除个人的博客
删除个人的博客需要删除数据库和搜索引擎上的文章,删除文章后不可恢复。
删除文章的原代码图5-36所示:
图5-36 删除个人的博客
5.8.3 用户的文章布局
完整博客的显示方式是采用GitHub的代码高亮布局,可以是用户看到自己的博客是嵌入式的面板,可以给予人一种清爽的感觉。由于采用Vue,可以不用动态渲染html,使用v-html命令就可以把后端传过来的数据利用showdown转换器转换给html直接显示给用户看。完整的用户观看的布局如图5-37所示:
图5-37 完整博客的显示
前端重要的核心代码如以下所示:
import showdown from 'showdown'
import 'github-markdown-css/github-markdown.css'
let converter = new showdown.Converter();
//转换为HTML
let html = converter.makeHtml(res.data.articleAll[0].articleMdContent);
5.8.4 点赞用户的文章
互联网时代每个人都或许都点赞过他人分享的文章,本次设计是博客所以会涉及到点赞,当用户太多时需要考虑到高并发的情况。正常情况的点赞并不会给后端造成多大的负载压力,如果是热门的文章博客,用户点赞与取消点赞,评论,分享等,对于后端来说这些都会带来巨大的流量,如果后端接口支撑不住,前端得不到响应,前端无法响应就会返回404,会导致用户体验极差。可以利用2-7-1中的分布式中间件Reidsson来实现点赞的功能。
博客点赞的用例图如图5-38所示:
省略
5.10 本章总结
本章的8个微服务中心全已实现,后续标题会详解对博客的测试做出分析,还会对博客代码设计阶段时遇到的“BUG”和不可预防的错误给出解决方案。
6 博客的测试分析
省略
8 结束语
这次的毕业设计,不仅让我在Java和JavaScript方面有了巨大的提升,而且让我养成了遇难而上的品质。在确定了毕业设计的导师和题目之后,通过不同的途径,阅读有关微服务的文献,了解分布式系统的设计,再结合自己之前学习Java开发的基础,对博客的开发有了想法,所以选择了这个题目。
通过半年时间的奋战,我终于完成了毕业设计的博客。博客的实现参杂着许多困难和挫折,但我都一一克服。从我开始着手毕业设计后,我遇到了不少代码的问题,每一次看到学习文档和别人的解决方案时我都想要放弃,可是由于毕业设计的重要性以及自己的开源目标,只能顶着压力学习和测试。每一次解决问题后的成就感都增加了我以后面对问题时不再逃避的勇气。在博客的代码阶段,我逐渐弥补了前端的薄弱能力,现在的我可以游刃有余的进行Web全栈开发。通过这次的毕业设计让我的学识和对自己的认知都有所提高,对我以后的工作会有许多积极的影响。但我依旧会保持谦虚的态度,对于每一个问题和困难都会虚心求教,对于每一个有需要帮助的人我都会乐于奉献帮助他人解决问题。
这次的毕业设计完成比较艰难,在过程中也解决了很多难题,还存在一些不是非常完美的代码。在这次设计之前我对中间件的使用并不是非常熟练,完成时每个中间件在微服务中心都有了它的存在,这对于我的个人信心有了非常大的提升。由于时间和自己能力的问题,功能也有很多不完善的地方,但是对于功能的扩充非常友好,随着时间的发展,我会从应届生进入社会,但是我会抽出一些空闲的时间用来一步步优化我写过的代码,并且扩充微服务中一些次要功能,完成从一名应届生到合格的程序员的蜕变,在社会中实现自己的人生价值。
致 谢
省略
参考文献
[1]陈国君.Java程序设计基础第五版,清华大学出版社出版,2015
[2]杨开振.JavaEE互联网轻量级整合开发(SpringMVC+Spring+Mybatis+redis).
电子工业出版社,2017.7
[3]王松.Spring Boot+ Vue全栈开发实战,清华大学出版社,2019.6
[4]周立.Spring Cloud与Docker(第二版)微服务架构实战,电子工业出版社,2018.7
[5]梁颍.Vue.js实战,清华大学出版社,2018.12
[6]刘伟.Java设计模式,清华大学出版社,2019.5
[7][美]Baron Scbwartz.高性能Mysql,[译]宁海元,电子工业出版社,2013.5
[8]百度阅读.胡杨的在线著作,Vue+Bootstarp+View-UI+element-UI的学习文档
[9]钟林森.分布式中间件技术实战(Java版),机械工业出版社,2020.1
[10][美]Matthew Lee Hinman.Elasticsearch实战,[译]黄申,人民邮电出版社,2019.10
[11]方志朋.深入理解Spring Cloud与微服务构建,人民邮电出版社,2018
[12]杨冠宝.阿里巴巴Java开发手册,电子工业出版社,2018.1
[13]胡荷芬.吴邵兴.UML系统建模基础教程,清华大学出版社,2016.7
[14][美]Brian Goetz.Java并发编程实战.[译]童兰云,机械工业出版社,2012.2
[15][美]Nicholas C.Zakas.JavaScript高级程序设计.[译]曹力,人民邮电出版社,2012.3
[16][美]Mark Allen Weiss.数据结构与算法分析(Java).[译]陈越,机械工业出版社,2016.2
[17]朱忠华.RabbitMq实战指南,电子工业出版社,2017.11
[18]小马哥.Spring Boot 编程思想(核心篇),电子工业出版社,2019.3
[19]高洪岩.Java多线程编程核心技术,机械工业出版社,2019.1
[20]方鹏飞.魏鹏.程晓明.Java并发编程的艺术,机械工业出版社,2015.7
本项目源码及完整论文如下,有需要的朋友可以点击进行下载。如果链接失效可点击下方卡片扫码自助下载。
序号 | 毕业设计全套资源(点击下载) |
---|---|
本项目源码 | 基于Vue+SpringCloud+Mysql的博客系统设计与实现(源码+文档)_Vue__博客系统.zip |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。