이미 눈치채셨겠지만, 새로운 카우치베이스 루비 젬 가 최근 출시되었습니다. 1.2.2 릴리스는 대부분 몇 가지 버그 수정이 포함된 유지 관리 릴리스이지만, 새로운 실험적 기능인 다음과 통합을 시도해 볼 수 있습니다. 이벤트 머신 라이브러리입니다. 이 게시물에서는 이벤트머신 비동기 모델에 기반한 애플리케이션에서 Couchbase Server를 사용하는 방법에 대해 간략하게 소개합니다.
EventMachine 통합은 (현재) UNIX 계열 시스템(예: Linux, Solaris, BSD)에서만 액세스할 수 있습니다. 또한 파이버를 사용하기 때문에 MRI 루비 버전 1.9 이상이 필요합니다.
샌드박스 설정
첫 번째 단계는 모든 저수준 Couchbase 프로토콜 세부 사항을 처리하는 libcouchbase 라이브러리를 설치하는 것입니다. 라이브러리를 설치하려면 공식 페이지의 설치 가이드. 여기서는 일반적인 GNU/Linux 박스(저는 Debian 불안정 버전을 사용 중입니다)에 필요한 단계만 복제하겠습니다:
-
리포지토리 PGP 키를 설치합니다:
$ wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add - -
설정 저장소 소스. 여기서는 우분투 12.04용 링크를 사용하고 있지만, 일반적으로는 젬 자체에 내장된 이벤트머신 플러그인을 사용할 것이므로 중요하지 않습니다. 패키지는 동일한 코드베이스를 사용하여 빌드된 다른 패키지 저장소에 있으며, 유일한 차이점은 IO 라이브러리 버전(libevent, 리베프) 배포 버전에 포함되어 있습니다.
$ sudo wget -O/etc/apt/sources.list.d/couchbase.list http://packages.couchbase.com/ubuntu/couchbase-ubuntu1204.list -
libcouchbase 헤더, 핵심 라이브러리 및 디버그 심볼을 설치합니다. 다시 말하지만, 명령줄 도구나 IO 백엔드 중 하나를 설치할 수도 있지만 현재 작업에는 필요하지 않습니다.
$ sudo apt-get 업데이트
$ sudo sudo apt-get 설치 libcouchbase-dev libcouchbase2-core libcouchbase-dbg그게 다입니다.
이제 다음을 설치해야 합니다. 카우치베이스 서버를 클릭하고 공식 사이트의 지침을 따릅니다. 설치 후에는 http://localhost:8091 에서 관리자 콘솔이 실행되고 동일한 포트에서 REST API도 액세스할 수 있습니다. 초기 구성 단계를 거치면 결국 "default"라는 이름의 버킷이 할당됩니다.
-
마지막으로 보석 자체를 설치해야 합니다. 터미널에 입력하는 것만큼이나 간단합니다:
$ 보석 설치 카우치베이스
기본 확장 프로그램 구축하기. 시간이 걸릴 수 있습니다...
couchbase-1.2.2 설치 성공
보석 1개 설치
couchbase-1.2.2용 ri 문서 설치...
couchbase-1.2.2용 RDoc 문서 설치...
애플리케이션 구축
통합을 시연하기 위해 EventMachine을 사용하여 간단한 채팅 애플리케이션을 빌드하고 모든 이벤트에 대한 로깅을 Couchbase 버킷에 추가해 보겠습니다. EventMachine을 사용하여 비동기 애플리케이션을 구축하는 것은 매우 쉬우며 이를 증명하기 위해 이 게시물에 전체 소스를 넣을 것입니다( examples/chat-em 디렉토리에 저장합니다).
@@clients = []
def post_init
사용자 이름 = nil
send_data("*** 이름이 무엇인가요?")
끝
def receive_data(data)
if @사용자명
브로드캐스트(데이터 스트립, @사용자 이름)
else
name = data.gsub(/s+|[[]]/, '').strip[0..20]
if name.empty?
send_data("*** 이름이 무엇인가요?")
else
사용자 이름 = 이름
@@clients.push(self)
broadcast("#{@사용자 이름}이 가입했습니다")
send_data("*** 안녕하세요, #{@username}!n")
끝
끝
끝
def unbind
@@clients.delete(self)
방송("#{@사용자 이름}이 떠났습니다") if @사용자 이름
끝
def broadcast(message, author = nil)
접두사 = 작성자 ? "" : "***"
@@clients.each do |client|
클라이언트 == self가 아니면
client.send_data("#{접두사} #{메시지}n")
끝
끝
끝
끝
이벤트머신.실행
#를 눌러 중지하려면 Control + C를 누릅니다.
Signal.trap("INT") { EventMachine.stop }
Signal.trap("TERM") { EventMachine.stop }
EventMachine.start_server("0.0.0.0", 9999, ChatServer)
끝
이것은 EM::Connection을 기반으로 하는 일반적인 이벤트 머신 서버입니다. 이러한 재정의된 메서드의 의미를 모르는 분들을 위해 다음은 공식 문서:
EventMachine::Connection은 새 연결이 생성될 때마다 EventMachine의 처리 루프에 의해 인스턴스화되는 클래스입니다. (새 연결은 원격 서버에 로컬로 시작되거나 원격 클라이언트에서 로컬로 수락될 수 있습니다). 연결 객체가 인스턴스화되면 connect 또는 start_server 호출에 지정된 사용자 정의 모듈에 포함된 기능이 혼합됩니다. 사용자 정의 핸들러 모듈은 여기에 정의된 표준 메서드의 일부 또는 전부를 재정의할 수 있을 뿐만 아니라 임의의 추가 코드를 추가하여 혼합할 수도 있습니다.
EventMachine은 주어진 시간에 활성화된 모든 네트워크 연결에 대해 EventMachine::Connection에서 상속된(그리고 혼합된 사용자 코드가 포함된) 하나의 객체를 관리합니다. 이벤트 루프는 아래 설명된 대로 해당 연결에서 특정 이벤트가 발생할 때마다 EventMachine::Connection 객체의 메서드를 자동으로 호출합니다.
이 클래스는 사용자 코드에 의해 인스턴스화되지 않으며 초기화 메서드를 게시하지 않습니다. 이벤트 루프에서 호출할 수 있는 EventMachine::Connection의 인스턴스 메서드는 다음과 같습니다: #post_init, #connection_completed, #receive_data, #unbind, #ssl_verify_peer(TLS를 사용하는 경우), #ssl_handshake_completed.
여기에 정의된 다른 모든 인스턴스 메서드는 사용자 코드에 의해서만 호출됩니다.
프로토콜은 매우 간단하고 회선 지향적입니다. 각 연결에 대해 EventMachine은 먼저 새 참가자의 이름을 물어보고 그의 모든 메시지를 그룹에 브로드캐스트하는 ChatServer의 인스턴스를 생성합니다. 텔넷이나 nc와 같은 임의의 텍스트 프로토콜을 통해 통신할 수 있는 선호하는 도구를 사용할 수 있습니다. 다음은 엔드포인트 간 세션의 샘플입니다.
127.0.0.1 시도 중... ??? *** 이름이 무엇인가요?
로컬 호스트에 연결되었습니다. ??? alice
이스케이프 문자는 '^]'입니다. ??? *** 안녕하세요, 앨리스!
*** 이름이 무엇인가요? ??? *** 밥이 가입했습니다
밥 ??? 안녕하세요 여러분
*** 안녕, 밥! ??? 안녕, 밥! 잘 지냈어?
안녕하세요 여러분 ??? ^C
안녕, 밥! 잘 지냈어? ??? ~ $
*** 앨리스가 떠났습니다 ???
^] ???
telnet> 연결이 닫혔습니다. ???
~ $ ???
이제 Couchbase를 조금 추가할 차례입니다. 모든 메시지를 가능한 한 효율적으로 분산 데이터베이스에 보관하고 싶다고 가정해 보겠습니다. Couchbase가 답입니다. :). 그렇게 해야 합니다:
메시지와 선택적 작성자(시스템 이벤트의 경우 nil)를 수락해야 하는 ChatServer 클래스에서 로그 메서드를 구현합니다:
Couchbase.bucket.incr("log:key", :initial => 1) do |res|
항목 = {
'time' => Time.now.utc,
'작성자' => 작성자 || "[시스템]",
'메시지' => 메시지
}
Couchbase.bucket.set("log:#{res.value}", entry)
끝
끝
그런 다음 연결된 모든 클라이언트를 반복하기 직전에 브로드캐스트 메서드에 log(message, author)에 대한 호출을 추가합니다. 그리고 클라이언트가 연결된 직후 서버를 실행하기 위해 EventMachine.start_server를 Couchbase::Bucket#on_connect 콜백으로 래핑합니다. 결과 루프 실행은 다음과 같습니다:
#를 눌러 중지하려면 Control + C를 누릅니다.
Signal.trap("INT") { EventMachine.stop }
Signal.trap("TERM") { EventMachine.stop }
Couchbase.connection_options = {:async => true, :engine => :eventmachine}
Couchbase.bucket.on_connect do |res|
if res.success?
EventMachine.start_server("0.0.0.0", 9999, ChatServer)
else
"카우치베이스 서버에 연결할 수 없습니다: #{res.error}"
끝
끝
끝
여기까지입니다! 향후에는 이 예제를 확장하여 다음과 같은 최신 기술을 사용할 수 있습니다. em-synchrony 웹소켓도 있습니다. 이 블로그에서 업데이트를 확인하세요.
보너스 포인트
단순한 로깅은 그다지 흥미롭지 않을 수 있지만, Couchbase Server를 사용하면 Couchbase의 놀라운 증분 맵-리듀스 기능을 사용하여 보기 쿼리로 간단한 분석을 수행할 수 있습니다. 예를 들어, 다음은 모든 항목을 시간순으로 가져오는 Map 함수입니다.
if (doc.message) {
if (doc.author == "[system]" && doc.time) {
emit(new Date(doc.time), "*** " + doc.message);
} else {
emit(새로운 날짜(doc.시간), " " + doc.메시지);
}
}
}
그리고 JSON 출력입니다.
{"id":"log:1″,"key":"2013-02-11T19:08:05.000Z","value":"*** 앨리스가 가입했습니다"},
{"id":"log:2″,"key":"2013-02-11T19:08:18.000Z","value":"*** bob이 가입했습니다"},
{“id”:”log:3″,”key”:”2013-02-11T19:08:38.000Z”,”value”:” hi everyone”},
{"id":"log:4″,"key":"2013-02-11T19:08:48.000Z","value":"안녕하세요, 밥! 잘 지내세요?"},
{"id":"log:5″,"key":"2013-02-11T19:08:58.000Z","value":"*** 앨리스가 떠났습니다"},
{"id":"log:6″,"key":"2013-02-11T19:09:01.000Z","value":"*** 밥이 떠났습니다"}
]}
자, 여기까지입니다. 이 실험적인 새 기능을 즐겨보세요. 이 기능은 향후 릴리스에서 완전히 지원될 예정입니다. 문제가 발생하면 문제를 제기해 주세요. RCBC 프로젝트 이슈 트래커. 수정과 기여도 언제나 환영하며 Apache 2.0 라이선스에 따라 오픈 소스입니다. 여러분은 깃허브의 소스.