问题描述:

I have a bluemix app pushed via packaged liberty server. The app looks for the instance IP/hostname internally. When the app is upscaled with more than one instance, using localhost as the hostname becomes obsolete. Host entry is set in our server.xml.

When i tried to use Referenceable variables such as ${host} or ${vcap_console_ip}, it is not getting the host name or ip address respectively.

  1. ${host} returns 0.0.0.0 in our server.xml
  2. ${vcap_console_ip} - it is not getting any value. I see the runtime-vars.xml doesn't show the ${vcap_console_ip} even if use it in the server.xml.

Looking for suggestion on how to get the host name or ip of the instance the app is running into my server.xml.

网友答案:

An application running in Bluemix will have at least two IP addresses, a private one and an externally addressable one. Similarly, for hostname, the route that others use to talk to the application server is configured externally - and there may not be a route at all. The best solution will depend on what you're trying to do with the hostname.

EDIT:

If the aim is to communicate between instances, relying on direct knowledge of IP addresses will have issues, since one of the things the cloud gives you is a dynamic networking environment. One option is messaging or a distributed cache, as some of the comments have mentioned. Another is to use the beta Bluemix Service Discovery service, which takes of care of mapping the private IP address (which your application knows) to the public IP address (which your application does not know).

An application can register itself with the registry by making a POST request to the 'https://servicediscovery.ng.bluemix.net/api/v1/instances' REST endpoint. For example, in cURL form, that would be

curl -X POST -H "Authorization: Bearer auth_token" -H "Content-Type: application/json" https://servicediscovery.ng.bluemix.net/api/v1/instances -d '{"service_name":"[service_name]", "endpoint": {"type":"tcp", "value":"[host]"}, "status":"UP", "ttl":[TTL_value], "metadata":{"name":"instance_name"}}'

where [host] is the private IP address of the application, and TTL_value is how long in seconds the instance will wait between heartbeats, and the token can be read off the Bluemix console for the service discovery service. To list the services you've registered, you would then do

curl -X GET -H "Authorization: Bearer auth_token" https://servicediscovery.ng.bluemix.net/api/v1/services/Service_Name

As well as allowing the internal IP address to be decoupled from the public IP address, a service discovery approach allows load balancing within different components of your application, and allows failover if one instance goes down.

网友答案:

You could use the VCAP_APPLICATION env variable and get the "uris" attribute.

    String VCAP_APPLICATION = System.getenv("VCAP_APPLICATION");
    if (VCAP_APPLICATION != null) {
            JsonNode node = Json.mapper().readValue(VCAP_APPLICATION, JsonNode.class);
            ArrayNode uris = (ArrayNode) node.get("uris");
            if (uris != null && uris.size() > 0 && uris.get(0) != null) {
                host = uris.get(0).textValue();
            }
网友答案:

If you look in runtime-vars.xml, you should see a variable called application_uris. If there's only one route configured for your application, you can reference it directly in server.xml using ${application_uris}. If there's more than one route, you can still use it, but you'll need to parse a comma-separated list.

The ${application_uris} variable will show a meaningful route (as long as there is one!) even though the ${host} variable gives 0.0.0.0. If there's more than one instance of an application running, it won't help distinguish between them, but that's the desired behaviour in most cases.

(I think this is the simplest answer to the original question.)

相关阅读:
Top