java - tomcat是什麼 - tomcat用途




在沒有請求的情況下從tomcat獲取服務器端口號 (8)

是否有任何Tomcat API或配置可以告訴應用程序(可能在啟動時),它運行的端口沒有請求?

想像一下,有兩個Web應用程序在同一個Tomcat中運行,其中一個需要從另一個調用Web服務。 我們不希望請求離開Tomcat(如果您使用Apache服務器名稱或絕對URL,請求將出去並再次返回並且它可以轉到任何實例)並返回。為此,我知道機器名稱但無法獲取端口號。 我知道我可以硬編碼這些信息,但我不想這樣做,因為我希望我的war文件與應用程序服務器無關。

我知道如果我們有HTTPServletRequest,我們可以找到它

這僅適用於Tomcat 6,不適用於Tomcat 7


以前在大型分佈式項目中,我使用的設計是讓集中式服務使用中央服務的URL(和端口)初始化多個服務。

顯然,這意味著中央服務必須維護一個要初始化的服務列表(URL和端口)。


嗯,沒有請求,應用程序如何在Tomcat中啟動? 也許我現在腦子裡已經死了一會兒,但我不認為任何課程會在請求到來之前加載。 當然,你可以擁有獨立於任何特定請求的類,但是他們需要一個請求來讓它們在某些時候被解僱。


對於任何對我們如何解決這個問題感興趣的人,這裡是模擬代碼

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


        }

您可以使用crossContext 。 但我不認為這是app服務器不可知的。

我將共享一個自定義類,表現為通過JNDI在同一個tomcat實例中運行應用程序的註冊表,正如我here解釋的那樣。

在啟動期間,通過ContextListener或通過Spring容器事件,我將通過JNDI查找獲取註冊表,使用從servletcontext.contextpath獲取的URL添加我的Web應用程序實例,最後註冊一個偵聽器以聽取其他應用程序註冊自己。 這是我能想到的更多服務器不可知論者。

獲取端口不會與服務器無關,您應該​​使用context參數。

編輯:對不起,忘了說我所描述的是在上下文之間共享對象,但不,你不能不知道端口,除非你使用一些服務器API(根本不是不可知)。


有了這個:

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

你會得到一個像這樣的列表:

[http://192.168.1.22:8080]

服務器端口號不存在。 它可以有任意數量的端口號。 所以你問的是沒有意義的。 與特定請求關聯端口號確實有意義。


public void getIpAddressAndPort() 
throws MalformedObjectNameException, NullPointerException,
            UnknownHostException {

        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();

        Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
                Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));

        String host = InetAddress.getLocalHost().getHostAddress();
        String port = objectNames.iterator().next().getKeyProperty("port");

        System.out.println("IP Address of System : "+host );
        System.out.println("port of tomcat server : "+port);

    }

  • 獲取Tomcat / Server實例的MBean / JMX對象
  • 從那裡獲取虛擬服務器實例相關數據

查看http://svn-mirror.glassfish.org/glassfish-svn/tags/embedded-gfv3-prelude-b07/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java以供參考

然後可以通過協議連接器[RMI / IIOP]或協議適配器[SNMP / HTTP]實現的各種協議公開MBeanServer的內容。 在這種情況下,使用SNMP適配器將是一種更好的方法,因此可以在不知道其他應用服務器的確切IP /端口的情況下放置SNMP陷阱







application-server