Get the server port number from tomcat without a request

前端 未结 12 1469
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 06:32

Is there any Tomcat API or configuration available which can tell an application (probably on startup), what port its running on without a request?

Imagine a scenari

相关标签:
12条回答
  • 2020-11-28 07:06

    With this:

    List<String> getEndPoints() throws MalformedObjectNameException,
            NullPointerException, UnknownHostException, AttributeNotFoundException,
            InstanceNotFoundException, MBeanException, ReflectionException {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        QueryExp subQuery1 = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"));
        QueryExp subQuery2 = Query.anySubString(Query.attr("protocol"), Query.value("Http11"));
        QueryExp query = Query.or(subQuery1, subQuery2);
        Set<ObjectName> objs = mbs.queryNames(new ObjectName("*:type=Connector,*"), query);
        String hostname = InetAddress.getLocalHost().getHostName();
        InetAddress[] addresses = InetAddress.getAllByName(hostname);
        ArrayList<String> endPoints = new ArrayList<String>();
        for (Iterator<ObjectName> i = objs.iterator(); i.hasNext();) {
            ObjectName obj = i.next();
            String scheme = mbs.getAttribute(obj, "scheme").toString();
            String port = obj.getKeyProperty("port");
            for (InetAddress addr : addresses) {
                if (addr.isAnyLocalAddress() || addr.isLoopbackAddress() || 
                    addr.isMulticastAddress()) {
                    continue;
                }
                String host = addr.getHostAddress();
                String ep = scheme + "://" + host + ":" + port;
                endPoints.add(ep);
            }
        }
        return endPoints;
    }
    

    You will get a List like this:

    [http://192.168.1.22:8080]
    
    0 讨论(0)
  • 2020-11-28 07:11

    You could use crossContext. But I don't think that's app server agnostic.

    I would share a custom class, behaving as a registry of running applications in the same tomcat instance through JNDI, as I explained here.

    During startup, through a ContextListener or through an Spring container event, I would obtain the registry through a JNDI lookup, add my web app instance with an url obtained from the servletcontext.contextpath, and finally register a listener to hear other applications registering themselves. That's the more server agnostic I can think of.

    Obtaining the port won't be server agnostic, you should use a context parameter.

    EDIT: I'm sorry, forgot to say that what I've described is to share objects among contexts, but no, you can't not know the port unless you use some server API (not agnostic at all).

    0 讨论(0)
  • 2020-11-28 07:13

    Hmm, how would an application get started in Tomcat without a request? Maybe I'm going brain dead for a moment here, but I don't think any classes will load until a request hits. Sure, you could have classes independent of any particular request, but they'd need a request to get them fired off at some point.

    0 讨论(0)
  • 2020-11-28 07:14

    Previously on a large distributed project, the design I used was to have the centralised service initialise the several services with the central service's URL(& port).

    Obviously this means that the central service must maintain a list of the services (URL & port) to initialise.

    0 讨论(0)
  • 2020-11-28 07:15
    • Get Hold of MBean/JMX Object for Tomcat/Server Instance
    • Get Virtual Server Instance Related Data from there

    Check http://svn-mirror.glassfish.org/glassfish-svn/tags/embedded-gfv3-prelude-b07/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java for reference

    The content of the MBeanServer can then be exposed through various protocols, implemented by protocol connectors[RMI/IIOP], or protocol adapters[SNMP/HTTP]. In this case, use of SNMP adapter will be a better approach so that a SNMP trap can be placed without knowing the exact IP/port of other Application Servers

    0 讨论(0)
  • 2020-11-28 07:17

    For anybody who is interested in how we solved this, here is the mock code

    Server server = ServerFactory.getServer();
            Service[] services = server.findServices();
            for (Service service : services) {
                for (Connector connector : service.findConnectors()) {
                    ProtocolHandler protocolHandler = connector.getProtocolHandler();
                    if (protocolHandler instanceof Http11Protocol
                        || protocolHandler instanceof Http11AprProtocol
                        || protocolHandler instanceof Http11NioProtocol) {
                        serverPort = connector.getPort();
                        System.out.println("HTTP Port: " + connector.getPort());
                    }
                }
    
    
            }
    
    0 讨论(0)
提交回复
热议问题