前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >上传图片失败问题的排查记录

上传图片失败问题的排查记录

原创
作者头像
莫空9081
修改于 2021-11-23 03:23:21
修改于 2021-11-23 03:23:21
2.3K0
举报
文章被收录于专栏:iOS 备忘录iOS 备忘录

背景

最近开发水印相机,遇到了个难缠的问题。这里记录分享一下。

之前上传图片功能的开发,一般都是修改用户头像之类的,所以印象中上传图片,没有什么难处理的,使用 AFNetworking的 formData 进行上传,直接就可以了。但是这次用户大批量使用水印相机后大量反馈上传慢、上传不成功的问题。

排查

用户反馈有问题后,开始排查;在用户反馈上传不成功的同一时间,在开发环境和线上环境尝试拍摄上传均可正常上传。

初步判断是网络问题,由于用户需要在工地现场使用此功能,所以猜测是用户网络环境的问题。建议用户尝试切换网络重新上传。同时让用户使用 SpeedTest.cn测速,发现部分用户月底流量限速网速被限制了,上传网速很低,导致上传不成功。

然而还是有部分用户,测速显示上传速度28M/s,但是上传依旧超时失败。继续排查后,有同事在测试环境出现了一直上传失败的情况,排查后发现安全组有策略:同一IP单位时间访问请求的数量超出几千次后,当前 IP 会被限制,任何操作都会限制。但是进一步排查后,发现线上因为这个原因被限制的用户并没有太多。

继续排查后,发现有用户反馈提示上传超时,但是实际上传成功。查看后发现,当网速不好时,客户端设置超时时间6秒,但是服务端的超时是12秒,所以当上传时间超出6秒时,客户端AFNetworking请求因超时,返回上传失败,但实际上传服务端成功的情况。针对这种情况,修改客户端超时时间大于等于服务端超时,即,上传超时的判断由服务端来判断而不是客户端。

过程中还发现用户反馈,选择多张上传失败,单张上传能成功的情况。这种情况排查后发现,同样是网络不好的情况下,超时时间已修改为15秒,3G 网络,选择多张时上传失败,单张则可以上传成功。排查后发现是并发请求的问题。(最开始的多张照片是打包上传,即多张照片,在 AFN 的FormData中添加组合,然后使用一个请求发出,后来发现有上传失败后,服务端说照片的打包上传并没有意义,因为压缩不了大小,让客户端修改为一张一个请求)于是选择多张上传时,是每张照片一个请求,使用 DispatchGroup判断是否所有请求是否成功,相当于假设拍摄了9张照片,点击上传,是同时发起了9个上传请求,然后等待9个请求的结果,这对于上传网速不太好的用户,很大的概率出现上传失败。分析原因是,假设上传网速有50K,这50K 如果都用来上传同一张照片,可能15秒内上传成功;但是如果用来同时上传9张,则一张也成功不了。这也是网盘类 APP上传每次同时只有两三个任务开启的原因。针对这种情况,修改上传为NSOperationQueue队列上传,设置队列最大并发数为2。

用户反馈上传失败问题时,服务端那边却看不到超时或者失败,甚至请求的日志也看不到。联系网络组协助排查后发现,有 token 过期网关拦截的日志,项目中的 token 有效期为7天,刷新 token 的逻辑与主工程的 Controller 绑定,而上传照片的项目是 CocoaPods 方式添加到项目中的,所以 token 过期后触发网络请求基类的通知,但是主工程的 Controller接受到后,判断当前页面没有显示就没有处理。针对这种情况,把 token 过期刷新逻辑从和 Controller 的绑定中抽出到单独的处理类,确保项目中任何地方的 token 过期都能够触发刷新处理逻辑。

同时,从听云后台看到,针对上传接口失败的日志,有些请求中的 localDNS 为空,针对这种没有 localDNS 的情况,项目添加阿里的 HTTPDNS,每次上传前,获取上传域名接口的 IP,然后替换请求链接中的域名,设置域名到 Host,再发起请求。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
图解LeetCode——102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。(即逐层地,从左到右访问所有节点)。
爪哇缪斯
2023/09/06
1620
图解LeetCode——102. 二叉树的层序遍历
图文详解 DFS 和 BFS
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在 leetcode,高频面试题中。
kunge
2020/04/26
5.9K0
好的,DFS,也学废了!
没错,本篇是上一篇《好的,BFS,又学废了!》的姊妹篇,意在通过简单回顾拾起学了忘、又忘了学的基础数据结构;
掘金安东尼
2022/09/19
3730
好的,DFS,也学废了!
Python学习中:最感到惊奇35个语言特征和编程技巧
从我开始学习python的时候,我就开始自己总结一个python小技巧的集合。后来当我什么时候在Stack Overflow或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!当时我会努力的自己尝试一下这段代码,直到我懂了它的整体思路以后,我就把这段代码加到我的集合里。这篇博客其实就是这个集合整理后一部分的公开亮相。如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但我想你应该也能发现一些你不知道的新技巧。而如果你之前是一个c,c++,java的程序员,同时在学习python,或者干脆就是一个刚刚学习编程的新手,那么你应该会看到很多特别有用能让你感到惊奇的实用技巧,就像我当初一样。
一墨编程学习
2019/07/10
3640
LeetCode 590: N 叉树的后序遍历 N-ary Tree Postorder Traversal
Given an n-ary tree, return the postorder traversal of its nodes' values.
爱写bug
2020/01/02
6570
每日一题(2022-04-18)——字典序排数
386. 字典序排数 题目描述: 给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。 示例1: 输入:n = 13 输出:[1,10,11,12,13,2,3,4,5,6,7,8,9] 示例2: 输入:n = 20 输出:[1,10,11,12,13,14,15,16,17,18,19,2,20,3,4,5,6,7,8,9] 思路: 解释: 以例二来看: 可以看到字典序的遍历,就是树的深度优
传说之下的花儿
2023/04/16
2060
每日一题(2022-04-18)——字典序排数
LeetCode 589: N 叉树的前序遍历 N-ary Tree Preorder Traversal
Given an n-ary tree, return the preorder traversal of its nodes' values.
爱写bug
2020/01/02
7290
回溯——77. 组合
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/combinations
向着百万年薪努力的小赵
2022/12/02
3430
回溯——77. 组合
英伟达小姐姐的Python隐藏技巧合集,推特2400赞,代码可以直接跑
常常发资源的英伟达工程师小姐姐Chip Huyen,又发射了一套Python隐藏功能合集。
量子位
2019/10/25
5190
数据结构与算法(四)| 队列、栈与Java集合
比如,实现图的宽度优先遍历,但是要求用栈实现;实现图的深度优先遍历,但是要求用队列实现。
行百里er
2021/07/14
5010
优雅编写Python3的62个小贴士!
▍42、创建一个迭代器,它从iterable中过滤元素,只返回谓词为False的元素
AI科技大本营
2019/08/01
7990
优雅编写Python3的62个小贴士!
弄懂这56个Python使用技巧,秒变Python大神!
你也许知道如何进行列表解析,但是可能不知道字典/集合解析。它们简单易用且高效。就像下面这个例子:
一墨编程学习
2019/08/12
1.3K0
流畅的Python 2. 数据结构 - 序列构成的数组
insort(seq, item) 把变量 item 插入到序列 seq 中,并能保持 seq 的升序顺序
Michael阿明
2021/09/06
5250
Python 容器使用的 5 个技巧和 2 个误区
在 Python 中,有四类最常见的内建容器类型: 列表(list)、 元组(tuple)、 字典(dict)、 集合(set)。通过单独或是组合使用它们,可以高效的完成很多事情。
一墨编程学习
2019/07/14
8360
35个高级Python知识点总结
众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底,因为Python中的类(class)也是对象,函数(function)也是对象,而且Python的代码和模块也都是对象。
py3study
2020/01/08
2.4K0
1 行 Python 代码能干哪些事,这 13 个你知道吗?
Python 之禅有一句话叫 “Simple is better than complex.”,简单,到底能多简单,一行代码?
崔庆才
2019/05/17
4600
40个你可能不知道的Python的特点和技巧
1、拆箱 >>> a, b, c = 1, 2, 3 >>> a, b, c (1, 2, 3) >>> a, b, c = [1, 2, 3] >>> a, b, c (1, 2, 3) >>> a, b, c = (2 * i + 1 for i in range(3)) >>> a, b, c (1, 3, 5) >>> a, (b, c), d = [1, (2, 3), 4] >>> a 1 >>> b 2 >>> c 3 >>> d 4     2、使用拆箱进行变量交换 >>> a, b = 1
Java学习123
2018/05/16
6830
Python基础之序列构成的数组
容器序列能够存放不同类型的数据,比扁平序列更灵活; 扁平序列只能存放一种类型的原子性的数据,体积更小速度更快。eg:数字,字符字节
py3study
2020/01/06
1.2K0
20个值得学习的 Python 技巧
本文为大家介绍20个值得记住的 Python 技巧,可以提升您编程技巧, 并为您节省大量时间。在平常编程过程中,以下技巧大多非常有用。
吾非同
2020/12/07
9710
20个值得学习的 Python 技巧
路径总和(I、II、III)
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
木子星兮
2020/07/17
1.3K0
推荐阅读
相关推荐
图解LeetCode——102. 二叉树的层序遍历
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档