阿里云SLB负载均衡https协议的一点小问题

最近在阿里云金融云ECS云服务器上部署程序后发现, 代码中的curl无法通过http/https请求同一ECS实例中的接口应用服务; 而在本地环境中测试无任何异常;

问题排查

最后排查发现是阿里金融云SLB的问题:  slb后端提供4层和7层负载均衡两种方式, 目前我们使用的正是4层TCP协议, 因为其优点是后端也支持https协议的443端口, 而且4层的源IP即客户端ip经过slb后不会发生变化, 因此可以直接获取到用户真实IP; 另外从性能上来说, 4层直接是LVS硬件负载均衡后, 不需再和7层一样经过Tengine 应用层, 就可以直达后端服务器, 因此速度更快. 但是问题就出在:

负载均衡超时问题

CASE4 从4层负载均衡后端服务器访问该4层负载均衡VIP

4层负载均衡,在该负载均衡的后端服务器上再去访问该负载均衡VIP,这个目前是无法支持的,会导致连接失败,常见的场景是用户后端应用使用URL拼接的方式跳转访问

又 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层SLB.

因为需要前端支持HTTPS (即用户通过443端口访问网站时),  slb后端只支持http, 加密过程是在slb上完成, 因此需要根据说明上传ssl证书到slb管理后台.

aliyun_slb_https

 

另外, 对于通过http 80端口的用户访问, 我们希望让它自动跳转到https端口, 因此slb上需要再建立一个支持http的前端协议监听端口, 后端也是只支持http协议, 这和https前端协议不矛盾, 只需将http协议的后端端口号设置成不一样即可. 同时在后端的服务器的nginx或apache中同时加上这两个http端口的监听, 如:

443-80port

注意下: 后端nginx设置了目录重写, 不带斜杠的url地址跳转到带斜杠的地址时, 因后端的$scheme是http, 跳转后的地址会变成http并带上443端口号, 如 https://www.example.com/h5 会跳转到http://www.example.com:443/h5/, 导致400错误: The plain HTTP request was sent to HTTPS port.  除非对/h5 地址特别指定重定向, 如下:

 location = /h5{
        rewrite ^/h5$ https://www.example.com/h5/ permanent;
 }
 location /h5{
        try_files $uri @rewrite;
 }
 location @rewrite{
         rewrite ^/h5/(.*)$ /h5/h5/public/index.php?_url=/$1;
 }

其他获取真实ip等问题

注意: 当负载均衡从4层更换到7层之后, 虽然开启了获取真实ip, 程序获取真实ip还需要做一些特别的设置, 阿里云官方文档有详细描述: 负载均衡 7 层 HTTP 模式获取来访客户端真实 IP 的方法(IIS/Apache/Nginx/Tomcat).

 

One thought on “阿里云SLB负载均衡https协议的一点小问题”

Leave a Reply

Your email address will not be published. Required fields are marked *