Golang微服务中并发技术的应用实践
Golang微服务中并发技术的应用实践 亲爱的论坛成员们,
我目前正在开发一个包含四个进程的微服务。这些进程之间存在依赖关系。具体来说:
- 进程 2 依赖于进程 1。
- 进程 3 和进程 4 依赖于进程 2。
我希望应用并发来提升性能,但不确定该如何进行。任何指导或最佳实践都将不胜感激。
谢谢!
2 回复
实现这一目标的方法有很多,我无法给出一个通用的示例,因为这取决于你的具体实现。Go语言通过Goroutines使得编写正确的并发代码变得容易,稍微学习一下Goroutines,你肯定会对如何在你的服务中实现这一点产生想法。
我推荐Rob Pike的演讲“并发不是并行”。它与你“如何着手”的问题没有直接关系,但或许能帮助你理解Go语言中的并发代码理论,以及为什么没有唯一的方法来做事情。
(我认为这个演讲可以在YouTube上找到,试着找一个能展示幻灯片的版本。)
更多关于Golang微服务中并发技术的应用实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang微服务中处理进程依赖的并发场景,推荐使用sync.WaitGroup和channel的组合方案。以下是具体实现:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
// 用于进程间通信的channel
proc1Done := make(chan struct{})
proc2Done := make(chan struct{})
// 进程1
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("进程1开始执行")
time.Sleep(1 * time.Second) // 模拟处理时间
fmt.Println("进程1执行完成")
close(proc1Done) // 通知进程1已完成
}()
// 进程2 - 依赖进程1
wg.Add(1)
go func() {
defer wg.Done()
<-proc1Done // 等待进程1完成
fmt.Println("进程2开始执行")
time.Sleep(1 * time.Second)
fmt.Println("进程2执行完成")
close(proc2Done) // 通知进程2已完成
}()
// 进程3 - 依赖进程2
wg.Add(1)
go func() {
defer wg.Done()
<-proc2Done // 等待进程2完成
fmt.Println("进程3开始执行")
time.Sleep(1 * time.Second)
fmt.Println("进程3执行完成")
}()
// 进程4 - 依赖进程2
wg.Add(1)
go func() {
defer wg.Done()
<-proc2Done // 等待进程2完成
fmt.Println("进程4开始执行")
time.Sleep(1 * time.Second)
fmt.Println("进程4执行完成")
}()
wg.Wait()
fmt.Println("所有进程执行完成")
}
对于需要传递数据的场景,可以使用带缓冲的channel:
func processWithDataTransfer() {
var wg sync.WaitGroup
// 进程1产生数据
dataChan := make(chan string, 10)
wg.Add(1)
go func() {
defer wg.Done()
defer close(dataChan)
for i := 0; i < 5; i++ {
data := fmt.Sprintf("data-%d", i)
dataChan <- data
fmt.Printf("进程1产生: %s\n", data)
}
}()
// 进程2处理数据
processedChan := make(chan string, 10)
wg.Add(1)
go func() {
defer wg.Done()
defer close(processedChan)
for data := range dataChan {
processed := fmt.Sprintf("processed-%s", data)
processedChan <- processed
fmt.Printf("进程2处理: %s -> %s\n", data, processed)
}
}()
// 进程3和进程4并发处理结果
for i := 3; i <= 4; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for data := range processedChan {
fmt.Printf("进程%d消费: %s\n", id, data)
}
}(i)
}
wg.Wait()
}
使用context处理超时和取消:
func processWithTimeout() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var wg sync.WaitGroup
proc1Done := make(chan struct{})
// 进程1
wg.Add(1)
go func() {
defer wg.Done()
select {
case <-time.After(2 * time.Second):
fmt.Println("进程1完成")
close(proc1Done)
case <-ctx.Done():
fmt.Println("进程1超时")
}
}()
// 进程2
wg.Add(1)
go func() {
defer wg.Done()
select {
case <-proc1Done:
fmt.Println("进程2开始执行")
case <-ctx.Done():
fmt.Println("进程2取消")
}
}()
wg.Wait()
}
这种模式确保了依赖关系的正确执行,同时充分利用了Golang的并发特性。

