今天遇到个奇葩问题,一直在使用的通知接口突然报错了
背景
我们提供了一个 post 通知接口(http://example.com/notify)突然失效了,导致三方发货失败,我们这边是java服务,三方是golang服务
我这边查了半天服务器日志,最后查到该请求报错是:Request method 'GET' not supported
,很奇怪,为什么变成了 GET
请求;
为啥查了半天日志,因为这帮开发不知道为啥老喜欢把日志级别改成 INFO ,众所周知,spring-webmvc 只会在 DEBUG 级别打印请求信息,
就导致我看不到测试的请求,改成 DEBUG 之后才看到报错信息虽然全局异常已经打印
GlobalBizExceptionHandler : Request method 'GET' not supported
,但是鬼知道是谁的请求导致的
当跑到三方后台去调试接口的时候,发现填写的通知链接是:http://example.com/notify
由于前几天运维把公司全部域名都加上了重定向配置
,那就先改成https
再试一把,果然成功了;
但是,为什么 POST
请求会变成 GET
请求?
当时想了很多可能引发的原因,但是首先还是从三方的golang服务来推测,golang 中请求接口用的是net/http
,不管3721,直接去google一番,
果然查到相似问题 Why do POST request in the Go http.Client not follow 301 redirects?
文中提到 it seems like GET requests follow 301 redirects, but not POST requests: http://golang.org/src/net/http/client.go
,似乎 GET 请求才能正常 301 重定向,而 POST 请求不会
,还引导我们去看 net/http/client
源码:
/usr/local/Cellar/go@1.13/1.13.15/libexec/src/net/http/client.go:433
1 |
case 301, 302, 303: |
这段代码意思即:当碰到 301
, 302
, 303
状态码,同时请求不是 GET
, HEAD
方法时,强制把重定向请求的方法改成了 GET
,到这里算是真相大白了!
同时,如果对这段代码感兴趣的话,也可以读读client
中net/http/client.go:393
–Get
方法的注释
最后
- 运维层修改配置,一定要确保通知到开发侧,否则找问题要费很大劲
- 像日志级别配置这种看似没技术含量的东西,没有经验的开发人员不要去管它,直接设置
DEBUG
级别即可,不要过多考虑服务器硬盘不够这种小问题