系统架构
问题描述
在公众号token验证,通过此域名一直请求不到服务器,报token check fail,但是通过浏览器、终端访问此url均可以访问成功,
问题定位
-
询问运维是否对SLB加了白名单,运维答复没加白名单限制
-
是不是微信回调不支持我们的域名格式,tmp.xxxxx.com,在我们内部进行验证可以支持
-
以上2个假设都没问题,于是查找公众号验证相关资料看看有什么线索,发现微信发送的请求是http1.0,所以可能是这块导致的问题,于是写了一个程序进行了验证
public class MyTest {
public void get(String url) throws Exception {
// 创建HttpClient实例
HttpClient client = HttpClientBuilder.create().build();
// 根据URL创建HttpGet实例
HttpGet get = new HttpGet(url);
//指定http1.0
get.setProtocolVersion(HttpVersion.HTTP_1_0);
// 执行get请求,得到返回体
HttpResponse response = client.execute(get);
// 判断是否正常返回
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 解析数据
String data = EntityUtils.toString(response.getEntity(), Charsets.UTF_8);
System.out.println("-----"+data+"----------");
}
String data = EntityUtils.toString(response.getEntity(), Charsets.UTF_8);
System.out.println("-----"+response+"----------");
}
/**
* 申请SLB测试
* @throws Exception
*/
@Test
public void test4() throws Exception {
get("http://tmp.xxxxx.com/s-park/middle/wechat/api/portal/xxxx");
}
}
执行以上脚本,返回以下结果
修改http版本为1.1,再次进行测试
通过以上的定位可以确定是由于istio不支持http1.0导致。
问题处理
目前已经定位到问题是由于istio不支持 http1.0导致,所以解决此问题也有几种方式
- 通过slb把http1.0转成http1.1
-
如果slb不支持,通过在slb到k8s之间搭建nginx进行协议版本转换
-
修改istio,支持http1.0
由于第三种方式,是最方便也是最通用的解决方式,所以先优先按照第三种方式去处理,如果支持不了,在考虑其他二种处理方法。
修复 istio 支持http1.0
查看资料istio相关资料,了解Istio 中负责流量转发的是 Envoy,Envoy 中可以设置支持 HTTP/1.0,Istio 负责分配“规则”的是 Pilot,Pilot 的环境变量 PILOT_HTTP10 默认为 0,即不支持 HTTP/1.0,如果要支持,需要修改PILOT_HTTP10的属性为1即可支持http1.0。
于是查看怎么指定此属性,由于我们是通过helm安装的istio,于是查看chart相关参数,发现有pilot.env应该可以指定参数
再次确认此属性的引用是在manifests/charts/istio-control/istio-discovery/templates/deployment.yaml的pilot的env中,应该没问题
由于istio已经安装完成,所以只能通过修改的方式进行更新
执行以下命令进行更新
helm upgrade istiod manifests/charts/istio-control/istio-discovery \
--set global.hub="docker.io/istio" \
--set global.tag="1.15.1" \
--set pilot.env.PILOT_HTTP10=1 \
-n istio-system
执行完成,检查PILOT_HTTP10是否配置成功,执行以下命令,可以看到结果返回为1,开启成功
kubectl describe deployment istiod -n istio-system | grep PILOT_HTTP10
结果验证
- 再次执行http1.0请求测试脚本,查看是否请求成功,可以看到有响应结果,请求成功
- 在公众号配置回调验证,一次成功。。。
总结
-
由于微信返回的信息实在有限,导致这个问题排查耗费了好几天,建议微信能把对应调用方的响应结果返回来,这样可以快速解决问题,正好微信社区里有人提到http1.0的问题,所以才能最终定位到问题,不然我们可能还在排查中
-
此问题也验证了我们对k8s的一些细节不了解,以及对k8s运维监控不到位,应该加强对这方面的研究