[root@qa bin]# ./run.sh -b 0.0.0.0 : command not found : command not found : command not found : command not found : command not found : command not found : command not found -bash: run.conf: line 52: syntax error: unexpected end of file
컹;;; JBoss 설치판을 만들면서 run.conf 를 원하는 값으로 변경하려고 하는데 위와 같은 오류가 발생합니다.
열심히 캐 삽질한 결과 원인을 발견했습니다.
UNIX/LINUX 의 쉘 스크립트에서는 개행 시에 Carriage return (OD) + Linefeed (OA) 가 있을 경우 위와 같이 정상적으로 읽어들이지 못하는 문제가 있습니다.
변환하는 프로그램에서 뉴 라인을 CR + LF 조합으로 쓰다보니 문제가 발생하는 것이였습니다.
String line = null; while ((line = reader.readLine()) != null ) { fileContents.append(line).append("\r\n"); }
>>
String line = null; while ((line = reader.readLine()) != null ) { fileContents.append(line).append("\n"); }
15:50:25,406 ERROR [AbstractKernelController] Error installing to Start: name=jboss.remoting:protocol=rmi,service=JMXConnectorServer state=Create mode=Manual requiredState=Installed java.net.MalformedURLException: Bad URL path: _oracle/jndi/rmi://ccu_oracle:1090/jmxconnector at javax.management.remote.JMXServiceURL.validate(JMXServiceURL.java:365) at javax.management.remote.JMXServiceURL.<init>(JMXServiceURL.java:225)
왠일인지 로컬 테스트용 JBoss 가 안 뜹니다... 오라클만 시키는대로 설치했을 뿐인데...
원인은 컴퓨터 이름에 언더바가 들어가면 어떠한 버그로 인해 처리가 안되는 것 이였습니다. (위에 보시면 컴퓨터 이름이 ccu_oracle 인데, Bad URL Path: _oracle 이라고 나옵니다. 언더바로 split 하는 로직이 있나봅니다.)
/etc/sysconfig/network 에서 HOSTNAME 을 언더바가 없는 이름으로 설정합니다.
JBossWS를 이용하여 웹 서비스를 배포하면 편한 점도 있지만 치명적인 단점도 포함하고 있습니다.
JBossWS 의 soap:address location 은 JBoss 를 띄운 서버의 리얼 IP 를 이용하여 배포를 하게 되는 것입니다. 만약 서버의 리얼 IP가 10.101.111.135 라면 아래와 같은 형태로 wsdl 이 배포될 것 입니다.
위와 같이 배포된 웹 서비스가 문제를 일으킬 수 있는 환경은 다음과 같습니다.
1. 내부 보안 정책 상 80 포트만 열려 있고 8080 포트가 막힌 경우
2. L4 를 통하여 로드벨런싱으로 구성된 멀티 서버의 경우 (1번과 같이 8080 포트가 오픈되지 않을 확률이 높음)
3. 리얼 IP 와 외부로 노출된 IP 가 다른 경우
이럴 경우 아래와 같이 별도의 jsp 를 만들어서 배포하는 것이 좋습니다.
80 포트가 열려있는 상태에서 AJP 를 통해 정상적으로 JBoss 쪽으로 요청만 넘겨진다면 정상적으로 웹 서비스를 사용할 수 있을 것 입니다.
Windows 2007 서버에 JBoss 5.1 을 인스톨하고 그냥 띄우면 문제가 없는제 "-b" 옵션을 주고 띄우면 아래와 같은 오류가 발생합니다.
java.net.BindException: Address already in use: JVM_Bind
원인은 8083 을 해당 서버에서 사용하고 있기 때문입니다... 어떤 프로그램인지 찾기 보다는 JBoss 의 설정을 바꾸는 것이 훨씬 편한 작업입니다.
해당 서버에서 포트를 사용하는 경우도 있지만... 외부에 공개된 아이피와 실제 머신의 아이피가 달라서 발생한 문제였습니다.
실제로 포트를 사용하는 경우라면 아래의 방법을 사용하시면 되고, 외부 아이피와 실제 아이피가 다른 경우에는 "-b" 옵션의 인자 값을 실제 아이피로 설정하시면 문제가 해결됩니다.
클러스터링 환경에서는 프로세스가 두 개가 뜨기 때문에 종료 스크립트가 있는 것이 편리합니다. 그렇지 않고 JBoss 에서 제공되는 종료 스크립트를 이용할 경우 바로 프로세스가 떨어지지 않아 사용자의 요청이 종료 중이 프로세스로 갈 수도 있습니다. 바로 프로세스를 죽이는 것이 운영 중에는 좋습니다.
# Status worker for managing load balancer
worker.status.type=status
각 서버의 Apache HTTP Server 설정을 위와 같이 바꾸어주면 자신의 서버에 올려져 있는 인스턴스 뿐만 아니라 다른 서버의 인스턴스까지 요청이 가능하게 됩니다.
단, 이러한 구성의 경우 세션 복제로 인한 오버헤드가 발생할 수 있습니다. buddy-replication 설정을 통해 근접한 인스턴스에게만 세션 복제를 할 수 있게 설정할 수 있습니다.
node1 -> node2, node2 -> node3, node3 -> node4, node4 -> node1 이런 방식으로 buddy-replication 을 설정하면 하나의 노드가 죽더라도 buddy 노드가 해당 세션을 복제 받을 수 있을 것 입니다. 하지만 이러한 경우 sticky-session 설정이 되어야 할 것으로 생각되네요...
쉬울지 알고 접근했던 JBoss 클러스터링인데, 역시 뭐든지 실제로 해보고 느껴봐야 할 것 같습니다.
안해봤으면 말을 하지 마요~ 어후...
configuration 을 설정하는 것 입니다. all 을 통해 복사한 node1, node2 를 각 인스턴스별로 설정합니다.
-g
클러스터 이름을 설정합니다. (그냥 자기가 좋아하는 이름을 지정하면 될 것 같습니다.)
-u
내부 클러스터 통신을 위한 멀티캐스트 주소를 설정합니다.
-b
소켓에 바운딩될 아이피 주소를 설정합니다.
System properties
jboss.messaging.ServerPeerID
각 노드마다 지정되는 유니크한 정수 값 입니다. 1부터 순차적으로 증가하면 될 것 같습니다.
jboss.service.binding.set
ServiceBindingManager 를 통해 포트 설정을 위한 프로퍼티입니다. 시스템별 첫번째 인스턴스에는 ports-default 로 설정하고 그 다음 인스턴스부터는 ports-01, ports-02 ... 과 같이 설정을 합니다. 기본적으로 JBoss 의 포트가 8080 이고 AJP 1.3 포트가 8009 라면 ports-default 는 8080, 8009 로 바인딩 되고, ports-01 은 8180, 8109 로 바인딩 됩니다.
나중에 나오겠지만 mod_jk 설정을 위해 미리 jvmRoute 를 설정합니다. <JBOSS_HOME>/server/"node1|node2"/deploy/jbossweb.sar/server.xml
각 인스턴스 별로 <Engine> element 의 attribute 로 jvmRoute 를 설정합니다.
웹 어플리케이션을 어떤 방식으로 배포하냐에 따라서 설정이 달라지게 됩니다.
두 인스턴스의 deploy 경로에 각각 배포를 하는 방식이 있고, 한 곳에 배포하여 공유하여 사용하는 방식이 있습니다.
한 곳의 배포하는 방식 중에 한가지는 farm 을 이용하는 것 입니다.
<JBOSS_HOME>/server/node1/farm 에 배포를 하게 되면 각 인스턴스들이 공유하여 사용할 수 있습니다.
(해보지는 않았습니다... 어디선가 본 자료입니다.)
다른 방법으로는 같은 배포 경로를 각 인스턴스에 설정을 하는 것 입니다. <JBOSS_HOME>/server/"node1|node2"/conf/bootstrap/profile.xml
<deployment>
...
<!--
The profile configuration
This contains required properties:
The uri to jboss-service.xml.
The uri to the deployers folder.
A list of uris to deploy folders. -->
<bean class="org.jboss.system.server.profileservice.repository.StaticProfileFactory" name="BootstrapProfileFactory">
<property name="bindingsURI">${jboss.server.home.url}conf/bindingservice.beans</property>
<property name="bootstrapURI">${jboss.server.home.url}conf/jboss-service.xml</property>
<property name="deployersURI">${jboss.server.home.url}deployers</property>
<property name="applicationURIs">
<list elementclass="java.net.URI">
<value>${jboss.server.home.url}deploy</value> <value>file:/home/webapps</value>
</list>
</property>
<property name="attachmentStoreRoot">${jboss.server.data.dir}/attachments</property>
<property name="profileFactory"><inject bean="ProfileFactory"></inject></property>
</bean>
...
</deployment>
저의 경우에는 /home/webapps 에 war 를 배포할 예정이므로 위와 같이 설정을 하였습니다.
# Mount your applications JkMount /test-jboss/* loadbalancer
# You can use external file for mount points.
# It will be checked for updates each 60 seconds.
# The format of the file is: /url=worker
# /examples/*=loadbalancer
JkMountFile conf/uriworkermap.properties
# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm
# Add jkstatus for managing runtime data
<Location /jkstatus/>
JkMount status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
웹 어플리케이션의 context-root 가 /text-jboss 이기 때문에 JkMount 에 설정하였습니다.
<APACHE_HOME>/conf/uriworkermap.properties
# Simple worker configuration file
# Mount the Servlet context to the ajp13 worker
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer
/test-jboss=loadbalancer
/test-jboss/*=loadbalancer
웹 어플리케이션의 context-root 로 마운트 포인트를 설정합니다.
<APACHE_HOME>/conf/workers.properties
# Define list of workers that will be used
# for mapping requests
worker.list=loadbalancer,status