社交项目实战第四天(朋友圈功能实现)

本文详细介绍了社交项目实战中朋友圈功能的实现过程,包括抽取common工程、圈子功能的设计与实现、好友关系数据、查询好友动态的接口服务、统一校验token机制、发布动态的dubbo服务和APP接口,以及查询推荐动态的逻辑。涉及到的技术包括数据库、Java、MySQL、Spring和大数据。
摘要由CSDN通过智能技术生成

1、抽取common工程

在项目中一般需要将公用的对象进行抽取放到common工程中,其他的工程依赖此工程即可。下面我们将sso以及server工程中的公用的对象进行抽取。

1.1、创建my-yile-common工程


    <parent>
        <artifactId>my-yile</artifactId>
        <groupId>cn.itcast.yile</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>my-yile-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
    </dependencies>

</project>

1.2、通用枚举

将SexEnum枚举移动至common工程,并且后续创建的枚举也要放到此工程中,以达到公用的目的。
SexEnum(性别枚举)

需要修改server与sso工程中的application.properties配置:

# 枚举包扫描
mybatis-plus.type-enums-package=com.yile.common.enums

将server与sso工程中的SexEnum对象删除以及将相关的类引用进行修改。

1.3、抽取mapper

需要将UserInfoMapper以及UserMapper放置到common工程的com.yile.common.mapper包下。

说明:抽取完成后,需要将原工程的代码删除以及修改其他代码中引入的依赖。

1.4、抽取pojo

将BasePojo、User、UserInfo移动至common工程:

1.5、抽取utils

将server工程的utils进行抽取公用,后续的工具类也放置到common工程中。

抽取完成后进行测试,确保可以正常启动以及功能都正常。

2、圈子功能

2.1、功能说明

探花交友项目中的圈子功能,类似微信的朋友圈,基本的功能为:发布动态、浏览好友动态、浏览推荐动态、点赞、评论、喜欢等功能。

2.2、实现方案分析

对于圈子功能的实现,我们需要对它的功能特点做分析:

  • 数据量会随着用户数增大而增大
  • 读多写少,一般而言,浏览朋友圈动态会多一些,发动态相对就会少一些
  • 非好友看不到其动态内容
  • ……

针对以上特点,我们来分析一下:

  • 对于数据量大而言,显然不能够使用关系型数据库进行存储,我们需要通过MongoDB进行存储
  • 对于读多写少的应用,尽可能的减少读取数据的成本
    • 比如说,一条SQL语句,单张表查询一定比多张表查询要快
    • 条件越多的查询速度将越慢,尽可能的减少条件以提升查询速度

所以对于存储而言,主要是核心的4张表:

  • 发布表:记录了所有用户的发布的东西信息,如图片、视频等。
  • 相册:相册是每个用户独立的,记录了该用户所发布的所有内容。
  • 评论:针对某个具体发布的朋友评论和点赞操作。
  • 时间线:所谓“刷朋友圈”,就是刷时间线,就是一个用户所有的朋友的发布内容。

流程:

在这里插入图片描述

流程说明:

  • 用户发布动态,动态中一般包含了图片和文字,图片上传到阿里云,上传成功后拿到图片地址,将文字和图片地址进行持久化存储
  • 首先,需要将动态数据写入到发布表中,其次,再写入到自己的相册表中,需要注意的是,相册表中只包含了发布id,不会冗余存储发布数据
  • 最后,需要将发布数据异步的写入到好友的时间线表中,之所以考虑异步操作,是因为希望发布能够尽快给用户反馈,发布成功
  • 好友刷朋友圈时,实际上只需要查询自己的时间线表即可,这样最大限度的提升了查询速度,再配合redis的缓存,那速度将是飞快的
  • 用户在对动态内容进行点赞、喜欢、评论操作时,只需要写入到评论表即可,该表中也是只会记录发布id,并不会冗余存储发布数据

2.3、表结构设计

发布表:

#表名:quanzi_publish
{
   
    "_id":"5fae53d17e52992e78a3db61",#主键id
    "pid":1001, #发布id(Long类型)
    "userId":1, #用户id
    "text":"今天心情很好", #文本内容
    "medias":"http://xxxx/x/y/z.jpg", #媒体数据,图片或小视频 url
    "seeType":1, #谁可以看,1-公开,2-私密,3-部分可见,4-不给谁看
    "seeList":[1,2,3], #部分可见的列表
    "notSeeList":[4,5,6],#不给谁看的列表
	"longitude":108.840974298098,#经度
	"latitude":34.2789316522934,#纬度
    "locationName":"上海市浦东区", #位置名称
    "created",1568012791171 #发布时间
}

相册表:

#表名:quanzi_album_{
   userId}
{
   
    "_id":"5fae539d7e52992e78a3b684",#主键id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "created":1568012791171 #发布时间
}

时间线表:

#表名:quanzi_time_line_{
   userId}
{
   
    "_id":"5fae539b7e52992e78a3b4ae",#主键id,
    "userId":2, #好友id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "date":1568012791171 #发布时间
}

评论表:

#表名:quanzi_comment
{
   
    "_id":"5fae539d7e52992e78a3b648", #主键id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "commentType":1, #评论类型,1-点赞,2-评论,3-喜欢
    "content":"给力!", #评论内容
    "userId":2, #评论人
    "publishUserId":9, #发布动态的人的id
    "isParent":false, #是否为父节点,默认是否
    "parentId":1001, #父节点id
    "created":1568012791171
}

3、好友关系数据

由于圈子中会涉及的好友关系数据,虽然现在主线是开发圈子功能,但是也需要对于好友关系有所了解,在我们提供的Mongodb数据库中有一些mock数据。

好友关系结构:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "yile_users")
public class Users implements java.io.Serializable{
   

    private static final long serialVersionUID = 6003135946820874230L;

    private ObjectId id;
    private Long userId; //用户id
    private Long friendId; //好友id
    private Long date; //时间

}

在mock数据中,为每个用户构造了10个好友数据:

4、查询好友动态

查询好友动态与查询推荐动态显示的结构是一样的,只是其查询数据源不同:

4.1、基础代码

在my-yile-dubbo-interface中编写:

/**
 * 发布表,动态内容
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_publish")
public class Publish implements java.io.Serializable {
   

    private static final long serialVersionUID = 8732308321082804771L;

    @Id
    private ObjectId id; //主键id
    private Long pid; //发布id
    private Long userId; //发布用户id
    private String text; //文字
    private List<String> medias; //媒体数据,图片或小视频 url
    private Integer seeType; // 谁可以看,1-公开,2-私密,3-部分可见,4-不给谁看
    private List<Long> seeList; //部分可见的列表
    private List<Long> notSeeList; //不给谁看的列表
    private String longitude; //经度
    private String latitude; //纬度
    private String locationName; //位置名称
    private Long created; //发布时间

}
/**
 * 相册表,用于存储自己发布的数据,每一个用户一张表进行存储
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_album_{userId}")
public class Album implements java.io.Serializable {
   

    private static final long serialVersionUID = 432183095092216817L;

    @Id
    private ObjectId id; //主键id

    private ObjectId publishId; //发布id
    private Long created; //发布时间

}
/**
 * 时间线表,用于存储发布的数据,每一个用户一张表进行存储
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_time_line_{userId}")
public class TimeLine implements java.io.Serializable {
   
    private static final long serialVersionUID = 9096178416317502524L;
    
    @Id
    private ObjectId id;
    private Long userId; // 好友id
    private ObjectId publishId; //发布id
    private Long date; //发布的时间

}


/**
 * 评论表
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_comment")
public class Comment implements java.io.Serializable{
   

    private static final long serialVersionUID = -291788258125767614L;

    @Id
    private ObjectId id;
    private ObjectId publishId; //发布id
    private Integer commentType; //评论类型,1-点赞,2-评论,3-喜欢
    private String content; //评论内容
    private Long userId; //评论人
    private Long publishUserId; //发布动态的用户id
    private Boolean isParent = false; //是否为父节点,默认是否
    private ObjectId parentId; // 父节点id
    private Long created; //发表时间

}

4.2、dubbo服务

圈子的具体业务逻辑的实现需要在dubbo中完成,所以需要开发dubbo服务。

4.2.1、定义接口

在my-yile-dubbo-interface工程中:


public interface QuanZiApi {
   

    /**
     * 查询好友动态
     *
     * @param userId 用户id
     * @param page 当前页数
     * @param pageSize 每一页查询的数据条数
     * @return
     */
    PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize);

}

4.2.2、实现接口

在my-yile-dubbo-service中完成:


@Service(version = "1.0.0")
public class QuanZiApiImpl implements QuanZiApi {
   

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {
   
        //分析:查询好友的动态,实际上查询时间线表
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);

        Pageable pageable = PageRequest.of(page - 1, pageSize,
                Sort.by(Sort.Order.desc("date")));

        Query query = new Query
  • 1
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
继“Java开发微信朋友圈PC版系统-架构1.0”之后,debug这段时间日撸夜撸,终于赶在春节放假前给诸位带来了这一系统的架构2.0版本,特此分享给诸位进行学习,以掌握、巩固更多的技术栈以及项目和产品开发经验,同时也为即将到来的金三银四跳槽季做准备! 言归正传,下面仍然以问答的方式介绍下本门课程的相关内容! (1)问题一:这是一门什么样的课程? 很明显,本门课程是建立在架构1.0,即 第1门课程 的基础上发布的,包含了架构1.0的内容,即它仍然是一门项目、产品实战课,基于Spring Boot2.X + 分布式中间件开发的一款类似“新浪微博”、“QQ空间”、“微信朋友圈”PC版的互联网社交软件,包含完整的门户网前端 以及 后台系统管理端,可以说是一套相当完整的系统! (2)问题二:架构2.0融入了哪些新技术以及各自有什么作用? 本课程对应着系统架构2.0,即第2阶段,主要目标:基于架构1.0,优化系统的整体性能,实现一个真正的互联网社交产品;其中,可以学习到的技术干货非常多,包括:系统架构设计、Spring Boot2.X、缓存Redis、多线程并发编程、消息中间件RabbitMQ、全文搜索引擎Elastic Search、前后端消息实时通知WebSocket、分布式任务调度中间件Elastic Job、Http Restful编程、Http通信OKHttp3、分布式全局唯一ID、雪花算法SnowFlake、注册中心ZooKeeper、Shiro+Redis 集群Session共享、敏感词自动过滤、Java8 等等; A.  基于Elastic Search实现首页列表数据的初始化加载、首页全文检索;B.  基于缓存Redis缓存首页朋友圈“是否已点赞、收藏、关注、评论、转发”等统计数据;整合Shiro实现集群部署模式下Session共享;C.  多线程并发编程并发处理系统产生的废弃图片、文件数据;D.  基于Elastic Job切片作业调度分布式多线程清理系统产生的废弃图片;E.  基于RabbitMQ解耦同步调用的服务模块,实现服务模块之间异步通信;F.  基于WebSocket实现系统后端 与 首页前端 当前登录用户实时消息通知;G.  基于OKHttp3、Restful风格的Rest API实现ES文档、分词数据存储与检索;H.  分布式全局唯一ID 雪花算法SnowFlake实现朋友圈图片的唯一命名;I.  ZooKeeper充当Elastic Job创建的系统作业的注册中心;J.  为塑造一个健康的网络环境,对用户发的朋友圈、评论、回复内容进行敏感词过滤;K.  大量优雅的Java8  Lambda编程、Stream编程;  (3)问题三:系统运行起来有效果图看吗?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值