在工作實際開發中需要開發一個訊息模組對外提供統一的介面feign呼叫提供訊息載入到MQ佇列的服務,採用泛型的形式。
剛開始搭建好之後,正好需要做一個全域性的日誌新增到zuul閘道器中,通過閘道器feign MQ模組傳送到佇列(這個操作是非同步的,不會影響主要業務流程),隨後log模組需要監聽這個channel。之前訊息模組剛搭建起來的時候是沒有問題的,但是在我寫統一的日誌記錄的時候,發生了意外情況。
情況一:Feign請求直接進入熔斷而非處理器
上午排查了2個小時feign的呼叫過程中也沒有發生報錯,*本身是GET 請求也就是意味著是URI 傳參後來因為特殊型別比較多,log傳參採用的 body傳參,記住這個點,破案的重點。
後來嘗試body去了,繼續採用GET請求仍然不行 * 這是另外一個情況造成的。
情況一:
無意間把body的傳參給刪除了,沒有方向的時候也百度不到答案只能嘗試從原始碼中找呼叫的問題但是沒有研究過Feign的呼叫過程但是知道其最終肯定也是傳送Http請求進行資料的互動,於是直接在Log模組中的dispatchServlet打上斷點(因為從feign的請求過來 直接進入熔斷,但是傳參有值說明接收到了請求),接著一步一步的走過去發現竟然走通了,進入了最終的處理器,十分的震驚多次請求不敢相信,結果都通過了。後來不知道在哪裡嘗試重新傳參,無意間發現Jackson序列化會提前將body,我的請求資料格式:{"name":"name", "age":"20", "user":{}}會直接將user 優先轉換為LinkedHashMap,導致進入傳參時會資料型別轉換失敗。後來將接收改成了Map<String, Object> 解決了問題。
情況二:
後來想到為什麼之前也嘗試了GET,把body傳參去除為什麼收不到訊息呢?甚至會存在第一次channel收到,第二次channel沒有收到。於是開啟rabbitmq的管理端,發現log——channel 存在2個消費者,*** 但是我清晰的知道我就採用了一個消費者進行佇列的監聽。** 經過重啟消費者全部清空,但是沒過一會又會新增幾個。突發奇想我目前開發環境使用了jrebel的熱部署外掛不會對專案重啟而是重新載入修改的class並對bean進行重新載入,因為rabbitmq預設的consumer-tag 是隨機的導致沒有覆蓋原有的消費者,形成了負載均衡和訊息不可達。
經過實踐測試原因找到並解決。