<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>stanwang (Stan)</title>
    <link>https://ruby-china.org/stanwang</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Ruby 基于 RabbitMQ 场景的应用</title>
      <description>&lt;p&gt;RabbitMQ 是基于 AMQP 的一种开源实现，使用 Erlang 语言开发，是一种重量级的消息中间件。特别适用于 SOA 场景下的消息异步处理，通过订阅者和发布者模式解耦各个模块的强依赖关系，一定程度上缓解分布式事务处理的复杂场景，通过 Ack 和 Nack 机制保证消息的相对必达性。&lt;/p&gt;
&lt;h2 id="RabbitMQ基础概念"&gt;RabbitMQ 基础概念&lt;/h2&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conection&lt;/td&gt;
&lt;td&gt;对应一个 TCP 连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Channel&lt;/td&gt;
&lt;td&gt;相对 Conection 更高层次的连接抽象，约等于&lt;strong&gt;进程&lt;/strong&gt;和&lt;strong&gt;线程&lt;/strong&gt;的关系，建立和关闭的代价小于 Connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exchange&lt;/td&gt;
&lt;td&gt;消息中转节点，一般会在这里设置各种路由规则&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Queue&lt;/td&gt;
&lt;td&gt;消息队列通道&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key&lt;/td&gt;
&lt;td&gt;即 routing_key，消息路由依据，Queue 没有 bind routing_key 时默认路由 Queue 的 name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id="路由规则"&gt;路由规则&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Direct Exchange&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;直接路由即根据绑定的 routing_key 完全匹配时才将消息路由到指定的 Queue&lt;/p&gt;

&lt;p&gt;&lt;img src="http://dl.iteye.com/upload/attachment/264104/0ec0f465-49c6-361c-ae2b-dd951a6ed1a9.png" title="" alt="直接路由"&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fanout Exchange&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;广播即路由消息至所有绑定到当前 Exchange 的所有队列&lt;/p&gt;

&lt;p&gt;&lt;img src="http://dl.iteye.com/upload/attachment/264106/0bbdcd3d-9fc6-3107-b7e0-db67c174d46a.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Topic  Exchange&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;主题订阅，通过特定的匹配规则模糊路由消息，# 匹配 0 个或更多关键字，* 匹配一个关键字&lt;/p&gt;

&lt;p&gt;&lt;img src="http://dl.iteye.com/upload/attachment/264108/11171ab4-af07-3ff6-bdf6-d1febda679c3.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="场景策略"&gt;场景策略&lt;/h2&gt;
&lt;p&gt;RabbitMQ 支持分布式消息负载路由，同级 N 个 Server 消费同一个 Queue，消息会根据策略（Round Robin）自动路由至&lt;strong&gt;一个&lt;/strong&gt;消费者，如果期望多个消费者同时收取同一条消息，请每个消费者创建各自 Queue，并绑定至指定的 routing_key.&lt;/p&gt;
&lt;h2 id="Ruby使用RabbitMQ"&gt;Ruby 使用 RabbitMQ&lt;/h2&gt;
&lt;p&gt;Ruby 中可以通过&lt;a href="http://rubybunny.info/" rel="nofollow" target="_blank" title=""&gt;Bunny&lt;/a&gt;访问 RabbitMQ，这个 Gem 包提供了 RabbitMQ 的一些基础访问方法和很好的异常处理机制。&lt;/p&gt;

&lt;p&gt;消息发送代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"bunny"&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Bunny&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;

&lt;span class="c1"&gt;#创建连接通道&lt;/span&gt;
&lt;span class="n"&gt;ch&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_channel&lt;/span&gt;

&lt;span class="n"&gt;q&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#向指定Topic发送消息&lt;/span&gt;
&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_exchange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:routing_key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;" [x] Sent 'Hello World!'"&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;消息接收代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"bunny"&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Bunny&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;

&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_channel&lt;/span&gt;

&lt;span class="c1"&gt;#声明消费主题为hello&lt;/span&gt;
&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;" [*] Waiting for messages in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. To exit press CTRL+C"&lt;/span&gt;

&lt;span class="c1"&gt;#启用block避免手动loop&lt;/span&gt;
&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:block&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;delivery_info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"[x] Received &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# 此处代码在接收到消息时将退出，注释掉可以一直消费直到中断&lt;/span&gt;
    &lt;span class="c1"&gt;# delivery_info.consumer.cancel&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bunny 支持各种容错性恢复，包括网络异常，如果因为特别场景需要关闭连接异常自动重连，可以在&lt;strong&gt;Bunny.new&lt;/strong&gt;中&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="ss"&gt;:automatic_recovery&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://www.rabbitmq.com/tutorials/tutorial-one-ruby.html" rel="nofollow" target="_blank" title=""&gt;参考地址&lt;/a&gt;&lt;/p&gt;</description>
      <author>stanwang</author>
      <pubDate>Sat, 01 Oct 2016 19:26:31 +0800</pubDate>
      <link>https://ruby-china.org/topics/31219</link>
      <guid>https://ruby-china.org/topics/31219</guid>
    </item>
    <item>
      <title>Windows 下面 Ruby 错误 Could not load 'active_record/connection_adapters/sqlite3_adapter'. </title>
      <description>&lt;ul&gt;
&lt;li&gt;Ruby 环境：ruby 2.1.3p242 (2014-09-19 revision 47630) [x64-mingw32]&lt;/li&gt;
&lt;li&gt;Rails 环境：Rails 4.1.6&lt;/li&gt;
&lt;li&gt;Widows 环境：win7 64bit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sqlite3-1.3.9-x64-mingw32.gemspec 文件中已修改为 s.require_paths= ["lib/sqlite3_native"]&lt;/p&gt;

&lt;p&gt;相关的 dll 文件也放入 Ruby 的 Bin 文件之中，而且 Gemfile 文件中的 sqlite3 和 Gemfile.lock 中的版本一致，但是访问网页会抛出错误如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Could not load 'active_record/connection_adapters/sqlite3_adapter'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;异常链如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `require'
activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `block in require'
activesupport (4.1.6) lib/active_support/dependencies.rb:232:in `load_dependency'
activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `require'
activerecord (4.1.6) lib/active_record/connection_adapters/sqlite3_adapter.rb:6:in `&amp;lt;top (required)&amp;gt;'
activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `require'
activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `block in require'
activesupport (4.1.6) lib/active_support/dependencies.rb:232:in `load_dependency'
activesupport (4.1.6) lib/active_support/dependencies.rb:247:in `require'
activerecord (4.1.6) lib/active_record/connection_adapters/connection_specification.rb:188:in `spec'
activerecord (4.1.6) lib/active_record/connection_handling.rb:50:in `establish_connection'
activerecord (4.1.6) lib/active_record/railtie.rb:129:in `block (2 levels) in &amp;lt;class:Railtie&amp;gt;'
activesupport (4.1.6) lib/active_support/lazy_load_hooks.rb:38:in `instance_eval'
activesupport (4.1.6) lib/active_support/lazy_load_hooks.rb:38:in `execute_hook'
activesupport (4.1.6) lib/active_support/lazy_load_hooks.rb:45:in `block in run_load_hooks'
activesupport (4.1.6) lib/active_support/lazy_load_hooks.rb:44:in `each'
activesupport (4.1.6) lib/active_support/lazy_load_hooks.rb:44:in `run_load_hooks'
activerecord (4.1.6) lib/active_record/base.rb:326:in `&amp;lt;module:ActiveRecord&amp;gt;'
activerecord (4.1.6) lib/active_record/base.rb:23:in `&amp;lt;top (required)&amp;gt;'
activerecord (4.1.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:628:in `rescue in call'
activerecord (4.1.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:619:in `call'
activerecord (4.1.6) lib/active_record/migration.rb:380:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.1.6) lib/active_support/callbacks.rb:82:in `run_callbacks'
actionpack (4.1.6) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/reloader.rb:73:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.1.6) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.1.6) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.1.6) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.1.6) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.1.6) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.1.6) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.1.6) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/static.rb:64:in `call'
rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
railties (4.1.6) lib/rails/engine.rb:514:in `call'
railties (4.1.6) lib/rails/application.rb:144:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
E:/Tool/Ruby21-x64/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'
E:/Tool/Ruby21-x64/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'
E:/Tool/Ruby21-x64/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;求解惑~~&lt;/p&gt;</description>
      <author>stanwang</author>
      <pubDate>Tue, 23 Sep 2014 14:09:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/21683</link>
      <guid>https://ruby-china.org/topics/21683</guid>
    </item>
  </channel>
</rss>
