最近在做服务器迁移, 之前是直接使用阿里云的slb. 随着业务的发展以及稳定性要求, 决定对服务器进行升级, 同时对业务进行拆分, 经过多种考虑最后使用slb+nginx路由方案.
前端使用slb的tcp监听, 开启会话保持. ecs上配置nginx进行二次转发.
浏览器访问一切正常, 也没有用户报任何使用问题.
就这样无风无雨的过了一天, 第二天业务人员报微信支付数据异常, 转账成功, 转账标识显示失败.
开发人员开始进行排查, 发现服务器可以正常接收微信回调, 不过服务器间调用出现异常.
后台日志显示: java.net.ConnectException: Connection timed out
我开始查看nginx日志, 发现没有找到请求日志, 怀疑是nginx问题, 使用curl请求ecs, 返回值正常, 使用curl请求外网域名, curl无反馈, 看来问题出现在阿里云的slb上面.
去网上搜了搜, 还真有人遇到同样的问题, 只是标题是不是很一致.
解决方案是将slb的tcp监听改为http监听.
以下为阿里云给出的理由:
https://help.aliyun.com/document_detail/27680.html?spm=5176.doc27671.6.240.6lfhRY
为什么用4层负载均衡后端ECS访问(如telnet)其实例服务地址不通?
这和负载均衡 TCP的实现机制有关。在4层(TCP协议)服务中,当前不支持添加进后端云服务器池的ECS既作为Real Server,又作为客户端向所在的负载均衡实例发送请求。因为,返回的数据包只在云服务器内部转发,不经过负载均衡,所以通过配置在负载均衡内的ECS去访问的VIP是不通的。
注意: 当负载均衡从4层更换到7层之后, 虽然开启了获取真实ip, 程序获取真实ip还需要做一些特别的设置, 阿里云官方文档有详细描述: 负载均衡 7 层 HTTP 模式获取来访客户端真实 IP 的方法(IIS/Apache/Nginx/Tomcat)
附参考网址: 阿里云SLB负载均衡https协议的一点小问题