一、点赞功能概述
点赞功能在几乎所有的涉及社交、电商等的项目中都是必不可少的功能,为了方便我们在不同的项目的不同业务中对点赞功能进行集成,应当尽量让点赞功能的实现与其他的模块解耦,这样在后续我们需要使用时,只需要将这个设计好的微服务模块放入到项目中使用即可,也就是要具备可迁移性,除此之外,一个通用的点赞功能还应当具备良好的处理高并发读写请求的能力。
实现点赞功能,储存点赞数据,我们首先可以考虑使用MYSQL进行实现。
二、MYSQL+MQ实现点赞功能
要实现完整可用的点赞功能,比如同一条信息用户不能重复点赞,或者是每条数据按照点赞数降序排序等功能,我们需要对两部分数据进行存储以便后续使用,一部分存储到用户点赞记录表中,表中存储好每一条点赞记录,每当用户点赞成功就存储一条数据到该表中,当用户取消了点赞就将该条记录从表中删除,以便后续判断当前用户是否对某条业务数据进行过点赞操作,为了实现这一功能,防止某个用户对同一条业务数据重复点赞,表中应当包含用户id、业务数据id、业务类型等字段,通过这几个字段我们就可以通过该表中的每一条数据判断出“谁”对“什么”进行过了点赞的操作;另一部分存储点赞数表,也就是对应的每条业务数据的总点赞数如何,方便前端对页面信息进行渲染展示,而点赞数是与业务数据进行关联的,因此我们可以选择为需要添加点赞功能的业务数据中添加一个点赞数的字段,所有涉及点赞数的业务只需要对该字段进行操作即可,也就是说,点赞数是由具体的业务方保存,当这一字段需要变化时,我们需要通知业务方对总点赞数进行更新,由于点赞功能使用广泛,涉及到的业务方的类型很多 ,我们选可以选取使用MQ低耦合的实现通知功能,提前在各个微服务中设置好监听器,每当点赞或取消点赞后,点赞数发生变化,我们就发送MQ通知到交换机上,交换机会根据需求将消息转发到对应的队列中供不同的微服务消费消息,更新数据。
整体业务流程如图:
由于用户点赞的每条记录都存储在点赞微服务中,因此点赞微服务还需要对外暴露出一个Feign的接口,供其他微服务调用,以判断某用户是否对某条业务数据已经进行过点赞操作,用户id我们可以从ThreadLocal中获取,因此只需要设置参数需要查询的业务数据的id,接收到后到用户点赞表中进行查询即可。
三、使用Redis进行优化
上述的操作已经基本上可以借助MYSQL和MQ实现我们需要的点赞功能,但是使用MYSQL的局限也很明显,那就是MYSQL对于高并发的处理能力很难满足点赞功能的需求,更不要说在上述的实现过程中,一次点赞业务包含多次数据库读写操作 ,在加上点赞业务可能会在短时间内访问量激增,此时数据库的压力就会非常大。
点赞业务既有高并发读操作,也有高并发写操作,我们可以分别对这两部分操作进行优化。对于并发读的优化,既然我们选用的是MYSQL,那么我们首先需要考虑的就是对SQL的优化,除此之外,我们还可以通过添加缓存的方式,减少对数据库的查询,也能很好的改善系统在高并发环境下的性能,要添加缓存,我们首选的就是使用Redis。而处理并发写请求时,我们除了优化SQL外还可以考虑将同步写改为异步写,以及将多次写请求合并到一起进行提交等操作,上述这两种优化操作的基础是用户对于点赞功能的准确性要求并不像其他业务那么高,点赞数据的延迟刷新对于用户来说完全是可以接受的。
结合上面两部分优化思路,最终我们的点赞业务流程变成了这样:
要在Redis中缓存用户的点赞数据,我们可以使用Set这种数据结构进行存储,我们可以选择使用业务数据id作为key,以用户id作为value,这样就可以记录下每一条业务数据都被哪些用户点过赞,同时因为Set中的数据不允许重复,当同一个用户向同一个业务中插入第二条数据时就会插入失败,这也满足了我们的业务需求。
而对点赞数量的缓存,我们可以考虑从Hash和ZSet中挑选,主要是根据是否存在根据点赞数进行排序的业务进行选择,如果没有可以选用占用存储空间小一些的Hash进行存储,如果有就可以考虑使用ZSet,将点赞数存储到其score字段中,这样ZSet就会根据点赞数自动进行排序,非常的方便。
四、总结
我们最终选择的点赞方案是,当有点赞数据需要存储时,直接使用Redis缓存进行记录,不再使用MYSQL对这部分数据进行存储;而点赞数的信息因为与业务数据关联,仍然需要使用到MYSQL,在数据变动时先修改Redis中的数据,最终再编写一个定时任务,每隔一段时间发送消息到MQ中,将最新的点赞数从Redis缓存同步到数据库中,就可以实现我们所需的点赞功能。
标签:功能,中点,解决方案,MYSQL,业务,用户,点赞,数据 From: https://blog.csdn.net/m0_61811956/article/details/144972893