首页
直播
壁纸
友链
搜索
1
MySQL如何解决深度分页问题?
11 阅读
2
buildadmin百度编辑器放两个只能显示一个
8 阅读
3
网站被 CC 攻击了?别慌,教你几招接地气的防护办法
7 阅读
4
thinkphp6 消息队列think-queue
6 阅读
5
microsoft store安装codex失败
5 阅读
服务器运维
后端技术
前端技术
梯子
数据库
小程序
登录
搜索
标签搜索
fastadmin
Redis
RabbitMQ
Go
服务器
codex
buildadmin
小程序
mysql
Nginx
Docker
Vue3
Node.js
MySQL优化
Linux
TypeScript
JWT
消息队列
Elasticsearch
搜索引擎
沿途的风景
累计撰写
37
篇文章
累计收到
0
条评论
首页
栏目
服务器运维
后端技术
前端技术
梯子
数据库
小程序
页面
直播
壁纸
友链
搜索到
2
篇与
» Go
的结果
2026-07-24
Go 语言基础教程:从语法到并发编程
前言Go 语言以简洁的语法、出色的并发模型和编译速度著称,在云原生和服务端开发领域占据重要地位。本文将系统介绍 Go 的核心语法和并发编程。一、环境与项目1.1 安装go version # go1.22.x # 设置国内代理 go env -w GOPROXY=https://goproxy.cn,direct go env -w GO111MODULE=on1.2 创建项目mkdir myapp && cd myapp go mod init github.com/yourname/myapp二、基础语法2.1 变量与类型package main import "fmt" func main() { var name string = "Go" var age int = 18 var score = 95.5 isReady := true x, y := 10, 20 fmt.Println(name, age, score, isReady, x, y) }2.2 结构体与方法type User struct { ID int Name string Age int } func (u User) Greet() string { return fmt.Sprintf("Hi, I am %s", u.Name) } func (u *User) SetAge(age int) { u.Age = age } func main() { u := User{ID: 1, Name: "张三", Age: 25} fmt.Println(u.Greet()) u.SetAge(26) fmt.Println(u.Age) }2.3 接口type Animal interface { Speak() string } type Dog struct{ Name string } type Cat struct{ Name string } func (d Dog) Speak() string { return d.Name + ": 汪汪!" } func (c Cat) Speak() string { return c.Name + ": 喵喵!" } func makeSpeak(a Animal) { fmt.Println(a.Speak()) } func main() { makeSpeak(Dog{"旺财"}) makeSpeak(Cat{"咪咪"}) }2.4 错误处理func divide(a, b float64) (float64, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil } func main() { result, err := divide(10, 0) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result) }三、并发编程3.1 Goroutinefunc sayHello(name string) { fmt.Printf("Hello, %s!\n", name) } func main() { go sayHello("张三") go sayHello("李四") time.Sleep(time.Second) }3.2 Channelfunc main() { ch := make(chan string) go func() { ch <- "来自 goroutine 的消息" }() msg := <-ch fmt.Println(msg) }3.3 带缓冲的 Channelch := make(chan int, 3) ch <- 1 ch <- 2 ch <- 3 // ch <- 4 // 阻塞!缓冲区已满 fmt.Println(<-ch) // 13.4 select 多路复用func main() { ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(1 * time.Second) ch1 <- "来自 ch1" }() go func() { time.Sleep(2 * time.Second) ch2 <- "来自 ch2" }() select { case msg := <-ch1: fmt.Println(msg) case msg := <-ch2: fmt.Println(msg) } }3.5 WaitGroup 等待多个 goroutinefunc worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d started\n", id) time.Sleep(time.Second) fmt.Printf("Worker %d done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() fmt.Println("All workers done") }3.6 并发安全:Mutextype Counter struct { mu sync.Mutex count int } func (c *Counter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++ } func (c *Counter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.count } func main() { c := &Counter{} var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() c.Increment() }() } wg.Wait() fmt.Println("Final count:", c.Value()) }四、HTTP 服务func main() { http.HandleFunc("/api/hello", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{ "msg": "Hello from Go!", }) }) fmt.Println("Server running on :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }五、总结Go 的核心优势在于:语法简洁上手快、goroutine 轻量级并发、编译速度快、标准库强大。掌握 struct/interface/goroutine/channel 这四个核心概念,就能写出高质量的 Go 程序。建议在实际项目中配合 Gin/Echo 等 Web 框架和 GORM 等 ORM 框架,进一步提升开发效率。
2026年07月24日
0 阅读
0 评论
0 点赞
2026-07-24
Go + RabbitMQ 构建高并发任务队列实战
前言Go 语言的 goroutine 并发模型配合 RabbitMQ 的可靠消息投递,是构建高并发任务队列的经典方案。本文将实现一个完整的 Go + RabbitMQ 任务队列系统,包含生产者、消费者、重试机制和优雅退出。一、项目结构go-rabbitmq-queue/ ├── go.mod ├── config/ │ └── config.go ├── producer/ │ └── main.go ├── consumer/ │ └── main.go └── rabbitmq/ └── connection.go二、安装依赖go mod init github.com/yourname/go-rabbitmq-queue go get github.com/rabbitmq/amqp091-go三、RabbitMQ 连接封装package rabbitmq import ( "log" "time" amqp "github.com/rabbitmq/amqp091-go" ) type Config struct { URL string Exchange string Queue string RoutingKey string PrefetchCount int } type RabbitMQ struct { conn *amqp.Connection channel *amqp.Channel config Config } func New(cfg Config) (*RabbitMQ, error) { var conn *amqp.Connection var err error for i := 0; i < 5; i++ { conn, err = amqp.Dial(cfg.URL) if err == nil { break } log.Printf("连接失败(%d/5): %v", i+1, err) time.Sleep(3 * time.Second) } if err != nil { return nil, err } ch, err := conn.Channel() if err != nil { return nil, err } err = ch.ExchangeDeclare( cfg.Exchange, "direct", true, false, false, false, nil, ) if err != nil { return nil, err } args := amqp.Table{ "x-message-ttl": int32(60000), "x-dead-letter-exchange": cfg.Exchange + ".dlx", } _, err = ch.QueueDeclare( cfg.Queue, true, false, false, false, args, ) if err != nil { return nil, err } err = ch.QueueBind( cfg.Queue, cfg.RoutingKey, cfg.Exchange, false, nil, ) if err != nil { return nil, err } ch.Qos(cfg.PrefetchCount, 0, false) return &RabbitMQ{conn: conn, channel: ch, config: cfg}, nil } func (r *RabbitMQ) Channel() *amqp.Channel { return r.channel } func (r *RabbitMQ) Close() { r.channel.Close() r.conn.Close() }四、生产者package main import ( "encoding/json" "fmt" "log" "time" "github.com/yourname/go-rabbitmq-queue/rabbitmq" amqp "github.com/rabbitmq/amqp091-go" ) type Task struct { ID string `json:"id"` Type string `json:"type"` Payload interface{} `json:"payload"` } func main() { cfg := rabbitmq.Config{ URL: "amqp://admin:admin123@localhost:5672/", Exchange: "task.exchange", Queue: "task.queue", RoutingKey: "task.process", PrefetchCount: 10, } mq, err := rabbitmq.New(cfg) if err != nil { log.Fatal(err) } defer mq.Close() for i := 0; i < 100; i++ { task := Task{ ID: fmt.Sprintf("task-%d", i), Type: "email", Payload: map[string]string{ "to": fmt.Sprintf("user%d@example.com", i), "subject": "通知邮件", }, } body, _ := json.Marshal(task) err = mq.Channel().Publish( cfg.Exchange, cfg.RoutingKey, false, false, amqp.Publishing{ DeliveryMode: amqp.Persistent, ContentType: "application/json", Body: body, Timestamp: time.Now(), }, ) if err != nil { log.Printf("发送失败: %v", err) continue } log.Printf("发送任务: %s", task.ID) } log.Println("所有任务发送完成") }五、消费者(多 Worker 并发)package main import ( "encoding/json" "fmt" "log" "os" "os/signal" "sync" "syscall" "time" "github.com/yourname/go-rabbitmq-queue/rabbitmq" amqp "github.com/rabbitmq/amqp091-go" ) type Task struct { ID string `json:"id"` Type string `json:"type"` Payload interface{} `json:"payload"` } func processTask(task Task) error { log.Printf("处理任务: %s, 类型: %s", task.ID, task.Type) time.Sleep(500 * time.Millisecond) if time.Now().Unix()%10 == 0 { return fmt.Errorf("模拟处理失败") } log.Printf("任务完成: %s", task.ID) return nil } func startWorker(id int, mq *rabbitmq.RabbitMQ, wg *sync.WaitGroup) { defer wg.Done() msgs, err := mq.Channel().Consume( "task.queue", fmt.Sprintf("worker-%d", id), false, false, false, false, nil, ) if err != nil { log.Printf("Worker %d 启动失败: %v", id, err) return } log.Printf("Worker %d 启动", id) for msg := range msgs { var task Task if err := json.Unmarshal(msg.Body, &task); err != nil { log.Printf("Worker %d 解析失败: %v", id, err) msg.Nack(false, false) continue } if err := processTask(task); err != nil { log.Printf("Worker %d 处理失败: %s -> %v", id, task.ID, err) retryCount := getRetryCount(msg) if retryCount < 3 { msg.Nack(false, true) } else { log.Printf("Worker %d 任务 %s 重试超限,进入死信", id, task.ID) msg.Nack(false, false) } continue } msg.Ack(false) } log.Printf("Worker %d 退出", id) } func getRetryCount(msg amqp.Delivery) int { if deaths, ok := msg.Headers["x-death"].([]interface{}); ok && len(deaths) > 0 { if death, ok := deaths[0].(amqp.Table); ok { if count, ok := death["count"].(int64); ok { return int(count) } } } return 0 } func main() { cfg := rabbitmq.Config{ URL: "amqp://admin:admin123@localhost:5672/", Exchange: "task.exchange", Queue: "task.queue", RoutingKey: "task.process", PrefetchCount: 5, } mq, err := rabbitmq.New(cfg) if err != nil { log.Fatal(err) } defer mq.Close() var wg sync.WaitGroup workerCount := 5 for i := 1; i <= workerCount; i++ { wg.Add(1) go startWorker(i, mq, &wg) } sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs log.Println("收到退出信号,等待 worker 完成...") mq.Close() wg.Wait() log.Println("所有 worker 已退出") }六、死信队列消费者func startDeadLetterConsumer(mq *rabbitmq.RabbitMQ) { ch := mq.Channel() ch.ExchangeDeclare("task.exchange.dlx", "fanout", true, false, false, false, nil) _, _ = ch.QueueDeclare("task.dlq", true, false, false, false, nil) _ = ch.QueueBind("task.dlq", "", "task.exchange.dlx", false, nil) msgs, _ := ch.Consume("task.dlq", "dlq-consumer", false, false, false, false, nil) go func() { for msg := range msgs { log.Printf("死信消息: %s", string(msg.Body)) msg.Ack(false) } }() }七、架构总结Producer → [task.exchange] → [task.queue] → 5个 Worker 并发消费 ↓ (失败/Nack) [task.exchange.dlx] → [task.dlq] → 死信消费者记录总结Go + RabbitMQ 的组合充分发挥了各自优势:Go 的 goroutine 让消费者可以轻松开几十个并发 worker,RabbitMQ 的 ACK 机制保证消息不丢失。生产环境注意:设置合理的 prefetch 避免消息堆积在单个 worker、实现死信队列处理失败消息、添加优雅退出逻辑避免消息中断。
2026年07月24日
0 阅读
0 评论
0 点赞
0:00