微服務註冊中心:Consul——服務發現

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系列文章:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/2636d77e2fe433e8144680eac","title":"","type":null},"content":[{"type":"text","text":"微服務架構:網關概念與 zuul","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/4154bb63f82f17b02e2dca2fb","title":"","type":null},"content":[{"type":"text","text":"微服務網關:Spring Cloud Gateway —— Zuul","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/96b51e801ac0fa2b8b59f9991","title":"","type":null},"content":[{"type":"text","text":"微服務網關:Spring Cloud Config- 配置中心","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/8f23ba021e573e876df221c6f","title":"","type":null},"content":[{"type":"text","text":"微服務網關方案:Kong & Nacos","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/4db8d97e7ca4f1ab679e4d0f3","title":"","type":null},"content":[{"type":"text","text":"Nacos 實踐","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/68c7c9ec4d99aab16315736d2","title":"","type":null},"content":[{"type":"text","text":"微服務網關:Nacos 源碼實踐(二)","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/61b260b61df452bd6fa47cbbb","title":"","type":null},"content":[{"type":"text","text":"微服務註冊中心:Consul——概念與基礎操作","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/958de779686fa98c3ac22c5b5","title":"","type":null},"content":[{"type":"text","text":"微服務註冊中心:Consul——服務註冊","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"一 概述","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 說完了Consul的服務註冊,那麼就該到服務發現了。大家有過rpc框架使用經驗的,例如nacos、eureka、dubbo等,就會了解服務中的角色,也就是生產者和消費者,也可以理解爲服務的提供方和服務使用方。服務註冊,是服務提供方把自己的信息(ip、端口、方法、參數&返回值信息)註冊到一箇中心;服務發現就是服務使用方,從中心獲取到可用的服務提供方信息,並像本地方法調用一樣調用其方法(遠程方法),這也就是RPC(遠程方法調用)的過程。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"二 Consul宏觀架構","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 這裏先說一下consul的架構,Consul的宏觀架構如下圖所示:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/70/70263786e0b197a268324b81028ca38e.png","alt":"Consul架構","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 其中\"DATACENTER1\"和 “DATACENTER2”代表兩個數據中心(Consul對多數據中心天然有比較好的支持)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 在每個數據中心內有","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Client","attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Server","attrs":{}},{"type":"text","text":"的混合。通常我們會部署","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"3~5","attrs":{}},{"type":"text","text":"臺Server。具體數量由","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可用性","attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"性能","attrs":{}},{"type":"text","text":"之間取得平衡,因爲隨着機器的增加,共識的速度會逐漸變慢。不過對Client的數量通常沒有限制,可以輕鬆地擴展到數千或數萬的量級。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 所有在數據中心的代理都會參與一個Gossip協議,這意味着有一個Gossip池,其中包含了某個數據中心的所有","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Agent","attrs":{}},{"type":"text","text":"。這有幾個目的:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一,客戶端不需要配置Server的地址,發現工作是自動完成的。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二,檢測代理故障的工作不放在Server上,而是分佈式的。這使得故障檢測的擴展性比原生的心跳方案要強得多。同時,它還爲節點提供了故障檢測,如果代理無法到達,那麼該節點可能已經發生了故障。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第三,它被用作消息層,當發生重要事件(如Leader 選舉)時進行通知。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 每個數據中心的Server都是單一Raft對等集的一部分。這意味着它們共同選出一個單一的Leader,一個被選中的Server,它有額外的職責。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Leader負責處理所有查詢和事務","attrs":{}},{"type":"text","text":"。事務也必須複製到所有參與共識協議的分片。由於這一要求,當","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"None-Leader Server","attrs":{}},{"type":"text","text":"收到RPC請求時,它會將其轉發給集羣Leader。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 一般情況下,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"不同的Consul數據中心之間不會複製數據","attrs":{}},{"type":"text","text":"。當對另一個數據中心的資源進行請求時,本地Consul服務器會將該資源的RPC請求轉發給遠程Consul服務器,並返回結果。如果遠程數據中心不可用,那麼這些資源也將不可用,但這不會以其他方式影響本地數據中心。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"三 Consul服務發現","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3.1 Consul已註冊服務查看","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 大概瞭解了Consul的架構,接下來回到本篇的主題,我們先搞清楚怎樣獲取到已註冊的服務,來供調用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 如果還不瞭解服務註冊怎樣實現,大家先再看一下這篇文章:","attrs":{}},{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/958de779686fa98c3ac22c5b5","title":"","type":null},"content":[{"type":"text","text":"微服務註冊中心:Consul——服務註冊","attrs":{}}]},{"type":"text","text":",可以直接拉取gitee代碼到本地,本地啓動Consul服務後,再啓動springboot-consul下的SpringBootConsulApplication,即可完成註冊。注意一下consul服務端口,默認使用的是8500。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6e/6e5e81122ceeade4117a6fc3e31d50c8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果上述操作完成且沒有問題,那麼我們在瀏覽器中查看http://localhost:8500/,可以看到Consul下的Services信息如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/be/be790a2c05eb972a03a7de218a40cf18.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"會有兩個Service,一個是consul——這個是Consul服務啓動後就有的,自帶的service; 下面的first-consul-client就是我們啓動並註冊的服務。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3.2 建立消費者工程","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.2.1 創建工程","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 創建一個名爲springboot-consul-consumer的maven工程。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.2.2 依賴配置","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 主要是spring-cloud,spring boot,以及spring-cloud-starter-consul-discovery,用於做consul的服務發現。pom.xml內容如下:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n \n UTF-8\n UTF-8\n 1.0.0\n 1.8\n Finchley.RELEASE\n \n\n \n \n org.springframework.boot\n spring-boot-starter-actuator\n \n \n org.springframework.cloud\n spring-cloud-starter-netflix-hystrix-dashboard\n \n \n org.springframework.cloud\n spring-cloud-starter-consul-discovery\n \n \n org.springframework.cloud\n spring-cloud-starter-openfeign\n \n \n org.springframework.boot\n spring-boot-starter-web\n \n \n org.springframework.boot\n spring-boot-starter-test\n test\n \n \n\n \n \n \n org.springframework.cloud\n spring-cloud-dependencies\n ${spring-cloud.version}\n pom\n import\n \n \n ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.2.3 application屬性配置","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏嘗試使用application.yml,zipkin不是必須,所以暫時註釋掉:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"server:\n port: 8521\nspring:\n application:\n name: spring-cloud-consul-consumer\n cloud:\n consul:\n host: localhost\n port: 8500\n discovery:\n serviceName: ${spring.application.name}\t# 註冊到consul的服務名稱\n # zipkin:\n # base-url: http://localhost:9411/\n sleuth:\n sampler:\n probability: 1 #樣本採集量,默認爲0.1,爲了測試這裏修改爲1,正式環境一般使用默認值\n#ribbon 負載均衡策略配置, service-producer爲註冊的服務名\nservice-producer:\n ribbon:\n NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule\n#開啓熔斷器\nfeign:\n hystrix:\n enabled: true","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.2.4 核心代碼","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)必不可少的啓動文件ConsulConsumerApplication:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n@EnableFeignClients\n@EnableDiscoveryClient\n@SpringBootApplication\npublic class ConsulConsumerApplication {\n\n public static void main(String[] args) {\n SpringApplication.run(ConsulConsumerApplication.class, args);\n }\n\n @Bean\n @LoadBalanced\n public RestTemplate restTemplate() {\n return new RestTemplate();\n }\n\n // 此配置是爲了服務監控而配置,與服務容錯本身無關,\n // ServletRegistrationBean因爲springboot的默認路徑不是\"/hystrix.stream\",\n // 只要在自己的項目裏配置上下面的servlet就可以了\n @Bean\n public ServletRegistrationBean getServlet() {\n HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();\n ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);\n registrationBean.setLoadOnStartup(1);\n registrationBean.addUrlMappings(\"/hystrix.stream\");\n registrationBean.setName(\"HystrixMetricsStreamServlet\");\n return registrationBean;\n }\n\n}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)訪問服務方法","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.cloud.client.discovery.DiscoveryClient;\nimport org.springframework.cloud.client.loadbalancer.LoadBalancerClient;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n@RestController\npublic class ServiceController {\n\n @Autowired\n private LoadBalancerClient loadBalancerClient;\n @Autowired\n private DiscoveryClient discoveryClient;\n\n private String serviceId = \"first-consul-client\";\n\n /**\n * 獲取所有服務\n */\n @RequestMapping(\"/services\")\n public Object services() {\n return discoveryClient.getInstances(serviceId);\n }\n\n /**\n * 從所有服務中選擇一個服務(輪詢)\n */\n @RequestMapping(\"/discover\")\n public Object discover() {\n return loadBalancerClient.choose(serviceId).getUri().toString();\n }\n}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至此,工程建立完畢。可見,核心邏輯還是在引入的依賴包spring-cloud-starter-consul-discovery中。consul服務配置在了application.yml中的consul屬性,controller中通過設置的serviceId來定位我們要使用的服務。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fb/fb880dee7a09b2de66b09c1ecd761dcc.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3.3 啓動驗證","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 啓動ConsulConsumerApplication,完成後,通過/services來驗證是否能夠獲取到服務列表,瀏覽器中輸入: http://localhost:8521/services,返回信息爲:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8f/8f9536fc85822c8a364eddff5df43d3d.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可見確實得到了預期的結果。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再次查看Consul的ui頁面(http://localhost:8500/ui/dc1/services):","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/05/05d60927e87923ccb2d296f1b4049891.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"標紅的就是我們剛剛啓動的消費者,也註冊到了Consul的services列表中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述代碼已提交至gitee: https://gitee.com/flamingskyline/spring-boot-integration,可自行拉取並做調整。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"四 小結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 至此,我們從本地安裝啓動Consul,到服務註冊和發現,可以簡單的使用起來了,但還是非常簡單的應用,並未深入到原理和架構,後面的文章中,將會對其原理進行分析,敬請期待。","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章