我已经设置了面向互联网的ELB来访问Apache airflow的webserver,它运行在8080的实例中。
组态
以下是ELB的terraform资源
resource "aws_elb" "airflow_elb" {
name = "${var.domain_name}-elb"
subnets = [
"${aws_subnet.private.id}"]
security_groups = [
"${aws_security_group.public.id}"]
"listener" {
instance_port = 8080
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
health_check {
healthy_threshold = "${var.elb_healthy_threshold}"
interval = "${var.elb_interval}"
target = "HTTP:8080/admin/"
timeout = "${var.elb_timeout}"
unhealthy_threshold = "${var.elb_unhealthy_threshold}"
}
access_logs {
bucket = "${aws_s3_bucket.bucket.bucket}"
bucket_prefix = "elb-logs"
interval = 60
}
cross_zone_load_balancing = false
idle_timeout = 400
connection_draining = true
connection_draining_timeout = 400
tags {
Name = "airflow-elb"
}
}
我可以通过堡垒主机ssh隧道到private-ip实例,门户网站没有任何问题。但是,当我通过ELB的DNS名称访问时,它要么非常慢,在这种情况下我可以看到请求几乎立即从Web服务器被请求,但需要永远加载或ELB抛出HTTP 503
请帮忙!!
EDIT1:后端处理时间非常长,但我可以看到只有从ELB访问时才会发生这种情况,当从隧道连接完成时它表现正常。
假设您正在使用经典ELB根据AWS Documentation
陈述的三个原因有:
原因1:负载均衡器中的容量不足,无法处理请求。
原因2:没有注册实例。
原因3:没有健康的实例。
登录到控制台并查看实例是否在ELB下注册,如果是,它们是否处于健康状态?
另外我很好奇你为什么只使用一个AZ?
诊断ELB问题时的一些有用资源:
问题实际上是使用带有python 3的同步工作程序以及ELB如何重用http连接。从同步工作器更改为gevent后,问题消失了。但是python 3还没有支持gevent,所以我们现在仍然坚持使用python 2.7
你可以尝试这个答案:https://stackoverflow.com/a/42300647/2727462
解决方案如果您将DNS配置为直接命中ELB - >您应该减少关联的TTL(IP,DNS)。 IP随时可以随ELB发生变化,因此您的流量可能会受到严重损害。
客户端将一些IP保留在缓存中的ELB中,这样您就可以遇到麻烦了。
扩展弹性负载均衡器创建弹性负载均衡器后,必须将其配置为接受传入流量并将请求路由到EC2实例。这些配置参数由控制器存储,控制器确保所有负载平衡器都以正确的配置运行。控制器还将监视负载平衡器并管理用于处理客户端请求的容量。它通过利用更大的资源(具有更高性能特征的资源)或更多的个人资源来增加容量。 Elastic Load Balancing服务将在扩展时更新负载均衡器的域名系统(DNS)记录,以便新资源在DNS中注册其各自的IP地址。创建的DNS记录包括60秒的生存时间(TTL)设置,期望客户端至少每60秒重新查找DNS。默认情况下,Elastic Load Balancing将在客户端执行DNS解析时返回多个IP地址,并在每个DNS解析请求上随机排序记录。随着流量配置文件的更改,控制器服务将扩展负载平衡器以处理更多请求,并在所有可用区中进行相同的扩展。
就我而言,问题出在TTL上。问题可以通过像wget https://your-url
这样的命令来跟踪。命令输出将显示它尝试连接的IP地址。当连接挂起时,您可以找出错误的过时IP地址。如果发生 - 请检查您的DNS设置并更新TTL。