Vue Storefront对接Magento后端出现Socket Hang Up问题
解决Vue Storefront连续页面切换时GraphQL请求Socket Hang Up (ECONNRESET) 错误
问题场景
站点基于Vue.js(Vue Storefront)开发,后端对接Magento,通过GraphQL调用API服务。用户快速连续切换页面时,触发Socket Hang Up错误(错误码ECONNRESET),复现方式为不间断页面导航。错误详情:
{ "name": "ApolloError", "graphQLErrors": [], "protocolErrors": [], "clientErrors": [], "networkError": { "message": "request to https://5bc36db30a.nxcli.io/graphql?query=query+categoryMeta%28%24filters%3ACategoryFilterInput%29%7Bcategories%28filters%3A%24filters%29%7Bitems%7Bmeta_title+meta_description+meta_keywords+name+__typename%7D__typename%7D%7D&operationName=categoryMeta&variables=%7B%22filters%22%3A%7B%22category_uid%22%3A%7B%7D%7D%7D failed, reason: socket hang up", "type": "system", "errno": "ECONNRESET", "code": "ECONNRESET" }, "message": "request to https://5bc36db30a.nxcli.io/graphql?query=query+categoryMeta%28%24filters%3ACategoryFilterInput%29%7Bcategories%28filters%3A%24filters%29%7Bitems%7Bmeta_title+meta_description+meta_keywords+name+__typename%7D__typename%7D%7D&operationName=categoryMeta&variables=%7B%22filters%22%3A%7B%22category_uid%22%3A%7B%7D%7D%7D failed, reason: socket hang up" }
已排查网络配置和服务器日志,未发现异常。
解决方案
1. 限制并发请求并添加重试机制
页面切换时并发请求过多可能触发API服务连接限制,通过Apollo Client配置节流和重试:
import { ApolloClient, InMemoryCache, from } from '@apollo/client'; import { createHttpLink } from 'apollo-link-http'; import { RetryLink } from '@apollo/client/link/retry'; import { setContext } from '@apollo/client/link/context'; const httpLink = createHttpLink({ uri: 'https://5bc36db30a.nxcli.io/graphql', timeout: 10000 // 延长请求超时时间 }); // 配置重试逻辑 const retryLink = new RetryLink({ delay: { initial: 300, max: Infinity, jitter: true }, attempts: { max: 3, retryIf: (error) => !!error } }); // 组合链路,控制请求流量 const link = from([ retryLink, setContext((_, { headers }) => ({ headers: { ...headers } })), httpLink ]); const client = new ApolloClient({ link, cache: new InMemoryCache() });
2. 页面卸载时取消未完成请求
避免无效请求占用连接资源,在页面组件中添加请求取消逻辑:
import { useQuery } from '@apollo/client'; import { onUnmounted } from 'vue'; import CATEGORY_META_QUERY from './queries/categoryMeta.gql'; export default { setup(props) { const { cancel } = useQuery(CATEGORY_META_QUERY, { variables: { filters: { category_uid: props.categoryUid } }, fetchPolicy: 'cache-first' // 优先使用缓存减少请求 }); // 页面卸载时取消未完成请求 onUnmounted(() => cancel()); return {}; } };
3. 优化缓存与预取逻辑
减少重复请求,利用路由守卫判断缓存状态,仅在无缓存时发起请求:
import { useApolloClient } from '@apollo/client'; import CATEGORY_META_QUERY from './queries/categoryMeta.gql'; router.beforeEach(async (to, from, next) => { const client = useApolloClient(); const categoryUid = to.params.categoryUid; // 检查缓存中是否已有数据 const cachedData = client.cache.readQuery({ query: CATEGORY_META_QUERY, variables: { filters: { category_uid: categoryUid } } }); if (!cachedData) { await client.query({ query: CATEGORY_META_QUERY, variables: { filters: { category_uid: categoryUid } } }); } next(); });
4. 启用HTTP/2多路复用
确认API服务端已启用HTTP/2,HTTP/2的多路复用特性可大幅提升并发请求处理效率,降低连接断开概率。
内容的提问来源于stack exchange,提问作者Harshit Vaishnav
相关产品推荐
相关产品推荐

