Kotlin环境下Picasso加载Flickr图片随机报HTTP 503错误
Android端Picasso加载Flickr图片随机返回HTTP 503问题
问题描述
- 应用使用Picasso库加载托管在Flickr的图片,完成Kotlin迁移后一段时间内功能运行正常,近期开始随机出现图片加载失败,错误码为HTTP 503
- 已在Flickr控制面板将所有图片设置为完全公开、安全等级调至最低,问题仍未解决;最初判断降低Flickr安全等级即可修复问题,调整配置后错误依旧出现。初步判断该问题和Kotlin迁移无关,确认相同配置下此前图片加载完全正常
- 反常特征:调试时复制报错的图片URL粘贴到浏览器中,可以正常打开图片
- 已排除Picasso库本身问题:测试加载其他域名的图片资源可正常加载,初步推测是Flickr官方调整安全相关策略导致,已联系Flickr支持暂未收到回复
- 现存异常点:所有图片的后台配置完全一致,但存在部分图片可正常加载、部分图片加载失败的情况
现有图片加载实现代码
private fun setTodaysThoughtPainting() { binding!!.ivTtodaysThought.setOnClickListener { v: View? -> startThoughtActivity("") } val isTodayThought = AWPreferences.todayThoughtPrefIsToday(this) mainPainting = mainViewModel!!.getTodaysPainting(isTodayThought) //FLICKR URL EXAMPLE: mainPainting.setUrl("https://live.staticflickr.com/xxx/xxx_xxx_o_d.jpg"); if (mainPainting != null) { Picasso.get().load(mainPainting!!.url) .transform(RoundedTransformation(cornerRadius, 0)) .into(binding!!.ivTtodaysThought, object : Callback { override fun onSuccess() { trackId = mainViewModel!!.getTodaysTrack(isTodayThought) mainThought = mainViewModel!!.getTodaysThought( mainPainting, isTodayThought, idLanguage, trackId ) if (mainThought != null) { setMainShortenThought(mainThought!!) setMainThoughtDate(Calendar.getInstance()) binding!!.ivTtodaysThought.viewTreeObserver.addOnGlobalLayoutListener( object : OnGlobalLayoutListener { override fun onGlobalLayout() { binding!!.ivTtodaysThought.viewTreeObserver.removeOnGlobalLayoutListener( this ) val realImgSize = ImageHelper.getRealImageSize( binding!!.ivTtodaysThought ) setThoughtMargin(realImgSize[0]) } }) } } override fun onError(e: Exception) { e.printStackTrace() } }) } }
错误堆栈信息
2022-06-15 23:59:03.231 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.lang.Thread.run(Thread.java:929) 2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354) // 重复同源错误堆栈省略 2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)

可落地排查方案
- 抓包对比浏览器发起的图片请求和Picasso发起请求的请求头差异,重点核对
User-Agent、Referer、Accept字段:Flickr静态CDN近期新增了异常客户端/WAF拦截规则,Picasso默认使用的网络客户端携带的UA标识大概率被识别为非浏览器爬虫,触发503拦截,浏览器可正常访问正是因为携带了合规的浏览器UA - 给Picasso配置自定义OkHttp客户端,为所有Flickr资源请求添加合规的浏览器UA标识、携带Flickr域名的Referer头,测试加载是否恢复正常
- 对比可正常加载、加载失败两类图片的URL参数、上传时间、解析到的CDN节点IP:CDN的规则上线通常是节点灰度推进,会出现同配置下部分节点拦截、部分节点可正常访问的情况,和当前“部分图片可加载、部分失败”的特征吻合
- 检查应用端图片请求频率:短时间内高频请求静态资源很容易触发CDN限流规则,503是限流、WAF拦截场景下的常见返回码,可添加指数退避重试逻辑,验证是否为临时限流导致
- 长期方案建议:Flickr本身是图片分享社区,并非面向生产应用的静态资源托管服务,平台随时可能调整防盗链、爬虫拦截规则,不适合作为应用静态资源源站,建议尽快迁移到专用对象存储服务
内容的提问来源于stack exchange,提问作者Diego Perez
相关产品推荐
相关产品推荐

