上個月,給app提供的app不能訪問了,驚呆了,突然間不能訪問了.上去看日誌沒有報錯,機器load,內存,cpu都正常,日誌也沒有報錯,真是遇見鬼了.最後發現是rabbitmq引起的.
項目的系統結構
項目是布的微服務,使用了dubbo做的rpc,使用的rabbitmq做的消息,mysql,redis等.對外提供的api,使用的netty(64個線程),最重要的一點是:試用了rabbitmq做了分佈式的本地cache.這次故障的原因:就是netty和rabbitmq的做分佈式local cache.
原因
分佈式local cache的設計是,當本地cache的有數據更新時候,就會廣播到其他實例.而rabbitmq機器的內存是8G,默認試用內存爲40%,也就是3.2G;在消息量很大的時候,就會把在rabbitmq的試用慢.我們的廣播試用的faout類型的交換做的,大概有100臺實例需要試用本地cache,也就是發3M就慢了,萬一消費來不了,就堵了.在這篇文章(http://www.rabbitmq.com/memory.html)中介紹:
By default, when the RabbitMQ server uses above 40% of the installed RAM, it raises a memory alarm and blocks all connections that are publishing messages. >Once the memory alarm has cleared (e.g. due to the server paging messages to disk or delivering them to clients that only consume) normal service resumes.
api的64個線程都堵住了,也就接不了app打過來的請求了.
解決問題
- 換臺大的內存的機器
- 發送消息時候線程池發送,同時使用試用固定大小的BlockingQueue
- 當本地cache因爲查詢而添加時候,不廣播了;只廣播因數據修改的消息