perf: 提升后端高并发承载能力

This commit is contained in:
2026-06-15 15:33:49 +08:00
parent 63c954da55
commit 8715c7bb3d
12 changed files with 600 additions and 151 deletions

View File

@@ -29,8 +29,8 @@ func AdminLogin(c *gin.Context) {
return
}
var user model.User
if err := db.DB.Where("username = ?", strings.TrimSpace(req.Username)).First(&user).Error; err != nil {
user, err := db.LoadUserByUsername(strings.TrimSpace(req.Username))
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
@@ -191,7 +191,7 @@ func UpdateUserRole(c *gin.Context) {
return
}
if err := db.DB.Model(&model.User{}).Where("id = ?", userID).Update("role", role).Error; err != nil {
if err := db.UpdateUserRole(userID, role); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update role"})
return
}
@@ -218,7 +218,7 @@ func UpdateUserEnabled(c *gin.Context) {
return
}
if err := db.DB.Model(&model.User{}).Where("id = ?", userID).Update("enabled", req.Enabled).Error; err != nil {
if err := db.UpdateUserEnabled(userID, req.Enabled); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update enabled status"})
return
}
@@ -251,7 +251,7 @@ func ResetUserPassword(c *gin.Context) {
return
}
if err := db.DB.Model(&model.User{}).Where("id = ?", userID).Update("password", hash).Error; err != nil {
if err := db.UpdateUserPassword(userID, hash); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to reset password"})
return
}
@@ -274,11 +274,7 @@ func DeleteUser(c *gin.Context) {
return
}
if err := db.DB.Where("user_id = ?", userID).Delete(&model.Room{}).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete rooms"})
return
}
if err := db.DB.Delete(&model.User{}, userID).Error; err != nil {
if err := db.DeleteUserCascade(userID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete user"})
return
}

View File

@@ -1,11 +1,13 @@
package api
import (
"errors"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"hightube/internal/db"
"hightube/internal/model"
@@ -41,10 +43,12 @@ func Register(c *gin.Context) {
}
// Check if user exists
var existingUser model.User
if err := db.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil {
if _, err := db.LoadUserByUsername(req.Username); err == nil {
c.JSON(http.StatusConflict, gin.H{"error": "Username already exists"})
return
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to validate username"})
return
}
// Hash password
@@ -61,20 +65,13 @@ func Register(c *gin.Context) {
Role: "user",
Enabled: true,
}
if err := db.DB.Create(&user).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
return
}
// Create a default live room for the new user
room := model.Room{
UserID: user.ID,
Title: user.Username + "'s Live Room",
StreamKey: utils.GenerateStreamKey(),
IsActive: false,
}
if err := db.DB.Create(&room).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create room for user"})
if err := db.CreateUserAndRoom(&user, &room); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
return
}
@@ -87,9 +84,10 @@ func Login(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
req.Username = strings.TrimSpace(req.Username)
var user model.User
if err := db.DB.Where("username = ?", req.Username).First(&user).Error; err != nil {
user, err := db.LoadUserByUsername(req.Username)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
@@ -127,8 +125,8 @@ func ChangePassword(c *gin.Context) {
return
}
var user model.User
if err := db.DB.First(&user, userID).Error; err != nil {
user, err := db.LoadUserByID(userID.(uint))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
@@ -147,7 +145,7 @@ func ChangePassword(c *gin.Context) {
}
// Update user
if err := db.DB.Model(&user).Update("password", hashedPassword).Error; err != nil {
if err := db.UpdateUserPassword(user.ID, hashedPassword); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update password"})
return
}

View File

@@ -12,6 +12,8 @@ import (
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true // Allow all connections
},

View File

@@ -89,8 +89,8 @@ func authenticateRequest(c *gin.Context) (*model.User, error) {
return nil, errInvalidToken
}
var user model.User
if err := db.DB.First(&user, uint(userID)).Error; err != nil {
user, err := db.LoadUserByID(uint(userID))
if err != nil {
return nil, errUserNotFound
}

View File

@@ -6,15 +6,14 @@ import (
"github.com/gin-gonic/gin"
"hightube/internal/db"
"hightube/internal/model"
)
// GetMyRoom returns the room details for the currently authenticated user
func GetMyRoom(c *gin.Context) {
userID, _ := c.Get("user_id")
var room model.Room
if err := db.DB.Where("user_id = ?", userID).First(&room).Error; err != nil {
room, err := db.LoadRoomByUserID(userID.(uint))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Room not found"})
return
}
@@ -29,9 +28,8 @@ func GetMyRoom(c *gin.Context) {
// GetActiveRooms returns a list of all currently active live rooms
func GetActiveRooms(c *gin.Context) {
var rooms []model.Room
// Fetch rooms where is_active is true
if err := db.DB.Where("is_active = ?", true).Find(&rooms).Error; err != nil {
rooms, err := db.ListActiveRooms()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch active rooms"})
return
}

View File

@@ -11,7 +11,8 @@ func SetupRouter(streamServer *stream.RTMPServer) *gin.Engine {
// 设置为发布模式,消除 "[WARNING] Running in debug mode" 警告
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
r := gin.New()
r.Use(gin.Recovery())
BindAdminDependencies(streamServer)
// Use CORS middleware to allow web access