# 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,順便做服務的負載均衡,有極大限度可讓開發人員自行定義服務走向。

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
},
]
```

:::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實現
###