Call now: 252-767-6166  
Oracle Training Oracle Support Development Oracle Apps

 
 Home
 E-mail Us
 Oracle Articles
New Oracle Articles


 Oracle Training
 Oracle Tips

 Oracle Forum
 Class Catalog


 Remote DBA
 Oracle Tuning
 Emergency 911
 RAC Support
 Apps Support
 Analysis
 Design
 Implementation
 Oracle Support


 SQL Tuning
 Security

 Oracle UNIX
 Oracle Linux
 Monitoring
 Remote s
upport
 Remote plans
 Remote
services
 Application Server

 Applications
 Oracle Forms
 Oracle Portal
 App Upgrades
 SQL Server
 Oracle Concepts
 Software Support

 Remote S
upport  
 Development  

 Implementation


 Consulting Staff
 Consulting Prices
 Help Wanted!

 


 Oracle Posters
 Oracle Books

 Oracle Scripts
 Ion
 Excel-DB  

Don Burleson Blog 


 

 

 


 

 

 
 

Access to multiple WebLogic servers or domains in parallel

Weblogic Tips by Donald BurlesonApril 20, 2015

 

Access to multiple WebLogic servers or domains in parallel

The connect operation is always the most expensive operation. In large environments where many servers and any domains are involved and have to be monitored, concurrent access to multiple servers or domains is not possible with WLST. In WLST, after you issue a connect command, WLST will switch to the online mode and operate on the mean tree of the connected server. Based on experience with many real production systems, I know that it is impossible to gather the monitoring data sequentially from all systems.

 

Imagine 2000+ managed-servers in production and you want to get performance/monitoring information from all of them using WLST. You have the following possibilities:

?  Connect to one server

?  Start one WLST process for each server.

?  Combine 1) and 2) and start one process for a group of servers to reduce the amount of processes.

All options have dramatic disadvantages for production:

?  Connect takes a long time. For a large number of servers, this means that one loop to collect data may take a very long time. Resource problems, failed applications or servers must be discovered within minutes or even faster. It is not acceptable for any production system to discover an out-of-memory server failure after 2 hours.

?  A WLST process needs a lot of memory since it has to load all the WebLogic classes, the Jython interpreter, and more. Even if you want to monitor the administration servers only, you may end up with requirements for hundreds of GB of RAM for only the WLST processes. The second problem is that you have a huge number of processes doing the same - running Jython interpreter, which means that you also need a lot of CPU power and many CPUs to do acceptable monitoring. And who is doing the monitoring of all those WLST processes?

JMX does not have these restrictions. In addition, if you do not need WebLogic proprietary classes (e.g. in the security area some JMX operations return or require WebLogic specific classes) and if you have iiop enabled on your servers for the administrative access, you do not even need the webglogic.jar files that make your process even smaller.

 

The following example shows a Java program that can open many connections to different WebLogic servers in parallel and query some example data. Which information is queried in the example is not important (you need to exchange it with your own needs anyway if you wish to reuse this code). It is the ability to connect to many servers in parallel and continuously query data which should be demonstrated.

 

public class ParallelAccessTest {

 

    public static void main(String[] args)

    {

       JMXThreadTest myJMXThreadTest;

       try {

           // create globalProperties from File

           Properties globalProperties = new Properties();

           globalProperties.load(new FileInputStream(args[0]));

           int counter=1;

           while (globalProperties.getProperty("domain."+counter+".name") != null)

           {

               try {

                   myJMXThreadTest =

                       new JMXThreadTest(counter,

                                         globalProperties.getProperty("domain."+counter+".url"),

                                         globalProperties.getProperty("domain."+counter+".user"),

                                         globalProperties.getProperty("domain."+counter+".password"),

                                         Integer.parseInt(globalProperties.getProperty(

                                                         ("domain."+counter+"reloadinterval","3"))

                             );

 

See the book code download for full script

                    myJMXThreadTest.start();

               }

               catch (Exception ex) {

                   ex.printStackTrace();

               }

               counter++;

           }

       }

       catch (Exception ex) {

         ex.printStackTrace();

       }

    }

}

 

The following implementation is an example of what could be done in each loop. In this example, only when the thread is initialized will a connection to the admin server be established. In each loop, information about the managed-server, cluster, and deployments will be collected. This should demonstrate the power of multi-threading with different WebLogic domains at the same time.

 

Of course this example is kept very simple to keep it short. Many improvements should be considered for a real production implementation like reacting to failed server connections in each loop (possibly restart) and many more.

 

import java.util.*;

import javax.management.MBeanServerConnection;

import javax.management.ObjectName;

import javax.management.remote.*;

import javax.naming.Context;

import java.io.FileOutputStream;

 

public class JMXThreadTest extends Thread  {

    // active (if any) mbean server connection

    private MBeanServerConnection connection;

 

    // connector

    private JMXConnector connector;

 

    private ObjectName domainRuntimeService = null;

 

    private ObjectName domainMBean = null;

 

    private int internalReloadInterval = 0;

 

    private int id;

 

    private boolean endOfLoop = false;

 

    public JMXThreadTest(int _id, String url, String username, String password, int reloadInterval)

    {

        try {

            id = _id;

            internalReloadInterval = reloadInterval;

 

            // get protocol from URL string

            String protocol = url.substring(0,url.indexOf("://"));

 

            // get hostname from URL string

            String hostname = url.substring(url.indexOf("//")+2,

                                            url.indexOf(":",protocol.length()+3));

 

            // get port from URL string

            String portString = url.substring(url.indexOf(":",protocol.length()+3)+1,url.length());

 

See the book code download for full script

            Integer portInteger = Integer.valueOf(portString);

            int port = portInteger.intValue();

            JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,

                           "/jndi/weblogic.management.mbeanservers.domainruntime");

 

            Hashtable h = new Hashtable();

            h.put(Context.SECURITY_PRINCIPAL, username);

            h.put(Context.SECURITY_CREDENTIALS, password);

            h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,"weblogic.management.remote");

            connector = JMXConnectorFactory.connect(serviceURL, h);

            connection = connector.getMBeanServerConnection();

 

            domainRuntimeService = new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");

            domainMBean =(ObjectName)

                          connection.getAttribute(domainRuntimeService,"DomainConfiguration");

 

        }

        catch (Exception ex) {

            ex.printStackTrace();

        }

    }

 

 

   public void run()  {

      while(!endOfLoop) 

      {

         getServersInformation();

 

         try {

             Thread.currentThread().sleep(internalReloadInterval*1000);

         }

         catch (Exception ex) {

               // ignore

         }

      }

 

   }

 

 

 

 

    public void disconnectFromAdminServer()

    {

        try {

            endOfLoop = true;

            connector.close();

            connector = null;

        }

        catch (Exception ex)

        {

            ex.printStackTrace();

        }

    }

 

    public void getServersInformation()

    {

      try

      {

        FileOutputStream os = new FileOutputStream(domainMBean.getKeyProperty("Name")+".log",true);

        try {

 

            String domainName = (String) connection.getAttribute(domainMBean,"Name");

            System.out.println("Aufruf Admin-Server Nr.: "+id+" : "+domainName);

 

            os.write(("\n"+"Domain-Name : " + domainName).getBytes() );

            os.write(("\n"+"  AdminServerName : "+(String)

                              connection.getAttribute(domainMBean,"AdminServerName")).getBytes());

            os.write(("\n"+"  RootDirectory : "+(String)

                              connection.getAttribute(domainMBean,"RootDirectory")).getBytes() );

            os.write(("\n"+"  ProductionModeEnabled : "+((Boolean)

                              connection.getAttribute(domainMBean,"ProductionModeEnabled")).

                              booleanValue() ).getBytes());

 

            // Managed Server

            os.write(("\n"+"  Managed-Server:").getBytes());

            String adminServerName = (String)

                                      connection.getAttribute(domainMBean,"AdminServerName");

            ObjectName[] serverRuntimes = (ObjectName[])connection.

                                                        getAttribute(domainMBean,"Servers");

            for (int i = 0; i < serverRuntimes.length; i++) {

                 String ms_name = (String) connection.getAttribute(serverRuntimes[i],"Name");

                 if (!ms_name.equals(adminServerName)) {

                     os.write(("\n"+"     -> "+ms_name + " : StartupMode = "+(String)

                              connection.getAttribute(serverRuntimes[i],"StartupMode")).getBytes());

                     os.write(("\n"+"        "+ (String)connection.getAttribute(serverRuntimes[i],

                              "ListenAddress")+":"+((Integer)connection.

                              getAttribute(serverRuntimes[i],"ListenPort")).intValue() ).getBytes());

                 }

            }

 

            // Cluster

            os.write(("\n"+"  Cluster:").getBytes());

            ObjectName[] cluster = (ObjectName[])connection.getAttribute(domainMBean,"Clusters");

            for (int i = 0; i < cluster.length; i++)

                os.write(("\n"+"     -> "+(String)

                                           connection.getAttribute(cluster[i],"Name")).getBytes());

 

            // Machines

            os.write(("\n"+"  Machines:").getBytes());

            ObjectName[] machines = (ObjectName[])connection.getAttribute(domainMBean,"Machines");

            for (int i = 0; i < machines.length; i++)

                os.write(("\n"+"     -> "+(String)

                                          connection.getAttribute(machines[i],"Name")).getBytes());

 

            // AppDeployments

            os.write(("\n"+"  AppDeployments:").getBytes());

            ObjectName[] appDeployments = (ObjectName[])

                                          connection.getAttribute(domainMBean,"AppDeployments");

            for (int i = 0; i < appDeployments.length; i++)

                os.write(("\n"+"     -> "+(String)

                                      connection.getAttribute(appDeployments[i],"Name")).getBytes());

        }

        catch (Exception ex) {

            os.write(("Probleme mit Admin-Server Nr.: "+id).getBytes());

            os.write(ex.getMessage().getBytes());

            disconnectFromAdminServer();

        }

        os.close();

        }

        catch (Exception ex) {

            System.out.println("Probleme mit Admin-Server Nr.: "+id);

            ex.printStackTrace();

            disconnectFromAdminServer();

        }

    }

}

 

In order to use this program, you need to provide a property file with all the domain information.

 

domain.1.name           = Domain_1

domain.1.url            = iiop://myserverhost_1:myserverport_1

domain.1.user           = <user for admin or monitoring access>

domain.1.password       = <password for admin or monitoring access>

domain.1.reloadinterval = 10   # seconds

 

domain.2.name           = Domain_2

domain.2.url            = iiop://myserverhost_2:myserverport_2

domain.2.user           = <user for admin or monitoring access>

domain.2.password       = <password for admin or monitoring access>

domain.2.reloadinterval = 10   # seconds

 

domain.3.name           = Domain_3

domain.3.url            = iiop://myserverhost_3:myserverport_3

domain.3.user           = <user for admin or monitoring access>

domain.3.password       = <password for admin or monitoring access>

domain.3.reloadinterval = 10   # seconds

 

If you do not need t3 or even t3s as protocol, you can avoid having the WebLogic classes in your classpath. For real production examples however, it is most likely necessary to have the weblogic.jar files in your classpath.

 

The above property example has a major weakness: It shows the usernames and passwords in clear text, which is usually prohibited in production systems anyway. For a real production systems, I highly recommend extending this program in order to provide at least user and password (URL might also be requested) in an encrypted way.


 
   
Advanced WebLogic Server Automation Book

The above is an excerpt from the book "Advanced WebLogic Server Automation: Administration and Monitoring with WLST and JMX". This book covers everything administrators need to know for WebLogic scripting and automation, and includes a comprehensive code download of powerful WLST and JMX scripts.
 


Hit Counter

 

Burleson is the American Team

Note: This Oracle documentation was created as a support and Oracle training reference for use by our DBA performance tuning consulting professionals.  Feel free to ask questions on our Oracle forum.

Verify experience! Anyone considering using the services of an Oracle support expert should independently investigate their credentials and experience, and not rely on advertisements and self-proclaimed expertise. All legitimate Oracle experts publish their Oracle qualifications.

Errata?  Oracle technology is changing and we strive to update our BC Oracle support information.  If you find an error or have a suggestion for improving our content, we would appreciate your feedback.  Just  e-mail:  

and include the URL for the page.


                    









Burleson Consulting

The Oracle of Database Support

Oracle Performance Tuning

Remote DBA Services


 

Copyright © 1996 -  2017

All rights reserved by Burleson

Oracle ® is the registered trademark of Oracle Corporation.

Remote Emergency Support provided by Conversational

 

 

��  
 
 
Oracle Training at Sea
 
 
 
 
oracle dba poster
 

 
Follow us on Twitter 
 
Oracle performance tuning software 
 
Oracle Linux poster