系统设计:用 Go 构建一个简单的社交媒体平台

在本文中,我们将演练使用 go 设计一个简化的社交媒体平台,重点关注底层系统设计原则。我们的平台包括用户注册、创建帖子、处理点赞和评论以及通知用户更新等核心功能。此示例说明了如何将这些功能构建到模块化、可扩展且高效的系统中。

我们将使用 go 的并发能力和外观设计模式来创建精简且可维护的结构,使平台能够无缝处理各种用户交互。

我们设计的关键组成部分

我们正在构建的社交媒体平台侧重于以下主要功能:

  • 用户管理:注册和管理用户配置文件。
  • 帖子创建和互动:创建帖子、点赞和评论。
  • 通知:提醒用户相关操作,例如点赞和评论。
  • 并发:有效处理并发用户操作。

系统核心组件

让我们分解一下我们平台的关键组件,看看每个部分如何集成到系统中。

  1. 用户管理

usermanager 组件负责用户注册和配置文件管理。每个用户都有重要的个人资料详细信息,如 id、姓名和个人简介,管理员确保可以有效地添加和检索用户。一些关键功能是:

type user struct {
    type user struct {
    id             int
    name           string
    email          string
    password       string
    displaypicture *string
    bio            *string
    friends        map[int]*user
    posts          []*post
}

type usermanager struct {
    users map[int]*user
    mu    sync.rwmutex
}

func (um *usermanager) adduser(user *user) {
    um.mu.lock()
    defer um.mu.unlock()
    um.users[user.id] = user
    fmt.printf("user added: %d
", user.id)
}

func (um *usermanager) getuserbyid(userid int) (*user, error) {
    um.mu.rlock()
    defer um.mu.runlock()
    user, ok := um.users[userid]
    if !ok {
        return nil, fmt.errorf("user not found")
    }
    return user, nil
}

func (um *usermanager) addfriend(requesterid, receiverid int) error {
    requester, err := um.getuserbyid(requesterid)
    if err != nil {
        return err
    }

    receiver, err := um.getuserbyid(receiverid)
    if err != nil {
        return err
    }

    requester.addfriend(receiver)
    receiver.addfriend(requester)
    fmt.printf("friendship added between users: %d and %d
", requesterid, receiverid)
    return nil
}

在现实世界的应用程序中,usermanager 将连接到数据库,但为了简单起见,这里我们使用地图。

  1. 后期管理

postmanager 通过管理帖子、点赞和评论来处理用户生成的内容。该组件允许用户创建帖子、点赞其他人的帖子、评论和检索帖子。一些关键功能是:

type post struct {
    id              int
    userid          int
    content         string
    ispublished     bool
    urls            []*string
    likes           int
    comments        []*comment
    publishedat     time.time
    commentsenabled bool
    hiddenfromusers map[int]bool
}

type postmanager struct {
    posts map[int]*post
    mu    sync.rwmutex
}

func (pm *postmanager) getpost(postid int) (*post, error) {
    pm.mu.rlock()
    defer pm.mu.runlock()

    post, exists := pm.posts[postid]
    if !exists {
        return nil, fmt.errorf("post not found")
    }
    return post, nil
}

func (pm *postmanager) addpost(post *post, user *user) {
    pm.mu.lock()
    defer pm.mu.unlock()
    pm.posts[post.id] = post

    user.addpost(post)
}

func (pm *postmanager) likepost(postid int) (*post, error) {
    pm.mu.lock()
    post := pm.posts[postid]
    pm.mu.unlock()

    if post == nil {
        return nil, fmt.errorf("post not found")
    }

    pm.mu.lock()
    defer pm.mu.unlock()

    post.like()
    return post, nil
}

postmanager 可以与数据库交互来存储和检索帖子,从而允许按各种标准进行过滤。

  1. 通知管理

notificationmanager 负责让用户了解平台活动的最新情况,例如接收对其帖子的点赞或评论。每种通知类型(点赞、评论、好友请求)均通过此管理器发送,确保用户实时收到通知。一些关键功能是:

type notification struct {
    id      string
    type    notificationtype
    content string
    userid  int
}

type notificationmanager struct {
    notifications map[int][]*notification
    mu            sync.rwmutex
}

func (nm *notificationmanager) addnotification(userid int, notificationtype notificationtype, message string) {
    nm.mu.lock()
    defer nm.mu.unlock()

    notification := newnotification(fmt.sprintf("notification-%d", time.now().unixmicro()), notificationtype, message, userid)
    nm.notifications[userid] = append(nm.notifications[userid], notification)
}

func (nm *notificationmanager) getnotificationsforuser(userid int) ([]*notification, error) {
    nm.mu.rlock()
    defer nm.mu.runlock()

    notifications, ok := nm.notifications[userid]
    if !ok {
        return nil, fmt.errorf("user not found")
    }
    return notifications, nil
}

通过notificationmanager,我们可以通知用户与其帖子相关的交互,从而提供更具吸引力的体验。在生产系统中,可以通过通道或推送通知发送通知。


将外观模式与 activityfacade 结合使用

为了简化不同组件之间的交互,我们使用 facade 模式。 activityfacade结合了usermanager、postmanager和notificationmanager的功能,为我们的社交媒体应用程序提供了统一的界面。

type ActivityFacade struct {
    userManager       *UserManager
    postManager       *PostManager
    notificationManager *NotificationManager
}

func (af *ActivityFacade) SendFriendRequest(requesterID, receiverID int) error {
    _, err := af.UserManager.GetUserByID(receiverID)
    if err != nil {
        return err
    }

    af.NotificationManager.AddNotification(receiverID, FriendRequestNotificationType, fmt.Sprintf("%d has sent you a friend request", requesterID))

    fmt.Printf("Friend request sent to user %d
", receiverID)
    return nil
}

func (af *ActivityFacade) CommentPost(userID, postID int, content string) error {
    user, err := af.UserManager.GetUserByID(userID)
    if err != nil {
        return err
    }

    post, err := af.PostManager.CommentPost(user, postID, content)

    af.NotificationManager.AddNotification(post.UserID, CommentNotificationType, fmt.Sprintf("%d has commented on your post: %d", userID, post.ID))

    fmt.Printf("Comment added to post: %d
", post.ID)
    return nil
}

func (af *ActivityFacade) HidePostFromUser(postID int, userID int) error {
    _, err := af.UserManager.GetUserByID(userID)
    if err != nil {
        return err
    }

    return af.PostManager.HidePostFromUser(postID, userID)
}

通过 activityfacade,我们可以简化用户与平台的交互,降低直接管理每个子系统的复杂性。这种方法使代码更加模块化、可维护且更易于扩展。


处理并发

在任何社交媒体平台中,多个用户同时执行操作。 go 的并发工具,特别是sync的 rwmutex,非常适合以安全的方式处理并发读写。

使用 rwmutex,我们确保多个用户可以同时阅读帖子,但一次只有一个用户可以点赞或评论,从而防止竞争条件和数据损坏。


结论和后续步骤

我们针对 go 社交媒体平台的底层系统设计为扩展功能奠定了坚实的基础,使其可扩展且易于维护。

未来增强的潜在领域包括:

  • 使用 websocket 或推送通知的实时通知。
  • 针对好友请求和帖子的高级隐私控制。
  • 使用数据库的持久数据存储来替换内存中的映射。

完整的代码实现,请检查以下存储库:

系统设计:用 Go 构建一个简单的社交媒体平台 主题树 / 低级设计 golang

golang 中的底层系统设计解决方案

go 中的底层系统设计

欢迎来到go 中的低级系统设计 存储库!该存储库包含各种低级系统设计问题及其在 go 中实现的解决方案。主要目的是通过实际示例展示系统的设计和架构。

目录

  • 概述
  • 停车场系统
  • 电梯系统
  • 图书馆管理系统
  • 自动售货机系统
  • 社交媒体平台

概述

底层系统设计涉及理解系统架构的核心概念以及设计可扩展、可维护和高效的系统。该存储库将尝试涵盖使用 go 的各种问题和场景的解决方案。

停车场系统

此存储库中的第一个项目是停车场系统。该系统模拟一个可以停放车辆和出库车辆的停车场。它演示了:

  • 用于管理停车场实例的单例设计模式。
  • 处理不同类型的车辆(例如汽车、卡车)。
  • 多个楼层的停车位管理。
  • 付款处理...


github 上查看

以上就是系统设计:用 Go 构建一个简单的社交媒体平台的详细内容,更多请关注其它相关文章!