Skip to content

Commit

Permalink
Merge branch 'backend-dev' of github.com:yiyj13/A08_V-Helper into bac…
Browse files Browse the repository at this point in the history
…kend-dev
  • Loading branch information
tzh21 committed Dec 27, 2023
2 parents 69b0b44 + c31f7b2 commit 83912f3
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 65 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ deploy_versions/
node_modules/
.DS_Store
.swc
.vscode/
.vscode/
*.pyc
174 changes: 159 additions & 15 deletions go-backend/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
- [x] 收藏帖子和疫苗
- [x] 解耦 接种记录 和 接种预约
- [x] 根据疫苗筛选帖子
- [ ] 消息提醒的发送 (https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html)
- [x] 消息提醒的发送 (https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html)
- [x] 图床
- [x] github action
- [ ] token验证
- [x] token验证
- [ ] 加密
- [ ] 代码规范(配置文件),详细注释
- [x] 数据库时区更改
- [ ] 单元测试
- [ ] 性能测试
- [x] 性能测试
- [x] 路由拦截和重定向,部署时只暴露api接口


Expand Down Expand Up @@ -179,6 +179,31 @@ Post 时的json样例:
}
```

## 消息

| 方法 | 路由 | 功能 |
| ---- | ---- | ---- |
| POST | /api/messages | 添加消息 |
| GET | /api/messages | 获取全部消息 |
| GET | /api/messages/:id | 获取指定 id 的消息 |
| PUT | /api/messages/:id | 更新指定 id 的消息 |
| DELETE |/api/messages/:id | 删除指定 id 的消息 |

Post 时的json样例:
```json
{
"openId": "1234567890",
"page": "pages/welcome/welcome",
"vaxName": "新冠疫苗",
"comment": "您的接种时间已到",
"vaxLocation": "本地社区医院",
"vaxNum": 1,
"realTime": true,
"sendTime": "2021-07-01 12:00",
"sent": false
}
```

# 模型设计

通过以下数据表来支持后端的功能:
Expand Down Expand Up @@ -311,22 +336,40 @@ type Reply struct {
// Message 消息模型
type Message struct {
gorm.Model
Content string `json:"content"` // 消息内容,将不同字段拼接成字符串
UserName string `json:"userName"`
UserID uint `json:"userId"`
SendTime string `json:"sendTime"` // 发送时间,注意用string与前端交互,例如"2021-07-01 12:00"
OpenID string `json:"openId"`
Page string `json:"page"` // 消息跳转页面,例如"pages/welcome/welcome"
VaxName string `json:"vaxName"`
Comment string `json:"comment"`
VaxLocation string `json:"vaxLocation"`
VaxNum int `json:"vaxNum"`
RealTime bool `json:"realTime"` // 是否实时提醒
SendTime string `json:"sendTime"` // 如果不是实时提醒,则需要设置提醒时间,用字符串存具体时间,例如"2021-07-01 12:00"
Sent bool `json:"sent"` // 是否已发送
}
```

**接种地点表 (VaccinationLocations)**:
9. **接种地点表 (VaccinationLocations)**:

- Name
- Address
- ContactNumber
- OperatingHours
- PositionX
- PositionY
- OptionalVaccine
```go
// 持有某种疫苗的所有诊所
type VaccineClinicList struct {
gorm.Model
VaccineName string `json:"vaccineName"`
ClinicList string `json:"clinicList"`
// ClinicName StringList `json:"clinicName"`
}

// 诊所信息
type Clinic struct {
gorm.Model
ClinicName string `json:"clinicName"`
VaccineList string `json:"vaccineList"`
Latitude string `json:"latitude"`
Longitude string `json:"longitude"`
PhoneNumber string `json:"phoneNumber"`
Address string `json:"address"`
}
```

## 项目优化

Expand Down Expand Up @@ -392,6 +435,51 @@ type Message struct {
- 精心设计数据库模型和关联,以优化性能和简化数据访问逻辑。
- 使用迁移来管理数据库结构的更改。

## 性能测试报告

### 测试概述

**测试工具**: 使用Locust 2.20.0进行了性能测试。

**测试目的**: 评估Web应用在并发用户负载下的性能表现。

**测试场景**:
- 测试了六个不同的API端点。
- 总共模拟了200个并发用户。
- 用户生成速率为每秒10个用户。

### 测试结果

**请求统计**:

| 类型 | 路径 | 请求数 | 失败率 | 平均响应时间 (ms) | 最小响应时间 (ms) | 最大响应时间 (ms) | 请求/秒 |
|------|-----------------------------|---------|--------|-------------------|-------------------|-------------------|---------|
| GET | / | 959 | 0.00% | 40 | 9 | 895 | 3.26 |
| GET | /api/profiles | 1915 | 0.00% | 78 | 9 | 3606 | 6.51 |
| GET | /api/temperature-records | 3906 | 0.00% | 41 | 8 | 3349 | 13.28 |
| GET | /api/users | 1945 | 0.00% | 60 | 10 | 1818 | 6.61 |
| GET | /api/vaccination-records | 3888 | 0.00% | 709 | 22 | 16251 | 13.22 |
| GET | /api/vaccines | 3905 | 0.00% | 1127 | 21 | 18216 | 13.28 |

**响应时间分位数**:

不同的API端点在不同的响应时间分位数上表现出了差异。特别是`/api/vaccination-records``/api/vaccines`在更高的分位数上显示了较长的响应时间,这可能表明在高负载下这些端点的性能表现下降。

### 性能分析

- **吞吐量**: 所有API端点总体上保持了较高的请求处理率。
- **响应时间**: 大多数API端点的响应时间较短,但`/api/vaccination-records``/api/vaccines`的响应时间较长,特别是在95%以上的分位数,表明在高负载下可能存在性能瓶颈。
- **可靠性**: 在测试过程中没有发现失败的请求,这说明服务在测试负载下保持了较高的可靠性。

### 后续

- **性能优化**: 对于响应时间较长的API端点,建议进行更深入的性能分析,以识别和解决可能的瓶颈。
- **资源监控**: 在进行性能测试时监控服务器资源使用情况,如CPU、内存和网络使用情况,以帮助识别性能瓶颈。
- **扩展性评估**: 考虑进行更高负载的测试,以评估服务在极端条件下的表现和扩展需求。

### 总结

总体而言,测试显示了应用在处理中等负载下的良好性能。然而,某些API端点在高分位数的响应时间表明可能存在性能优化的空间。

## 遇到的问题

Expand Down Expand Up @@ -486,3 +574,59 @@ JWT 主要包含三个部分,用点(`.`)分隔:
- **短期有效性**: 为 JWT 设置合理的过期时间,以减少被盗用的风险。

通过使用 JWT,我们可以实现无状态的身份验证,这意味着服务器不需要存储任何用户的登录信息,从而使应用更加易于扩展。同时,它也为客户端和服务器之间的通信提供了一种安全可靠的方式来验证和传输用户身份信息。


## 消息通知

设计一个优雅的系统来处理定时消息发送功能涉及多个方面:数据库设计、消息调度逻辑、错误处理、性能优化等。以下是一个设计方案及其相关思路:

### 1. **系统目标**
- 实现一个可靠的消息调度系统,能够在预定时间发送消息。
- 确保系统可扩展性和高效性能。
- 提供稳健的错误处理和日志记录。

### 2. **数据库设计**
- `messages` 表用于存储消息信息。
- 字段包括:`id`, `open_id`, `page`, `vax_name`, `comment`, `vax_location`, `vax_num`, `real_time`, `send_time`, `sent`, `created_at`, `updated_at`.
- `send_time` 用于确定消息发送时间。
- `sent` 标记消息是否已发送。

### 3. **消息调度逻辑**
- 实现一个消息调度器,定期从数据库中检索未发送的消息,并按`send_time`排序。
- 对于每个未发送的消息,计算当前时间与`send_time`的差值,若到达或超过发送时间,则触发发送逻辑。

### 4. **消息发送机制**
- 消息发送逻辑封装在`SendTemplateMessage`函数中,利用微信小程序的模板消息接口实现。
- 发送成功后,更新数据库中对应消息的`sent`状态为`true`

### 5. **错误处理和日志记录**
- 在消息发送过程中,任何错误都应被捕获并记录。
- 提供详细的日志记录,包括消息发送时间、状态和任何失败的原因。

#### 6. **性能考虑**
- 消息调度器应避免创建过多goroutine,以减少资源消耗。
- 数据库查询应优化,避免过大的数据加载和频繁查询。

### 7. **安全和隐私**
- 确保处理用户数据时遵循隐私法规。
- 敏感信息(如用户OpenID)应被适当保护。

```mermaid
graph TD
A[启动消息调度器] --> B[定期从数据库中检索消息]
B --> C{检查消息是否未发送<br>和发送时间是否到达}
C -->|是| D[触发消息发送逻辑]
C -->|否| E[等待下一次检索]
D --> F{发送消息<br>使用SendTemplateMessage}
F -->|成功| G[更新数据库<br>标记为已发送]
F -->|失败| H[记录错误<br>保持消息未发送状态]
style A fill:#f9f,stroke:#333,stroke-width:4px
style B fill:#bbf,stroke:#f66,stroke-width:2px
style C fill:#ddf,stroke:#333,stroke-width:2px
style D fill:#bdf,stroke:#333,stroke-width:2px
style E fill:#bdf,stroke:#333,stroke-width:2px
style F fill:#daf,stroke:#333,stroke-width:2px
style G fill:#bdf,stroke:#333,stroke-width:2px
style H fill:#fbb,stroke:#333,stroke-width:2px
```
8 changes: 8 additions & 0 deletions go-backend/cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"time"
"v-helper/internal/handler"
"v-helper/pkg/db"

Expand All @@ -10,6 +11,13 @@ import (
)

func main() {
// 设置时区为中国时区
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
panic(err)
}
time.Local = loc

cfg := config.LoadConfig()
database := db.Init(cfg)

Expand Down
Loading

0 comments on commit 83912f3

Please sign in to comment.