当前位置: 首页 > 知识库问答 >
问题:

如何使ribbon和eureka意识到服务器不再运行

丁德义
2023-03-14

我在一个微服务体系结构中工作,其工作原理如下

我有两个服务Web应用程序(REST服务),在eureka服务器中正确注册自己,然后我有一个客户端应用程序,获取eureka注册表,并使用ribbon作为客户端负载均衡器,确定哪个服务应用程序去(目前,一个简单的正在使用圆形罗宾)。

我的问题是,当我停止其中一个服务应用程序(它们目前在docker容器中运行)时,eureka不会将它们从注册表中删除(似乎需要几分钟),因此ribbon仍然认为有两个可用的服务,使大约50%的调用失败。

不幸的是,我没有使用SpringCloud(原因我无法控制)。因此,我对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 ribbon)

###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

共有1个答案

黎玺
2023-03-14

在我的发展中,我也面临过类似的问题,我尝试过很多事情,并为我工作。

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 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;
    }

}2)您可以指定刷新列表的时间间隔

ribbon.eureka.ServerListRefreshInterval={time in ms}
 类似资料:
  • 我正在使用带有 netflix 堆栈和 Spring 启动的微服务构建一个应用程序。困扰我的一件事是,我还没有集成测试,我可以在其中模拟周围的服务。 因此,我有一个服务 A,它是一个带有功能区的尤里卡客户端,用于在呼叫期间将尤里卡名称解析为已注册服务 B 的 URL。 所以理想情况下,我想用 spring boot 的 integrationtest 注释启动应用程序,使用 wiremock 模拟

  • 我们目前正在探索Netflix的磁通电容器,以研究其微服务架构的实现。目前,我们的兴趣集中在服务注册和动态查找功能上。 浏览代码、示例和配置,但有些地方不清楚;服务版本控制。如果eureka提供发现服务,而ribbon是基于eureka的REST客户端,那么客户端如何表示需要service的service?客户机在哪里存储/获取该版本号;从这样的本地配置文件,还是通过archaius动态获取?

  • 我成功地使用Eureka让我的RestTemplate客户端发现远程服务,并使用Ribbon将调用转发给它,如文档中所述。基本上,只需为我的应用程序类添加以下注释,然后让Spring Boot的魔力完成其余部分: (注:您注意到我使用的是spring云:1.0.0-SNAPSHOT-BUILD,而不是1.0.0.M3-但这似乎不会影响我的问题)。 当两个服务实例启动时,rest模板客户端成功地在两

  • spring webclient无法从eureka服务器的服务实例名称中检索实际主机,出现以下异常: Spring启动版本:2.2.3。BUILD-SNAPSHOT

  • 样品https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server非常适合构建TCP服务器应用程序。它很简单,可以在JVM上运行。它不需要任何应用服务器。 示例使用命令行输入来运行程序。我希望服务器仅从套接字端口而不是通过命令行接受数据。如果删除命令行输入,主线程将完