New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong port used to create DiscoveryNode #1
Comments
Sorry for the late answer, not sure I got the explanation on how you think it can be fixed. Do you let Hazelcast register it itself? |
Yes. I let Hazelcast to register itself. Just after Hazelcast starts I put Hazelcast port number to Eureka instance metadata map. Metadata map is shared between nodes at every heartbeat. Then I read Hazelcast port of other nodes during discovery like this: https://github.com/ebjwc/eurekast-one/blob/gh-1/src/main/java/com/hazelcast/eurekast/one/EurekastOneDiscoveryStrategy.java#L131 |
@tjuchniewicz Hi, Is defined problem is still valid on your side? Do you need support? Also, please note that We have recently updated Eureka V1 discovery mechanism. |
Hi @lazerion |
Hi @tjuchniewicz, Current implementation and tests do not produce the problem currently. Could you please elaborate case, for instance are you overriding Could you please check out the new version? |
OK. I will prepare example project for this case. |
Works for me now. |
Sorry but this wasn't fixed. Applications use two different ports for web and Hazelcast. In my solution I use Eureka metadata map to provide Hazelcast host and port used by application registered into Eureka. This requires some additional Eureka configuration in application: // provide Hazelcast host and port in Eureka metadata
Map<String, String> map = applicationInfoManager.getInfo().getMetadata();
Member member = (Member) hazelcast.getLocalEndpoint();
Address address = member.getAddress();
String host = address.getHost();
int port = address.getPort();
map.put(EurekaHazelcastMetadata.HAZELCAST_HOST, host);
map.put(EurekaHazelcastMetadata.HAZELCAST_PORT, Integer.toString(port)); and then I use this information in hazelcast-eureka discovery code: // read Hazelcast host and port from Eureka metadata
Map<String, Object> metadata = (Map) instance.getMetadata();
if (metadata.containsKey(EurekaHazelcastMetadata.HAZELCAST_PORT)) {
port = Integer.parseInt(metadata.get(EurekaHazelcastMetadata.HAZELCAST_PORT).toString());
}
if (metadata.containsKey(EurekaHazelcastMetadata.HAZELCAST_HOST)) {
try {
address = InetAddress.getByName(metadata.get(EurekaHazelcastMetadata.HAZELCAST_HOST).toString());
} catch (UnknownHostException e) {
getLogger().warning("Instance address '" + instance + "' could not be resolved", e);
}
}
nodes.add(new SimpleDiscoveryNode(new Address(address, port), metadata)); |
Can you elaborate a bit about your use case and how to reproduce the issue? Points that are not really clear to me:
Thanks, Guglielmo |
Hi @googlielmo
I will prepare example how I use this now. |
Thank you for contributing to Hazelcast. If I understand correctly, I think the issue you are experiencing (i.e., finding the wrong port) stems from using one Eureka client for two "Applications" (in the Eureka sense), as follows:
Now, both Hazelcast and the web application live in the same process and are using the same client instance, which is configured to use app name NAME in namespace NS1. The Discovery Plugin, which uses the same client again, requests a list of application from the same namespace and name and gets a list of all the instances of application NAME in namespace NS1. So depending on the order of registration, for app NAME in namespace NS1 for host HOST it will only get one port, either 5701 or 8080. (By the way, if you pass a Eureka client instance to Now, I don't know how common this use case is: normally, I would recommend to use a separate client for Hazelcast Discovery, one that points to the same Eureka server instance, but with a different namespace (e.g., "hazelcast") and/or a different name. What do you think? |
I understand the issue similar to @googlielmo, meaning that in your example [1], your namespace in [1] https://github.com/tjuchniewicz/hazelcast-eureka-examples |
Thanks for analysis and opinions @googlielmo and @leszko. Now I understand current implementation idea! I was missing the point all the time! So we have two possible solutions for Hazelcast - Eureka integration:
I believe (and this is how we use Eureka in our environment and probably Netflix does) 2. option is more common for our case. My pros and cons:
I think we should support both scenarios. Current scenario is definitely required for the cases when Eureka is used only to build Hazelcast cluster. If web application cluster is already created we should reuse it. |
Hi @tjuchniewicz , Thanks for your explanation. I agree we could support both approaches, however I just have a couple of more questions. Note that I'm not Eureka expert, so some of them might by obvious :)
[1] https://github.com/hazelcast/hazelcast-eureka/pull/18/files#diff-497d97735c08391fca6a2598564e3599R261 |
Hi @leszko
@Configuration
@AutoConfigureAfter(value = HazelcastConfiguration.class)
@ConditionalOnBean(HazelcastInstance.class)
public class HazelcastToEurekaPropagationConfiguration {
@Bean
public HazelcastEurekaMetadataMapInfo updateEurekaMetadataMap(HazelcastInstance hazelcast,
ApplicationInfoManager applicationInfoManager) {
return new HazelcastEurekaMetadataMapInfo(hazelcast, applicationInfoManager);
}
}
public class HazelcastEurekaMetadataMapInfo {
public HazelcastEurekaMetadataMapInfo(HazelcastInstance hazelcast, ApplicationInfoManager applicationInfoManager) {
log.info("Updating Eureka metadata map with Hazelcast info");
Map<String, String> map = applicationInfoManager.getInfo().getMetadata();
Member member = (Member) hazelcast.getLocalEndpoint();
Address address = member.getAddress();
String host = address.getHost();
int port = address.getPort();
log.info("Hazelcast member address: {}", address);
map.put(EurekaHazelcastMetadata.HAZELCAST_HOST, host);
map.put(EurekaHazelcastMetadata.HAZELCAST_PORT, Integer.toString(port));
map.put(EurekaHazelcastMetadata.HAZELCAST_GROUP_NAME, hazelcast.getConfig().getGroupConfig().getName());
}
}
|
I see your point, at the same time I think that if we want to have an alternative way to store Hazelcast info in Eureka, i.e., in metadata, then the discovery plugin should be configured both to write and read those metadata. I don’t want to depend on some spring magic, because the Eureka discovery plugin is meant to be used in a variety of settings, e.g., in a standalone Hazelcast cluster, in non-spring apps, etc. What I suggest is that you introduce a new boolean flag in the plugin config, say "USE_METADATA_FOR_HOST_AND_PORT" (default
Thoughts? |
Hi @googlielmo That's perfect for me! I will improve my PR after my holidays. |
Perfect. We definitely need to provide both: write & read, not only read. I'd consider if we need a flag at all. Or maybe a node can do both at the same time: always register in metadata AND host+port. And metadata takes the precedence. @googlielmo @tjuchniewicz, Wdyt? |
Not sure, if user wants to use host+port for their (other) App maybe the setting both will happen at the wrong time and override the other App's values ? |
You mean that in the case from @tjuchniewicz , Spring overrode Hazelcast, but Hazelcast may override Spring as well? I'm not sure it's an issue, because Hazelcast uses different namespace. Or I am missing something? |
Not sure either: My understanding was that if someone wanted to use host+port for other purposes (e.g., for their spring app) then the plugin should not interfere and just use the metadata. |
You are right @googlielmo. This is exactly my idea. |
ok, it makes sense. Thanks @tjuchniewicz @googlielmo for the explanation! |
Hi guys. I've updated my PR. Please take a look: #18 |
Thanks for the update @tjuchniewicz! We'll have a look ASAP. |
Current code from
EurekastOneDiscoveryStrategy
:Problem is that port is eureka client port e.g. 8080 not Hazelcast port e.g. 5701.
I'm not sure if this is possible but this is my rough idea how to solve this problem or at least start discussion:
EurekastOneDiscoveryStrategy
uses metadata map to get the port instead ofinstance.getPort();
.The text was updated successfully, but these errors were encountered: