JBoss Web Service Sample을 작성해보도록 하겠습니다. JBoss Web Service는 jboss.org의 jbossws 프로젝트를 이용하여 구성되어 있으며, JBoss Application Server 내에서 jbossws에 대한 sar(service archive)로 포팅되어 있습니다.
보통의 WebService예제는 vendor specific 으로 구성되어 있지만 JBoss의 특징이라면 "무조건 표준으로 간다"(워낙에 표준 준수가 심해서 가끔은 짜증이 납니다)이므로 JBoss Web Service라지만 다른 엔진 라이브러리만 있다면 아무데서나 구동될 수 있습니다.
Eclipse를 띄우고 일반 웹 애플리케이션 프로젝트를 띄운 후 JBoss library를 프로젝트의 Build Path로 지정합니다. 이 부분에 대해서는 별도 설명을 하지 않습니다.
/** * This is a webservice class exposing a method called greet which takes a input * parameter and greets the parameter with hello. * * @author Ji-Woong Choi */
/* * @WebService indicates that this is webservice interface and the name * indicates the webservice name. */ @WebService(name = "Hello", targetNamespace="http://client.jboss.com/", serviceName="GreetService") /* * @SOAPBinding indicates binding information of soap messages. Here we have * document-literal style of webservice and the parameter style is wrapped. */ //@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) @SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL) public class Hello { /** * This method takes a input parameter and appends "Hello" to it and returns * the same. * * @param name * @return */ @WebMethod public String greet(@WebParam(name = "name") String name) { System.out.println("JBoss Web Service was invoked by " + name); return "Hello!, " + name; } }
Web Service Annotation을 이용하여 필요한 메소드들을 구성합니다.
2. Web.xml 파일을 편집합니다. 본 예제에서는 servlet style을 이용하여 처리합니다.
// Message property setting for reply message.setJMSReplyTo(replyQueue); String uuid = (UUID.randomUUID()).toString();/* * generate a unique * id */ message.setJMSCorrelationID(uuid);
// Send message sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // sender.setTimeToLive(10000); sender.send(message); System.out.println("The message was successfully sent to the " + queue.getQueueName() + " queue");
// ALWAYS close your connection in a finally block to avoid leaks. // Closing connection also takes care of closing its related objects // e.g. sessions. closeConnection(connection); } }
// ALWAYS close your connection in a finally block to avoid leaks. // Closing connection also takes care of closing its related objects // e.g. sessions. closeConnection(connection); } }
TextMessage message = session.createTextMessage("Hello!"); sender.send(message); System.out.println("The message was successfully sent to the " + queue.getQueueName() + " queue");
// ALWAYS close your connection in a finally block to avoid leaks. // Closing connection also takes care of closing its related objects // e.g. sessions. closeConnection(connection); } }
while( true ){ TextMessage message = (TextMessage) consumer.receive(2000); if( message == null ) break; System.out.println("Message From [" + destinationName + "] is [" + message.getText() + "]"); } System.out.println("There is no more message in Queue"); } finally { if (ic != null) { try { ic.close(); } catch (Exception e) { throw e; } }
// ALWAYS close your connection in a finally block to avoid leaks. // Closing connection also takes care of closing its related objects // e.g. sessions. closeConnection(connection); } }
먼저 각각 구동시킨 JBoss 인스턴스 의 JvmRoute 와 UseJK를 true로 설정해야 합니다.
각 인스턴스의 해당 파일들을 수정합니다. (*) ...../jboss-web.deploy/server.xml 에서 <Engine name="jboss.web" defaultHost="localhost" jvmRoute="host1" > jvmRoute 는 각 인스턴스 마다 고유의 이름으로 설정합니다. (*)...../jboss-web.deploy/META-INF/jboss-service.xml <attribute name="UseJK">true</attribute> 를 true로설정
BindingManager 를 사용하시었다면 AJP port를 확인하도록 합니다.
Apache에서 다음의 httpd.conf 및 workers.properties 파일을 아래와 비교하여 점검합니다.
# Load mod_jk module # Update this path to match your modules location #LoadModule jk_module modules/mod_jk-1.2.26-httpd-2.2.6.so LoadModule jk_module modules/mod_jk.so
# Where to find workers.properties # Update this path to match your conf directory location (put workers.properties next to httpd.conf) JkWorkersFile conf/workers.properties
# Where to put jk logs # Update this path to match your logs directory location (put mod_jk.log next to access_log) JkLogFile logs/mod_jk.log
# Set the jk log level [debug/error/info] #JkLogLevel debug JkLogLevel info
# Select the log format JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
(*) ...../jboss-web.deploy/server.xml 에서 <!-- A AJP 1.3 Connector on port 8009 --> <Connector port="8009" address="${jboss.bind.address}" maxThreads="250" connectionTimeout="20000" emptySessionPath="true" EnableLookups="false" redirectPort="8443" protocol="AJP/1.3"/> 을 설정
주의 사항은 다음과 같습니다. maxThreads값은 Apache의 MaxClients값보다 커야 함. maxThreads는 성능 테스트 후 최대 성능 지점으로 잡고, Apache의 MaxClients는 이 값보다 작게 설정하는 방식으로 진행 특히 몇 대의 JBoss로 두고 Apache에서 로드 밸런싱할 경우에는 20% 정도 더 maxThreads를 크게 해서 여유를 둬야 함.
더더욱 주의 사항 HTTP Session replication을 위해서는 한 가지 더 web application의 web.xml파일에 아래의 같이 distributable 태그가 포함되어야 세션 설정이 됩니다.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>JBoss Sample Web Application</display-name> <distributable/> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
해당 클러스터에 참여 하는 partition 네임은 같아야 합니다. 위의 정의 에서는 DefaultPartition 이 라설정한 것이 고 다른 이름으로 바꾸시는 것이 좋습니다.
해당 cluster 설정파일에서 설정하지 않으면 서버구동스크립트의 Java Option에서 -Djboss.partition.name=XXX 설정하시면 됩니다. 또는 start script에서 run.sh ?c all ?b 203.231.14.15 ?g XXX 으로 바꾸 시면 됩니다.
클러스터링에 참여하는 서버들은 멀티캐스트 IP 와 port 로 서로의 상태를 복제합니다. 먼저 해당 멀티캐스트 IP 가 통신이 되는지부터 확인 하셔야 됩니다. ================================================================= 멀티캐스트 테스트 하시는 방법은 ★ 멀티캐스트 IP 설정 ? 멀티캐스트 대역에서 선택 - 224.0.0.1 ~ 239.255.255.254 ? -u X.X.X.X ? -Djboss.partition.udpGroup=X.X.X.X
★ JBoss 4.2에서는 multicast port도 설정 가능 (*) ? -Djboss.hapartition.mcast_port=45566 ? -Djboss.webpartition.mcast_port=45577 ? -Djboss.ejb3sfsbpartition.mcast_port=45551 ? -Djboss.ejb3entitypartition.mcast_port=43333
==================================== ? 멀티캐스트 테스트에 실패했을 때 ? 해당 NIC의 멀티캐스트를 활성화 ? ifconfig eth0 MULTICAST ? 해당 NIC로 멀티캐스트 메시지가 가도록 라우팅 ? NIC가 여러 개일 경우 ? route add -net 224.0.0.0 netmask 224.0.0.0 dev eth0 ? OS에 방화벽이 설치되어 있는지 확인 ? OS 방화벽이 있다면 멀티캐스트에 사용할 포트를 열어야 함 "iptables -F" ? Network Switch가 멀티캐스트를 지원하는지 확인 ? 멀티캐스트 테스트는 통과했는데 클러스터 동작이 안될 때 ? /etc/hosts 파일의 127.0.0.1에 호스트가 설정된 경우 이를 제거 127.0.0.1 yourhostname yourhostname.yourdomain localhost.localdomain localhost
Java EE 5의 경우에는 총 27098개의 테스트가 있습니다. 서비스의 종류로는 다음과 같은데 결국 스펙에서 이야기하는 내용입니다.
appclient
assembly
connector
ejb
ejb30/*
ejb30/persistence
integration
j2eetools
jacc
javamail
jaxr
jaxrpc
jaxws
jdbc
jms
jsf
jsp
jta
saaj
servlet
webservices
xa
compat12
compat13
jstl
jws
rmiiiop
webservices12
interop-ejb
interop-integration
interop-naming
interop-rmiiiop
interop-security
interop-tx
interop-webservices
interop-csiv2
signaturetest
이 중에서도 많은 비중을 차지하는 것을 보면 JDBC가 4932개로 압도적으로 많고 그 다음이 2655개의 JSF, 그리고 JMS, EJB3.0/persistence가 2500가량의 테스트로 이루어져 있습니다.
결국 WAS라는 것은 Web Client에서 Database tier를 담당하는 역할이 주를 이루고 있으므로 신규로 생성된 persistence layer에 많은 테스트가 할당된 것을 볼 수 있습니다. 조만간 Sun의 JEE5.0 Compatibility에 JBoss AS5가 포함될 것입니다.