# Anser Service Discovery 實作問題 ###### tags: `Anser` [TOC] ## URI scheme 問題 (已解) Service Setting時需帶入isHttp,判斷是否為HTTPS Request,但Consul api取得Service info時無法取得關於scheme的訊息。 ### 解決辦法1 透過Consul設定中的scheme欄位,為所有服務發現的服務填充scheme,但可能衍生另一個問題,如果服務發現中的service無法用Https訪問時,會造成Action請求錯誤,硬解的話,目前想到一個辦法,先打開發人員在Consul設定的scheme,假設是HTTPS,如果無效,再打Http,如果再無效就註銷服務,並通知該服務不可用。 ### 解決辦法2 - 目前解法 :::success 於服務註冊時,於Tag標記使用的scheme,後續Service Setting時直接取用即可。 一開始於Tag標註HTTP或HTTPS,如果都沒標註則預設使用HTTPS。 ::: ### 解決辦法3 從根本解決,服務註冊的同時,使用KV儲存服務資訊,後續直接對KV List取用。 <hr> ## 服務對接 (未解) Q : Anser取得服務位置後,可能出現同個服務多個IP的狀況,例如product service有127.0.0.1:8080、127.0.0.1:8081 ....位置。 如此一來,Anser的服務請求該導向哪邊? ### 解法1 搭配Fabio,順便做服務的負載均衡,有極大限度可讓開發人員自行定義服務走向。 ![](https://i.imgur.com/E0hSmXh.jpg) Fabio會自動向Consul-server獲取健康的服務,並於Fabio本地紀錄路由表 例如打這組請求 ```curl -s http://140.127.74.171:9998/api/routes | jq '.'``` fabio會回傳所有健康路由表,ANSER只需拿到Fabio暴露出來的service名稱就可以開始打API了。 ``` [ { "service": "product_service", "host": "", "path": "/product_service", "src": "/product_service", "dst": "http://140.127.74.162:8081/", "opts": "strip=/product_service", "weight": 0.5, "tags": [ "HTTP", "rails" ], "cmd": "route add", "rate1": 0, "pct99": 0 }, { "service": "product_service", "host": "", "path": "/product_service", "src": "/product_service", "dst": "http://140.127.74.137:80/", "opts": "strip=/product_service", "weight": 0.5, "tags": [ "HTTP", "rails" ], "cmd": "route add", "rate1": 0, "pct99": 0 }, ] ``` ![](https://i.imgur.com/MWXTP8g.png) :::info 如有相同服務名稱註冊進consul的話,fabio會自動認為他們是一樣的服務,進而分配訪問權重,訪問方式fabio提供兩個分別是 RR(輪詢)、RND(微秒級別的random調度),以上皆為fabio內部實現,也可透過參數細調。 ::: :::success 優點: * 這麼做的好處是,ANSER不必透過consul取得服務列表,再進一步對微服務訪問,只在乎fabio服務是否活著即可。 * 不用管服務多寡,統一用fabio進行服務存取,做到服務的負載均衡,以及反向代理。 * 解決了一開始同個服務多個IP的狀況。 * fabio目前可負荷每秒2W5個請求流量。 ::: :::danger 缺點: * 微服務集成為cluster後,如果微服務叢集只對外暴露一個接口(叢集內部又做了一次負載均衡+反向代理)的話,fabio就顯得多餘了。 * 維運團隊如何顧好fabio的運行狀況。 * 如fabio遭遇意外關機,維運團隊重啟後,ANSER需即時獲得fabio的對外port,這個port fabio並不會向consul註冊,就算註冊了也會出現服務不健康的標誌。 ::: ## ANSER GATEWAY實現單服務多節點選擇功能 ### 作法 :::success 1.當客戶端對某個服務發起請求時,anser先到consul撈出該服務對應的健康IP 2.透過輪詢演算法找出某個訪問IP 3.對該IP發起訪問 4.回傳結果 ::: ### 需面臨的問題 :::danger 1.服務請求發起時,本地列表的搜尋優先度是否要高於consul搜尋。 2.如果每次請求發起時,都對consul進行服務列表取得的動作,是否會耗費多於資源。 3.承2.,可以改為anser gateway於背景執行服務列表的更新,這樣就可以將服務統一儲存於本地服務列表進行存取。 4.服務節點的演算法 ::: ## Service Discovery實現 ###