Spring 云/Netflix OSS 中的负载平衡
Load Balancing in Spring Cloud / Netflix OSS
我正在查看 Spring Boot / Cloud 和 Netflix FW(Eureka、Ribbon)。我正在处理这个例子:
https://spring.io/blog/2015/07/14/microservices-with-spring
基本上它是关于一些使用 Eureka Service Registry 的小型 Spring Boot 微服务。
我现在想启动同一服务的多个实例(在本例中为 AccountService,在不同的端口上)。我阅读的所有内容(上面的文章,http://callistaenterprise.se/blogg/teknik/2015/04/10/building-microservices-with-spring-cloud-and-netflix-oss-part-1/ 等)都表明,如果我这样做,所有实例都会冗余地注册到 Eureka,并且当我调用该服务时,应用客户端负载平衡并动态选择要调用的服务.
然而,事实并非如此。当我启动第一个服务实例时,它会注册并显示在 Eureka 仪表板中。当我在不同的端口上启动相同的服务时,它也会注册,但它似乎替换了以前的服务实例:Eureka 仪表板仍然只显示一个可用区 = 1(应该是 2?)的实例和对此服务的所有调用由二审处理。当我查询注册表时,只有这个实例被应用。
当我停止第二个实例时,一段时间后 Eureka 切换回第一个实例并且它仍然有效。所以它似乎保留了所有实例,但只使用最新注册的实例。
我错过了什么重要的事情吗?我以为应该同时使用所有实例?
==========
应用程序属性是(与 Spring 站点中的示例几乎没有变化):
EurekaServer
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
server:
port: 1111
spring:
thymeleaf:
enabled: false
AccountsServer
spring:
application:
name: accounts-service
freemarker:
enabled: false
thymeleaf:
cache: false
prefix: classpath:/accounts-server/templates/
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/
server:
port: 4444 # HTTP (Tomcat) port, for the second instance this is changed to a different port
我认为,由于您在 AccountsServer
上使用静态端口号,Eureka 只会注册一个实例...
你可以在客户端上做这样的事情
server:
compression.enabled: true
port: 0
(在这种情况下,我使用 YAML 进行配置,而不是属性)
在网关上,你应该指定你想要一个负载均衡器,就像那样
@Autowired
private LoadBalancerClient loadBalancer;
....
private String getUrl(){
return loadBalancer.choose("your-service-name").getUri().toString();
}
我做过类似的,有兴趣的可以看看here
@dshuld 如果您使用的是 Angel 发布火车或版本 1。0.x 您需要让每个实例都有一个唯一的 ID。参见docs here。类似于:
eureka:
instance:
metadataMap:
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
对于 Brixton 发布系列 (1.1.x),它应该有一个合理的默认值。
我正在查看 Spring Boot / Cloud 和 Netflix FW(Eureka、Ribbon)。我正在处理这个例子:
https://spring.io/blog/2015/07/14/microservices-with-spring 基本上它是关于一些使用 Eureka Service Registry 的小型 Spring Boot 微服务。
我现在想启动同一服务的多个实例(在本例中为 AccountService,在不同的端口上)。我阅读的所有内容(上面的文章,http://callistaenterprise.se/blogg/teknik/2015/04/10/building-microservices-with-spring-cloud-and-netflix-oss-part-1/ 等)都表明,如果我这样做,所有实例都会冗余地注册到 Eureka,并且当我调用该服务时,应用客户端负载平衡并动态选择要调用的服务.
然而,事实并非如此。当我启动第一个服务实例时,它会注册并显示在 Eureka 仪表板中。当我在不同的端口上启动相同的服务时,它也会注册,但它似乎替换了以前的服务实例:Eureka 仪表板仍然只显示一个可用区 = 1(应该是 2?)的实例和对此服务的所有调用由二审处理。当我查询注册表时,只有这个实例被应用。
当我停止第二个实例时,一段时间后 Eureka 切换回第一个实例并且它仍然有效。所以它似乎保留了所有实例,但只使用最新注册的实例。
我错过了什么重要的事情吗?我以为应该同时使用所有实例?
========== 应用程序属性是(与 Spring 站点中的示例几乎没有变化):
EurekaServer
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
server:
port: 1111
spring:
thymeleaf:
enabled: false
AccountsServer
spring:
application:
name: accounts-service
freemarker:
enabled: false
thymeleaf:
cache: false
prefix: classpath:/accounts-server/templates/
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/
server:
port: 4444 # HTTP (Tomcat) port, for the second instance this is changed to a different port
我认为,由于您在 AccountsServer
上使用静态端口号,Eureka 只会注册一个实例...
你可以在客户端上做这样的事情
server:
compression.enabled: true
port: 0
(在这种情况下,我使用 YAML 进行配置,而不是属性)
在网关上,你应该指定你想要一个负载均衡器,就像那样
@Autowired
private LoadBalancerClient loadBalancer;
....
private String getUrl(){
return loadBalancer.choose("your-service-name").getUri().toString();
}
我做过类似的,有兴趣的可以看看here
@dshuld 如果您使用的是 Angel 发布火车或版本 1。0.x 您需要让每个实例都有一个唯一的 ID。参见docs here。类似于:
eureka:
instance:
metadataMap:
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
对于 Brixton 发布系列 (1.1.x),它应该有一个合理的默认值。