服務拆分原則
單一職責原則
單一職責原則原本是面向對象設計的一個基本原則,是指一個類應該專注于單一的功能,不要存在多于一個導致類變更的原因
在微服務架構中,是指一個微服務只負責一個功能或者業務領域,每個服務應該由清晰的定義和邊界,只關注自己的特定業務領域。
服務自治
服務自治是指每個微服務都應該具備高度自治的能力,即每個服務要做到獨立開發,獨立測試,獨立構建,獨立部署,獨立運行
單向依賴
微服務之間需要做到單向依賴,嚴禁循環依賴,雙向依賴
父子工程
微服務的搭建,我們這里使用父子工程。
我們先創建一個空項目:
這個項目就是我們的父項目,之后在這個父項目下創建我們的子項目即可
父工程的 pom 文件的完善:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>order-service</module><module>product-service</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><mybatis.version>3.0.3</mybatis.version><mysql.version>8.0.33</mysql.version><spring-cloud.version>2022.0.3</spring-cloud.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>${mybatis.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement>
</project>
DependencyManagement 和 Dependencies 的標簽的介紹
DependencyManagement :只是一個聲明的標簽,并沒有將里面的 jar 包導入進去。
如果子項目需要用到相關的依賴,需要顯式聲明,也就說使用 < dependencies> 標簽 來進行導入
如果子項目沒有指定版本的話,就會從父項目讀取 version 版本,如果子項目中指定了版本號,那就會導入指定的 jar 包
父工程的打包方式應該是 pom 而不是 jar,所以這里需要指定 pom 打包:
< packaging>pom< /packaging>
Dependencies 這個標簽就是將所依賴的 jar 直接加入到項目中,父項目的 Dependencies 引入的 jar 包會被子項目繼承。
RestTemplate
當我們要進行服務與服務之間的調用的時候,可能就會使用到 RestTemplate
RestTemplate 是 Spring 3.0 開始支持的一個 HTTP 請求工具,它是一個同步的 REST API 客戶端工具,提供了 常見的 REST 請求方案的模板。
REST 的介紹
REST 是表現層資源狀態轉移
資源:網絡上所有的事務可以抽象為資源,每個資源都有唯一的資源標識符 【URL】
表現層:資源的表現形式:txt、xml、json、html 等等
狀態轉移:訪問 URL ,也就說客戶端和服務器的交互過程,我們通過網絡訪問資源,對資源進行增刪改等操作的時候,都會引起資源狀態的變化。
REST 描述的是網絡中 Client 和 Server 的一種交互方式,REST 本身不實用,實用的是如何設計 RESTful API
演示:
我們先創建 RestTemplate 對象并交給 Spring 管理
@Configuration
public class BeanConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
這里有兩個類,其中 ProductDetailInfo 是在另一個服務中獲取的,因此我們要使用 RestTemplate 來進行調用。
@Data
public class OrderInfo {private Integer id;private Long userId;private Long productId;private Integer num;private Long price;private int deleteFlag;private Date createTime;private Date updateTime;private ProductDetailInfo productDetailInfo;
}
@Data
public class ProductDetailInfo {private Integer id;private String productName;private Long productPrice;private Integer state;private Date createTime;private Date updateTime;
}
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public OrderInfo getOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectById(orderId);String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();ProductDetailInfo productDetailInfo = restTemplate.getForObject(url, ProductDetailInfo.class);orderInfo.setProductDetailInfo(productDetailInfo);return orderInfo;}
}
問題
在遠程調用的時候,我們通過 http://127.0.0.1:9090/product/ ,這個 url 是寫死的,如果我們需要更換 ip 的話,就需要頻繁修改代碼。
在實際開發中,如果業務的需求和 RESTful API 不太匹配或者很麻煩的話,我們可以不用 RESTful API,除此之外,還有很多問題(負載均衡等),后面會介紹如何使用 spring cloud 來解決上述的問題。