我正在使用微服务架构,其工作方式如下
我有两个服务Web应用程序(REST服务)在eureka服务器中正确注册,然后我有一个客户端应用程序获取eureka注册表并使用功能区作为客户端负载均衡器,确定哪个服务应用程序去(目前,正在使用简单的Round Robin)。
我的问题是,当我停止其中一个服务应用程序(它们目前在docker container btw中运行)时,eureka不会将它们从注册表中删除(似乎需要几分钟),因此功能区仍然认为有2个可用服务,使大约50%的呼叫失败。
不幸的是我没有使用Spring Cloud(出于我无法控制的原因)。所以我对eureka的配置如下。
对于服务应用程序:
eureka.registration.enabled=true
eureka.name=skeleton-service
eureka.vipAddress=skeleton-service
eureka.statusPageUrlPath=/health/ping
eureka.healthCheckUrlPath=/health/check
eureka.port.enabled=8042
eureka.port=8042
eureka.appinfo.replicate.interval=5
## configuration related to reaching the eureka servers
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://eureka-container:8080/eureka/v2/
eureka.decoderName=JacksonJson
对于客户端应用程序(eureka +功能区)
###Eureka Client configuration for Sample Eureka Client
eureka.registration.enabled=false
eureka.name=skeleton-web
eureka.vipAddress=skeleton-web
eureka.statusPageUrlPath=/health/ping
eureka.healthCheckUrlPath=/health/check
eureka.port.enabled=8043
eureka.port=8043
## configuration related to reaching the eureka servers
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://eureka-container:8080/eureka/v2/
eureka.decoderName=JacksonJson
eureka.renewalThresholdUpdateIntervalMs=3000
#####################
# RIBBON STUFF HERE #
#####################
sample-client.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# expressed in milliseconds
sample-client.ribbon.ServerListRefreshInterval=3000
# movieservice is the virtual address that the target server(s) uses to register with Eureka server
sample-client.ribbon.DeploymentContextBasedVipAddresses=skeleton-service
答案 0 :(得分:0)
如果要在Eureka Server中更快地检测死实例,请尝试使用eureka.instance.leaseExpirationDurationInSeconds参数。默认情况下,该值设置为90秒,这意味着在连续3次丢失心跳后租约已过期。
答案 1 :(得分:0)
我在开发中也遇到过类似的问题, 我尝试过很多事情,为我工作。
1)代替使用eureka注册表,仅使用基础功能区并根据我们的需要修改其运行状况检查机制,为此,可为IPing提供自己的实现方式
buildSrc
覆盖负载平衡行为
public class PingUrl implements com.netflix.loadbalancer.IPing {
public boolean isAlive(Server server) {
String urlStr = "";
if (isSecure) {
urlStr = "https://";
} else {
urlStr = "http://";
}
urlStr += server.getId();
urlStr += getPingAppendString();
boolean isAlive = false;
try {
ResponseEntity response = getRestTemplate().getForEntity(urlStr, String.class);
isAlive = (response.getStatusCode().value()==200);
} catch (Exception e) {
;
}
return isAlive;
}
}
}
@SpringBootApplication
@EnableZuulProxy
@RibbonClients(defaultConfiguration = LoadBalancer.class)
@ComponentScan(basePackages = {"com.test"})
public class APIGateway {
public static void main(String[] args) throws Exception {
SpringApplication.run(APIGateway .class, args);
}
提供可用性过滤规则
public class LoadBalancer{
@Autowired
IClientConfig ribbonClientConfig;
@Bean
public IPing ribbonPing() {
return new PingUrl(getRoute() + "/ping");
}
}
private String getRoute() {
return RequestContext.getCurrentContext().getRequest().getServletPath();
}
} 2)您可以指定刷新列表的时间间隔
public class AvailabilityBasedServerSelectionRule extends AvailabilityFilteringRule {
@Override
public Server choose(Object key) {
Server chosenServer = super.choose(key);
int count = 1;
List<Server> reachableServers = this.getLoadBalancer().getReachableServers();
List<Server> allServers = this.getLoadBalancer().getAllServers();
if(reachableServers.size() > 0) {
while(!reachableServers.contains(chosenServer) && count++ < allServers.size()) {
chosenServer = reachableServers.get(0);
}
}
return chosenServer;
}