Go并发调用超时处理实践与示例
189 浏览量
更新于2024-08-31
收藏 76KB PDF 举报
在Go语言中,实现并发调用的超时处理是一个常见的需求,特别是在处理微服务间通信或者有明确响应时间限制的场景。本文将详细介绍如何在Go的并发编程模型中,利用`goroutine`、`channel`、`select`以及`context`机制来处理这种场景。
首先,让我们回顾一下Go的并发模型。`goroutine`是Go中的轻量级线程,它们通过`go`关键字启动并在运行时与`main`函数并行执行。`channel`是Go语言中用于进程间通信的关键特性,它可以在多个`goroutine`之间传递数据,提供了一种同步和通信的方式。
在我们的示例中,作者假设有一个Web应用(使用Gin框架)接收请求,并需要并发调用A、B、C三个微服务获取结果。由于微服务处理可能存在延迟或复杂性,需要设置一个3秒的超时限制。为了实现这个功能,我们需要做以下几点:
1. **创建goroutines**:
在`calHandler`中,作者直接使用`go`关键字发起对`microService1`、`microService2`和`microService3`的并发调用。然而,这不包括超时处理,因为`go`本身没有内置的超时机制。
2. **引入channel**:
为了解决接收并行调用的结果问题,作者创建了一个大小为3的`int`类型的channel `resChan`。这样可以确保最多存储3个返回值,同时允许goroutines依次发送结果。
3. **使用select语句**:
Go的`select`语句允许在一个通道选择器中处理多个通道,提供了优雅的方式来处理多个输入源。在这个场景中,我们可以在`calHandler`中使用`select`来监听`resChan`,并在其他goroutines完成任务时接收结果,或者在超时后进行处理。
4. **添加context**:
为了实现超时,我们可以创建一个`context`,并在每个goroutine中使用它来监控执行时间。一旦超过设定的超时时间,`context`的`Done`通道会被关闭,`select`会检测到这个信号并采取相应措施。例如,取消正在进行的请求,或者捕获已有的部分结果。
5. **完整实现**:
实现`calHandler`可能如下所示:
```go
func calHandler(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var wg sync.WaitGroup
results := make([]int, 0)
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
select {
case <-ctx.Done():
log.Println("Task ", i, " timed out.")
// 取消尚未完成的任务或返回已有的结果
default:
result := microService(i)
resChan <- result
}
}(i)
}
go func() {
wg.Wait()
// 检查所有结果是否到达,如果没有则返回部分结果
for i := 0; i < len(results); i++ {
if len(results) > 0 {
c.JSON(http.StatusOK, gin.H{"result": sum(results)})
return
}
}
// 如果所有结果都未到达,返回超时信息
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Timeout"})
}()
}
```
通过这种方式,我们实现了在Go并发调用中处理超时,确保了在响应时间达到限制时能够及时响应客户端,同时还能优雅地处理多路结果。这种方式展示了Go语言并发编程的强大之处,同时也强调了合理使用`context`和`channel`对于控制并发流程的重要性。
2019-08-13 上传
2018-12-25 上传
点击了解资源详情
2021-01-08 上传
点击了解资源详情
点击了解资源详情
点击了解资源详情
点击了解资源详情
点击了解资源详情
weixin_38702844
- 粉丝: 2
- 资源: 921
最新资源
- 高清艺术文字图标资源,PNG和ICO格式免费下载
- mui框架HTML5应用界面组件使用示例教程
- Vue.js开发利器:chrome-vue-devtools插件解析
- 掌握ElectronBrowserJS:打造跨平台电子应用
- 前端导师教程:构建与部署社交证明页面
- Java多线程与线程安全在断点续传中的实现
- 免Root一键卸载安卓预装应用教程
- 易语言实现高级表格滚动条完美控制技巧
- 超声波测距尺的源码实现
- 数据可视化与交互:构建易用的数据界面
- 实现Discourse外聘回复自动标记的简易插件
- 链表的头插法与尾插法实现及长度计算
- Playwright与Typescript及Mocha集成:自动化UI测试实践指南
- 128x128像素线性工具图标下载集合
- 易语言安装包程序增强版:智能导入与重复库过滤
- 利用AJAX与Spotify API在Google地图中探索世界音乐排行榜