吐槽一下阿里云图片服务

起因

近期由于 UPYUN 的图片服务频繁出现低级问题(具体啥问题就不列出来了, 反正影响到我们的业务逻辑), 我们决定整体切换到阿里云图片存储服务. 接入阿里云的过程中, 我们又发现一系列让人恼火的问题, 干脆总结一下解决方法, 顺带吐个槽

问题

依赖

问题始于我们 App 的网络库与阿里云 SDK 的依赖冲突上:

  • 我们的 App 使用 Retrofit2 实现网络请求层, 而 Retrofit2 依赖于 okhttp3 以及 okio
  • 阿里云 SDK 的网络请求依赖于 okhttp2 + okio, 并且无法替换

由于 okhttp2 和 okhttp3 不兼容, 我们必须同时保留对两者的依赖

Proguard

同时保留 okhttp2 和 okhttp3 带来了新的问题: Proguard
由于两个库都包含了一些同名类, 在编译时这些同名类会产生冲突导致编译失败

解决

方案

在狠狠吐槽阿里云 SDK 后, 我们决定将它抛弃, 毕竟不能为了它而强行降级我们的库.
但是我们仍然希望使用阿里云图片存储, 怎么办? 自己实现!

实现

对于我们的业务来说, 目前 SDK 最重要的事情就是帮助生成鉴权信息, 其他功能于我们(暂时)都没啥作用.
根据阿里云 SDK 的文档以及阅读源码, 我们了解到了阿里云的 STS 鉴权机制. 剩下来的就是自己实现了.

具体的代码没有必要贴出来, 毕竟阅读文档 + 参考源码就能实现. 这里列一下去 SDK 的具体过程吧:

  1. 分析业务逻辑依赖的 SDK 接口
  2. 实现自定义类 AliyunUtils, 代理对 SDK 的依赖
  3. 将业务逻辑中所有对 SDK 的依赖重定向到 AliyunUtils 中, 这一步解除了业务代码与阿里云 SDK 的耦合
  4. 修改 AliyunUtils 的实现, 不再代理 SDK 接口, 而是自己实现鉴权等方法
  5. 删除阿里云 SDK, 至此, 我们的 App 不再依赖阿里云 SDK, 同时也去掉了对 okhttp2 的依赖

思考

阿里云 SDK 使用优秀的网络库是一件极好的事情, 毕竟 okhttp 好用, 可以提升 SDK 开发效率. 但是开发者们忽略了几个问题:

  1. 作为一个优秀的网络库, okhttp 可能早已存在于需求方的依赖列表中
  2. okhttp 是在不断更新的
  3. 阿里云 SDK 里并没有提供设置自定义网络库的接口

言尽于此, 想必大家心里有数了, 这个 SDK 的问题不在代码质量而在设计思路, 我们以后在工作中务必引以为戒.