티스토리 툴바


Amazon Linux AMI에서 Apache2.2 + Tomcat7 연동

2012/02/02 17:24 | Posted by 포데브(엄지사랑) 엄지사랑
: 서버구축환경

OS: Amazon Linux AMI release 2011.09 <== CentOS 계열(5.x)
WS: Apache/2.2.21 (Unix)
WAS: tomcat-7.0.22


: Apache2(httpd) 설치

$ sudo yum install httpd


: 설치확인

$ chkconfig  --list | grep httpd
httpd           0:off   1:off   2:off   3:off   4:off   5:off   6:off
$ apachectl -v
Server version: Apache/2.2.21 (Unix)
Server built:   Oct 26 2011 22:12:40


: 설치정보

$ cd /etc/httpd
$ ll
total 8
drwxr-xr-x 2 root root 4096 Feb  2 05:33 conf
drwxr-xr-x 2 root root 4096 Feb  2 05:33 conf.d
lrwxrwxrwx 1 root root   19 Feb  2 05:33 logs -> ../../var/log/httpd
lrwxrwxrwx 1 root root   29 Feb  2 05:33 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx 1 root root   19 Feb  2 05:33 run -> ../../var/run/httpd


: apache 실행

$ sudo /usr/sbin/apachectl start
$ netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN
tcp        0      0 :::80                       :::*                        LISTEN
tcp        0      0 :::8080                     :::*                        LISTEN
tcp        0      0 :::22                       :::*                        LISTEN
tcp        0      0 ::ffff:127.0.0.1:8005       :::*                        LISTEN
tcp        0      0 :::8009                     :::*                        LISTEN


: apache2.2 + tomcat7 연동 설정(mod_proxy_proxy)

> 참고: http://bugcide.blogspot.com/2011/07/centos-apache-tomcat-yum.html

> /etc/httpd/conf/httpd.conf 에 mod_proxy 활성화 되어있는지 확인 (기본 설치값은 활성화되어 있음)
> * LoadModule proxy_module modules/mod_proxy.so
> conf/httpd.conf 에 주석처리된 mod_proxy.c 부분을 설정해도 좋지만
> /etc/httpd/conf.d/ 에 tomcat.conf 파일을 새로 생성함


$ sudo vi /etc/httpd/conf.d/tomcat.conf

<IfModule mod_proxy.c>

ProxyRequests off

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

<IfModule mod_disk_cache.c>
   CacheEnable disk /
   CacheRoot "/var/cache/mod_proxy"
</IfModule>

</IfModule>


$ sudo /usr/sbin/apachectl restart 


끝.
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

Amazon Linux AMI에 대하여...

2012/02/01 13:48 | Posted by 포데브(엄지사랑) 엄지사랑
AWS 에서 사용하고 있는 OS는 Amazon Linux AMI 입니다.
Amazon Linux AMI는 CentOS를 기반으로 하고 있으며
CentOS는 RedHat Enterprise Linux AS 기반의 리눅스 배포판입니다.

참고: 
http://centos.pe.kr/owiki/index.php?url=centos
http://www.jopenbusiness.com/mediawiki/index.php/CentOS

또한 Amazon Linux AMI User Guide 문서에는 아래와 같은 내용이 있습니다.

Is the Amazon Linux AMI compatible with other Linux distributions?
The Amazon Linux AMI is very similar to CentOS in file system layout and package management. 
Applications built for CentOS 5 and later should run without recompilation of the Amazon Linux AMI. 
However, the Amazon Linux AMI is configured for use only in Amazon EC2.

Does the Amazon Linux AMI support third-party independent software vendor (ISV) applications?
Yes. Most ISV applications that are designed to run on CentOS 5 or later will run on the Amazon Linux AMI. 
However, the Amazon Linux AMI has not gone through any formal certification efforts with ISVs. 
If you have a specific question about whether an ISV will officially support running its application on the Amazon Linux AMI, 
please contact the ISV directly.


즉, Amazon Linux AMI는 CentOS와 호환되며 
ISV들에 의해 CentOS 5 또는 이후 버전에서 동작하는 것들은 Amazon Linux AMI에서 동작될 것이나
ISV들과 공식적인 인증 노력을 하지 않기 때문에 ISV 들의 애플리케이션이 지원하는지 여부는 직접 문의해라.

그리고 해당 OS 버전을 확인할때는 아래와 같이 하되 정확한 CentOS 버전을 확인할 방법은 없어 보입니다.

$ cat /etc/issue
Amazon Linux AMI release 2011.09

$ cat /etc/image-id 
image_name="amzn-ami"
image_version="2011.09"
image_arch="x86_64"
image_file="amzn-ami-2011.09.2.x86_64.ext4"
image_stamp="46f7-fb98"
image_date="20111027225247"
recipe_name="amzn ami"
recipe_id="2aaca5dd-b34f-4a46-8281-d2471ce38631"

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

Amazon EC2 / S3 mount process

2011/12/21 03:48 | Posted by 포데브(엄지사랑) 엄지사랑
목표: Amazon EC2 (Amazon Linux AMI 64) 와 S3 mount 연동
환경: Amazon Linux AMI 64는 CentOS 기반으로 만들어 졌음을 추정.
http://www.cloudave.com/4872/open-source-and-cloud-computing-the-amazon-linux-ami-is-now-available/

Step 1: 아래 URL을 참조하여 mount 할 수 있는 기술 중 S3FS를 적용하기로 결정
http://code.google.com/p/s3ql/wiki/other_s3_filesystems

※ 처음에 S3QL을 적용하였으나 실제 마운트시 에러가 발생하였고 이를 해결하지 못해서 S3FS로 변경함.

Step 2: S3FS 설치 절차

01. sudo yum remove fuse fuse* fuse-devel
02. sudo yum install gcc libstdc++-devel gcc-c++ curl curl* curl-devel libxml2 libxml2* libxml2-devel openssl-devel mailcap
03. mkdir ~/installed-tools/s3fs-tmp
04. cd ~/installed-tools/s3fs-tmp

05. wget http://sourceforge.net/projects/fuse/files/fuse-2.X/2.8.6/fuse-02.8.6.tar.gz/download
06. tar xf fuse-2.8.6.tar.gz
07. cd fuse-2.8.6
08. ./configure --prefix=/usr
09.  make
10. sudo make install

11. export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/lib64/pkgconfig/
12. sudo ldconfig
13. sudo modprobe fuse
14. pkg-config --modversion fuse (confirm that 2.8.4 is the version displayed)
15. cd ../

16. wget http://s3fs.googlecode.com/files/s3fs-1.61.tar.gz
17. tar xf  s3fs-1.61.tar.gz
18. cd s3fs-1.61
19. ./configure --prefix=/usr
20. make
21. sudo make install

22. sudo vi /etc/passwd-s3fs
23. accessKeyId:secretAccessKey or bucketName:accessKeyId:secretAccessKey 
24. sudo chmod 640 /etc/passwd-s3fs
25. sudo cp  /etc/passwd-s3fs ~/.passwd-s3fs
26. sudo chown ec2-user:ec2-user ~/.passwd-s3fs
27. chmod 600  ~/.passwd-s3fs

28. sudo mkdir /mnt/cardbook-contents
29. sudo chown ec2-user:ec2-user /mnt/cardbook-contents
29. /usr/bin/s3fs cardbook /mnt/cardbook-contents


Ref:
http://code.google.com/p/s3fs/wiki/FuseOverAmazon
http://code.google.com/p/s3fs/issues/detail?id=170
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

locate and updatedb on Amazon Linux(CentOS)

2011/12/21 00:32 | Posted by 포데브(엄지사랑) 엄지사랑
Ref.: http://www.beguelin.com/2009/05/locate-and-updatedb-on-centos.html

리눅스에서 apt-get, yum, rpm 등을 사용하여 소프트웨어를 설치한 경우 어디에 설치가 되어있는지 대략난감할때가 있다.

보통 명령어의 존재를 확인할 때는 which command 를 사용하지만 이는 어디까지나 명령어의 위치만을 알려줄 뿐 실제 설치된 위치를 알려주는 것은 아니다. 더구나 리눅스는 심볼릭링크 등을 제공하기 때문에 실제 설치 위치는 더욱 알기 어렵다.

그래서 설치위치를 알려주는 유용한 명령어를 소개하고자 한다.

sudo yum install mlocate
sudo /etc/cron.daily/mlocate.cron


첫번째 문장을 실행하면 locate와 updatedb 명령어를 설치하며 하루에 한번 디스크를 리인텍싱하는 크론을 설정한다.
두번째 문장을 실행하면 크론을 실행하여 인덱스를 즉시 생성한다.
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

Eclipse + GAE class hot deploy

2011/05/20 17:23 | Posted by 포데브(엄지사랑) 엄지사랑
개발환경: JDK1.6.0_24 + Eclipse Helios SR2 + appengine-java-sdk-1.5.0 + Googel App Engine for Eclipe 

서블릿 클래스를 아무리 변경해도 반영이 안되고 서버를 재시작해야 반영이 되었다.
분명 클래스의 변경은 서버 재시작과 상관이 없다고 했거늘....

그런데 서버를 시작하는 방법이 이상했다. 많은 곳에서 서버를 시작할 때 [Debug As]로 실행하는 것이 아닌가? 나는 Debug는 안할 거니 [Run As]로 실행했다. 

이런! 바로 이 차이가 서블릿 클래스의 변화를 감지하지 못하는 원인이 었다.
즉, Debug As로 서버를 시작해야 서블릿 클래스 등 클래스의 변화를 감지하여 서버 재시작과 무관하게 되는 것이 었다. 

결론: GAE는 Debug As로 실행시켜라!

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

GAE/J(Google App Engine for Java)에서 JPA를 사용할 때 지원되지 않는 것들

2009/09/23 11:51 | Posted by 포데브(엄지사랑) 엄지사랑
GAE/J와 DataStore(DataNuclues)를 접한지 일주일이 되었다.
처음엔 Maven을 적용하나라 고생했고 다음엔 Spring + Struts2를 적용하느라 삽질하고
이제좀 적응되려나 싶었는데 JPA때문에 또 힘들어 졌다.

Unsupported Features of JPA

The following features of the JPA interface are not supported by the App Engine implementation:

  • Owned many-to-many relationships, andunowned relationships. You can implement unowned relationships usingexplicit Key values, though type checking is not enforced in the API.
  • "Join"queries. You cannot use a field of a child entity in a filter whenperforming a query on the parent kind. Note that you can test theparent's relationship field directly in query using a key.
  • Aggregation queries (group by, having, sum, avg, max, min)
  • Polymorphicqueries. You cannot perform a query of a class to get instances of asubclass. Each class is represented by a separate entity kind in thedatastore.

http://code.google.com/intl/ko-KR/appengine/docs/java/datastore/usingjpa.html#Unsupported_Features_of_JPA 참고

이런 문제가 있다고 하니 이정도는 감수하려고 했다. 그런데 진행도중 다름과 같은 예외가 발생한다는 것을 디버깅해서(예외를 던져주지 않아서...) 알게 되었다.

Problem with query <SELECT count(entity.name) cnt FROM NameCard entity WHERE entity.name LIKE :name>: Unsupported method <matches> while parsing expression: InvokeExpression{[PrimaryExpression{name}].matches(ParameterExpression{name})}

위의 JPQL은 그닥 어렵지 않은 쿼리이다. 그런데 왜 동작하지 않을까?...
열심히 구글링을 한 결과 DataStore 라는 BigTable은 LIKE를 지원하지 않는다고 한다.

http://blog.newsplore.com/2009/06/06/reviewing-google-appengine-for-java-part-2

를 참고하기 바란다.

위의 사이트 내용중 DataStore의 제한사항(limitation)을 보면 아래와 같다.

1. LIKE 지원 안함
org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreFeatureException:Problem with query : Unsupported method <upper> while parsing expression: InvokeExpression {[null].upper(PrimaryExpression {station, usState})}

org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreOperatorException:Problem with query <SELECT station FROM com.newsplore.weather.bo.Station station WHERE UPPER(station.name) LIKE :stationName ORDER BY station.name>: App Engine datastore does not support operator  LIKE

2. PK로 int 타입을 사용할 수 없다. (내가 해본결과 long 타입도 안된다.) Long 으로 대체해야만한다.
3. JPA 쿼리는 클래의 완전한 경로명을 필요로 한다. select의 from 절에 사용할 때(지금은 약식명(SimpleName)을 사용해도 된다.)
4. 처음으로 어떤 엔티티를 액세스할때 일치하지 않는 NullPointerException이 발생한다.
ERROR MainHandlerExceptionResolver:18  Exception processing page: Name is null
java.lang.NullPointerException: Name is null
    at java.lang.Enum.valueOf(Enum.java:195)
    at com.google.appengine.api.datastore.dev.
CompositeIndexManager$IndexSource.valueOf(CompositeIndexManager.java:64)

이후 엔티티를 재요청하면 정상 페치된다.

5. 복합키를 수락하지 않는다. <== 요거는 확인해 봐야 겠다.  안되면 안되는데...
6. java.sql.TImestamp를 지원하지 않는다. 아래예외는 해당타입을 포함한 엔티티를 액세스할 때 발생한 것이다.
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: java.sql.Timestamp is not a supported property type.; nested exception is java.lang.IllegalArgumentException: java.sql.Timestamp is not a supported property type.]

7. 유니크 제약(uniqueness constraints)을 지원하지 않는다.
8. @ManyToOne 관계를 생성할 수 없다. <== 음 난 생성되었는데 좀더 해봐야 겠다.
9. Not equals(<>, !=)와 IN 연산자를 지원하지 않는다. <== 정말??.. IN은 그렇다쳐도

위의 내용을 내가 모두 테스트한 것은 아니므로 정말 모두 안되는지는 잘 모르겠다.
참고한 글이 쓰여진때가 2009.06.06 인걸로 보면 지금으로부터 3개월 전의 내용인데
제법 일치하지 않을까 조심스럽게 판단해본다.
위의 내용이 사실이 아니기를 아니면 언젠가 지원된다는 희망이라도 있었으면 하는 바램이다.
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

Struts 2 ONGL issue on Google App Engine

2009/09/19 15:04 | Posted by 포데브(엄지사랑) 엄지사랑
GAE/J(Google App Engine for Java)는 매우 높은 보안 환경을 제공하고 있어서 struts2를 사용할 때 OgnlRuntime security manager를 변경해줘야 한다.

아래는 보안관리자때문에 속성을 설정하려고 할때 메소드에 접근할 수 없다는 예외가 발생한 결과를 보여주고 있다.

ognl.MethodFailedException: Method "setNameCardId" failed for object kr.nextree.ncbcrm.action.NameCardController@14e40da [java.lang.IllegalAccessException: Method [public void kr.nextree.ncbcrm.action.NameCardController.setNameCardId(long)]
cannot be accessed.]   
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:823)
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:823)
    at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:964)
    at ognl.ObjectPropertyAccessor.setPossibleProperty(ObjectPropertyAccessor.java:75)
    at ognl.ObjectPropertyAccessor.setProperty(ObjectPropertyAccessor.java:131)
    at com.opensymphony.xwork2.ognl.accessor.ObjectAccessor.setProperty(ObjectAccessor.java:28)
    at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:1656)
    at com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor.setProperty(CompoundRootAccessor.java:50)
    at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:1656)
    at ognl.ASTProperty.setValueBody(ASTProperty.java:101)
    at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:177)
    at ognl.SimpleNode.setValue(SimpleNode.java:246)
    at ognl.Ognl.setValue(Ognl.java:476)


이것을 해결하기 위해서는 security manager를 null로 설정한 listener를 추가해줘야한다.

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import ognl.OgnlRuntime;

/**
 * OgnlRuntime 보안관리자를 널로 설정하는 Servlet 리스너
 * @author <a href="mailto:byleem@nextree.co.kr">임병인</a>
 * @since 2009. 9. 17.
 */
public class ONGLFixListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {

    /** UID */
    private static final long serialVersionUID = 6090732506717974395L;

    /**
     * 기본생성자
     */
    public ONGLFixListener() {
        // nothing to do.
    }

    /* (non-Javadoc)
     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce) {
    }

    /* (non-Javadoc)
     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce) {
        OgnlRuntime.setSecurityManager(null);
    }
...


그런다음 web.xml에 아래와 같이 추가한다.

  <listener>
    <description>To change the OgnlRuntime security manager</description>
    <listener-class>kr.nextree.ncbcrm.util.ONGLFixListener</listener-class>
  </listener>


참고 :
http://programmingpanda.blogspot.com/2009/07/struts-2-ongl-issue-on-google-app.html
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

GAE/J runserver : java.lang.NoClassDefFoundError: javax/jdo/metadata/TypeMetadata

2009/09/17 10:05 | Posted by 포데브(엄지사랑) 엄지사랑
GAE/J(Google App Engine for Java) + maven2 + spring + struts2 를 이용하여 프로젝트를 진행하는 도중에 제목과 같은 에러를 만나 더이상 진행하기 어려웠다.

의외로 해결방법은 간단했다.

http://www.jpox.org/servlet/forum/viewthread_thread,5723#30932

에서 그 해결방법을 찾을 수 있으며 그 내용은 아래와 같다.

use jdo2-api-2.3-eb

<dependency>
  <groupId>javax.jdo</groupId>
  <artifactId>jdo2-api</artifactId>
  <version>2.3-eb</version>
  <!-- architype으로 생성하면 2.3-ea 버전을 사용하고 있다  -->
</dependency>


from http://www.datanucleus.org/downloads/maven2/
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
이전 1 다음