Search This Blog

Tuesday, January 8, 2013

Cluster manuplation with WLST

There could be situations where you might have seen this. such as in production environment one of the site will be decommissioned. All the site member machines hosting WebLogic Managed Servers will be kicked out of domain. finally the cluster will be removed.

In some cases your production environment might having business enhancement plans, so that there could be new geographical site will be added to to existing running domain then, there would be need of cluster or clusters addition to the domain and respective managed servers all added to it.

Here I got a thought that why don't we make a WLST script that will give you option of High Availability(HA) with above said options as well additon to it addtion of managed server and removal of managed servers.

OEPE is giving ready made scripts so I thought this would be easy to implement the logic.

Designing WebLogic Cluster

First you need to identify type of the cluster you need to implement. Single WebLogic Cluster can serve the minimum size of business requests. You need to identify the number of the server required on a cluster. You can choose Multi-tier cluster where you can have dedicated cluster for each service. After experiancing many production issues identified what all the configuration changes that makes standard and easy to handle the troubleshooting in production environments are collected and compiled as "Best practices" implementation for Managed server configuration with Jython script.

1. Log LEVELwith best suitable attributes
2. Log rotation for managed servers
3. Threadpool size settings with WLST
4. Diagnostic framework enabling with WLST

from java.util import *
from java.io import FileInputStream
from javax.management import *
import javax.management.Attribute
import sys

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)

def getp(x):
 """ This function will be used to fetch the properties file"""
        return configProps.get(x)
 

def logLevel(ms, k):
 lg = ms.getLog()
 lg.setFileName(''+domainHome+'/logs/bea/ms'+str(k)+'_'+domainName+'.log')
 lg.setLogFileSeverity('Info')
 lg.setRotationType('byTime')
 lg.setRotationTime("23:59")
 lg.setFileTimeSpan(24)
 lg.setDomainLogBroadcastSeverity('Error')
 lg.setMemoryBufferSeverity('Error')
 lg.setRedirectStdoutToServerLogEnabled(true)
 lg.setRedirectStderrToServerLogEnabled(true)
 lg.setStdoutSeverity('Error')
 
def setDiagnostics(ms, k):
 svrdiag = ms.getServerDiagnosticConfig()
 svrdiag.setDiagnosticContextEnabled(false)
 svrdiag.setDiagnosticStoreDir(''+domainHome+'/logs/store/diagnostics/ms'+str(k)+'_'+domainName+'/')

 defFileStore = ms.getDefaultFileStore()
 defFileStore.setDirectory(''+domainHome+'/logs/store/default/ms'+str(k)+'_'+domainName+'/')
  
 hvDataRetire = svrdiag.createWLDFDataRetirementByAge("HarvestDataRetirePolicy")
 hvDataRetire.setArchiveName(""+getp("ms_harvesarchivename")) 
 hvDataRetire.setEnabled(bool(getp("ms_harvesenabled")))
 hvDataRetire.setRetirementAge(int(getp("ms_harvesretireage")))
 hvDataRetire.setRetirementPeriod(int(getp("ms_harvesretireperiod")))
 hvDataRetire.setRetirementTime(int(getp("ms_harvesretiretime")))

 eventDataRetire = svrdiag.createWLDFDataRetirementByAge("EventDataRetirePolicy")
 eventDataRetire.setArchiveName(""+getp("ms_evtarchivename"))
 eventDataRetire.setEnabled(bool(getp("ms_evtenabled")))
 eventDataRetire.setRetirementAge(int(getp("ms_evtretireage")))
 eventDataRetire.setRetirementPeriod(int(getp("ms_evtretireperiod")))
 eventDataRetire.setRetirementTime(int(getp("ms_evtretiretime")))

def webserver_log(ms, k):
 wbsvr = ms.getWebServer()
 wbsvr.setPostTimeoutSecs(30)
 wbsvrlog = wbsvr.getWebServerLog()
 wbsvrlog.setFileName(''+domainHome+'/logs/ms'+str(k)+'_'+domainName+'_access.log')
 wbsvrlog.setLoggingEnabled(bool(getp("ms_accesslogenabled")))
 wbsvrlog.setLogFileFormat(""+getp("ms_accesslogformat"))
 wbsvrlog.setELFFields(""+getp("ms_extlogfomart"))
 wbsvrlog.setRotationType('byTime')
 wbsvrlog.setRotationTime("23:59")
 wbsvrlog.setFileTimeSpan(24)

 #execQ1 = ms.createExecuteQueue("weblogic.kernel.Default")
 #execQ1.setThreadCount(30)
 #execQ1.setThreadsIncrease(0) 
#####################################################################################
#  MANAGED SERVER CONFIGURATIONS
###################################################################################

def create_ms(k):
 ms = create(""+getp("man"+str(k)),'Server')
 ms.setListenAddress(""+getp("ms_listenaddress"+str(k)))
 ms.setListenPort(int(getp("ms_listenport"+str(k))))
 
 ms.setWeblogicPluginEnabled(bool(getp("ms_defaultwlplugin")))
 #ms.setUse81StyleExecuteQueues(true)
 ms.setMaxOpenSockCount(int(getp("ms_maxopensockcount")))
 ms.setNativeIOEnabled(bool(getp("ms_nativeioenabled")))
 ms.setStuckThreadMaxTime(int(getp("ms_stuckthreadmaxtime")))
 ms.setStuckThreadTimerInterval(int(getp("ms_stuckthreadtimerinterval")))
 ms.setLowMemoryGCThreshold(int(getp("ms_lowmemorygcthreshold")))
 ms.setLowMemorySampleSize(int(getp("ms_lowmemorysamplesize")))
 ms.setLowMemoryTimeInterval(int(getp("ms_lowmemorytimeinterval")))
 ms.setStagingMode(""+getp("ms_stagingmode"))
 ms.setAcceptBacklog(int(getp("ms_acceptbacklog")))
 ms.setLoginTimeoutMillis(int(getp("ms_logintimeoutmillis")))
 ms.setManagedServerIndependenceEnabled(bool(getp("ms_managedserverindependenceenabled")))
 ms.setTransactionLogFilePrefix(""+getp("ms_transactionlogfileprefix"))
 print ' ******* SETTTING MANAGED SERVER ATTRIBUTES for *********** '+getp("man"+str(k))
 logLevel(ms, k)
 setDiagnostics(ms, k)
 webserver_log(ms, k)
 ms.setCluster(clusTgt)
 
################ main program ####################################################
domainName=getp("domainName")
adminServerListenaddr=getp("adminServerListenaddr")
admin_listerport=getp("admlistenport")
adminURL="t3://"+adminServerListenaddr+":"+str(admin_listerport)
domainHome=getp("domainHome")

adminUser=getp("adminUser")
adminPassword=getp("adminPassword")
userConfigFile=""+domainHome+"/bin/userconfigfile.secure"
userKeyFile=""+domainHome+"/bin/userkeyfile.secure"

adminServerName=getp("adminServerName")
clusterName=getp("clusterName")
numMS=getp("total_mansrvr")

connect(adminUser,adminPassword,adminURL)
edit()
startEdit()
cd('/')
#####################################################################################
#  CLUSTER CONFIGURATIONS
#####################################################################################
print ' ******* CREATING CLUSTER *********** '
clu = cmo.createCluster(""+clusterName)
isMulticastTrue=getp("isMulticastTrue")
if (isMulticastTrue == "true"):
 clu.setMulticastAddress(getp("multi_address"))
 clu.setMulticastPort(getp("multi_port"))
else:
 clu.setClusterMessagingMode('unicast')

clu.setWeblogicPluginEnabled(true)
clu.setClusterAddress('')
#cd('/Clusters/'+clusterName+'/OverloadProtection/'+clusterName+'/ServerFailureTrigger/'+clusterName)
#clu.setMaxStuckThreadTime(300)
#clu.setStuckThreadCount(0)
#cd('/Clusters/'+clusterName+'/OverloadProtection/'+clusterName)
#clu.setPanicAction('system-exit')
#clu.setFailureAction('admin-state')
#clu.createServerFailureTrigger()
cd('/Clusters/'+clusterName)
clusTgt = cmo
cd('/')
for k in range(1, int(numMS)+1): 
 print getp("man"+str(k))
 create_ms(k) 
cd('/')
save()
activate(block="true")

disconnect()
#####################################################################################

Here I am publishing the sample properties file that I have tried on my Windows operating system, after the execution of basic domain running with Admin server. When we start the WebLogic 12c or 10.3.6 version on Windows 7 it is not able to open the 'Console'. Alternative solution for this is change the PermSize to 512m in the setDomainEnv.cmd select proper Java vendor and update the following lines.
 set WLS_MEM_ARGS_64BIT=-Xms512m -Xmx512m -XX:PermSize=512m
 set WLS_MEM_ARGS_32BIT=-Xms512m -Xmx512m -XX:PermSize=512m
Start the Admin server so that we can run the online WLST script to configure the number of managed server that are mentioned in the properties file. The properties file is extended for this Cluster implemenation is as follows:
#####################################################################################
# DOMAIN LEVEL CONFIGURATION
##################################################################################
domainTemplate=C:/Oracle/Middleware/wlserver_10.3/common/templates/domains/wls.jar
#Following property is the default property and should not be changed.
weblogicdomainpasspath=Security/base_domain/User/weblogic

adminUser=weblogic
adminPassword=weblogic123$
adminServerName=admin_cldom
adminServerListenaddr=localhost
admlistenport=7100

OverwriteDomain=true
domainName=cldom1
domainHome=C:/wldomains/cldom1

clusterName=cluster_cldom
isMulticastTrue=false
multi_address=
multi_port=
##################################################################################
# MANAGED SERVERS CONFIGURATIONS
##################################################################################
total_mansrvr=2

man1=rdms1_cldom
man2=rdms2_cldom

ms_listenaddress1=localhost
ms_listenaddress2=localhost

ms_listenport1=61001
ms_listenport2=61002

ms_selftunningthreadpoolsizemin=30
ms_selftunningthreadpoolsizemax=35
ms_defaultwlplugin=true
ms_maxopensockcount=1000
ms_nativeioenabled=true
ms_stuckthreadmaxtime=300
ms_stuckthreadtimerinterval=300
ms_lowmemorygcthreshold=5
ms_lowmemorysamplesize=10
ms_lowmemorytimeinterval=3600
ms_stagingmode=nostage
ms_acceptbacklog=65
ms_logintimeoutmillis=5000
ms_managedserverindependenceenabled=true
ms_transactionlogfileprefix=/xa_logs/cldom

ms_accesslogenabled=true
ms_accesslogformat=extended
ms_extlogfomart=c-ip date time cs-method sc-status time-taken bytes cs-uri cs(Referer)

ms_harvesarchivename=HarvestedDataArchive
ms_harvesenabled=true
ms_harvesretireage=168
ms_harvesretireperiod=24
ms_harvesretiretime=0

ms_evtarchivename=EventsDataArchive
ms_evtenabled=true
ms_evtretireage=168
ms_evtretireperiod=24
ms_evtretiretime=0
When we run the sample cluster domain on the Windows 7 the outcome is as follows:
C:\pbin>java weblogic.WLST cluster_conf.py mycldom.properties

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

Connecting to t3://localhost:7100 with userid weblogic ...
Successfully connected to Admin Server 'admin_cldom' that belongs to domain 'cld
om1'.

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

Location changed to edit tree. This is a writable tree with
DomainMBean as the root. To make changes you will need to start
an edit session via startEdit().

For more help, use help(edit)

Starting an edit session ...
Started edit session, please be sure to save and activate your
changes once you are done.
 ******* CREATING CLUSTER ***********
rdms1_cldom
MBean type Server with name rdms1_cldom has been created successfully.
 ******* SETTTING MANAGED SERVER ATTRIBUTES for *********** rdms1_cldom
rdms2_cldom
MBean type Server with name rdms2_cldom has been created successfully.
 ******* SETTTING MANAGED SERVER ATTRIBUTES for *********** rdms2_cldom
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ...
The edit lock associated with this edit session is released
once the activation is completed.
Activation completed
Disconnected from weblogic server: admin_cldom

Sunday, November 18, 2012

Input and Output in WLST

In WLST we can have same kind of command line inputs and outputs as in Python and Jython languages. This can be useful when it is required to prepare a huge monitoring report using WLST or when you work for hundreds of servers in a domain such as in cloud where Middleware as a service (MAAS) and you need to find an automation task with WLST scripts.

Inputs in WLST

To read simple string of values we can use raw_input() built in function or sys.stdin.readline() method. For reading different data types such as number values we can use input() function, which internally calls raw_input() function and apply eval() to convert the input value to number values.
wls:/offline> x=raw_input('Enter a number:')
Enter a number:4009
wls:/offline> print x*2
40094009
wls:/offline> y=input('Enter a number: ')
Enter a number: 400
wls:/offline> print y*3
1200
Let’s experiment with Boolean type of variable in WLST
wls:/offline> b=input('Do you love WLST?')
Do you love WLST?True
wls:/offline> print b
1
wls:/offline> b=input('Do you love WLST?')
Do you love WLST?False
wls:/offline> print b
0
Here you enter as True or False but, the Boolean variables are stores on WLST SHELL as either zero or one. This is somewhat confusing you with regular Boolean types in other languages or UNIX it is opposite. One represents True value, zero represents False. So take care while you scripting for the Boolean type variables.
When you have the option to select the data in string format then go for raw_input() built-in function. This is much better way when situation demands your script to enter name of the WebLogic server instance or some questions to repeat the script task. On the other hand input() will be good option when you have to select multiple options for monitoring geographical sites to choose one of them with a numbered input.

Reading variable in WLST with stdin

We have one more option to read the values from the WLST command prompt that is using sys module. We can use sys.stdin.readline() method to read the input and assign it to a variable. This will fetches only text data in to the variable, so you use this when you want to input the strings.
wls:/offline> serv=sys.stdin.readline()
managed3_server
wls:/offline> serv
'managed3_server\n'
wls:/offline> print serv
managed3_server

Output in WLST

An output can be displayed using print command as we have seen many statements in WLST already. Although, we cover few basics of print statement, which accepts string as an argument.
  • Simple string to display
    print ‘Welcome to WLST!!!’
    
  • To display the string and variables combinations in Java Style concatenation that is using ‘+’ operator
    print  ‘Server Status ’+ stat
    
  • To display only WLST script variables then you can use the comma separated variables you can use the combination of string in the same line too
    print x, y
    
  • Now, we will see the good old C style formatting for the output, here we use % symbol followed by paranthesized list of variables that will be substituted in place of embedded conversion types (such as string - s, decimal - d, float - f) in the order.
    print ‘%14s %d %f’ %(server, freeJvm, throughput)
    
In WLST we can use the print statement for displaying the data from a variable or strings objects. We can display the combination of variables in the same line. This is possible with comma separation or simply we can use Java style of concatenation using plus symbol.

Obtain Environment variables in WLST

WLST supports the Jython capability that obtaining the environment variables from the System. To do this we need to import the os module (operating system) and use the environ dictionary variable.

wls:/offline> import os
wls:/offline> os.environ
{'WL_HOME': 'C:\\wls12c\\wlserver',  …}

You can pull out your required values of environment variable as you access the dictionary variable. Example you can retrieve WL_HOME or JAVA_HOME values as show below.

wls:/offline> os.environ["WL_HOME"]
'C:\\wls12c\\wlserver'

wls:/offline> os.environ["JAVA_HOME"]
'C:\\Java\\jdk1.6.0_34'

This WLST trick can be most often used; when you are configuring resources are creating WebLogic domains. Remember, This WLST trick will works on UNIX platform as well.



Popular Posts