如何优化一个大接口的流量

背景

接口流量占比很大,比如app启动时需要获取的下发大量资源的数据接口。这种接口会下发大量的数据并且请求的频率也比较高,返回体的数据包很大导致流量很大。

优化思路

  • 减少包体大小,省略或简化字段
  • 客户端减少请求次数
  • 304 etag 或类似的重复利用返回数据的规则
  • 分机房部署

优化方案

减少包体大小,省略或简化字段

  • 所有的返回字段json tag添加上omitempty,加上这个tag后,当这个字段是默认空值时,json序列会将其省略。这会使得返回体的字段数减少。在实际使用的时候需要特殊注意一下,例如,在go语言中,假设有如下结构
type StructA struct {
	xxxxxx
}

type StructB struct {
	xxxx
	A StructA `json:"a,omitempty"`
	xxx
}

当有一个StructB的实例b,它没有给A赋任何值的时候,A的值为空的StructA结构体,而不是nil, 这会使得即便加上了omitempty Tag,序列化之后依旧会有这个A字段,如果想要达到省略A字段的目的的话应该使用指针,因为指针的默认值为nil,eg:

type StructB struct {
	xxxx
	A *StructA `json:"a,omitempty"`
	xxx
}
  • 简化字段, 假设这个接口下发了大量的资源数据,它是一个超大的list,每个元素都是一个资源的具体信息,包括icon,大图,动画效果等资源的地址。这些其实可以提取出公共部分以减少字段的大小。假设返回体类似:
{
    "datas":[
        {
            "icon":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "image":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "anim_pag":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.pag"
        },
        {
            "icon":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "image":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "anim_pag":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.pag"
        },
        {
            "icon":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "image":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.png",
            "anim_pag":"https:xxxx.xxx.com/xxx/xxxxxxx/xx.pag"
        }
    ]
}

其实域名部分都是重复的,完全可以提取出来用另一个字段下发,改造成这个样子

{
    "datas":[
        {
            "icon":"xxx/xxxxxxx/xx.png",
            "image":"xxx/xxxxxxx/xx.png",
            "anim_pag":"xxx/xxxxxxx/xx.pag"
        },
        {
            "icon":"xxx/xxxxxxx/xx.png",
            "image":"xxx/xxxxxxx/xx.png",
            "anim_pag":"xxx/xxxxxxx/xx.pag"
        },
        {
            "icon":"xxx/xxxxxxx/xx.png",
            "image":"xxx/xxxxxxx/xx.png",
            "anim_pag":"xxx/xxxxxxx/xx.pag"
        }
    ],
    "domain": "https:xxxx.xxx.com/",
}

这种优化方法也可以用在redis等缓存的内存优化上,有些缓存cache了大量的资源路径,用户头像等信息,这些url往往很长,但是域名和桶路径占了大部分,可能只有最后一点后缀是不一样的

  • 整理已经不再使用了的字段,随着业务的迭代有很多字段已经被废弃了,有很多代码分支是通过版本判断来区分的,过早的历史版本几乎已经不可用,所以可以定期进行精简。

客户端减少请求次数

  • 客户端本地做缓存处理,每次请求前先查缓存,这样有个坏处就是服务端的更新不会立即生效,如果是下发的静态资源,更新比较少的,可以这样做。
  • 客户端不以接口为整体来缓存数据,以每个资源为单位来进行缓存处理。比如下发的是大量的商品信息,那就根据每个商品id来进行缓存,这样缓存数据比较灵活,后续更新也比较灵活,比如可以一次性只获取某几个商品的数据而不是全获取。但是客户端的逻辑比较复杂。

304 etag 或类似的重复利用返回数据的规则

  • 304 etag。大概的用法就是header中添加一个字段来标注当前请求的内容,客户端请求之前先把上次拿到的一起传给服务端,服务端重新计算一下当前的返回值的etag,如果和上次的一样,那么就直接返回空数据,http code 304,相当于不返回任何数据,减少了流量消耗。客户端接收到这个code后就知道数据没有更新,继续使用老的数据。
  • 由服务端来控制减少请求次数, 添加一个last_requst_time字段,客户端每次请求的时候带上这个上次请求时间的字段,字段内容是上次请求时的时间戳。服务端拿到这个字段之后就知道客户端多久之前请求过这个接口,比如限定30min内只允许请求一次,那么只要now()-last_requst_time<30min,就直接返回空数据。服务端来控制减少请求次数的好处是这个逻辑比较容易修改可控,如果是客户端来处理的话发版之后不容易控制

分机房部署

  • 分机房部署并不能减少流量的大小,但是一般如果返回体比较大并且跨地区访问的话,数据传输时间会比较大,分机房部署可以减少相应时间。另外可以在各个地区配置cdn来加速访问。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值