423 lines
8.9 KiB
Markdown
423 lines
8.9 KiB
Markdown
# Sender 消息通知微服务
|
||
|
||
|
||
一个基于 Go 语言开发的高性能消息通知微服务,提供短信、邮件发送和验证码管理功能。采用 gRPC + HTTP Gateway 架构,支持多种服务商集成。
|
||
|
||
## ✨ 功能特性
|
||
|
||
### 📱 短信服务
|
||
- **多服务商支持**:阿里云短信、腾讯云短信
|
||
- **模板管理**:支持短信模板和参数替换
|
||
- **发送限制**:基于手机号的日发送量限制
|
||
- **黑名单过滤**:支持手机号黑名单机制
|
||
- **验证码生成**:自动生成和验证短信验证码
|
||
|
||
### 📧 邮件服务
|
||
- **SMTP支持**:支持标准SMTP协议发送邮件
|
||
- **模板引擎**:基于Go template的邮件模板系统
|
||
- **多服务商**:支持QQ邮箱、Gmail等主流邮箱服务
|
||
- **TLS加密**:支持TLS/SSL安全连接
|
||
|
||
### 🔐 验证码管理
|
||
- **自动生成**:支持4-10位数字验证码
|
||
- **Redis缓存**:验证码存储和过期管理
|
||
- **限流控制**:防止验证码频繁发送
|
||
- **验证接口**:提供验证码校验功能
|
||
|
||
### 🏗️ 微服务架构
|
||
- **gRPC服务**:高性能RPC通信
|
||
- **HTTP Gateway**:RESTful API支持
|
||
- **服务发现**:基于Etcd的服务注册发现
|
||
- **健康检查**:完整的健康检查机制
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 环境要求
|
||
|
||
- Go 1.26.5
|
||
- Redis 6.0+
|
||
- PostgreSQL 12+
|
||
- Etcd 3.5+
|
||
|
||
### 安装依赖
|
||
|
||
```bash
|
||
# 克隆项目
|
||
git clone git.apinb.com/bsm-apps/sender.git
|
||
cd sender
|
||
|
||
# 下载依赖
|
||
make deps
|
||
```
|
||
|
||
### 配置服务
|
||
|
||
1. **复制配置文件**:
|
||
```bash
|
||
cp etc/sender_dev.yaml etc/sender_local.yaml
|
||
```
|
||
|
||
2. **修改配置**:
|
||
```yaml
|
||
# etc/sender_local.yaml
|
||
Service:
|
||
Name: sender
|
||
Port: "12201"
|
||
BindIP: "0.0.0.0"
|
||
|
||
# 数据库配置
|
||
Databases:
|
||
Default:
|
||
Driver: postgres
|
||
Host: localhost
|
||
Port: 5432
|
||
Database: sender_db
|
||
Username: postgres
|
||
Password: your_password
|
||
|
||
# Redis配置
|
||
Cache:
|
||
Redis:
|
||
Host: localhost
|
||
Port: 6379
|
||
Password: your_redis_password
|
||
Database: 0
|
||
|
||
# 短信服务配置
|
||
SMS:
|
||
aliyun:
|
||
Endpoint: "dysmsapi.aliyuncs.com"
|
||
AccessKeyId: "your_access_key_id"
|
||
AccessKeySecret: "your_access_key_secret"
|
||
Region: "cn-hangzhou"
|
||
|
||
# 邮件服务配置
|
||
SMTP:
|
||
qq:
|
||
Endpoint: "smtp.qq.com"
|
||
Port: 587
|
||
Username: "your_email@qq.com"
|
||
Password: "your_smtp_password"
|
||
FromAddress: "your_email@qq.com"
|
||
FromName: "系统通知"
|
||
```
|
||
|
||
### 运行服务
|
||
|
||
#### 方式一:直接运行
|
||
```bash
|
||
# 开发模式
|
||
make dev
|
||
|
||
# 生产模式
|
||
make build
|
||
make run
|
||
```
|
||
|
||
#### 方式二:Docker运行
|
||
```bash
|
||
# 构建镜像
|
||
make docker-build
|
||
|
||
# 使用docker-compose启动完整环境
|
||
make docker-compose-up
|
||
```
|
||
|
||
## 📖 API文档
|
||
|
||
### gRPC接口
|
||
|
||
#### 短信服务
|
||
```protobuf
|
||
service Sms {
|
||
rpc Send(SmsSendRequest) returns (SmsReply);
|
||
rpc Verify(SmsVerifyRequest) returns (SmsReply);
|
||
}
|
||
```
|
||
|
||
#### 邮件服务
|
||
```protobuf
|
||
service Mail {
|
||
rpc Send(SendMailRequest) returns (SendMailReply);
|
||
}
|
||
```
|
||
|
||
### HTTP接口
|
||
|
||
服务启动后,可通过以下地址访问:
|
||
|
||
- **gRPC服务**:`localhost:12201`
|
||
- **HTTP Gateway**:`localhost:12202`
|
||
- **Swagger文档**:`http://localhost:12202/swagger/`
|
||
|
||
#### 发送短信示例
|
||
```bash
|
||
curl -X POST "http://localhost:12202/v1/sms/send" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"provider": "aliyun",
|
||
"sign_name": "您的签名",
|
||
"template_code": "SMS_123456789",
|
||
"phone": "13800138000",
|
||
"paramters": {
|
||
"code": "123456"
|
||
}
|
||
}'
|
||
```
|
||
|
||
#### 发送邮件示例
|
||
```bash
|
||
curl -X POST "http://localhost:12202/v1/mail/send" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"provider": "qq",
|
||
"template_key": "welcome",
|
||
"to": "user@example.com",
|
||
"paramters": {
|
||
"username": "张三",
|
||
"verification_code": "123456"
|
||
}
|
||
}'
|
||
```
|
||
|
||
## 🛠️ 开发指南
|
||
|
||
### 项目结构
|
||
|
||
```
|
||
sender/
|
||
├── cmd/ # 应用程序入口
|
||
│ ├── main/ # 主服务入口
|
||
│ └── cli/ # 命令行工具
|
||
├── internal/ # 内部包
|
||
│ ├── config/ # 配置管理
|
||
│ ├── excode/ # 错误码定义
|
||
│ ├── impl/ # 依赖实现
|
||
│ ├── logic/ # 业务逻辑
|
||
│ │ ├── mail/ # 邮件服务
|
||
│ │ └── sms/ # 短信服务
|
||
│ ├── models/ # 数据模型
|
||
│ └── server/ # 服务器实现
|
||
├── pb/ # protobuf生成代码
|
||
├── proto/ # protobuf定义文件
|
||
├── etc/ # 配置文件
|
||
├── test/ # 测试文件
|
||
├── scripts/ # 脚本文件
|
||
└── swagger/ # API文档
|
||
```
|
||
|
||
### 开发命令
|
||
|
||
```bash
|
||
# 查看所有可用命令
|
||
make help
|
||
|
||
# 生成protobuf代码
|
||
make proto
|
||
|
||
# 运行测试
|
||
make test
|
||
|
||
# 代码检查
|
||
make lint
|
||
|
||
# 格式化代码
|
||
make fmt
|
||
|
||
# 构建所有平台版本
|
||
make build-all
|
||
|
||
# 运行完整构建流程
|
||
make all
|
||
```
|
||
|
||
### 添加新的短信服务商
|
||
|
||
1. **在配置中添加服务商配置**:
|
||
```yaml
|
||
SMS:
|
||
new_provider:
|
||
Endpoint: "api.newprovider.com"
|
||
AccessKeyId: "your_key"
|
||
AccessKeySecret: "your_secret"
|
||
Region: "us-east-1"
|
||
```
|
||
|
||
2. **在 `internal/logic/sms/send.go` 中添加处理逻辑**:
|
||
```go
|
||
case "new_provider":
|
||
if impl.Provider.NewProvider == nil {
|
||
return nil, excode.ErrProviderIsNil
|
||
}
|
||
result, err = NewProviderSender(in, smsCode)
|
||
```
|
||
|
||
3. **实现具体的发送函数**:
|
||
```go
|
||
func NewProviderSender(args *pb.SmsSendRequest, code string) (map[string]any, error) {
|
||
// 实现新服务商的发送逻辑
|
||
}
|
||
```
|
||
|
||
### 添加新的邮件服务商
|
||
|
||
1. **在配置中添加SMTP配置**:
|
||
```yaml
|
||
SMTP:
|
||
gmail:
|
||
Endpoint: "smtp.gmail.com"
|
||
Port: 587
|
||
Username: "your_email@gmail.com"
|
||
Password: "your_app_password"
|
||
FromAddress: "your_email@gmail.com"
|
||
FromName: "系统通知"
|
||
```
|
||
|
||
2. **在 `internal/logic/mail/send.go` 中添加处理逻辑**:
|
||
```go
|
||
case "gmail":
|
||
err = GmailSender(cfg, tmpl, in.GetTo(), tplRecord.Subjet, in.GetParamters())
|
||
```
|
||
|
||
3. **实现具体的发送函数**:
|
||
```go
|
||
func GmailSender(cfg *config.SmtpConf, tmpl *template.Template, to string, subject string, args map[string]string) error {
|
||
// 实现Gmail的发送逻辑
|
||
}
|
||
```
|
||
|
||
## 🧪 测试
|
||
|
||
### 运行测试
|
||
|
||
```bash
|
||
# 运行所有测试
|
||
make test
|
||
|
||
# 运行邮件测试
|
||
make test-mail
|
||
|
||
# 运行短信测试
|
||
make test-sms
|
||
|
||
# 生成测试覆盖率报告
|
||
make test-coverage
|
||
```
|
||
|
||
### 测试环境
|
||
|
||
项目提供了完整的Docker测试环境:
|
||
|
||
```bash
|
||
# 启动测试环境(包含Mailhog用于邮件测试)
|
||
docker-compose --profile development up -d
|
||
|
||
# 查看服务状态
|
||
docker-compose ps
|
||
|
||
# 查看日志
|
||
docker-compose logs -f sender-service
|
||
```
|
||
|
||
## 📦 部署
|
||
|
||
### Docker部署
|
||
|
||
```bash
|
||
# 构建生产镜像
|
||
make docker-build
|
||
|
||
# 使用docker-compose部署
|
||
make docker-compose-up
|
||
|
||
# 停止服务
|
||
make docker-compose-down
|
||
```
|
||
|
||
### 生产环境配置
|
||
|
||
1. **环境变量设置**:
|
||
```bash
|
||
export SERVICE_ENV=prod
|
||
export POSTGRES_PASSWORD=your_strong_password
|
||
export REDIS_PASSWORD=your_redis_password
|
||
```
|
||
|
||
2. **配置文件**:
|
||
使用 `etc/sender_prod.yaml` 作为生产环境配置
|
||
|
||
3. **健康检查**:
|
||
```bash
|
||
# 检查服务健康状态
|
||
curl http://localhost:12202/health
|
||
```
|
||
|
||
## 🔧 配置说明
|
||
|
||
### 主要配置项
|
||
|
||
| 配置项 | 说明 | 默认值 |
|
||
|--------|------|--------|
|
||
| `Service.Port` | 服务端口 | 12201 |
|
||
| `Service.BindIP` | 绑定IP | 0.0.0.0 |
|
||
| `Code.Length` | 验证码长度 | 6 |
|
||
| `Code.Expire` | 验证码过期时间(秒) | 300 |
|
||
| `Code.MaxSentLimit` | 每日最大发送次数 | 10 |
|
||
|
||
### 环境变量
|
||
|
||
| 环境变量 | 说明 | 示例 |
|
||
|----------|------|------|
|
||
| `SERVICE_ENV` | 服务环境 | dev/test/prod |
|
||
| `POSTGRES_PASSWORD` | 数据库密码 | your_password |
|
||
| `REDIS_PASSWORD` | Redis密码 | your_redis_password |
|
||
|
||
## 📊 监控和日志
|
||
|
||
### 健康检查
|
||
|
||
- **HTTP健康检查**:`GET /health`
|
||
- **gRPC健康检查**:使用gRPC健康检查协议
|
||
|
||
### 日志管理
|
||
|
||
- 日志文件位置:`/app/logs/`
|
||
- 支持结构化日志输出
|
||
- 集成ELK日志收集(可选)
|
||
|
||
### 性能监控
|
||
|
||
- 支持APM监控集成
|
||
- 提供Prometheus指标导出
|
||
- 支持分布式链路追踪
|
||
|
||
## 🤝 贡献指南
|
||
|
||
1. Fork 本仓库
|
||
2. 创建特性分支:`git checkout -b feature/new-feature`
|
||
3. 提交更改:`git commit -am 'Add new feature'`
|
||
4. 推送分支:`git push origin feature/new-feature`
|
||
5. 提交Pull Request
|
||
|
||
### 代码规范
|
||
|
||
- 遵循Go官方代码规范
|
||
- 使用 `gofmt` 格式化代码
|
||
- 运行 `make lint` 进行代码检查
|
||
- 确保测试覆盖率 > 80%
|
||
|
||
## 📄 许可证
|
||
|
||
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
|
||
|
||
## 📞 支持
|
||
|
||
如有问题或建议,请通过以下方式联系:
|
||
|
||
- 提交 [Issue](https://git.apinb.com/bsm-apps/sender/issues)
|
||
- 发送邮件至:david.yan@qq.com
|
||
- 查看 [Wiki](https://git.apinb.com/bsm-apps/sender/wiki) 获取更多文档
|
||
|
||
---
|
||
|
||
**注意**:本项目为企业内部使用,请确保在生产环境中正确配置安全参数。 |