问答系统的系统设计方案

一、软件架构风格

“每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复工作”。模式的关键在于模式的可重复性,问题与场景的可重复性带来解决方案的可重复使用。而架构也与此同义,为了实现系统的高性能、高可用、易伸缩、可扩展、安全等各种技术架构目标,各大互联网公司提出各种解决方案,这些方案被业界复用,从而逐渐形成大型网站架构模式。

分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对比较单一的职责,然后通过上层对下层的依赖和调用组成一个完整的系统。

分层在计算机世界无处不在,在本项目也用到了,如下图:

问答 架构 问答系统框架_概念模型

主要层分为负责处理请求的api层,负责业务处理的service层,负责数据处理的model层,其他还有负责缓存的cache层,中间件层middleware以及一些配置层等等,具体见下图:

问答 架构 问答系统框架_问答 架构_02

分割就是即是纵向方面对软件进行切分。本系统以问答为核心,粒度适中,比如服务层目前分割成用户,问题,回答等,其中问题又可分割成普通问题和热点问题,其对应页面展示也有所不同。

问答 架构 问答系统框架_问答 架构_03

数据访问热点不均衡,频繁数据放在缓存中,并且有一定期限不会长期占用宝贵内存,通过缓存加快数据访问速度,减轻后端应用和数据存储的负载能力,这种设计对数据库架构十分重要。

本系统采用redis远程字典式缓存服务,将部分热点数据进行缓存,能够快速响应用户对热点内容读取的需求,另外点赞收藏等易变化的部分数据不立即存入数据库,而是通过缓存操作加定时任务,实现弱一致性的数据存取。

系统的安全问题也是架构设计中必须要考虑到的,比如直接使用https进行通信,选择更好的加密算法也是需要考虑好的。本项目主要使用Bcrypt算法。用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串加密,然后再使用一个随机的salt加密。 特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。 BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。

二、接口设计风格

谈完了系统的架构风格,我们来谈谈接口设计的策略风格。一个后端系统主要任务就是设计好各种不同任务的底层接口,一个好的接口设计往往利于提高系统的解耦程度,而一个好的设计规范更能方便使用者调用,也利于后端开发人员理解任务的性质。

本系统采用restful风格的API设计规范,即"动词 + 宾语"的结构组成的数据操作指令,主要涉及get(读取)、post(新建)、put(更新)、patch(部分更新)和delete(删除)。

问答 架构 问答系统框架_问答 架构_04

此外,响应状态码也应该精确,这里是内部返回响应,主要包含状态码,提示信息,数据,如下图通用返回结构体:

问答 架构 问答系统框架_数据类型_05

问答 架构 问答系统框架_缓存_06

三、软件系统概念原型下的视图

一个系统无论大小,皆可分模块,通过视图勾划出系统结构,往往会通过不同抽象层级的软件模块形成层次化的结构。

如下图,可知大致功能划分。

问答 架构 问答系统框架_缓存_07

各层依赖视图:

问答 架构 问答系统框架_概念模型_08

关于泛化视图,由于采用的是面向过程的go语言没有类与类的继承等特性,但采用了组合方式来实现各层函数的调用。例如model层需要定义answer结构体,并且为这个实体嵌入一些常用方法,以供service层调用。

问答 架构 问答系统框架_缓存_09

  关于执行视图,这里以判断用户是否能修改问题的时序图来举例:

问答 架构 问答系统框架_问答 架构_10

  也可看看用例图:

问答 架构 问答系统框架_数据类型_11

  部署视图,本系统采用docker部署:

问答 架构 问答系统框架_数据类型_12

四、软件系统运行环境和技术选型说明

编程语言:go

web框架:gin

orm:gorm

缓存:redis

消息中间件:rabbitMQ

运行环境:Linux+docker

五、数据库设计

设计者的概念模型和最终用户的概念模型。设计模型作为产品设计者的概念模型,是对产品构成结构和操作方式的系统化、结构化描述;相对应的用户模型,是用户在产品使用过程中形成的关于产品构成和操作方式等的结构化理解。而设计者是通过一系列视觉线索,以及用户的产品使用过程将设计模型传递给用户,并最终转换为用户概念模型。设计模型和用户模型的最理想状态就是二者完全等同,即产品的所有设计意图和操作方式完全被用户所理解。因此实体的划分与联系至关重要,由功能结构分析可知,系统需包含用户、用户信息、问题、问题标签、回答、收藏、消息实体,大致E-R图如下:

 

问答 架构 问答系统框架_缓存_13

 

  • 通用字段

列名

数据类型

长度

唯一

非空

注释

id

int

11

通用主键

created_at

datetime

 

创建时间

updated_at

datetime

 

更新时间

deleted_at

datetime

 

删除时间

  • 用户表(user)

列名

数据类型

长度

唯一

非空

注释

username

varchar

255

用户名

password

varchar

255

密码

nickname

varchar

255

昵称

email

varchar

255

邮箱

avatar

text

 

头像

status

int

11

状态

user_profile_id

int

11

用户信息逻辑外键

  • 用户信息表(user_profile)

列名

数据类型

长度

唯一

非空

注释

email

varchar

255

邮箱

phone

varchar

255

手机号

description

varchar

100

个人介绍

  • 问题标签表(tag)

列名

数据类型

长度

唯一

非空

注释

name

varchar

255

名字

description

varchar

1000

描述

icon

varchar

255

图标url

topic_count

int

11

所属问题个数

  • 问题表(topic)

列名

数据类型

长度

唯一

非空

注释

title

varchar

255

标题

content

text

1000

简述

user_id

Int

11

用户id

comment_count

int

11

评论总数

collect_count

int

11

收藏总数

view

int

11

点击量

top

bit

1

是否置顶

up_count

int

11

点赞次数

down_count

Int

11

点踩次数

  • 标签-问题表(topic_tag)

列名

数据类型

长度

唯一

非空

注释

tag_id

int

11

标签id

topic_id

int

11

问题id

六、项目源代码文件结构

总体如下:

问答 架构 问答系统框架_缓存_14

主要层下级目录:

问答 架构 问答系统框架_问答 架构_15

七、概念原型核心工作机制

在系统架构时经常会采用概念原型来使得跟系统相关的所有成员,如客户、用户、开发人员等对系统初步达成一致的理解。其中,分解不同的视图,能狗从不同的视角来掌握整个业务的大致流程。

从上文结合数据库设计可知,本系统主要有用户模型,问题模型,回答模型等主体模型。关于工作过程,匿名用户可以不登陆进行浏览问题、回答和查看他人信息,但是不能进行发布问题回答操作;登录用户可以有全部权限,即登录后可发布问题,回答问题,回复他人,查看账号信息及相关操作等。