GoESL结合Temporal对接FreeSWITCH时呼叫阻塞问题求助
GoESL+Temporal+FreeSWITCH外呼阻塞问题
问题背景
我正在集成GoESL与Temporal,基于FreeSWITCH搭建自动化外呼系统。配置支持1000并发通道、每秒50次呼叫(CPS),每次拨号尝试都会启动一个Temporal工作流,通过活动发起呼叫。
运行时出现异常:成功发起约96次呼叫(数量不固定)后,FreeSWITCH不再处理后续呼叫。CLI无相关日志,事件套接字层也没有后续呼叫尝试的事件。但停止Temporal worker后,之前"阻塞"的呼叫会立刻出现在FreeSWITCH CLI中——说明这些呼叫被GoESL客户端排队了。我已经确认worker并未阻塞,仍在持续发起线索工作流。
相关代码片段
线索处理循环
for _, lead := range leadResult.Leads { // [省略的初始化与检查] // 检查通道可用性并休眠以遵守CPS限制 workflow.Await(ctx, func() bool { return dialerQueryResponse.AvailableChannels > 0 }) timeToSleep := time.Second / time.Duration(dialerQueryResponse.CallsPerSecondLimit) workflow.Sleep(ctx, timeToSleep) // 呼叫线索 fmt.Printf("dialing lead %s\n", lead) dialLead(lead, selectedDialer.Id, callTimeout) fmt.Print("lead dialed\n\n") }
呼叫线索逻辑
dialLead := func(lead string, selectedDialerId, dialerCallTimeout int) { // 设置带唯一ID的子工作流上下文 cwo.WorkflowID = fmt.Sprintf("Campaign_Call_%s", lead) childCtx := workflow.WithChildOptions(ctx, cwo) // 传递给子工作流的输入结构体 input := domain.CallWorkflowInput{ Lead: lead, DialerId: selectedDialerId, CampaignName: cds.CampaignName, DialplanExtension: cc.Survey.DialplanExtension, CallTimeout: dialerCallTimeout, } // 执行子工作流并处理其Future future := workflow.ExecuteChildWorkflow(childCtx, CallWorkflow, input) var dialerId int selector.AddFuture(future, func(f workflow.Future) { err := f.Get(ctx, &dialerId) // 错误处理与并发状态更新 // ... }) }
Call Workflow函数
func CallWorkflow(ctx workflow.Context, input domain.CallWorkflowInput) (int, error) { // [省略的初始化] // 执行发起呼叫的活动 var dialLeadResult domain.DialLeadResponse if err := workflow.ExecuteActivity(ctx, activity.Dialer.OriginateCallActivity, dialInput).Get(ctx, &dialLeadResult); err != nil { // 错误处理 } // [省略的呼叫后处理] }
发起呼叫的活动
func (a *DialerActivities) OriginateCallActivity(ctx context.Context, input domain.DialLeadRequest) (domain.DialLeadResponse, error) { // [省略的客户端选择] // 发起呼叫的命令 cmd := fmt.Sprintf("originate {%s}%s/%s/%s 704 XML default test %s 10", variables, protocol, gateway, input.DestinationNumber, input.OriginatingNumber) err := selectedClient.BgApi(cmd) if err != nil { // 错误处理 } // [省略的响应准备] return domain.DialLeadResponse{}, nil }
已尝试的排查操作
- 严格遵守限流规则(通道数、CPS限制)
- 通过FreeSWITCH CLI调试并检查CDR记录
- 排查FreeSWITCH日志寻找异常
- 尝试提升FreeSWITCH中GoESL事件日志级别,但未生成对应日志文件
- 修改
workflow.Sleep时长(从几毫秒改为5-10秒),排除网络延迟影响 - 确认工作流终止前无代码错误、日志报错
- 停止FreeSWITCH实例排查通信问题:仅停止时日志显示通信失败,正常运行时无相关日志
- 调研相关问题:找到FreeSWITCH用户邮件列表中的类似案例,但无有效解决方案
提问
有没有人遇到过GoESL或Temporal类似的呼叫排队后无法执行的问题?请问如何调试该场景,或是为什么终止Temporal worker会触发排队呼叫的处理?
内容的提问来源于stack exchange,提问作者Pierre van der Westhuizen
相关产品推荐
相关产品推荐

