3

Spring Cloud の Eureka クライアント/サーバー メカニズムに慣れるために、クライアントを Eureka サーバーに接続し、5 分ごとに接続のオン/オフを切り替えて、Eureka サーバーがこれをどのように処理するかを確認します。

Eureka のクライアントが 2 つあります。

最初に、次のコードを使用して、登録されたアプリケーションに関する情報を提供します。

@Autowired
private DiscoveryClient discoveryClient;

@RequestMapping(value = "/services", produces = MediaType.APPLICATION_JSON)
public ResponseEntity<ResourceSupport> applications() {
    ResourceSupport resource = new ResourceSupport();

    Set<String> regions = discoveryClient.getAllKnownRegions();

    for (String region : regions) {
        Applications allApps = discoveryClient.getApplicationsForARegion(region);
        List<Application> registeredApps = allApps.getRegisteredApplications();
        Iterator<Application> it = registeredApps.iterator();

        while (it.hasNext()) {
            Application app = it.next();

             List<InstanceInfo> instancesInfos = app.getInstances();

             if (instancesInfos != null && !instancesInfos.isEmpty()) {
                 //only show one of the instances
                 InstanceInfo info = instancesInfos.get(0);
                 resource.add(new Link(info.getHomePageUrl(), "urls"));
             }
        }
    }

    return new ResponseEntity<ResourceSupport>(resource, HttpStatus.OK);
}

2 番目の Eureka Client は、5 分ごとに自分自身を登録/登録解除します。

private static final long EUREKA_INTERVAL = 5 * 60000;

public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(MyServiceApplication.class);

    long currentTime = System.currentTimeMillis();
    long lastToggleTime = System.currentTimeMillis();
    boolean connected = true;
    while (true) {
        if (currentTime - lastToggleTime > EUREKA_INTERVAL) {
            if (connected) {
                System.err.println("disconnect");
                DiscoveryManager.getInstance().shutdownComponent();
                connected = false;
                lastToggleTime = System.currentTimeMillis();
            }
            else {
                System.err.println("connect");
                DiscoveryManager.getInstance().initComponent(
                        DiscoveryManager.getInstance().getEurekaInstanceConfig(),
                        DiscoveryManager.getInstance().getEurekaClientConfig());
                connected = true;
                lastToggleTime = System.currentTimeMillis();
            }
        }
        currentTime = System.currentTimeMillis();
    }

}

2 番目の Eureka クライアントのログ出力は次のようになります。

disconnect
2015-03-26 13:59:23.713  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MYAPPNAME/MYMEGAHOSTNAME - deregister  status: 200
connect
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2015-03-26 14:04:23.870  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2015-03-26 14:04:23.889  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2015-03-26 14:04:23.892  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
2015-03-26 14:04:23.894  INFO 3452 --- [           main] com.netflix.discovery.DiscoveryClient    : Starting heartbeat executor: renew interval is: 30
2015-03-26 14:04:53.916  INFO 3452 --- [ool-11-thread-1] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MYAPPNAME/MYMEGAHOSTNAME - Re-registering apps/MYAPPNAME
2015-03-26 14:04:53.916  INFO 3452 --- [ool-11-thread-1] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MYAPPNAME/MYMEGAHOSTNAME: registering service...
2015-03-26 14:04:53.946  INFO 3452 --- [ool-11-thread-1] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MYAPPNAME/MYMEGAHOSTNAME - registration status: 204

両方の Eureka クライアントを初めて起動する場合、これはうまく機能します。2 番目のクライアントは最初のクライアントによって表示され、かつ 2 番目のクライアントは Eureka サーバー コンソールに表示されます。2 番目のクライアントが Eureka サーバーから切断されると、そこには表示されなくなり、最初のクライアントにも表示されなくなります。

残念ながら、2 番目のクライアントが Eureka サーバーに再接続すると、Eureka サーバー コンソールには大きな赤色で強調表示された "DOWN (1)" が表示され、最初のクライアントには 2 番目のクライアントが表示されなくなります。ここで何が欠けていますか?





解決:

Dave Sayer の回答に基づいて、私の解決策は、EurekaDiscoveryClientConfiguration が自動配線され、登録を切り替えるためのスレッドを開始するカスタム @Configuration を追加することでした。これはテストのみを目的としているため、非常に醜い解決策になる可能性があることに注意してください;-)

@Configuration
static public class MyDiscoveryClientConfigServiceAutoConfiguration {

    @Autowired
    private EurekaDiscoveryClientConfiguration lifecycle;

    @PostConstruct
    public void init() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                long currentTime = System.currentTimeMillis();
                long lastToggleTime = System.currentTimeMillis();
                boolean connected = true;

                while (true) {
                    if (currentTime - lastToggleTime > EUREKA_INTERVAL) {
                        if (connected) {
                            System.err.println("disconnect");

                            lifecycle.stop();
                            DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
                            connected = false;
                            lastToggleTime = System.currentTimeMillis();
                        }
                        else {
                            System.err.println("connect");
                            DiscoveryManager.getInstance().initComponent(
                                    DiscoveryManager.getInstance().getEurekaInstanceConfig(),
                                    DiscoveryManager.getInstance().getEurekaClientConfig());

                            lifecycle.start();
                            connected = true;
                            lastToggleTime = System.currentTimeMillis();
                        }
                    }
                    currentTime = System.currentTimeMillis();
                }
            }
        }).start();
    }

}
4

1 に答える 1

6

への呼び出しDiscoveryManager.getInstance().initComponent()はステータスを設定しません (デフォルトは DOWN です)。Spring Cloud では、特別なEurekaDiscoveryClientConfiguration.start()ライフサイクルで処理します。それを注入して、次のように再利用できます。

@Autowired
private EurekaDiscoveryClientConfiguration lifecycle;

@PostConstruct
public void init() {
    this.lifecycle.stop();
    if (DiscoveryManager.getInstance().getDiscoveryClient() != null) {
        DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
    }
    ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
    DiscoveryManager.getInstance().initComponent(this.instanceConfig,
            this.clientConfig);
    this.lifecycle.start();
}

(これはここから取得したコードです: https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/ netflix/config/DiscoveryClientConfigServiceAutoConfiguration.java#L58 )。

于 2015-03-26T13:52:28.170 に答える