Spring Cloud和Dubbo整合開發筆記(1)

来源:https://www.cnblogs.com/liujie037/archive/2019/01/24/10311840.html
-Advertisement-
Play Games

一、需求背景: 二、Dubbo和Spring Cloud 的比較 首先Dubbo是一個分散式服務框架,以及SOA治理方案。它的功能主要包括:高性能NIO通訊及多協議集成,服務動態定址與路由,軟負載均衡與容錯,依賴分析與降級等,它是著名的阿裡服務治理的核心框架。Spring Cloud更加關心為開發人 ...


一、需求背景:

  1. 公司內部老項目微服務技術棧使用Dubbo, 新項目技術棧使用主流的Spring Cloud相關組件開發,新舊項目涉及交互調用,無法直接通信數據傳遞。
  2. 老項目基於Dubbo,重構代碼升級使用Spring Cloud,改造升級要求成本最低,不影響現有系統運行。

二、Dubbo和Spring Cloud 的比較

  首先Dubbo是一個分散式服務框架,以及SOA治理方案。它的功能主要包括:高性能NIO通訊及多協議集成,服務動態定址與路由,軟負載均衡與容錯,依賴分析與降級等,它是著名的阿裡服務治理的核心框架。Spring Cloud更加關心為開發人員提供開箱即用的一系列常見的分散式工具(例如配置管理,服務發現,斷路器,智能路由,微代理,控制匯流排),它是基於輕量級框架Spring家族,維護版本速度相對較快。

想深入瞭解的朋友,可以參考這篇文章專門分析了兩者的區別:聽聽八年阿裡架構師怎樣講述Dubbo和Spring Cloud微服務架構  

改造思路:Spring Cloud和Dubbo用於協調服務組件需要進行統一,使得Dubbo服務和Spring Cloud 服務能夠相互感知。其次統一微服務之間的通信協議,Spring Cloud使用Http協議,Dubbo支持Dubbo,Hessian,rmi,http,webservice,thrift,redis,rest,memcached協議;數據傳輸載體或者說格式在網路中也是統一的,和調用的服務架構無關。改造前需要明確的是兩種架構Spring Cloud和Dubbo在項目中的主次,不然容易造成開發人員使用API困惑,代碼介面混亂,其次不要急於期望短期將架構統一,改造完整,特別是Spring Cloud帶來了項目開發更多的環節,更多的組件(意味著有更多的坑)。

改造方案:

  • 傳統方案:保留完整的Dubbo老系統,Dubbo服務不需要向SpringCloud組件註冊服務,通過Ribbon/Fegin調用Dubbo服務暴露的Restful Api.缺點也明顯,需要人工維護Dubbo服務和Spring Cloud服務的關係,當Dubbo服務較多時,不同的環境配置太多。
  • 傳統方案:藉助SideCar支持多語言的特性,連接Dubbo和Spring Cloud底層使用Sidecar交互,同時Dubbo也可以將信息傳播到Eureka上面。缺點明顯,需要每個Dubbo服務節點額外配置Sidecar服務節點,同時增加了鏈路的長度。

我的方案:Spring Cloud和Dubbo的服務中心選擇阿裡的Nacos,它是一個動態服務發現、配置管理和服務管理平臺,為什麼不選擇使用Zookeeper,因為zookeeper是個CP系統,強一致性。如果其中master掛掉,此時zookeeper集群會進行重新選舉,不能提供服務列表信息的服務,其次zookeeper通過tcp不能準確判斷服務此時是否可用,資料庫掛了,資料庫連接池滿了等也能提供TCP信息。通信協議我選擇Http協議,Dubbo2.6之後支持http協議,數據格式使用Json,前端無需根據服務區分數據格式解析。

Nacos支持部署的模式有單機,集群,多集群模式,Nacos 0.8之後支持資料庫持久化,可以方便看見服務信息的前後變化。單機模式很簡單啟動,下載最新版Nacos:https://github.com/alibaba/nacos/releases ,解壓直接運行bin/startup.sh或者startup.cmd即可。

Nacos不僅提供服務發現和服務健康監測,它也提供控制台可視化頁面進行動態配置服務,動態 DNS 服務,服務及其元數據管理等功能,Nacos0.8版本支持簡單登錄功能,預設用戶名/密碼為 nacos/nacos。:

相比Eureka提供的單一的看板頁面,提供的管理功能可以說沒得比,具體使用手冊參考官方:https://nacos.io/zh-cn/docs/console-guide.html,這裡不再贅述。

首先開發基於Spring Cloud+Nacos架構的微服務,nacos-discovery-provider為服務提供者,nacos-discovery-consumer為服務消費方, 

nacos-discovery-provider的pom.xml加入相關依賴:

 1 <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.cloud</groupId>
 4             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 5             <version>0.2.1.RELEASE</version>
 6         </dependency>
 7         <dependency>
 8             <groupId>org.springframework.boot</groupId>
 9             <artifactId>spring-boot-starter-web</artifactId>
10             <version>2.0.6.RELEASE</version>
11         </dependency>
12         <dependency>
13             <groupId>org.springframework.boot</groupId>
14             <artifactId>spring-boot-starter-actuator</artifactId>
15             <version>2.0.6.RELEASE</version>
16         </dependency>
17     </dependencies>

 

 

application.properties的配置為:

1 server.port=18082
2 spring.application.name=service-provider
3 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848   
4 management.endpoints.web.exposure.include=*

 

其中spring.cloud.nacos.discovery.server-addr為配置的Nacos地址,management.endpoints.web.exposure.include=*表示對外暴露所有項目信息。

啟動類的代碼:

 1 package org.springframework.cloud.alibaba.cloud.examples;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 6 import org.springframework.web.bind.annotation.PathVariable;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RequestMethod;
 9 import org.springframework.web.bind.annotation.RequestParam;
10 import org.springframework.web.bind.annotation.RestController;
11 
12 @SpringBootApplication
13 @EnableDiscoveryClient
14 public class ProviderApplication {
15 
16     public static void main(String[] args) {
17         SpringApplication.run(ProviderApplication.class, args);
18     }
19 
20     @RestController
21     class EchoController {
22         @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
23         public String echo(@PathVariable String string) {
24             return "hello Nacos Discovery " + string;
25         }
26 
27         @RequestMapping(value = "/divide", method = RequestMethod.GET)
28         public String divide(@RequestParam Integer a, @RequestParam Integer b) {
29             return String.valueOf(a / b);
30         }
31     }
32 }

 

使用SpringCloud的原生註解@EnableDiscoveryClient 開啟服務註冊發現功能。

接下來創建服務消費方nacos-discovery-consumer進行服務消費:

pom.xml:

 1 <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-web</artifactId>
 5             <version>2.0.6.RELEASE</version>
 6         </dependency>
 7         <dependency>
 8             <groupId>org.springframework.cloud</groupId>
 9             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
10             <version>0.2.1.RELEASE</version>
11         </dependency>
12         <dependency>
13             <groupId>org.springframework.boot</groupId>
14             <artifactId>spring-boot-starter-actuator</artifactId>
15             <version>2.0.6.RELEASE</version>
16         </dependency>
17         <dependency>
18             <groupId>org.springframework.cloud</groupId>
19             <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
20             <version>2.0.2.RELEASE</version>
21         </dependency>
22         <dependency>
23             <groupId>org.springframework.cloud</groupId>
24             <artifactId>spring-cloud-starter-openfeign</artifactId>
25             <version>2.0.2.RELEASE</version>
26         </dependency>
27         <dependency>
28             <groupId>org.springframework.cloud</groupId>
29             <artifactId>spring-cloud-alibaba-sentinel</artifactId>
30             <version>0.2.1.RELEASE</version>
31         </dependency>
32     </dependencies>

 

其中sentinel和傳統的Spring Cloud組件Hystrix類似,提供熔斷降級,系統負載保護等功能。application.properties的配置為:

 1 spring.application.name=service-consumer
 2 server.port=18083
 3 management.endpoints.web.exposure.include=*
 4 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
 5 
 6 feign.sentinel.enabled=true
 7 
 8 spring.cloud.sentinel.transport.dashboard=localhost:8080
 9 spring.cloud.sentinel.eager=true
10 
11 spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
12 spring.cloud.sentinel.datasource.ds1.file.data-type=json
13 spring.cloud.sentinel.datasource.ds1.file.rule-type=flow

 

其中flowrule.json配置了限流降級的規則:

 1 [
 2   {
 3     "resource": "GET:http://service-provider/echo/{str}",
 4     "controlBehavior": 0,
 5     "count": 1,
 6     "grade": 1,
 7     "limitApp": "default",
 8     "strategy": 0
 9   }
10 ]

 

消費啟動類ConsumerApplication.java:

 1 package org.springframework.cloud.alibaba.cloud.examples;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.alibaba.cloud.examples.ConsumerApplication.EchoService;
 6 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 7 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 8 import org.springframework.cloud.openfeign.EnableFeignClients;
 9 import org.springframework.cloud.openfeign.FeignClient;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.web.bind.annotation.PathVariable;
12 import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RequestMethod;
14 import org.springframework.web.bind.annotation.RequestParam;
15 import org.springframework.web.client.RestTemplate;
16 
17 /**
18  * @author liujie037
19  */
20 @SpringBootApplication
21 @EnableDiscoveryClient
22 @EnableFeignClients
23 public class ConsumerApplication {
24 
25     @LoadBalanced
26     @Bean
27     public RestTemplate restTemplate() {
28         return new RestTemplate();
29     }
30 
31     public static void main(String[] args) {
32         SpringApplication.run(ConsumerApplication.class, args);
33     }
34 
35     @FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
36     public interface EchoService {
37         @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
38         String echo(@PathVariable("str") String str);
39 
40         @RequestMapping(value = "/divide", method = RequestMethod.GET)
41         String divide(@RequestParam("a") Integer a, @RequestParam("b") Integer b);
42 
43         @RequestMapping(value = "/notFound", method = RequestMethod.GET)
44         String notFound();
45     }
46 
47 }
48 
49 class FeignConfiguration {
50     @Bean
51     public EchoServiceFallback echoServiceFallback() {
52         return new EchoServiceFallback();
53     }
54 }
55 
56 class EchoServiceFallback implements EchoService {
57     @Override
58     public String echo(@PathVariable("str") String str) {
59         return "echo fallback";
60     }
61 
62     @Override
63     public String divide(@RequestParam Integer a, @RequestParam Integer b) {
64         return "divide fallback";
65     }
66 
67     @Override
68     public String notFound() {
69         return "notFound fallback";
70     }
71 }

 

通過 Spring Cloud 原生註解 @EnableDiscoveryClient 開啟服務註冊發現功能。給 RestTemplate 實例添加 @LoadBalanced 註解,開啟 @LoadBalanced 與 Ribbon 的集成:

消費的介面TestController.java:

 1 package org.springframework.cloud.alibaba.cloud.examples;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.cloud.alibaba.cloud.examples.ConsumerApplication.EchoService;
 5 import org.springframework.cloud.client.discovery.DiscoveryClient;
 6 import org.springframework.web.bind.annotation.PathVariable;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RequestMethod;
 9 import org.springframework.web.bind.annotation.RequestParam;
10 import org.springframework.web.bind.annotation.RestController;
11 import org.springframework.web.client.RestTemplate;
12 
13 /**
14  * @author liujie037
15  */
16 @RestController
17 public class TestController {
18 
19     @Autowired
20     private RestTemplate restTemplate;
21     @Autowired
22     private EchoService echoService;
23 
24     @Autowired
25     private DiscoveryClient discoveryClient;
26 
27     @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
28     public String rest(@PathVariable String str) {
29         return restTemplate.getForObject("http://service-provider/echo/" + str,
30                 String.class);
31     }
32 
33     @RequestMapping(value = "/notFound-feign", method = RequestMethod.GET)
34     public String notFound() {
35         return echoService.notFound();
36     }
37 
38     @RequestMapping(value = "/divide-feign", method = RequestMethod.GET)
39     public String divide(@RequestParam Integer a, @RequestParam Integer b) {
40         return echoService.divide(a, b);
41     }
42 
43     @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
44     public String feign(@PathVariable String str) {
45         return echoService.echo(str);
46     }
47 
48     @RequestMapping(value = "/services/{service}", method = RequestMethod.GET)
49     public Object client(@PathVariable String service) {
50         return discoveryClient.getInstances(service);
51     }
52 
53     @RequestMapping(value = "/services", method = RequestMethod.GET)
54     public Object services() {
55         return discoveryClient.getServices();
56     }
57 }

 

訪問Nacos控制台:

 

測試服務消費正常使用postman:

 下一篇中我將繼續展示Dubbo服務創建和Spring Cloud 互相調用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 歷史 以前做後端時,接觸過一點Spring,也是第一次瞭解DI、IOC等概念,面向切麵編程,對於面向對象編程還不怎麼熟練的情況下,整個人慌的一批,它的日誌記錄、資料庫配置等都非常方便,不回侵入到業務代碼中,後來轉戰前端,就沒怎麼關註了..... JS引入DI編程概念 學習 redux 時,看到語法里 ...
  • 無需考慮數據結構,效果如圖 話不多說,先上代碼 1.wxml 2.wxss Action添加一個簡單的漸顯動畫 3.js 原理:通過onPageScroll() 方法返回的e.scrollTop值與手機視窗寬高進行計算,較完美的解決了等高或均高圖片序列的圖片懶載入。 關於圖片高度:圖片+容器寬高必須 ...
  • Vim關於Vue的生態鏈還是很少,不過湊活湊活還是能用的。 縮進 縮進採用的是兩個空格,.vimrc配置: 語法高亮 重要的語法高亮,支持最好的應該是vim-vue。 使用Vundle下載: 這樣語法高亮基本上就實現了,不過會出現滑動過快高亮失效的情況,文檔中給出的原因是vue包含html、css、 ...
  • 1. 簡單的函數: 2.1 帶參數的函數: 2.2 帶參數的函數: 3.1 帶返回值的函數 3.2 帶有參數和返回值的函數 嘗試把返回值用字元串拼接的方式組合了一下,還真成功了 結果: ...
  • 要開始寫Vue的功能了,是不是很激動呢!開始吧! 1、首先建立一個html頁面,導入Vue js包 1 <script type="text/javascript" src="js/vue.min.js"></script> 2、架包導入之後,我們需要創建一個Vue對象,用來綁定元素節點,從而達到操 ...
  • 作為一個後臺開發人員,幾年前參與過Ionic1開發過一微信公眾號的經歷,所以這次開發企業微信應用,就使用了ionic,正好ionic4 rc版本發佈,雖然不是正式版,作為本項目的項目經理,還是決定使用ionic4開發,因為項目組員也是我。簡單記錄一下本次開發的過程,很多命令不經常輸入,就忘記了。 0 ...
  • 一. 範圍不同 readonly 只對 <input> 和 <textarea> 標簽有效 disabled 對所有表單元素都有效, 包括:<input>, <textarea>, <button>, <label>, <option>, <select>等 二. 程度不同 readonly 只是將 ...
  • 昨天碰到這樣一個場景,調用後端介面返回的數據發現所有數據都是正常的,只有一個商品ID的最後兩位是錯的,每一個商品都是,導致無法進行商品的上下架和刪除, 經過查資料發現: 瀏覽器解析數字的坑,一旦超出一定長度最後兩位會精度失準變為兩位隨機數,所以出現這種問題先列印出來 typeof(出錯的數字欄位), ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...