기존 애플리케이션이 레일스 2.0으로 작성되었다면, 2.1로 업그레이드 하기를 추천한다. 내가 생각하는 레일스 2.1의 키워드는 다음과 같다. 특히 namd_scope와 ActiveSupport::Caching을 높게 평가하고 있다.

 

  • named_scope
  • Dirty Object / Partial Updates
  • ActiveSupport::Caching
  • Timezone
  • Association lazy loading
  • Gem dependencies
  • 성능 / 보안 개선

 

보다 자세한 내용은 http://rails21-book.springnote.com/를 참고하기로 하고, 이 글에서는 레일스 2.1로 업그레이드하면서 주의할 점을 몇가지 정리해보기로 한다. 약간 뒷북이지만 없는 것보다는 나을 것 같기는 하다 :)

 

Partial Updates에 주의

좋은 기능이지만, 기존 애플리케이션을 업그레이드 하는 경우라면 일단 꺼두고 충분히 테스트를 마친 후 적용하는 것이 좋겠다. 애매한(?) 오동작이 있을 수도 있다.

 

  1. ActiveRecord::Base.partial_updates = false

 

 

Rename template files

이제 때가 되었다. 아직도 rhtml, rxml과 같은 확장자를 사용하고 있다면 모두 html.erb, xml.builder 와 같은 새로운 형식으로 바꿔주자. 그렇지 않으면 Template을 찾을 수 없다는 오류를 보게 될지도 모른다.

 

 

꺼진 플러그인도 다시 보자

레일스 플러그인은 장점? 단점?이라는 글에서 이런 말을 한 적이 있다.

 

애플리케이션에 플러그인을 설치한다는 것은 그 플러그인 소스를 100% 읽고 이해하겠다는 전제 조건이 필요하다.

 

레일스 2.1로 가는 여정에 플러그인이 발목을 잡을 수도 있기에 예전 글을 다시 한번 꺼내본 것이다. 레일스 버전이 올라가면, 레일스 코드를 재정의하는 플러그인들은 대부분 최신 버전으로 함께 업데이트하는 것이 좋다. 내 경우에는 Will Paginate, ActiveScaffold, Selenium on rails를 업데이트했다. 레일스 2.1 호환을 보장하는 최신 버전이 나오지 않아, 따로 패치를 해야하는 경우도 있었으니, 구글을 잘 활용하는 것이 좋겠다.

 

 

named_scope처럼 따로 설치할 필요가 없는 플러그인도 있다. tzinfo, memcache_client 등 필요없어진 gem(레일스에 포함되었으므로)도 있으니 가볍게 지워주자.

 

Acts_as_paranoid는 validates_uniqueness_of에 적용되지 않아 버그(유일한데 아니라고 거짓말하는 버그)를 만든다. :scope에 :deleted_at 필드를 추가해서 혀결하면 된다. (via http://giantrobots.thoughtbot.com/2008/6/19/gotchas-when-upgrading-to-rails-2-1)

 

  1. validates_uniqueness_of :name, :scope => [:parent_id, :deleted_at], :if => :parent_id

 

사랑받는 레일스 캐싱 플러그인인 Acts_as_cached의 경우, 문제가 될 것 같아 매우 신중하게 여기저기 소스를 읽어봤지만, 크게 문제가 되는 부분은 없었다. 다만 이미 레일스에 cache_key 기능이 포함된 만큼 DRY에 위배되는 플러그인이 되버린만큼 ActiveSupport를 이용한 새 버전이 만들어지고, 이 버전을 사용해야 마음이 개운할 것 같다.

 

그 외에도 혹시 문제가 되는 플러그인이 있을 수 있다. 하지만, 문제가 되도 걱정 할 필요없다. 레일스 플러그인이 읽기 힘든 외계어로 개발된 것도 아니고, 대부분 친숙한 루비 코드일 뿐이기 때문이다. 안되면 직접 고쳐서 쓰면 된다!

 

예방이 중요해

흔해빠진 표어같은 말이지만, 사실이다. 레일스 업그레이드를 일종의 리팩토링 과정이라고 본다면, 역시나 필요한 건 테스트다. 그래야 코드 변경 전/후에 행동이 바뀌지 않았다는 사실에 안도할 수 있을테니 말이다. 스프링노트는 레일스 업데이트 후 몇가지 깨지는 테스트를 통해 생길 수 있는 문제 몇가지를 미리 감지할 수 있었다.

 

뭐, 레일스 2.0에서 2.1로 가는 업데이트는 1.x에서 2.0으로 이주하던 것에 비하면 정말 큰 문제없이 진행할 수 있다. 그렇지만 여기 적은 내용 외에 다른 어떤 문제를 만났다면, 댓글로 남겨주기 바란다. (이 글도 계속 갱신할 예정이다)

 

한줄 요약: 고고싱!

 

 

요즘 새로운 아이디어가 생기면 Sinatra부터 찾게 된다. 작은 코드와 깔끔한 DSL로 코딩하는 맛이 있기 때문일 것 같다.

 

그런데 딱 하나 아쉬운 점이 있다면, 바로 레일스의 수많은 플러그인들이다. 다행히 요즘은 Merb나 Sinatra같은 프레임워크를 위해서 플러그인을 젬으로 제작하는 일도 많지만, 아직은 레일스 전용 플러그인이 훨씬 많다. 아, 이거 X 플러그인 설치만 하면 끝인데, 라는 생각을 하면서 구현을 하는 맛은 그리 유쾌하지 못하다. 

 

오늘은 오픈아이디 RP(Relaying Party)를 만들어야하는데, 이전에 만들어둔 5분만에 만드는 레일스 오픈아이디 인증 - OpenIdAuthentication 플러그인이 떠올랐다. 그래서 간단하게 Sinatra로 포팅을 했다.

 

뭐 그리 대단한 코드도 아니다. OpenIdAuthentication라는 모듈을 만들고 이 모듈을 EventContext에 포함시켰다.

 

  1. module OpenIdAuthentication
      #....
  2. end
  3. Sinatra::EventContext.send :include, OpenIdAuthentication

 

그리고 액션 URL을 등록해줬다.

 

  1. Sinatra.application.define_event(:post, '/openid/begin') do
      begin_openid_authentication(params[:openid_identifier])
    end

  2. Sinatra.application.define_event(:post, '/openid/complete') do
      complete_openid_authentication
    end

 

전체 소스 코드는 http://github.com/deepblue/snippets/tree/master/sinatra/lib/openid_authentication.rb에서 확인할 수 있다.

 

그리고 아래는 이 모듈을 사용한 간단한 예제 애플리케이션 소스다.

 

  1. # OpenID Consumer sample application built with sinatra
    # by deepblue (http://myruby.net)

    %w(rubygems sinatra haml).each{|lib| require lib}

    get '/' do
      haml :login
    end

    load File.dirname(__FILE__) + '/lib/openid_authentication.rb'

    module OpenIdAuthentication
      def authentication_succeed(oidresp)
        nickname = sreg_data(oidresp)['nickname']
        @message = "Logged in as #{nickname}(#{oidresp.display_identifier})"
        haml :login
      end

      def authentication_failed(oidresp, message)
        @message = "FAILED!!"
        haml :login
      end
     
      def sreg_request
        OpenID::SReg::Request.new(%w(nickname))
      end
    end

    use_in_file_templates!

    __END__

    ## layout
    %html
    %body
      =yield

    ## login
    %h1= @message || 'Login'
    %form{:action => '/openid/begin', :method => 'post'}
      %input{:name => 'openid_identifier'}
      %input{:type => 'submit'}

 

 

6월 28일 여섯번째 루비세미나가 있었다. 이번에는 장소가 조금 넓은 곳이 섭외되어, 좀 더 많은 분들(백여명이 넘는)이 함께 할 수 있었다. 그리고 루비/레일스를 처음 접하는 분들을 위한 짧은 튜토리얼을 준비하기도 했다. 루비 언어에 대한 튜토리얼은 ikspres님이 맡아주셨고, 나는 레일스를 소개했다.

 

       

 

발표자료는 StotyQ에 올렸다(pdf는 여기). 진즉, 이 곳을 알았으면 slideshare는 안 쓰는건데 그랬다(storyQ는 레일스로 개발된 국내 서비스다. chang님께 다음 세미나에서 소개도 부탁드렸다).

 

이번에는 실제적인 코드보다는, 레일스가 어떤 생각으로 만들어졌고, 어떤 점이 다른지, 어느 부분에 열광할 수 있는지 전달하고 싶었다. 발표를 준비하며, 발표를 마치고 daesan님과 짧은 대화를 나누며 내 생각도 어느 정도 더 정리할 수 있어서 의미있는 시간이었다. 듣는 분들은 어떻게 느끼셨을지 궁금하기도 하다.

 

촬영은 했으니 곧 세미나 공식 블로그를 통해 동영상도 올릴 예정이다(부끄럽긴 하지만). 루비세미나 행사 후기는 다음 글에!

 

이 글은 지난 한 주간 뜨거운 루비에 올라온 소식을 중심으로, 지난 주 화제가 되었던 소식을 개인 취향으로 정리합니다. 뜨거운 루비 주간 정리 #001 :: 2008/6/16 ~ 2008/6/23

 

뜨거운_루비____함께_전하는_루비_뉴스-1.jpg

최고 인기는 Rails 2.1

레일스 2.1이 나온지 한달이 되어가지만, 아직 관심이 식지 않고 있네요. Ruby on Rails 2.1 - What's new라는 이북이 인기였고 2판까지 나왔습니다. 그리고 이 책의 번역 프로젝트사 시작되었고, 현재는 초벌이 완성되기 직전에 있습니다.

 

Nome_do_Jogo_»_Artigo_»_New_Free_Book__“Ruby_on_Rails_2.1_-_What’s_new”.jpg

 

보안도 좋고, 캐싱 지원도 좋은 레일스 2.1을 반기지 않을 이유는 없겠죠? 업그레이드시 주의점입니다.

아, 레일스는 2.1 이후에도 조금씩 개선되고 있습니다.

 

 

날 좀 봐주세요

 

금주의 말

미투데이가 세상에 나온 이후로, 한국에서도 갈 수록 인기를 얻고 있는 Ruby on Rails. 혹시 남친이 아직도 Java를 하는지 점검들 해보시길.  - 만박

 

후기

이번주에는 루비세미나가 있죠?  많은 분들 만날 수 있기를 기대합니다.

 

마지막으로 뜨거운 루비 구독하기!

 

출근길에 문득 Rails Deployment의 글을 빨리 수정해야겠다고 생각했다. 6개월 정도 글을 업데이트하지 않았을 뿐인데, 그 사이에 바뀐 내용이 반영되지 않아, 어쩌면 틀린 글이 되어버렸는지도 모르겠다는 위기감이 들었기 때문이다.  관련해서 올초에 도 한권 출판되었는데, 내가 이 책의 저자라면 이런 속도가 무척이나 당혹스러울 것 같다(책을 쓰는 중간에도 대대적인 업데이트가 있었다고 한다).

 

세상은 빠르게 변하고, IT 업계는 더 빨리 변하고 있지만, 정말 내 주변에서 레일스 배포 환경만큼 빠르게 변하는 것도 없는 것 같다. 먼저 지금까지의 역사를 한번 돌아보면 좋겠다. 지난 5회 루비 세미나에서 ikspres님이 잘 정리해주신 내용이 있으니 이 내용을 한번 읽어보자. 참 파란만장했다.        

 

 

마지막으로 깔끔한 정리버전도 있다. 역시 출처는 ikspres님 발표 자료다.

 

레일스 오늘 처음이에요 Webrick
이제 조금 알 것 같네요. Mongrel ( evented Mongrel)
좀 더 빠른거요. 쉬우면서. Pen/Balance + Mongrel_cluster
좀 더 빠르거요. SSL 되면서요 Pound + Mongrel_cluster
아파치 아니면 안되요. 좀  복잡해도 참을께요 Apache + mod_proxy_balance + Mongrel_cluster
무지 빠르고. 간지나는 NginX + Mongrel_cluster

 

이제 그 이후 어떤 변화가 있었는지 돌아보자.

 

Thin의 등장

한동안 몽그렐 천하였던 루비 웹서버 판에 새로운 도전자가 나타났다. 바로 Thin이다. Thin은 현재 루비가 가진 것을 잘 활용해, 조금 더 나은 것을 만들었다. 몽그렐의 파서와 루비 프로젝트를 슈퍼카로 만들어즌 EventMachine, 그리고 Rack이 Thin을 있게한 요소들이다. 물론 Thin의 판매 전략은 성능이다.

 

그림: Evented Mongrel보다 나은 성능을 보여주는 Thin(출처 - Thin 홈페이지)

 

몽그렐이 훌륭하게 자기 몫을 하고 있기는 하지만, 약간의 잡음(그 유명한 Rant)으로 살짝 위기감이 들었는데, Thin이라는 좋은 경쟁자 또는 대체제가 생겨서 다행이라는 생각이다. 그치만, 현재 Mongrel에 큰 문제가 없다면 꼭 Thin으로 바꿔야할 이유는 없어보이기도 한다. 이 부분은 좀 더 지켜보자.

 

Merb, 누구냐 넌!

몽그렐 클러스터가 필요한 이유에서 설명했던 그 이유, 레일스가 쓰레드 안전성(Thread-Safety)를 갖추고 있지 않다는데 대부분의 사람들은 개의치 않지만, 어떤 사람들은 매우 민감하다. 가장 민감한 곳은 자원의 효율성이 돈과 직결되는 호스팅 업체들이다. 그래서 나타난 것이 쓰레드 안전성을 전면에 내세운 Merb다.

 

Merb는 EngineYard에서 일하며, 레일스 배포환경에 큰 공헌을 한 Ezra Zygmuntowicz이 주도적으로 개발하고 있다. 더 빠르고 가벼운 레일스를 추구한다. ORM을 선택해서 사용할 수 있는 것도 큰 차이점이다.

 

Merb가 레일스보다 느릴 이유가 없기에, 여러 벤치마크에서도 Merb의 성능이 더 나은 것으로 나온다(그렇지 않으면 Merb의 존재 이유 No.1이 사라진다).

 

출처: Performance Comparison For Rails and Merb

 

최근 Merb가 조금이나 새력을 확장해가고 있다. 곧 1.0이 나올텐데, 그 때는 레일스의 대안으로 자리매김할 수도 있을 것 같다.

 

2008년 상반기 히트작 Phusion Passenger(aka. mod_rails)

마지막으로 소개할 것은 최근 큰 인기를 얻고 있는 Phusion Passenger다. 왜 레일스 애플리케이션은 PHP 처럼 배포가 간단하지 않은 것인가?라는 문제에서 시작한 프로젝트로, 이 문제를 훌륭하게 풀어냈다. 이제 복잡한 클러스터 세팅 없이 mod_rails를 설치하고 Virtual Host를 설정해주는 것만으로 레일스 애플리케이션이 돌아간다. 정말 쉽고 편해졌다! 레일스 배포 환경이 너무 꼬졌다고 불편하던 Dreamhost도 최근 Passenger를 도입했다는 소식이 들린다. 클러스터의 관리를 요청에 따라 아파치가 관리하도록 위임하는 것이기때문에, 항상 N개의 인스턴스가 떠 있었던 기존 방식에 비해 더 많은 리소스를 확보할 수 있다는 큰 장점이 있는 것이다.

 

Passenger의 존재 이유는 쉬운 설정, 적은 관리 비용이지만, 성능도 괜찮은 편이라니 이보다 좋을 수 없다(이 부분은 약간의 이견이 있기도 하다).

 

passenger_mongrel_thin_benchmark.png

출처: Benchmark: Passenger (mod_rails) vs Mongrel vs Thin

 

설치 및 사용법은 먼저 잘 설명해주신 분들이 많으니 이 글을 참고하자.

 

 

국내에서도 이미 몇개의 서비스가 Passenger를 사용하고 있다.

 

 

Passenger와 함께 등장한 Ruby Enterprise Edition도 GC를 패치해서 메모리 사용량을 줄요준다고 하니 참고하자.

 

결론

또 6개월이 지나면 얼마나 바뀔지 모르겠지만, 현 시점에서 추천하는 배포 스택은 선호하는 웹서버에 따라 아래 두가지다.

 

  • Apache 2.2 + Phusion Passenger
  • Nginx + EventedMongrel + Monit

 

경쟁과 변화는 항상 좋은 일이다. 나도 뒤쳐지지 않으르면 오늘도 내 루비를 닦아야겠다. 항상 반짝거릴 수 있게..

 

참고

 

 

<< 이전 글