0

処理する必要がある一連の JSON メッセージがあり、文字エンコーディングで問題が発生しました。次のように、RabbitMQ キューからこのメッセージを取得します。

@data = []
@queue.pop do |metadata, payload|
  parsed_message = JSON.parse(payload)
  @data << parsed_message
end

次に、Resque を使用してそれらを処理し、次のようにキューに入れます。

Resque.enqueue(Worker, @data)

ワーカーを実行すると、次のエラーがスローされます。

** [16:06:13 2012-09-14] 5375: Error reserving job: #<Encoding::InvalidByteSequenceError: "\xC3" on US-ASCII>
** [16:06:13 2012-09-14] 5375: /usr/local/lib/ruby/1.9.1/json/common.rb:148:in `encode'
/usr/local/lib/ruby/1.9.1/json/common.rb:148:in `initialize'
/usr/local/lib/ruby/1.9.1/json/common.rb:148:in `new'
/usr/local/lib/ruby/1.9.1/json/common.rb:148:in `parse'
/usr/local/lib/ruby/gems/1.9.1/gems/multi_json-1.3.6/lib/multi_json/adapters/json_common.rb:7:in `load'
/usr/local/lib/ruby/gems/1.9.1/gems/multi_json-1.3.6/lib/multi_json.rb:93:in `load'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/helpers.rb:38:in `decode'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque.rb:149:in `pop'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/job.rb:100:in `reserve'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque.rb:303:in `reserve'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:209:in `block in reserve'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:207:in `each'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:207:in `reserve'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:136:in `block in work'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:133:in `loop'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/worker.rb:133:in `work'
/usr/local/lib/ruby/gems/1.9.1/gems/resque-1.22.0/lib/resque/tasks.rb:36:in `block (2 levels) in <top (required)>'
/usr/local/lib/ruby/1.9.1/rake/task.rb:205:in `call'
/usr/local/lib/ruby/1.9.1/rake/task.rb:205:in `block in execute'
/usr/local/lib/ruby/1.9.1/rake/task.rb:200:in `each'
/usr/local/lib/ruby/1.9.1/rake/task.rb:200:in `execute'
/usr/local/lib/ruby/1.9.1/rake/task.rb:158:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/usr/local/lib/ruby/1.9.1/rake/task.rb:151:in `invoke_with_call_chain'
/usr/local/lib/ruby/1.9.1/rake/task.rb:144:in `invoke'
/usr/local/lib/ruby/1.9.1/rake/application.rb:116:in `invoke_task'
/usr/local/lib/ruby/1.9.1/rake/application.rb:94:in `block (2 levels) in top_level'
/usr/local/lib/ruby/1.9.1/rake/application.rb:94:in `each'
/usr/local/lib/ruby/1.9.1/rake/application.rb:94:in `block in top_level'
/usr/local/lib/ruby/1.9.1/rake/application.rb:133:in `standard_exception_handling'
/usr/local/lib/ruby/1.9.1/rake/application.rb:88:in `top_level'
/usr/local/lib/ruby/1.9.1/rake/application.rb:66:in `block in run'
/usr/local/lib/ruby/1.9.1/rake/application.rb:133:in `standard_exception_handling'
/usr/local/lib/ruby/1.9.1/rake/application.rb:63:in `run'
/usr/local/bin/rake:32:in `<main>'
rake aborted!

ワーカーからの実行関数のすべてのコードを begin/rescue ブロックでラップして、例外をキャッチしようとしましたが、役に立たなかったため、Resque のどこかにあると思いました。

Resque ワーカーに生データをエンキューしてから、ワーカー内で JSON に解析し、UTF-8 エンコーディングを設定しようとしました。

raw_data.each do |msg|
  msg = msg.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "")                        
  parsed_msg = JSON.parse(msg) rescue nil                                                                     
  next if parsed_msg.nil?                                                                                     
  parsed_data << parsed_msg                                                                                   
 end

それでも同じエラーが発生します。常に同じ文字であるとは限りません。記憶が正しければ、\xC2 または \xD8 の場合もあります。

何か案は?

4

1 に答える 1

1

ファイルのエンコーディングが間違っている可能性はありますか?

挿入してみてください:

# encoding: UTF-8

関連する ruby​​ ソース ファイルの先頭に . これは、Ruby 1.9 で最も厄介なことの 1 つです。

于 2012-09-18T20:48:20.843 に答える