知乎上看到一个问题,说 Nginx 的 upstream 不就是负载均衡嘛,配几台后端机器,请求自动分发,和 Nacos、Eureka 这些注册中心干的事有什么本质区别?为什么还要额外引入一整套服务注册发现的东西?
这个问题热度挺高,其实这个问题问得挺好好,因为很多人对这个似是而非,感觉挺明白,面试问他他又不知道怎么组织语言。
Nginx和注册中心解决的他就不是一个问题啊!
Nginx 解决的是「请求该转发给谁」,属于转发规则;注册中心解决的是「后端服务实例的状态」,属于实时状态感知。
Nginx 负载均衡的不足
Nginx 负载均衡缺点很明显,实例列表是写死的,Nginx 做负载均衡的配置大家都见过,非常的简单。
upstream order-service{
server192.168.1.10:8080;
server192.168.1.11:8080;
server192.168.1.12:8080;
}
server{
location/api/orders{
proxy_passhttp://order-service;
}
}
三台机器轮询转发,服务数量少、实例基本不变动的情况下,这完全没问题。
问题是这个列表是静态的,写死在配置文件里了。
我每次后端实例变化,比如扩容加机器、缩容摘机器、某台挂了,就需要修改配置文件,然后执行nginx -s reload,如果部署了多台 Nginx,每台都得改,比较麻烦。
机器少的时候这还能接受,微服务都几十个服务打底、每个服务多个实例、还要支持弹性扩缩容,靠手工改配置,上个线那肯定要通宵啊!
Nginx 感知不到实例挂了
Nginx 有被动健康检查机制,后端连续返回错误时,会把那台机器暂时摘掉。但这个机制有个前提:必须有真实请求打过去失败了,才能发现这台机器有问题。
举个具体场景:
图片
T1和T2的请求是用真实用户的流量去试错的,在这段时间内所有打到 .11 的请求全部超时。
注册中心的机制不一样
服务实例启动后会持续向注册中心发送心跳,默认 5 秒一次。心跳超时没收到,注册中心直接把这个实例从注册表里摘掉。消费方下次拉取实例列表时,这个实例就已经不在了,整个过程不需要用真实流量去探路。


闽公网安备 35020602001684号