Search This Blog

Sunday, April 14, 2013

Self-tuned Thread Pool Count


-->
Thread Pool count will give you the idea about the WebLogic Server instance throughput. First let us see how to monitor a server instance with WLST. if you provide the instance name the script will search the corresponding listen address, listen port for that instances then forms a URL using t3 protocal(WebLogic specific protocol) which is used to connect the instance and get the serverRuntime MBean which will contains that servers ThreadPoolRuntime.

Hogging Threads
Hogging Threads that have taken the too much time and we can assume that they are never going to come back. Hogging threads help us take some decisions, lets say many threads are hogging, we may take a decision to create new threads for next cycle.
My understanding about Thread States in WebLogic Server:
  1. ACTIVE
  2. STUCK
  3. STANDBY
A live thread which is ready to process the request, which is known as ACTIVE state. That is indicated when therad newly created. WebLogic Server start the server instance with 1 ACTIVE thread and the thread count grows as per the min size if specified other wise it will do self-tune as per the request.

Threads might wait for other thread to release resource. This might happen due to application varialbles. The variables are 2 types thread-safe other is risk for thread. All local variables in the methods are thread-safe. The variable defined in class level are unsafe. which causes memory leak, this state of threads are known as hogging. WebLogic identify a thread as hog by the time interval. If thread is waiting more than 600 sec will be treated as hog. STUCKthread interval we can tune as per the project need.

animations
If the number of HoggingThreadCount increases then the server health is in dangerous. That time you can take the ThreadDump
After Threads increase to a max utilization then the thread will be in STANDBY state.

Let us see the following script will get the Thread statistics for a given Weblogic server instance.


# This script is for single instance thread statistics
# You can enhance it further to take thread dump as per your env.

import sys
from java.util import Date

ucf='scriptpath/userConfigFile.sec'
ukf='scriptpath/userKeyFile.sec'
ECODE='\n \033[0m' # ending of color code

def ThreadCnt():
    try:
        print 'Connecting to Admin server....'
        connect(userConfigFile=ucf, userKeyFile=ukf, url='t3://admindns:port')
    except:
        print 'Admin Server NOT in RUNNING state....'
    urldict={}
    serverlist=getRunningServerNames()  # Getting Serverlist
    for svr in serverlist:
        cd("/Servers/"+svr.getName())
        urldict[svr.getName()]='t3://'+get('ListenAddress')+':'+str(get('ListenPort'))

    x = raw_input('Enter a server instance name : ')
    try:
        connect(userConfigFile=ucf, userKeyFile=ukf,url=urldict[x])
        serverRuntime()
        openSocks = cmo.getOpenSocketsCurrentCount();
        print('Open Sockets:: ' + str(openSocks));
        cd('serverRuntime:/ThreadPoolRuntime/ThreadPoolRuntime/')
        compReq = cmo.getCompletedRequestCount()
        status = cmo.getHealthState()
        hoggingThreads = cmo.getHoggingThreadCount()
        totalThreads = cmo.getExecuteThreadTotalCount()
        idleThrds = cmo.getExecuteThreadIdleCount()
        pending = cmo.getPendingUserRequestCount()
        qLen = cmo.getQueueLength()
        thruput = cmo.getThroughput()
        if idleThrds == 0:
            pstr='\033[1;47;31m'    # RED color
        else:
            pstr='\033[1;40;32m'    # GREEN color
        print(pstr+'Status of the Server: ' + str(status)  +ECODE
            +'The completed Requests: ' + str(compReq) +ECODE'
            +'Total the threads no s: ' + str(totalThreads)+ECODE
            +'The Idle threads: ' + str(idleThrds)+ECODE
            +'Hogging threads : ' + str(hoggingThreads)+ECODE
            +'Pending : ' + str(pending)+ECODE
            +'ThreadPool QueueLength: ' + str(qLen)+ECODE
            +'Server (Throughput): ' +str(thruput)+ECODE)
    except:
        print 'Exception... Unable to connect to given Server', x
        pass
    quit()

def quit():
    d = Date() # now
    print  d
    print '\033[1;40;32mHit any key to Re-RUN this script ...'+ECODE
    Ans = raw_input("Are you sure Quit from WLST... (y/n)")
    if (Ans == 'y'):
         disconnect()
        stopRedirect()
        exit()
    else:
        ThreadCnt()

def getRunningServerNames():
    domainConfig()
    return cmo.getServers()

if __name__== "main":
    redirect('./logs/ThreadCntwlst.log', 'false')
    ThreadCnt()
    print 'done'




WebLogic Server Health Status can be one of the following:

  1. HEALTH_OK
  2. HEALTH_WARN
  3. HEALTH_FAILED
  4. HEALTH_CRITICAL
  5. LOW_MEMORY_REASON
  6. HEALTH_OVERLOADED

OK is indicates everything fine, no worries!!

WARN raised when there is few stuck threads in the server instance.

LOW_MEMORY_REASON is going to tell you about JVM crash expected. You can configure to 'Exit' the managed server on low memory conditions with the help of NodeManager and WorkManager.

CRITICAL when multiple number of stuck threads happening and the threadpool count reaching unsual number. This case you need to suspect Network, JDBC or back-end connectivity has trouble.
FAILED happen when the new deployments fails. The NodeManager should not restart this managed server.

OVERLOADED Change the server health state to OVERLOADED on overload. The Nodemanager need to work at this state and bounce such WebLogic instance. This is a new feature of WebLogic 9.x and later versions, for detecting, avoiding and recovering from an overload condition of a WebLogic managed server. Overload protection can be used to throttle Work Managers and thread pools for performance. You can configure Shutdown the Work Manager or application on stuck threads when it crosss more than 5 or you can set threshold.
-->

Good Reference links:

http://forums.oracle.com/forums/thread.jspa?threadID=683752

Thursday, April 11, 2013

Home

Do you know this fun thing about Python scripting sing a poem of quotations just by by importing 'this' module.
wls:/offline> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
wls:/offline>

Content

You are invited for the contribution of WLST scripts and articles.

Technorati Claim token code JDU3DCFE66EH

Saturday, March 2, 2013

JMS Foreign Server

What is Foreign Servers?

Foreign JMS servers can be used as a stand-alone component, similar to messaging bridges. These components  target application servers or clusters directly instead of an intermediary component like a JMS server.

Bridges vs Foreign Server


The JMS messaging bridge does introduce with an extra hop; messages are put into a local destination and then forwarded to the final destination. This is useful when the remote destination is not on highly available JEE container. The bridge will take the messages even when remote destination is not available and then forward them with build-in retry logic when the remote destination becomes available.

If the remote destination is highly available (WebLogic JMS or IBM MQ Series), foreign JMS server is preferable since it directly access the final destination without an extra hop. Mostly preferable for incoming queues on WebLogic 11g and later releases.

Best practices for Foreign Servers


Our best practices were centered around the standard of creating a single JMS Module per cluster (or app server if it wasn't clustered) and then creating both the Foreign server and the weblogic JMS queues/connection factories within the same module.
Also, having good naming conventions for your sub-deployments and JMS Modules

How does Weblogic Foreign Server works with external messaging system?


Configuring Foreign server on JMS Module

Foreign Server feature makes it possible to easily map to remote instances of WebLogic Server in another cluster or domain. so that they appear in the local JNDI tree as a local JMS object. Once the Foreign Provider is configured within Weblogic, for all practical JMS implementations within the code - it can be called as if it was on local JNDI lookup. Weblogic will make the remote calls transparent to your code. This allows you to change your destination via configuration on the Weblogic console or thru WLST.

Working in WLST, We need to connect to the Admin Server because this configuration changes can be done in online mode.
##################################
# FOREIGN JMS MODULE CONFIGURATION
##################################
fsjms_mod_name1=aFSmod
 
fr_server1=ForeignServer1
cnfurl1=file:/path/mq/bindings 
initialContextFactory1=com.sun.jndi.fscontext.RefFSContextFactory




Create JMS Module for Foreign Servers
 With the WebLogic 11g and later releases, Oracle has tried to merge both the internal and foreign JMS under a universal umbrella. However, the target options were kept different. To provide flexibility with the JMS portion, sub-deployments were introduced. Oracle seems to have been extended sub-deployments to Foreign Servers for the sake of consistency, making things quite complicated/messy.
WebLogic Foreign Server - IBM MQ 

Create JMS Foreign Server
This we can configure with the help of three arguments -There must be single JMS Module name per cluster, Multiple definitions of your connection factory will skew the JMS load-balancing.
  1. Connectiony Factory URL
  2. Foreign Server name
  3. Initial Context

Foreign Server MBean
JMS Foreign server is parent MBean with Foreign Connection Factory and Foreign Destination as childs.
Foreign Server MBean tree

The foreign JMS provider can be targeted to a WebLogic Server or a WebLogic Cluster.
Create JMS Foreign Destination
Create JMS Foreign Connection Factory

JMS Foreign Server Destination can be configured with the following details

  • Destination Name
  • Local JNDI
  • RemoteJNDI

The destination properties can be given as follows:

###############################################
# FOREIGN JMS DESTINATION CONFIGURATION
###############################################
destname1=ForeignDestination1
dest_ljndi1=mq/incoming/response
dest_rjndi1=MQSRC_TO_WL_JMS1

Similarly Foreign Connection Factory can be defined with the MQ connection factory details
###############################################
# FORIEGN JMS CONNECTION FACTORY CONFIGURATION
###############################################
fconf_name1=ForeignConnectionFactory1
fconf_ljndi1=MqConnectionFactory
fconf_rjndi1=REMOTE_JNDI1

create_ForeignServer.py

 
from java.io import File
from java.io import FileOutputStream
from java import io
from java.lang import Exception
from java.lang import Throwable
import os.path
 
import sys
 
def getJMSModulePath(jms_module_name):
        jms_module_path = "/JMSSystemResources/"+jms_module_name+"/JMSResource/"+jms_module_name
        return jms_module_path
 
def createFSJMSModule(jms_module_name,target_name):
        cd('/')
        module = create(jms_module_name, "JMSSystemResource")
        cluster = getMBean("Clusters/"+cluster_target_name)
        module.addTarget(cluster)
 
def createJMSFS(jms_module_name,cnurl,jms_fs_name,ini_fac):
        jms_module_path = getJMSModulePath(jms_module_name)
        cd(jms_module_path)
        cmo.createForeignServer(jms_fs_name)
        cd(jms_module_path+'/ForeignServers/'+jms_fs_name)
        cmo.setInitialContextFactory(ini_fac)
        cmo.setConnectionURL(cnurl)
        cmo.setDefaultTargetingEnabled(bool("true"))
        cmo.unSet('JNDIPropertiesCredentialEncrypted')
 
def getFSpath(jms_module_name,jms_fs_name):
        jms_module_path = getJMSModulePath(jms_module_name)
        jms_fs_path = jms_module_path+'/ForeignServers/'+jms_fs_name
        return jms_fs_path
 
def createFSdest(jms_module_name,jms_fs_name,jms_dest_name,ljndi,rjndi):
        cd('/')
        jms_fs_path = getFSpath(jms_module_name,jms_fs_name)
        cd(jms_fs_path)
        print jms_fs_path
        cmo.createForeignDestination(jms_dest_name)
        jms_fs_path=jms_fs_path+'/ForeignDestinations/'+jms_dest_name
        print jms_fs_path
        cd(jms_fs_path)
        cmo.setLocalJNDIName(ljndi)
        cmo.setRemoteJNDIName(rjndi)
 
def createFSconf(jms_module_name,jms_fs_name,jms_fconf_name,cljndi,crjndi):
        jms_fs_path = getFSpath(jms_module_name,jms_fs_name)
        cd(jms_fs_path)
        cmo.createForeignConnectionFactory(jms_fconf_name)
        cd(jms_fs_path+'/ForeignConnectionFactories/'+jms_fconf_name)
        cmo.setLocalJNDIName(cljndi)
        cmo.setRemoteJNDIName(crjndi)
############## MAIN SCRIPT starts  ##########
envproperty=""
if (len(sys.argv) > 1):
        envproperty=sys.argv[1]
else:
    print "Environment Property file not specified"
    sys.exit(2)
propInputStream=FileInputStream(envproperty)
configProps=Properties()
configProps.load(propInputStream)
 
adminUser=configProps.get("adminUser")
adminPassword=configProps.get("adminPassword")
adminURL=configProps.get("adminURL")
 
connect(adminUser,adminPassword,adminURL)
 
edit()
startEdit()
 
##############################################
#FOREIGN JMS SERVER CONFIGURATION
##############################################
total_dest=configProps.get("total_dest")
total_fconf=configProps.get("total_fconf")

cluster_target_name=configProps.get("clusterName")
 
trg=configProps.get("ForeignTargetServer")
fs_mod_name=configProps.get("fsjms_mod_name")
createFSJMSModule(fs_mod_name,trg)
 
n= int(tot_fs)
for i in range(1,n+1):
        fr_server=configProps.get("fr_server"+ str(i))
        cnfurl=configProps.get("cnfurl"+ str(i))
        ini_context=configProps.get("initialContextFactory"+ str(i))
        createJMSFS(fs_mod_name,cnfurl,fr_server,ini_context)
 
        d_name=configProps.get("destname"+ str(i))
        d_ljndi=configProps.get("dest_ljndi"+ str(i))
        d_rjndi=configProps.get("dest_rjndi"+ str(i))
        print d_ljndi,' == ', d_rjndi, b
        createFSdest(fs_mod_name,fr_server,d_name,d_ljndi,d_rjndi)
 
        fr_server=configProps.get("fr_server"+ str(i))
        j_conf=configProps.get("fconf_name"+ str(i))
        cn_ljndi=configProps.get("fconf_ljndi"+ str(i))
        cn_rjndi=configProps.get("fconf_rjndi"+ str(i))
        createFSconf(fs_mod_name,fr_server,j_conf,cn_ljndi,cn_rjndi)
 
# ####   MAIN SCRIPT END ########################################
save()
activate(block="true")
disconnect()
This script is generic you can add as many foreign server as you wish. You can better use it for receive the message with foreign servers that are having source at remote location. It could be connect to WebLogic JMS or it can connect to third party messaging servers such as MQ series or ActiveMQ etc. You can execute the script as follows:
$ java weblogic.WLST Foreign_jms.py ForeignJms.properties

References:

JMS Foreign Server MDB

Oracle doumentation on Foreign Server creation
  1. MQ Series 2 WebLogic
  2. WebLogic 10.3 with IBM MQ
  3. Jsure blog on WebLogic MQ

Popular Posts