【架构】一些架构和为什么要这么设计

1 篇文章 0 订阅
1 篇文章 0 订阅

数据库设计

分析对象,确认范围与联系
比如用户和企业,与用户有关系的,帐号,所在企业id,邮箱,手机号,昵称,放在同一张表中
与企业有关的,id,企业名称,企业大小,企业套餐
需不需要设计附表,也就是关系表?

有时候强相关会导致程序的健壮性,或者容错性不够好,但是弱相关的话又可能会导致数据不同步。
怎么去界定这个范围,还是要看对项目的目的。

密码表
为什么密码表单独设计,因为密码需要加密,而且与认证相关,分开比较好.

业务数据获取(Redis)

设计key,value

对于查询很多,变化很少的数据,可以整张表缓存在redis中,以减少查库的使用量。
比如用户信息,与用户相关的所有信息以

key:特定标识+username
value:用户信息

的方式存放。
这样,在校验用户信息时,可以直接用key去redis中拿取,而不用查库。
如果redis中没有,则查一次库,并将数据存入redis中。

这样做的好处就是查数据时很方便,减少查库操作提高程序的可用性。
但是需要在数据变化的时候清除数据库的缓存,比如修改了用户信息,或删除了用户信息。

注意redis中存入的数据还是需要设置过期时间,不然垃圾数据会越来越多。

设计内容

需要注意的是,设计缓存时,缓存的应该是大多数,而不是少数。
比如校验企业状态,企业已注销,是大多数还是少数?
大多数用户登陆时企业都是未注销的,此时我们应该减少校验企业状态时的查库量。

如果设计成企业已注销的缓存在redis中,如果找不到就去查库,那大部分人都找不到,并且会去查库看企业是否已注销,并且缓存还是没有加到redis中,这样虽然在redis中的数据少,但是查库的量大到吓人.

而如果把企业没注销的状态缓存在redis中,找不到再去查库,那就可以减少同一用户的查库量,如果发现企业没在缓存中,再去查库,发现未注销,添加缓存,发现已注销,返回企业已注销.并在企业注销接口加入删除该缓存的操作.

另外如何防止redis穿透,也就是一直查询一个不存在的东西,那么就会越过redis一直访问数据库?布隆过滤器就是一种防止redis穿透的工具,大概原理类似于,把数据库的数据都hash映射到足够大(比原数据量少,但是又能区分有数据和没数据的区别.)的缓存到一个过滤器,一个请求过来,先从过滤器查,因为过滤器内容比较少,所以hash完以后全表查询时间很短,如果查不到,说明数据库没有这个数据,那就不需要查库,如果有hash,那说明数据库有很大可能有这个数据.这个时候再去查数据库就能降低穿透的概率.

设计先后顺序

一次性获取所有校验的数据,而不是分几次去查库,先查库,拿出来,有需要的就用来校验,没有的就过.
反复的查库一定要避免!
比如校验手机号和邮箱是否输入正确,根据用户帐号查库搜出整个对象,存入redis中,下一次查的时候直接从redis中获取。
拿出整个对象以后,可以对比帐号与手机,帐号与邮箱是否匹配.而不是拿手机去查一次库,邮箱去查一次库.

另外把操作库操作放在权限校验之后,因为没有正常的权限,却能频繁操作数据库,很容易被攻击.
所以是先校验密码,再校验其他涉及操作数据库的操作.

接口设计

对于web端,使用json格式作为前后端数据交互的载体,可以很好的兼容多种场景.
也就是@requestbody、@responsebody这两个注解

而对于客户端与PC端,因为旧客户端发布以后无法对其代码进行变动,处理逻辑无法变动,所以最好是设计成动作类型驱动,
而不是根据每种场景设计一个特定的错误码,然后再执行特定的操作.

比如以下错误案例:

if(code==999||code==1000){
	提示错误信息
}
else if(code==1001||code==1002){
	弹窗
}
//默认
提示网络异常

这样做的话,新增一个错误码,客户端就要新发一个版本,服务端就要新做一套接口,因为新的错误码旧客户端不识别,会默认弹出网络异常,比如帐号已注销功能.用户帐号被注销以后,不提示已注销,反而每次提示网络异常,这是非常奇怪的.
而如果开发新接口加新客户端,又导致旧的接口需要维护.非常的浪费资源.

正确的设计方式应该是,客户端统计出已实现的交互类型
比如提示,弹窗,跳转url,跳转页面,UI展示,图片展示
服务器返回该情况下需要客户端进行的操作
而客户端根据服务端返回的操作类型,进行操作

比如提示用户密码错误,服务端只要返回
operate:tip
message:帐号或密码错误

客户端的逻辑则是,
if(operate==tip){
从message中拿出提示语展示
}

以此类推
if(operate==redirect){
从redirectUrl中拿取地址进行跳转
}

if(operate==float){
弹窗确认
左边是确认右边是取消,触发的接口是什么,提示是什么。都可以自定义。
}

客户端就像一个黑盒子,提供一系列的指令集,而服务端只需要提供对应的操作就行了.

这样做虽然还是不能在增加全新功能(操作类型)的时候,减少代码的开发

但是已经可以做到大部分重复场景下不需要客户端更新,可以服务端进行静默更新。用户的体验更好,服务端也不需要维护大量兼容接口。

配置中心

1.一些需要动态设置的东西,比如超级管理员帐号,加密配置在配置中心,便于在项目上线后不需要变更就能对其进行改动.

2.或者是不同环境,测试环境与生产环境下,域名不同,密钥不同,也可以配置在配置中心中.

3.一些代码的开关,新功能上线,影响范围过大,担心出生产事故,设计一个开关,通过读取配置中心的开关来确认是否开启新功能。

4.初始化用到的一些资料,项目如果有要部署多个环境,可以把初始化的一些资料放入配置中心,读取后写入对应的数据库.或者直接生效.

Flyway

使用flyway对数据库进行版本管理,数据库中的表,字段增删改都是会对生产造成重大影响的操作.
应该将所有操作记录下来.并且如果有flyway,之后部署其他环境也可以很方便的执行.

flyway可以做成整个项目启动前运行,不过启动速度有影响。也可以单独做一个job类的模块。有数据库变动时再跑。

消息队列

kafka可以做的事情很多,有收集日志,异步请求,消息队列消费请求。比较好用的是异步以后非常迅速,可以对程序的运行速度和并发有很大帮助
缺点是可能有消费不及时,如果是抢购之类的需要及时反馈的建议还是用同步

而且注意kafka消息如果磁盘满了,消息是进不去的.

kafka里的信息是自己定义的,应该设计成加密公钥的key和已加密的内容content,消费方有私钥解密.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值