## 前言
这周很值得纪念,首先是 [`goproxy.cn`](https://goproxy.cn) 已缓存的模块版本总数突破了**一百万**,这甚至比起 Go 官方的 [`proxy.golang.org`](https://proxy.golang.org) 已缓存的还要多出不少。其次是 [`goproxy.cn`](https://goproxy.cn) 的日访问量已稳定在**千万级**,正在朝着亿级进发,目前这在国内我了解到的别的几个同类服务中是最多的了。另外尤为重要的一点是,经过我们的不懈努力,甚至付出了两次事故的代价(详见:[`status.goproxy.cn`](https://status.goproxy.cn)),我们终于使得 [`goproxy.cn`](https://goproxy.cn) 达到了**零错误率**!现在的 [`goproxy.cn`](https://goproxy.cn) 可以说是很稳的了,大家可以放心使用。当然,我也知道最近一个月可能有些朋友对 [`goproxy.cn`](https://goproxy.cn) 产生了些许的不信任感,这个责任在我个人。我为了实现零错误率尝试过了太多不寻常的操作,很多人都告诉我不可能、别想了,但我自己爱折腾的毛病致使我无法不去研究。我坚信哪怕只有两三天的零错误率也能为服务的可靠性大大地加上一分,所以我不停地尝试不同的方法,导致了这个月间断性地出过几次问题。我在 [`www.v2ex.com/t/651330 `](https://www.v2ex.com/t/651330) 这片帖子中也有解释过,我曾在潜意识里认为 [`goproxy.cn`](https://goproxy.cn) 还是那个我自己搭建自己跑的鲜有人用的小服务,所以做事欠考虑,甚至还跟别人说出过“我不介意用事故来换取低错误率的优化方式”这种不负责任的话……在这里我再次为自己的鲁莽行为向大家郑重地道个歉,以后我会铭记“基础服务以稳定为本”这句话,克制住自己爱折腾的毛病……恐怕在所有同类服务的维护者中只有我是最喜欢瞎搞的了……
好了,开头稍微为这一个月发生的事情做了个小总结。接下来说一下本次的重点,也就是 [`goproxy.cn`](https://goproxy.cn) 推出了 Go 模块代理世界中的**首个**统计数据 API(文档详见:[`goproxy.cn/stats`](https://goproxy.cn/stats)),这是个原本计划在二月底就发布的特性。统计数据 API 其实很早就开发完了(几个月前就基本完工了),但却迟迟未发布,主要原因是跟我们前一阵子在探索零错误率相关,我们想在一个完美的时间点把它介绍给大家。这一阵子有很多大佬催过我,比如光无闻大哥一人就已经催过我很多次了……在这里统一道个歉……当然,迟到总比不到好,让大家久等了!
目前先推出了 4 种呼声较高的 API,后续可能还会有其他 API 被添加进来。
***注意:由于数据不慎丢失,目前 [`goproxy.cn`](https://goproxy.cn) 的数据统计 API 所展示的只是最近三个月的数据,而不是自 [`goproxy.cn`](https://goproxy.cn) 上线起的所有历史数据。**
## API:获取服务摘要
首先是一个用于获取服务摘要信息的 API,通过调用这个 API 你可以获取到 [`goproxy.cn`](https://goproxy.cn) 中诸如所有模块版本的总尺寸和总数等信息。
获取服务摘要 API 的 URL 是固定的,没有路径参数:`goproxy.cn/stats/summary`。
```json
{
"cacher_size": 2663405247231,
"module_version_count": 1035421,
"module_host_count": 1120,
"top_10_module_hosts": [
{"module_host": "github.com", "module_version_count": 921606},
{"module_host": "k8s.io", "module_version_count": 24982},
{"module_host": "gitlab.com", "module_version_count": 13172},
{"module_host": "gopkg.in", "module_version_count": 10479},
{"module_host": "golang.org", "module_version_count": 8000},
{"module_host": "gitee.com", "module_version_count": 4650},
{"module_host": "bitbucket.org", "module_version_count": 4177},
{"module_host": "sigs.k8s.io", "module_version_count": 3280},
{"module_host": "google.golang.org", "module_version_count": 2703},
{"module_host": "istio.io", "module_version_count": 2487}
]
}
```
上面的示例响应中各字段的含义如下:
* `cacher_size`:所有模块版本的总尺寸,单位是“字节”
* `module_version_count`:所有模块版本的总数
* `module_host_count`:模块主机地址的总数
* `top_10_module_hosts`:所拥有的模块版本数排名前十的模块主机地址
* `top_10_module_hosts.module_host`:模块主机地址
* `top_10_module_hosts.module_version_count`:模块主机地址所拥有的模块版本总数
## API:获取模块趋势
然后呼声蛮高的一个 API 就是获取服务中的模块趋势,有很多人好奇自己的模块在 [`goproxy.cn`](https://goproxy.cn) 中的活跃度排名究竟是怎样的。
目前我们提供了三类趋势,它们均只返回一段时间内的最活跃的最多前 1000 个模块:
* `goproxy.cn/stats/trends/latest`:获取最新趋势
* `goproxy.cn/stats/trends/last-7-days`:获取最近 7 天的趋势
* `goproxy.cn/stats/trends/last-30-days`:获取最近 30 天的趋势
```json
[
{"module_path": "golang.org/x/sys", "download_count": 1822180},
{"module_path": "golang.org/x/net", "download_count": 1713080},
{"module_path": "golang.org/x/tools", "download_count": 1503522},
{"module_path": "golang.org/x/crypto", "download_count": 1032270},
{"module_path": "gopkg.in/yaml.v2", "download_count": 578120}
]
```
上面的示例响应中各字段的含义如下:
* `module_path`:模块路径
* `download_count`:模块路径对应的所有模块版本的总下载次数
## API:获取模块(版本)统计
当然,我们支持获取服务中指定模块(版本)的统计,这也算是统计数据 API 的刚需了。
获取模块(版本)统计的 API 的 URL 格式为 `goproxy.cn/stats/<module-path>[@<module-version>]`。如 `goproxy.cn/stats/golang.org/x/text` 表示获取模块路径为 `golang.org/x/text` 的模块的所有模块版本的总统计,而 `goproxy.cn/stats/golang.org/x/text@v0.3.2` 表示获取该模块的 `v0.3.2` 版本的统计。
```json
{
"download_count": 476705,
"last_30_days": [
{"date": "2020-03-25T00:00:00Z", "download_count": 8778},
{"date": "2020-03-24T00:00:00Z", "download_count": 16884},
{"date": "2020-03-23T00:00:00Z", "download_count": 15842},
{"date": "2020-03-22T00:00:00Z", "download_count": 11232},
{"date": "2020-03-21T00:00:00Z", "download_count": 11894},
{"date": "2020-03-20T00:00:00Z", "download_count": 14968},
{"date": "2020-03-19T00:00:00Z", "download_count": 11017},
{"date": "2020-03-18T00:00:00Z", "download_count": 5209},
{"date": "2020-03-17T00:00:00Z", "download_count": 5759},
{"date": "2020-03-16T00:00:00Z", "download_count": 4166},
{"date": "2020-03-15T00:00:00Z", "download_count": 2145},
{"date": "2020-03-14T00:00:00Z", "download_count": 2218},
{"date": "2020-03-13T00:00:00Z", "download_count": 4609},
{"date": "2020-03-12T00:00:00Z", "download_count": 5503},
{"date": "2020-03-11T00:00:00Z", "download_count": 5412},
{"date": "2020-03-10T00:00:00Z", "download_count": 6453},
{"date": "2020-03-09T00:00:00Z", "download_count": 4798},
{"date": "2020-03-08T00:00:00Z", "download_count": 2323},
{"date": "2020-03-07T00:00:00Z", "download_count": 2332},
{"date": "2020-03-06T00:00:00Z", "download_count": 4806},
{"date": "2020-03-05T00:00:00Z", "download_count": 6339},
{"date": "2020-03-04T00:00:00Z", "download_count": 5858},
{"date": "2020-03-03T00:00:00Z", "download_count": 5579},
{"date": "2020-03-02T00:00:00Z", "download_count": 8862},
{"date": "2020-03-01T00:00:00Z", "download_count": 2119},
{"date": "2020-02-29T00:00:00Z", "download_count": 2053},
{"date": "2020-02-28T00:00:00Z", "download_count": 4735},
{"date": "2020-02-27T00:00:00Z", "download_count": 6578},
{"date": "2020-02-26T00:00:00Z", "download_count": 4954}
],
"top_10_module_versions": [
{"module_version": "v0.3.2", "download_count": 232795},
{"module_version": "v0.3.0", "download_count": 146009},
{"module_version": "v0.3.1-0.20180807135948-17ff2d5776d2", "download_count": 67096},
{"module_version": "v0.3.1-0.20181227161524-e6919f6577db", "download_count": 11494},
{"module_version": "v0.0.0-20160726164857-2910a502d2bf", "download_count": 11223},
{"module_version": "v0.0.0-20170915032832-14c0d48ead0c", "download_count": 3991},
{"module_version": "v0.3.1-0.20171227012246-e19ae1496984", "download_count": 1128},
{"module_version": "v0.0.0-20170915090833-1cbadb444a80", "download_count": 937},
{"module_version": "v0.3.1-0.20181030141323-6f44c5a2ea40", "download_count": 480},
{"module_version": "v0.3.1", "download_count": 353}
]
}
```
上面的示例响应中各字段的含义如下:
* `download_count`:模块(版本)的总下载次数
* `last_30_days`:模块(版本)最近 30 天的统计
* `last_30_days.date`:模块(版本)统计的日期
* `last_30_days.downlaod_count`:模块(版本)单日的下载次数
* `top_10_module_versions`:该字段仅在根据模块路径获取其对应的所有模块版本的总统计时才会返回,表示其下载次数排行前十的模块版本
* `top_10_module_versions.module_version`:模块版本
* `top_10_module_versions.download_count`:模块版本的下载次数
### API:获取模块总下载次数徽章
为了使模块作者们能更好地展示自己的模块在 [`goproxy.cn`](https://goproxy.cn) 的总下载次数,我们支持了 SVG 徽章。
获取模块总下载次数徽章的 API 的 URL 格式为 `goproxy.cn/stats/<module-path>/badges/download-count.svg`。
你可以通过下述 Markdown 语法轻松地将指定模块的总下载次数徽章放入项目 `README.md` 中:
```
[![goproxy.cn](https://goproxy.cn/stats/<module-path>/badges/download-count.svg)](https://goproxy.cn)
```
比如 [`goproxy.cn/stats/golang.org/x/text/badges/download-count.svg`](https://goproxy.cn/stats/golang.org/x/text/badges/download-count.svg):
[![goproxy.cn](https://goproxy.cn/stats/golang.org/x/text/badges/download-count.svg)](https://goproxy.cn)
## 结语
由于我们是首家支持统计数据 API 的 Go 模块代理,所以我们预留了一段时间的功能探索期,在此期间内我们欢迎大家随时通过 [`goproxy.cn/stats`](https://goproxy.cn/stats) 页面中提到的联系方式来分享你们的意见建议,一起为咱们中国 Go 语言社区的这个 Go 模块代理打造出一个功能性良好的统计数据 API。
最后再强调一点,[`goproxy.cn`](https://goproxy.cn) 由七牛运营,服务于 Go 语言社区,它永久免费,也一如既往地不加以任何形式的带宽限制、速率限制,大家可以敞开了用、放心地用。有问题?问;有建议?提。我们一直那里,欢迎随时来访。
有疑问加站长微信联系(非本文作者)