本節內容會用到之前給大家講過的這兩篇: 2流高手速成記(之六):從SpringBoot到SpringCloudAlibaba 2流高手速成記(之三):SpringBoot整合mybatis/mybatis-plus實現數據持久化 鏈接掛出來,方便咱們中途對比著看 老規矩,先放出本節的項目結構: 我們 ...
本節內容會用到之前給大家講過的這兩篇:
2流高手速成記(之六):從SpringBoot到SpringCloudAlibaba
2流高手速成記(之三):SpringBoot整合mybatis/mybatis-plus實現數據持久化
鏈接掛出來,方便咱們中途對比著看
老規矩,先放出本節的項目結構:
我們參考上一節中講到的創建SpringCloudAlibaba工程模板的步驟,在工程下在創建三個子模塊,創建過程中勾選相同的依賴項
這三個子模塊也是三個獨立的可執行的工程,他們的用途分別為:
dubbo-nacos-provider:服務(Service)提供方
dubbo-nacos-consumer:消費方,服務的調用者
dubbo-nacos-api:介面及模型類定義,同時作為前邊二者的依賴方
接下來,我們共同見證神奇的一幕:
大家都知道,我們在第三節中實現的工程是一個結構相對完備(包含Service、Controller,View由Postman替代)且可以直接執行的獨立進程
本節我們依靠上一節講到的微服務技術,以幾乎不改變原有代碼為前提,將其一分為三:
provider和consumer分別獨立執行
consumer藉助微服務技術完成對provider的調用
api模塊是二者的依賴項,並非可執行的進程
1. Service介面、Model聲明遷移到dubbo-nacos-api
package com.example.dubbonacosapi.model; import java.io.Serializable; public class Person implements Serializable { private Integer id = 0; private String name = ""; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.example.dubbonacosapi.service; import com.example.dubbonacosapi.model.Person; import java.util.List; public interface PersonService { Integer insert(Person person); Integer update(Person person); Integer delete(int id); List<Person> select(); }
因為api的作用僅是構成provider、consumer的二者依賴,所以其僅是持有相關聲明即可
Person類及PersonService在原有代碼基礎上保持不變!
2. Service介面實現類、Mapper聲明(mybatis-plus)遷移到dubbo-nacos-provider
既然provider保有mybatis-plus訪問mysql的能力,所以相關的依賴必定不可或缺
<!-- 引入mybatis、mybatis-plus、mysql等依賴 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>dubbo-nacos-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
引入的方式和第三節講到的方式一樣
此外還包含了對於剛纔我們創建的dubbo-nacos-api的依賴,引入非常的方便
package com.example.dubbonacosprovider.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.dubbonacosapi.model.Person; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface PersonMapper extends BaseMapper<Person> { }
package com.example.dubbonacosprovider.service.impl; import com.example.dubbonacosapi.model.Person; import com.example.dubbonacosapi.service.PersonService; import com.example.dubbonacosprovider.mapper.PersonMapper; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; @DubboService public class PersonServiceImpl implements PersonService { @Autowired PersonMapper mapper; public Integer insert(Person person) { return mapper.insert(person); } public Integer update(Person person) { return mapper.updateById(person); } public Integer delete(int id) { return mapper.deleteById(id); } public List<Person> select() { return mapper.selectList(null); } }
Mapper的聲明沒有任何變化,而PersonServiceImpl依然保有對介面PersonService的實現,區別在於後者來自api模塊
唯一的區別在於PesonServiceImpl類的註解,由原有的@Service變更為@DubboService —— 這是唯一的區別!
3. Controller遷移到dubbo-nacos-consumer
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>dubbo-nacos-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
consumer作為外部可訪問的web服務,自然需要持有web相關依賴項
同時,與provicer相同,其與api模塊保持依賴關係
package com.example.dubbonacosconsumer.controller; import com.example.dubbonacosapi.model.Person; import com.example.dubbonacosapi.service.PersonService; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/person") public class PersonController { @DubboReference PersonService service; @PostMapping("/insert") public Integer insert(Person person) { return service.insert(person); } @PostMapping("/update") public Integer update(Person person) { return service.update(person); } @PostMapping("/delete") public Integer delete(int id) { return service.delete(id); } @GetMapping("/select") public List<Person> select() { return service.select(); } }
留意PersonService的引入方式:不再是@Autowired,而是變更為@DubboReference —— 這是唯一的區別!
4. Consumer和Provider的配置項
這裡我們依然沿用上一節講到的知識——以nacos作為配置中心
二者同時僅在本地保留一個bootstrap.properties配置文件,application.properties托管給nacos
# Nacos幫助文檔: https://nacos.io/zh-cn/docs/concepts.html # Nacos認證信息 spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 設置配置中心服務端地址 spring.cloud.nacos.config.server-addr=127.0.0.1:8848 # Nacos 配置中心的namespace。需要註意,如果使用 public 的 namcespace ,請不要填寫這個值,直接留空即可 # spring.cloud.nacos.config.namespace= # 應用名稱 spring.application.name=dubbo-nacos-consumer
# Nacos幫助文檔: https://nacos.io/zh-cn/docs/concepts.html # Nacos認證信息 spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 設置配置中心服務端地址 spring.cloud.nacos.config.server-addr=127.0.0.1:8848 # Nacos 配置中心的namespace。需要註意,如果使用 public 的 namcespace ,請不要填寫這個值,直接留空即可 # spring.cloud.nacos.config.namespace= # 應用名稱 spring.application.name=dubbo-nacos-provider
內容均為nacos相關配置,以及各自聲明瞭自己的應用名稱(spring.application.name)
然後是他們在nacos上托管的配置數據:
註意,新創建配置的Data Id需要與他們的應用名稱同名
provider需要持有mysql相關配置
consumer作為controller的持有者,需要聲明外部的可訪問埠
全部的移植工作到這裡就完畢了!
我們分別執行provider、consumer兩個獨立進程
此時我們打開nacos服務列表,會看到dubbo-nacos-consumer、dubbo-nacos-provider兩個執行中的服務
執行結果如下:
怎麼樣?是不是非常神奇?我們只改動了兩個註解,原本還是一個整體的工程就被一分為二了,並且是兩個可以彼此獨立運轉在兩台獨立機器上的服務
—— 這就是微服務的神奇之處!
藉助於強大的SpringCloudAlibaba,我們不僅可以對所有的業務實現統合拆分,充分調動團隊人員配置各司其職各自編寫自己的服務模塊,
更大的意義在於我們可以充分調動多台獨立設備的技能,使之串聯為一個龐大服務集群,較之於單台機器實現整個架構性能成千上萬倍的飛躍!
但是,微服務帶來研發、管理、性能便捷的同時,整個集群也在運維層面面對了前所未有的挑戰,最明顯的:
consumer在業務上依賴於後端的provider,如果provider運轉不正常,前方的consumer又該如何自處?!
圍繞這個問題,又有新的概念誕生了——【限流、熔斷、容錯、服務降級】
Sentinel要來咯~ 敬請期待! properties