【Rails】Unicorn5.3.0にはGC関連のバグがあるため5.3.1へアップデートする（`hash' called on hidden T_ARRAY objectエラーへの対処？）


# はじめに
production環境のUnicornが不定期にアクセスできなくなる問題が発生しました。
Unicornのプロセスは起動しているものの、ブラウザでアクセスすると502が返されます。

## 環境
- AWS
- Ubuntu16.04
- Unicorn 5.3.0
- Rails 5.1
- Ruby 2.4.1

## 発生したエラー
`Unicorn.log`には以下が出力されていました。


```bash
/home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_request.rb:80:in `parse': method `hash' called on hidden T_ARRAY object (0x0055645c4cf7a0 flags=0x1a067) (NotImplementedError)
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_request.rb:80:in `read'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:606:in `process_client'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:702:in `worker_loop'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:563:in `maintain_worker_count'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:293:in `join'
        from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/bin/unicorn_rails:209:in `<top (required)>'
        from /home/ubuntu/.rbenv/versions/2.4.1/bin/unicorn_rails:22:in `load'
        from /home/ubuntu/.rbenv/versions/2.4.1/bin/unicorn_rails:22:in `<main>'
```

## 考えられる原因
エラーログに出ている`T_ARRAY`という変数は、`unicorn/bindings/ruby/unicorn_gem/ext/unicorn.c` が使っている変数のようです（214行目）
https://github.com/unicorn-engine/unicorn/blob/master/bindings/ruby/unicorn_gem/ext/unicorn.c

213行目の`UC_X86_REG_TR`で調べてみると、`UC_HOOK_MEM_FETCH_INVALID`の中にあり、
メモリのフェッチが無効？という事象のようです。。
http://cpansearch.perl.org/src/VIKAS/UnicornEngine-0.02/lib/UnicornEngine.pm

また、herokuで類似したエラーが出てる人がいました。
Google翻訳によると、以下が原因とのこと。
>異なるRubyバージョンのオブジェクトからのバージョンの不一致
>またはC拡張によって引き起こされるメモリの破損
 
[unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help](https://bogomips.org/unicorn-public/20140722163900.GA1032@dcvr.yhbt.net/T/)

また、Unicorn5.3.0には**GC関連の問題がある**そうです。
[unicorn 5.3.1 / 2017-10-03 19:03 UTC](https://bogomips.org/unicorn/NEWS.html)

>unicorn 5.3.1 / 2017-10-03 19:03 UTC
This release fixes an occasional GC problem introduced in v5.3.0
to reduce global variable overhead (commit 979ebcf91705709b)
>
>Thanks to Xuanzhong Wei for the patch which lead to this release:
>
>https://bogomips.org/unicorn-public/20171003182054.76392-1-azrlew@gmail.com/T/#u
>https://bogomips.org/unicorn-public/20171003145718.30404-1-azrlew@gmail.com/T/#u
>
>Xuanzhong Wei (1):
>      fix GC issue on rb_global_variable array

上記を踏まえ、Unicornを5.3.1に更新することにしました。

## 事前準備
`Gemfile`のバージョンを固定化する。

```rb
  gem 'unicorn', '5.3.1'
```

## アップデートの失敗例
`bundle install`で入れようとすると、lockファイルと違うと怒られるので注意。

```bash
$ bundle install --without development test staging
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
You have requested:
  unicorn = 5.3.1

The bundle currently has unicorn locked at 5.3.0.
Try running `bundle update unicorn`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`
```

## アップデートの成功例
`bundle update unicorn`で更新する。

```
$ bundle update unicorn
・・・略・・・
Fetching unicorn 5.3.1 (was 5.3.0)
Installing unicorn 5.3.1 (was 5.3.0) with native extensions
```

# おわりに
これでひとまず様子を見てみることにします。
エラーが改善されることを期待します。