魔法死 2025-09-08 17:51 采纳率: 0%
浏览 4

RpcSocketCloseError 服务无法调用

我前端gateway网关服务调用resouce服务的时候报错了,调用其他服务是正常的。


root@437923439f88:~/logs/gateway# cat common-error.log 
2025-09-08 09:48:21,134 ERROR 69 [-/10.10.10.169/ac100a051757324899640100169/1492ms GET /api/v1/editor/4920569e-9cdd-48f6-988a-f7a8fa5b716d?limit=1&userId=7855&id=4920569e-9cdd-48f6-988a-f7a8fa5b716d&role=241] nodejs.RpcSocketCloseError: The socket was closed. (address: address => bolt://172.16.10.3:13337?startTime=1757320239373&pid=69&uniqueId=&dynamic=true&appName=resource&timeout=3000&serialization=protobuf&weight=100&accepts=100000&language=nodejs&rpcVer=50400&protocol=&interface=com.ddd.rpc.ResourceProjectService&version=1.0&group=SOFA)
    at RpcConnection._cleanRequest (/app/node_modules/sofa-rpc-node/lib/client/connection/rpc.js:257:13)
    at RpcConnection._handleClose (/app/node_modules/sofa-rpc-node/lib/client/connection/rpc.js:277:10)
    at Socket.<anonymous> (/app/node_modules/sofa-rpc-node/lib/client/connection/rpc.js:86:45)
    at Object.onceWrapper (node:events:632:26)
    at Socket.emit (node:events:529:35)
    at TCP.<anonymous> (node:net:350:12)
    at TCP.callbackTrampoline (node:internal/async_hooks:128:17)
name: "RpcSocketCloseError"
resultCode: "02"
headers: {"Access-Control-Allow-Origin":"http://10.10.10.111:8098","vary":"Origin"}
pid: 69
hostname: 437923439f88

root@437923439f88:~/logs/gateway# 
  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-09-08 17:52
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你遇到的 RpcSocketCloseError 是一个 RPC 调用过程中连接被关闭 的错误。这通常发生在客户端(这里是你的 Gateway 网关)与服务端(Resource 服务)之间的通信中断,可能是由于网络问题、服务端异常、超时、配置不一致等原因导致。


    🛠️ 一、可能的原因分析

    1. 服务端(Resource 服务)未正常运行或崩溃

      • Resource 服务可能没有启动,或者在处理请求时发生了异常,导致连接被主动关闭。
    2. 网络不稳定或防火墙限制

      • 网络连接不稳定,或防火墙/安全组规则阻止了从 Gateway 到 Resource 服务的连接。
    3. RPC 配置不一致

      • Gateway 和 Resource 服务的 RPC 配置(如协议、版本、接口等)不一致,导致调用失败。
    4. 服务端响应超时

      • Resource 服务处理时间过长,超过了 Gateway 设置的超时时间,导致连接被关闭。
    5. 负载过高或资源不足

      • Resource 服务可能因为高负载、内存不足或线程池耗尽而无法处理新请求。

    🔧 二、解决方案步骤

    1. 检查 Resource 服务状态

    • 确认服务是否正常运行

      # 查看 resource 服务的容器状态
      docker ps | grep resource
      
      # 查看 service 日志
      docker logs <resource_container_id>
      
    • 检查服务是否监听指定端口

      netstat -tuln | grep 13337
      
    • 查看服务日志是否有异常

      tail -n 100 /path/to/resource/service.log
      

    重点:确保 Resource 服务正在运行,并且能够接收来自 Gateway 的请求。


    2. 检查网络连接

    • 测试从 Gateway 到 Resource 服务的网络连通性

      ping 172.16.10.3
      telnet 172.16.10.3 13337
      
    • 检查防火墙规则

      ufw status
      iptables -L -n -v
      

    重点:确保 Gateway 与 Resource 服务之间的网络是通畅的,并且 13337 端口开放。


    3. 检查 RPC 配置一致性

    • 检查 Gateway 与 Resource 服务的 RPC 接口定义是否一致

      • 确保接口名称、版本号、分组(Group)、序列化方式(如 protobuf)等配置一致。
    • 检查配置文件中是否设置了正确的地址和端口

      // 示例配置(Node.js 中)
      const client = new Client({
        address: 'bolt://172.16.10.3:13337',
        appName: 'resource',
        version: '1.0',
        group: 'SOFA',
        timeout: 3000,
        serialization: 'protobuf'
      });
      

    重点:确保所有 RPC 参数完全匹配,尤其是 appNameversiongroupinterface 等关键字段。


    4. 增加超时设置和重试机制

    • 调整超时时间

      // 在调用前设置更长的超时时间
      const client = new Client({
        timeout: 5000 // 5秒
      });
      
    • 添加重试逻辑(可选):

      async function callWithRetry(client, method, args) {
        let retries = 3;
        while (retries > 0) {
          try {
            return await client.invoke(method, args);
          } catch (err) {
            if (err instanceof RpcSocketCloseError) {
              console.warn(`Retrying... ${retries} left`);
              retries--;
            } else {
              throw err;
            }
          }
        }
        throw new Error("Max retries exceeded");
      }
      

    重点:适当增加超时时间和重试次数,提高系统容错能力。


    5. 检查服务负载情况

    • 查看 Resource 服务的 CPU、内存使用情况

      top
      free -h
      
    • 查看服务线程池状态(如果是 Java 服务):

      jstack <pid_of_resource_service>
      

    重点:如果服务负载过高,考虑扩容或优化性能。


    📌 三、代码示例(Node.js)

    如果你使用的是 sofa-rpc-node,可以尝试如下修改:

    const { Client } = require('sofa-rpc-node');
    
    const client = new Client({
      address: 'bolt://172.16.10.3:13337', // 服务地址
      appName: 'resource',               // 应用名
      version: '1.0',                    // 版本
      group: 'SOFA',                     // 分组
      timeout: 5000,                     // 超时时间
      serialization: 'protobuf',         // 序列化方式
      retryTimes: 3                      // 重试次数
    });
    
    client.start();
    
    // 调用方法
    async function callResourceService() {
      try {
        const result = await client.invoke('com.ddd.rpc.ResourceProjectService', 'yourMethod', {
          // 参数
        });
        console.log('Call success:', result);
      } catch (err) {
        console.error('Call failed:', err.message);
      }
    }
    

    ✅ 四、总结

    | 问题类型 | 解决方案 | |----------|----------| | 服务未启动 | 检查 Resource 服务状态,重启服务 | | 网络不通 | 使用 pingtelnet 测试网络,检查防火墙 | | 配置不一致 | 确保 addressversiongroup 等参数一致 | | 超时问题 | 增加超时时间,添加重试逻辑 | | 服务负载过高 | 监控资源使用,考虑扩容或优化 |


    如果你能提供更多的服务端日志或配置信息,我可以进一步帮助你定位具体原因。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月8日