生产者代码
- 引入库:使用了
gin库来构建Web服务器,confluent-kafka-go库来与Kafka通信,以及redis库来与Redis交互。 - 初始化Redis客户端:连接到本地的Redis服务。
- 定义主函数:
- 创建一个Gin引擎来处理HTTP请求。
- 定义一个POST路由
/sendCode,当接收到该请求时会触发验证码的生成和发送到Kafka的操作。 - 从请求中获取电子邮件地址。
- 生成验证码。
- 创建一个Kafka生产者并连接到本地Kafka服务器。
- 将验证码作为消息发送到Kafka的特定主题(在此例中,主题是电子邮件地址)。
- 返回一个成功的JSON响应。
- 开始运行服务器,监听8080端口。
- 定义生成验证码的函数:这里可以添加您自己的验证码生成逻辑。
消费者代码
- 引入库:与生产者相似,但不包括
gin。 - 初始化Redis客户端:连接到本地的Redis服务。
- 定义主函数:
- 创建一个Kafka消费者并连接到本地Kafka服务器,设置消费组ID等。
- 订阅所有主题(使用正则表达式
^.*)。 - 无限循环读取Kafka的消息。
- 当接收到消息时,将其打印出来。
- 调用发送电子邮件的函数,并将验证码存储在Redis中。
- 如果出现错误,则打印错误。
- 关闭消费者。
- 定义发送电子邮件的函数:
- 定义SMTP服务器的凭据和地址。
- 创建邮件正文。
- 使用SMTP协议发送电子邮件。
- 如果发送失败,则打印错误。
技术用法
- Gin:用于构建Web服务器,处理HTTP请求和响应。
- Kafka:用作消息队列,以异步方式传输验证码。生产者将验证码发送到队列,消费者从队列中获取并处理。
- Redis:用作数据存储,存储验证码,以便以后进行验证或其他用途。
- SMTP:用于发送电子邮件验证码。可以与各种电子邮件服务提供商一起使用。
生产者(发送验证码)
package main
import (
"github.com/gin-gonic/gin" // 导入Gin框架
"github.com/go-redis/redis/v8" // 导入Redis库
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka" // 导入Kafka库
"net/http"
"context"
)
var redisClient *redis.Client
func init() {
redisClient = redis.NewClient(&redis.Options{ // 初始化Redis客户端
Addr: "localhost:6379",
})
}
func main() {
r := gin.Default() // 创建Gin引擎
// 定义POST路由来接收验证码发送请求
r.POST("/sendCode", func(c *gin.Context) {
email := c.PostForm("email") // 获取邮箱地址
code := generateCode() // 生成验证码
p, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": "localhost"}) // 创建Kafka生产者
if err != nil {
panic(err)
}
defer p.Close()
// 将验证码作为消息发送到Kafka队列
p.Produce(&kafka.Message{
TopicPartition: kafka.TopicPartition{Topic: &email, Partition: kafka.PartitionAny},
Value: []byte(code),
}, nil)
c.JSON(http.StatusOK, gin.H{"message": "验证码发送成功"}) // 返回成功的响应
})
r.Run(":8080") // 运行服务器,监听8080端口
}
func generateCode() string { // 生成验证码的函数
// 这里添加生成验证码的逻辑
return "123456"
}
消费者(接收验证码并发送)
package main
import (
"context" // 导入上下文库
"fmt"
"github.com/go-redis/redis/v8" // 导入Redis库
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka" // 导入Kafka库
"net/smtp" // 导入SMTP库
"os"
)
var redisClient *redis.Client
var ctx = context.Background()
func init() {
redisClient = redis.NewClient(&redis.Options{ // 初始化Redis客户端
Addr: "localhost:6379",
})
}
func main() {
// 创建Kafka消费者
c, err := kafka.NewConsumer(&kafka.ConfigMap{
"bootstrap.servers": "localhost",
"group.id": "myGroup",
"auto.offset.reset": "earliest",
})
if err != nil {
panic(err)
}
c.SubscribeTopics([]string{"^.*"}, nil) // 订阅所有主题
// 循环读取Kafka的消息
for {
msg, err := c.ReadMessage(-1)
if err == nil {
fmt.Printf("Received message on %s: %s\n", msg.TopicPartition, string(msg.Value))
sendEmail(*msg.TopicPartition.Topic, string(msg.Value)) // 调用发送邮件的函数
redisClient.Set(ctx, *msg.TopicPartition.Topic, string(msg.Value), 0).Err() // 将验证码存储在Redis中
} else {
fmt.Printf("Consumer error: %v (%v)\n", err, msg)
}
}
c.Close() // 关闭消费者
}
func sendEmail(to string, code string) { // 发送邮件的函数
from := "your-email@example.com"
password := "your-password"
body := "Subject: Verification Code\n\n" + "Your verification code is: " + code
smtpHost := "smtp.example.com"
smtpPort := "587"
auth := smtp.PlainAuth("", from, password, smtpHost) // 创建SMTP认证
// 使用SMTP发送邮件
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, []byte(body))
if err != nil {
fmt.Println("Failed to send email:", err)
}
}
生产者部分负责接收来自Web客户端的请求,生成验证码,并将其发送到Kafka队列。消费者部分从Kafka队列读取验证码,并通过电子邮件发送给用户,然后将验证码存储在Redis中。