Spring Cloud 2.2.2 源碼之五十nacos服務端處理獲取配置請求
nacos服務端
其實nacos
大致功能就兩個,一個是配置中心,一個是命名服務,我們先看配置中心是如何提供配置請求服務的,主要處理是在com.alibaba.nacos.config.server.controller.ConfigController
中。其實很多處理請求看官方open-api就可以知道大概的原理了。
獲取配置ConfigController的getConfig
官方API
有的就不多說了,直接看源碼大致原理。
先獲取參數,檢驗,通過後調用ConfigServletInner
的doGetConfig
方法。
@GetMapping
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
public void getConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("dataId") String dataId, @RequestParam("group") String group,
@RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY)
String tenant,
@RequestParam(value = "tag", required = false) String tag)
throws IOException, ServletException, NacosException {
tenant = processTenant(tenant);
// check params
ParamUtils.checkParam(dataId, group, "datumId", "content");
ParamUtils.checkParam(tag);
final String clientIp = RequestUtil.getRemoteIp(request);
inner.doGetConfig(request, response, dataId, group, tenant, tag, clientIp);
}
RequestUtil的getRemoteIp儘可能獲取真實IP
這裏獲取IP是儘可能獲取真實的,而不是代理的,如果有NGINX
的話,可以進行X_REAL_IP
自定義頭透傳,不過他這裏優先使用X_FORWARDED_FOR
也是可以的,取出第一個就是最開始的客戶端真實地址。如果都沒有的話,只能用RemoteAddr
,這個可能會是代理的,這樣就不好做風控了。
ConfigServletInner的doGetConfig
代碼比較長,截取重點說吧,其實就是根據groupKey
更新緩存的屬性,然後根據單例運行是否用mysql
,進行mysql查詢或者直接用文件零拷貝傳輸,因爲有個DumpService
在初始化的時候回去mysql
比對記錄,把文件保存到本地/data\config-data
文件夾中,所以可以直接用零拷貝了。
首先獲取讀鎖,有了緩存如果沒有在修改的話就可以獲取讀鎖了:
如果獲取不到說明配置文件不存在或者有線程正在寫配置文件,那也不給讀,爲了保證數據的一致性:
根據緩存獲取Config-Type
,比如yaml
:
這裏如果是單例且沒有用mysql
,就從持久化服務裏獲取,貌似有個叫Derby
的,否則的話用了mysql
的話在DumpService
初始化的時候已經把文件保存到本地上了,可以直接用零拷貝技術。
設置一些頭信息後,進行響應輸出,如果有本地文件就用零拷貝,否則就用字符流。
最後成功:
這樣我們知道了獲取配置的大致原理,下次說長輪詢刷新配置的原理。
好了,今天就到這裏了,希望對學習理解有幫助,大神看見勿噴,僅爲自己的學習理解,能力有限,請多包涵。