вторник, 11 сентября 2012 г.

Создание кластера серверов приложений WebLogic с помощью WLST и утилит pack/unpack

В заметке полуторагодичной давности Создаем кластер серверов приложений WebLogic: балансировка нагрузки, обнаружение ошибок, репликация сессий Суровый расказывал о том, как создать домен с помощью Configuration Wizard. Однако у данного способа есть недостаток - он трудоемок для администратора. Посудите сами: администратор, каждый раз создавая домен, вынужден проходить по двум десяткам окон мастера, внося одни и те же изменения. А т.к. классический процесс разработки и внедрения предполагает наличие как минимум трех сред: разработки, интеграционного тестирования и промышленной эксплуатации, то придется создать как минимум три домена. При этом грамотно настроеная среда промышленной эксплуатации подразумевает кластеризацию и соответствующее увеличение экземпляров домена. К счастью, процесс создания домена можно автоматизировать с помощью утилиты WebLogic Scripting Tool (WLST).


Этапы создания домена с помощью WLST


С помощью WLST домен создается в несколько этапов:

  1. Создание каталога с доменом. Каталог с доменом содержит все ресурсы домена. Дальнейшие действия предполагают лишь настройку данного домена. Создать каталог с помощью WLST можно только на основе шаблона домена. Шаблон домена - специальный архив, содержащий множество ресурсов домена: инфраструктурные компоненты, приложения, сервисы, настройки безопасности и переменные окружения. С сервером приложений WebLogic поставляется набор базовых шаблонов доменов, см. каталог $MIDDLEWARE_HOME\wlserver_10.3\common\templates\domains. Приложения, входящие в семейство продуктов Oracle Fusion Middleware, содержат свои шаблоны доменов, включающие те или иные функции.

    Каталог с доменом создается либо с помощью команды createDomain(TEMPLATE_PATH, DOMAIN_PATH, USER, PASSWORD), либо с помощью пары команд readTemplate(TEMPLATE_PATH)/writeDomain(DOMAIN_PATH). Между выполнением данных команд можно расширить домен с помощью нужного количества шаблонов, выполняя команды addTemplate(TEMPLATE_PATH) и создать администратора домена (см. пример создания домена).

    После создания каталога домена можно запускать сервер администрирования данного домена, например, с помощью команды startServer().

  2. Настройка параметров SSL. Все пункты, начиная с данного, являются необязательными. Если предполагается использовать специфичные настройки SSL для домена, то их необходимо задать в отдельной сессии запуск сервера администрирования - редактирование свойств - останов сервера администрирования. В данной секции можно, например, отключить верификацию имени хоста в сертификате при создании безопасного подключения и сделать выбор между одно- или двунаправленным SSL-соединением.

  3. Настройка параметров безопасности NodeManager'а. Если домен создается в режиме эксплуатации, то по-умолчанию для NodeManager'а случайным образом генерируется пара логин/пароль, используемая для подключения к домену. Если предполагается использовать NodeManager для управления серверами домена, то пару логин/пароль нужно задать явно с помощью соответствующих свойств компонента SecurityConfiguration.

  4. Создание инфраструктурных компонентов. После того как заданы настройки безопасности, можно создать необходимые инфраструктурные компоненты домена: машины, серверы, кластеры, источники данных, JMS-ресурсы, менеджеры задач и т.д. Так же не стоит забывать, что сервер администрирования домена - это тоже сервер и ему так же можно указать машину (свойство Machine компонента /Servers/AdminServer, где AdminServer - наименование сервера администрирования).

    В дополнение, стоит заметить, что если у сервера администрирования не указать адрес слушателя, то он начинает работать на всех интерфейсах машины. Это не страшно, проблема в том, что управляемые сервера не понимают по какому адресу им соединяться с сервером администрирования. Поэтому рекомендуется явно указать адрес для сервера администрирования (свойство ListenAddress компонента /Servers/AdminServer, где AdminServer - наименование сервера администрирования).

Пример создания домена с помощью WLST


Продемонстрируем описанные выше этапы создания домена:

#Conditionally import wlstModule only when script is executed with jython

if __name__ == '__main__':

    from wlstModule import *#@UnusedWildImport



print 'starting the script ....'



beahome = 'C:/oracle/Middleware6'

soahome = beahome + '/soa_11.1'

adminusername = 'weblogic'

adminpassword = '12345678'

adminservername = 'AdminServer'

adminserverurl ='t3://192.168.177.34:7001'

machine1ip = '192.168.177.34'

machine2ip = '192.168.177.48'

domainname = 'demo_domain'



domaindir = 'C:/oracle/user_projects/domains/' + domainname

appdir = 'C:/oracle/user_projects/applications/' + domainname

domaintemplate = beahome + '/wlserver_10.3/common/templates/domains/wls.jar'

soatemplate = soahome + '/common/templates/applications/oracle.soa_template_11.1.1.jar'

emtemplate = beahome + '/oracle_common/common/templates/applications/oracle.em_11_1_1_0_0_template.jar'

jvmdirectory = 'C:/Java/jdk1.7.0_07'



print 'creating domain ' + domainname

readTemplate(domaintemplate)

#addTemplate(soatemplate)

#addTemplate(emtemplate)

setOption('DomainName', domainname)

setOption('OverwriteDomain', 'true')

setOption('ServerStartMode', 'prod')

setOption('JavaHome', jvmdirectory)

setOption('AppDir', appdir)



cd('/Security/base_domain/User/weblogic')

cmo.setName(adminusername)

cmo.setUserPassword(adminpassword)

cd('/')



writeDomain(domaindir)

closeTemplate()



try:

    print 'starting the admin server...'

    startServer(adminServerName=adminservername, domainName=domainname, url=adminserverurl, username=adminusername,

            password=adminpassword, domainDir=domaindir, jvmArgs='-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')



    print 'connect to the admin server...'

    connect(adminusername, adminpassword, adminserverurl)



    print 'start edit mode'

    edit()

    startEdit()    

   

    print 'disable hostname verification'        

    adminssl = getMBean('/Servers/' + adminservername).getSSL()

    adminssl.setHostnameVerificationIgnored(true)

    adminssl.setHostnameVerifier(None)

    adminssl.setTwoWaySSLEnabled(false)    



    print 'save and activate changes'    

    save()

    activate(block="true")

   

    print 'shutdown the admin server'

    shutdown(block = 'true')



    print 'disconnect from the admin server'

    disconnect()



    print 'starting the admin server'

    startServer(adminServerName=adminservername, domainName=domainname, url=adminserverurl, username=adminusername,

            password=adminpassword, domainDir=domaindir, jvmArgs='-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

   

    print 'connecting to the admin server'

    connect(adminusername, adminpassword, adminserverurl)

   

    print 'start edit mode'

    edit()

    startEdit()



    print 'change nodemanager username and password'    

    cd('/SecurityConfiguration/' + domainname)

    set('NodeManagerUsername', adminusername)

    set('NodeManagerPasswordEncrypted', encrypt('12345678', domaindir))

    cd('/')            



    print 'save and activate changes'    

    save()

    activate(block="true")

   

    print 'shutdown the admin server'

    shutdown(block = 'true')



    print 'disconnect from the admin server'

    disconnect()

   

    print 'starting the admin server'

    startServer(adminServerName=adminservername, domainName=domainname, url=adminserverurl, username=adminusername,

            password=adminpassword, domainDir=domaindir, jvmArgs='-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

   

    print 'connecting to the admin server'

    connect(adminusername, adminpassword, adminserverurl)

   

    print 'start edit mode'

    edit()

    startEdit()



    print 'create machine: athena'

    machine1 = cmo.createMachine('athena')

    machine1.getNodeManager().setListenAddress(machine1ip)

    machine1.getNodeManager().setNMType('ssl')

   

    print 'create machine: demetra'

    machine2 = cmo.createMachine('demetra')

    machine2.getNodeManager().setListenAddress(machine2ip)

    machine2.getNodeManager().setNMType('ssl')

   

    print 'create cluster: cluster'

    cluster = cmo.createCluster('cluster')

    cluster.setClusterMessagingMode('unicast')

   

    print 'create managed server: NL1'

    server1 = cmo.createServer('NL1')

    server1.setListenPort(7101)

    server1.setListenAddress(machine1ip)

    server1.setAutoRestart(true)

    server1.setAutoKillIfFailed(true)

    server1.setRestartMax(2)

    server1.setRestartDelaySeconds(10)

    server1.getServerStart().setJavaHome(jvmdirectory)

    server1.getServerStart().setJavaVendor('Sun')

    server1.getServerStart().setArguments('-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

   

    print 'create managed server: NL2'

    server2 = cmo.createServer('NL2')

    server2.setListenPort(7102)

    server2.setListenAddress(machine2ip)

    server2.setAutoRestart(true)

    server2.setAutoKillIfFailed(true)

    server2.setRestartMax(2)

    server2.setRestartDelaySeconds(10)

    server2.getServerStart().setJavaHome(jvmdirectory)

    server2.getServerStart().setJavaVendor('Sun')

    server2.getServerStart().setArguments('-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

   

    print 'create managed server: NL3'

    server3 = cmo.createServer('NL3')

    server3.setListenPort(7103)

    server3.setListenAddress(machine2ip)

    server3.setAutoRestart(true)

    server3.setAutoKillIfFailed(true)

    server3.setRestartMax(2)

    server3.setRestartDelaySeconds(10)

    server3.getServerStart().setJavaHome(jvmdirectory)

    server3.getServerStart().setJavaVendor('Sun')

    server3.getServerStart().setArguments('-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

   

    print 'add managed servers to cluster'

    server1.setCluster(cluster)

    server2.setCluster(cluster)

    server3.setCluster(cluster)

   

    print 'add managed servers to machines'

    server1.setMachine(machine1)

    server2.setMachine(machine2)

    server3.setMachine(machine2)    

   

    print 'add the admin server to machine'

    adminserver = getMBean('/Servers/' + adminservername)

    adminserver.setMachine(machine1)

    adminserver.setListenAddress(machine1ip)    

   

    print 'save and activate changes'    

    save()

    activate(block="true")

   

    print 'shutdown the admin server'

    shutdown(block = 'true')

   

    print 'disconnect from the admin server'

    disconnect()



    print "script returns SUCCESS"

except Exception, e:

    print e

    print "Error while trying to save and/or activate!!!"

    dumpStack()

    raise

В результате будет создан домен demo_domain, содержащий три управляемых сервера: NL1, NL2 и NL3. Управляемые сервера объединены в кластер cluster. При этом, сервер администрирования и управляемый сервер NL1 расположены на машине athena, а управляемые сервера NL2 и NL3 - на машине demetra. Верификация имени хоста при установке SSL-соединения отключена, двунаправленная авторизация не используется.

Запуск серверов домена


После того, как домен был создан, необходимо убедиться в работоспособности его серверов. Для этого попробуем запустить сервера, расположеные на локальной машине athena. Предположим, что утилита WLST уже запущена.

Прежде всего необходимо запустить сервер администрирования домена. Выполнить это можно с помощью команды startServer(), например так:

wls:/offline> startServer(adminServerName='AdminServer', domainName='demo_domain', url='t3://192.168.177.34:7001', username='weblogic', password='12345678', domainDir='C:/oracle/user_projects/domains/demo_domain', jvmArgs='-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m')

После успешного старта сервера администрирования необходимо запустить NodeManager:

wls:/offline> startNodeManager()

Теперь можно подключиться к административному серверу домена:

wls:/offline> connect('weblogic', '12345678', 't3://192.168.177.34:7001')

И запустить управляемый сервер NL1:

wls:/offline> start('NL1')

В результате административный сервер и сервер NL1 будут успешно запущены. Остальные управляемые сервера можно будет запустить после их распротранения на соответствующие узлы кластера.


Распространение управляемых серверов домена на другие узлы кластера


После создания домена на одной машине кластера необходимо обеспечить работу его управляемых серверов и на других узлах. Для этого нужно туда скопировать каталог домена. Это, конечно, можно сделать и с помощью утилиты scp, но данный способ накладывает на нас ряд ограничений: во-первых, нужно убедиться, что все файлы имеют такие же пути, как и файлы оригинального домена, во-вторых, нужно убедиться, что правильно выставлены права на файлы. Есть более надежные способы, самым простым из которых является использование утилит pack/unpack.

Утилита pack

Данная утилита предназначена для создания шаблона домена, при этом в качестве источника используется готовый домен. Расположена утилита в каталоге $MIDDLEWARE_HOME\wlserver_10.3\common\bin. Одним из наиболее интересных ключей данной утилиты является -managed, который может принимать два значения: true и false. Значением по-умолчанию является false. Данный ключ указывает какой тип шаблона нужно создать: шаблон домена (создается при значении ключа, равном false) или шаблон управляемых серверов (создается при значении ключа, равном true). Отличаются данные типы шаблонов следующим:

Шаблон домена содержит полное множество ресурсов домена, включая инфраструктурные компоненты, приложения, сервисы, настройки безопасности, переменные окружения и т.д. Данный шаблон можно использовать как основу для создания нового домена.

Шаблон управляемых серверов предназначен для распространения управляемых серверов домена на другие машины в сети. При разворачивании данного шаблона не создается новый домен, а создается продолжение существующего, в частности и это очень важно, не изменяется наименование домена.

Пример использования утилиты:

pack -domain=C:/oracle/user_projects/domains/demo_domain -template=C:/oracle/user_projects/domains/demo_domain.jar -template_name="Demo Domain" -template_author="Samolisov" -template_desc="Demo template for demo_domain" -managed=true -log=demo.log

Утилита unpack

Данная утилита предназначена для развертывания домена из шаблона. При этом, если шаблон является шаблоном домена, то можно поменять следующие параметры:

  • логин администратора домена (ключ -user_name);

  • пароль администратора домена (ключ -password);

  • каталог для хранения приложений домена (ключ -app_dir);

  • путь к JVM (ключ -java_home);

  • режим запуска серверов (режим разработки - dev - или режим эксплуатации - prod, ключ -server_start_mode)

При разворачивании шаблона управляемых серверов параметры -java_home, -server_start_mode, -user_name, -password игнорируются. Однако, добавляется параметр -overwrite_domain, имеющий значение по-умолчанию false. Если значение данного параметра равно true, то запускается изменение существующего каталога домена. Расположена утилита в каталоге $MIDDLEWARE_HOME\wlserver_10.3\common\bin.

Пример использования:

unpack -template=C:/oracle/user_projects/domains/demo_domain.jar -domain=C:/oracle/user_projects/domains/my_demo_domain -overwrite_domain=true

После распространения управляемых серверов по узлам кластера их можно подключить к балансировщику нагрузки. Сервер приложений WebLogic готов к работе.

Ресурсы



Понравилось сообщение - подпишитесь на блог и Twitter

4 комментария:

Эмин Аскеров комментирует...

Павел, интересная, содержательная статья особенно ценная для рунета. Я бы еще отметил здесь необходимость применения команды nmEnroll на каждой физической машине где развернут управляемый сервер в формате:

pathseparator = '\\';

beahome='C:\\Oracle\\Middleware';
domainname='MyDomain';
domainlocation = beahome + pathseparator + 'user_projects' + pathseparator + 'domains' + pathseparator + domainname;
nodemanagerhomelocation = beahome + pathseparator + 'wlserver_10.3' + pathseparator + 'common' + pathseparator + 'nodemanager';

connect('weblogic', 'password1', 't3://MS-MACHINE:7001');
nmEnroll(domainlocation, nodemanagerhomelocation);

disconnect('true');

Эмин Аскеров комментирует...

В случае, если на развертываемой инфраструктуре предполагается использовать платформу Oracle ADF, то после установки ADR и накатывания патчей до актуальной версии Oracle ADF необходимо применение команд в offline режиме:

...
applyJRF('*', domainlocation);
closeDomain();

upgradeADF(domainlocation);
...

Команды необходимо выполнить на всех машинах с управляемыми серверами + на отдельной машине с AdminServer.

Pavel Samolisov комментирует...

Эмин, спасибо большое за комментарии.

По поводу nmEnroll, данная команда нужна, чтобы зарегистрировать домен в NodeManager, опытным путем установленно, что при выполнении unpack домен так же регистрируется в Node Manager. Т.е. у меня получалось корректно настроить работу Node Manager'а на другой машине с доменом без выполнения nmEnroll, но все равно спасибо за замечание.

По поводу регистрации ADF не знал, потому что с ADF особо не работал. Спасибо за информацию.

Emin Askerov комментирует...

Да Павел, попробовал развернуть тестовую кластерную инфраструктуру в среде Oracle Linux, необходимости в команде nmEnroll не возникло. Хотя до этого я пробовал множить конфигурацию домена не командами pack и unpack, а простым копированием каталога домена, как об этом, например, говорится здесь: http://www.oracle-base.com/articles/11g/weblogic-11g-clustered-domains.php
Вот в этом случае команда nmEnroll необходима, но такой способ переноса конфигурации домена не рекомендован.

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!