Java 如何使ribbon和eureka意识到服务器不再运行
我在一个微服务体系结构中工作,其工作原理如下 我有两个服务web应用程序(REST服务),它们在eureka服务器中正确注册,然后我有一个客户端应用程序,它获取eureka注册表,并使用ribbon作为客户端负载平衡器,确定要使用哪个服务应用程序(目前正在使用一个简单的循环) 我的问题是,当我停止其中一个服务应用程序(它们目前在docker容器中运行)时,eureka不会将它们从注册表中删除(似乎需要几分钟),因此ribbon仍然认为有两个可用的服务,使大约50%的调用失败 不幸的是,我没有使用SpringCloud(原因我无法控制)。因此,我对eureka的配置如下 对于服务应用程序:Java 如何使ribbon和eureka意识到服务器不再运行,java,netflix-eureka,netflix,netflix-ribbon,Java,Netflix Eureka,Netflix,Netflix Ribbon,我在一个微服务体系结构中工作,其工作原理如下 我有两个服务web应用程序(REST服务),它们在eureka服务器中正确注册,然后我有一个客户端应用程序,它获取eureka注册表,并使用ribbon作为客户端负载平衡器,确定要使用哪个服务应用程序(目前正在使用一个简单的循环) 我的问题是,当我停止其中一个服务应用程序(它们目前在docker容器中运行)时,eureka不会将它们从注册表中删除(似乎需要几分钟),因此ribbon仍然认为有两个可用的服务,使大约50%的调用失败 不幸的是,我没有使
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+ribbon)
我在发展过程中也遇到过类似的问题, 我为自己做了很多尝试和工作 1) 与其使用eureka注册表,不如只使用底层ribbon,并根据需要修改其运行状况检查机制,这样做可以为IPing提供自己的实现
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 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;
}
我认为您应该手动将eureka unregister步骤添加到JVM关闭钩子中。我怀疑@SakuraKyouko是正确的,因为如果您正在终止您的一个服务,那么eureka可能永远不会得到您实例的注销调用(),然后必须等到它的续订失败90秒(defualt-)。出于好奇,您通常要处理多少个实例?我还想知道自我保护模式是否是一个因素。
public class LoadBalancer{
@Autowired
IClientConfig ribbonClientConfig;
@Bean
public IPing ribbonPing() {
return new PingUrl(getRoute() + "/ping");
}
}
private String getRoute() {
return RequestContext.getCurrentContext().getRequest().getServletPath();
}
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;
}
ribbon.eureka.ServerListRefreshInterval={time in ms}