日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

SpringCloud 微服務(wù)與遠(yuǎn)程調(diào)用測試

作者:是林春ya 更新時間: 2022-10-14 編程語言

微服務(wù)相關(guān)簡述

微服務(wù)架構(gòu)中的重要角色

  • 服務(wù)調(diào)用者:可以暫時認(rèn)為是與用戶交互的角色(因?yàn)榇嬖谖⒎?wù)之間的調(diào)用),可以根據(jù)該用戶的類型將其賦予不同的服務(wù)調(diào)用權(quán)限,通過一次http請求訪問調(diào)用對應(yīng)的微服務(wù)獲取想要的數(shù)據(jù)。
  • 微服務(wù):你可以將一個具備對外開放接口的springboot項(xiàng)目作為一個服務(wù),當(dāng)然這個服務(wù)最基本的功能必須要能夠具備數(shù)據(jù)庫數(shù)據(jù)交換與持久的能力。這樣的一個springboot項(xiàng)目可以將其稱之為一個微服務(wù)。通常在一個微服務(wù)架構(gòu)中,微服務(wù)A可能會存在多個(為了保證軟件系統(tǒng)的可用性)。
  • 服務(wù)注冊中心:相當(dāng)于一個微服務(wù)架構(gòu)中的組件通訊錄,不僅可以保存注冊信息,還可以進(jìn)行服務(wù)的心跳監(jiān)聽(健康檢測)。
  • 熔斷:當(dāng)下游微服務(wù)業(yè)務(wù)訪問量劇增的時候,為了防止上層微服務(wù)收到其影響,采用熔斷器對其進(jìn)行強(qiáng)行熔斷。
  • 鏈路追蹤:為了記錄復(fù)雜的微服務(wù)之間調(diào)用的過程,采用鏈路的追蹤確保能夠清晰的看到微服務(wù)之間調(diào)用的過程可以很好的排查和治理微服務(wù)。
  • API服務(wù)網(wǎng)關(guān):統(tǒng)一管理微服務(wù)的接口。

微服務(wù)架構(gòu)

?優(yōu)點(diǎn):通過服務(wù)的原子化拆分,以及微服務(wù)的獨(dú)立打包、部署和升級,小團(tuán)隊(duì)的交付周期將縮短,運(yùn)維成本也將大幅度下降,微服務(wù)遵循單一原則。微服務(wù)之間采用Restful等輕量協(xié)議傳輸。

缺點(diǎn):微服務(wù)過多,服務(wù)治理成本高,不利于系統(tǒng)維護(hù)。分布式系統(tǒng)開發(fā)的技術(shù)成本高(容錯、分布式事務(wù)等)。

分布式遠(yuǎn)程調(diào)用

我們知道,兩個springboot項(xiàng)目如果放在同一臺主機(jī)上運(yùn)行,那么我們可以通過HttpClient或者Okhttp等等方式去創(chuàng)建一個Http客戶端實(shí)現(xiàn)由這一個springboot項(xiàng)目去訪問另一個springboot項(xiàng)目的過程,那么如果這兩個項(xiàng)目不在同一個主機(jī)上呢?在局域網(wǎng)中?在公網(wǎng)中?其實(shí)大同小異,只要我們能夠通過http協(xié)議的方式遠(yuǎn)程訪問到對應(yīng)的API接口就可以實(shí)現(xiàn)兩個項(xiàng)目之間的調(diào)用。這就是一次遠(yuǎn)程調(diào)用,當(dāng)然這里指的是基于Http的遠(yuǎn)程調(diào)用方式。

在微服務(wù)架構(gòu)中,通常存在多個服務(wù)之間的遠(yuǎn)程調(diào)用的需求。遠(yuǎn)程調(diào)用通常包含兩個部分:序列化和通信協(xié)議。常見的序列化協(xié)議包括json、xml、hession、protobuf、thrift、text、bytes等,目前主流的遠(yuǎn)程調(diào)用技術(shù)有基于HTTP的RESTFUL接口以及基于TCP的RPC協(xié)議。

RESTFUL接口

REST,即Representational State Transfer的縮寫,如果一個架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)。

資源

所謂"資源",就是網(wǎng)絡(luò)上的一個實(shí)體,或者說是網(wǎng)絡(luò)上的一個具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個具體的實(shí)在。你可以用一個URI(統(tǒng)一資源定位符)指向它,每種資源對應(yīng)一個特定的URI。要獲取這個資源,訪問它的URI就可以,因此URI就成了每一個資源的地址或獨(dú)一無二的識別符。REST的名稱"表現(xiàn)層狀態(tài)轉(zhuǎn)化"中,省略了主語。"表現(xiàn)層"其實(shí)指的是"資 源"(Resources)的"表現(xiàn)層"。

表現(xiàn)層

"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來的形式,叫做它的"表現(xiàn)層"(Representation)。比如,文本可以用txt格式表現(xiàn),也可以用HTML格式、XML格式、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式;圖片可以用JPG格式表現(xiàn),也可以用PNG格式表現(xiàn)。URI只代表資源的實(shí)體,不代表它的形式。嚴(yán)格地說,有些網(wǎng)址最后的".html"后綴名是不必要的,因?yàn)檫@個后綴名表示格式,屬于"表現(xiàn)層"范疇,而URI應(yīng)該只代表"資源"的位置。

狀態(tài)轉(zhuǎn)化

訪問一個網(wǎng)站,就代表了客戶端和服務(wù)器的一個互動過程。在這個過程中,勢必涉及到數(shù)據(jù)和狀態(tài)的變化?;ヂ?lián)網(wǎng)通信協(xié)議HTTP協(xié)議,是一個無狀態(tài)協(xié)議。這意味著,所有的狀態(tài)都保存在服務(wù)器端。因此,如果客戶端想要操作服務(wù)器,必須通過某種手段,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)??蛻舳擞玫降氖侄危荒苁荋TTP協(xié)議。具體來說,就是HTTP協(xié)議里面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應(yīng)四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源。綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):每一個URI代表一種資源;客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;客戶端通過四個HTTP動詞,對服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

RPC

RPC(Remote Procedure Call ) 一種進(jìn)程間通信方式。允許像調(diào)用本地服務(wù)一樣調(diào)用遠(yuǎn)程服務(wù)。RPC框架的主要目標(biāo)就是讓遠(yuǎn)程服務(wù)調(diào)用更簡單、透明。RPC框架負(fù)責(zé)屏蔽底層的傳輸方式(TCP或者UDP)、序列化方式(XML/JSON/二進(jìn)制)和通信細(xì)節(jié)。開發(fā)人員在使用的時候只需要了解誰在什么位置提供了什么樣的遠(yuǎn)程服務(wù)接口即可,并不需要關(guān)心底層通信細(xì)節(jié)和調(diào)用過程。RPC 框架作為架構(gòu)微服務(wù)化的基礎(chǔ)組件,它能大大降低架構(gòu)微服務(wù)化的成本,提高調(diào)用方與服務(wù)提供方的研發(fā)效率,屏蔽跨進(jìn)程調(diào)用函數(shù)(服務(wù))的各類復(fù)雜細(xì)節(jié)。讓調(diào)用方感覺就像調(diào)用本地函數(shù)一樣調(diào)用遠(yuǎn)端函數(shù)、讓服務(wù)提供方感覺就像實(shí)現(xiàn)一個本地函數(shù)一樣來實(shí)現(xiàn)服務(wù)。

CAP原理

  • Consistency(一致性):數(shù)據(jù)一致更新,所有數(shù)據(jù)的變化都是同步的
  • Availability(可用性):在集群中一部分節(jié)點(diǎn)故障后,集群整體是否還能響應(yīng)客戶端的讀寫請求
  • Partition tolerance(分區(qū)容忍性):某個節(jié)點(diǎn)的故障,并不影響整個系統(tǒng)的運(yùn)行

任何情況下一個分布式架構(gòu)系統(tǒng)下CAP三者只能滿足其中兩個。

springCloud簡述

springcloud是常見的微服務(wù)框架之一,作為spring家族的金字塔尖,它并不是一項(xiàng)新的項(xiàng)目,而是集成市面上大部分的分布式微服務(wù)工程中優(yōu)質(zhì)的項(xiàng)目,具備各種優(yōu)秀的組件使得在一個微服務(wù)工程中程序員可以直接通過springcloud這一個包去調(diào)用各種優(yōu)質(zhì)的jar包。

服務(wù)注冊與發(fā)現(xiàn)

服務(wù)注冊:服務(wù)實(shí)例將自身服務(wù)信息注冊到注冊中心。這部分服務(wù)信息包括服務(wù)所在主機(jī)IP和提供服務(wù)的Port,以及暴露服務(wù)自身狀態(tài)以及訪問協(xié)議等信息。

服務(wù)發(fā)現(xiàn):服務(wù)實(shí)例請求注冊中心獲取所依賴服務(wù)信息。服務(wù)實(shí)例通過注冊中心,獲取到注冊到其中的服務(wù)實(shí)例的信息,通過這些信息去請求它們提供的服務(wù)。

?負(fù)載均衡

負(fù)載均衡是高可用網(wǎng)絡(luò)基礎(chǔ)架構(gòu)的關(guān)鍵組件,通常用于將工作負(fù)載分布到多個服務(wù)器來提高網(wǎng)站、應(yīng)用、數(shù)據(jù)庫或其他服務(wù)的性能和可靠性

熔斷

熔斷這一概念來源于電子工程中的斷路器(Circuit Breaker)。在互聯(lián)網(wǎng)系統(tǒng)中,當(dāng)下游服務(wù)因訪問壓力過大而響應(yīng)變慢或失敗,上游服務(wù)為了保護(hù)系統(tǒng)整體的可用性,可以暫時切斷對下游服務(wù)的調(diào)用。這種犧牲局部,保全整體的措施就叫做熔斷。

鏈路追蹤

隨著微服務(wù)架構(gòu)的流行,服務(wù)按照不同的維度進(jìn)行拆分,一次請求往往需要涉及到多個服務(wù)?;ヂ?lián)網(wǎng)應(yīng)用構(gòu)建在不同的軟件模塊集上,這些軟件模塊,有可能是由不同的團(tuán)隊(duì)開發(fā)、可能使用不同的編程語言來實(shí)現(xiàn)、有可能布在了幾千臺服務(wù)器,橫跨多個不同的數(shù)據(jù)中心。因此,就需要對一次請求涉及的多個服務(wù)鏈路進(jìn)行日志記錄,性能監(jiān)控即鏈路追蹤

API網(wǎng)關(guān)

隨著微服務(wù)的不斷增多,不同的微服務(wù)一般會有不同的網(wǎng)絡(luò)地址,而外部客戶端可能需要調(diào)用多個服務(wù)的接口才能完成一個業(yè)務(wù)需求,如果讓客戶端直接與各個微服務(wù)通信可能出現(xiàn):

  • 客戶端需要調(diào)用不同的url地址,增加難度
  • 在一定的場景下,存在跨域請求的問題
  • 每個微服務(wù)都需要進(jìn)行單獨(dú)的身份認(rèn)證

針對這些問題,API網(wǎng)關(guān)順勢而生。API網(wǎng)關(guān)直面意思是將所有API調(diào)用統(tǒng)一接入到API網(wǎng)關(guān)層,由網(wǎng)關(guān)層統(tǒng)一接入和輸出。一個網(wǎng)關(guān)的基本功能有:統(tǒng)一接入、安全防護(hù)、協(xié)議適配、流量管控、長短鏈接支持、容錯能力。有了網(wǎng)關(guān)之后,各個API服務(wù)提供團(tuán)隊(duì)可以專注于自己的的業(yè)務(wù)邏輯處理,而API網(wǎng)關(guān)更專注于安全、流量、路由等問題。

測試模擬遠(yuǎn)程調(diào)用

構(gòu)想一下思路:我們建立同一個父工程remote_call下的兩個子模塊server_a與server_b,要將兩個子模塊跑起來,之后利用server_b模塊去調(diào)用server_a的一個API接口并獲取它的返回信息展示在頁面上,server_b 去通信 server_a 的方法不限,我這里采取RestTemplate這個spring為我們封裝好的Http客戶端工具。

1、創(chuàng)建父工程remote_call模塊

只需要配置它的pom文件即可,這里我的remote_call模塊的父工程已經(jīng)將用到的SpringBoot依賴都導(dǎo)入且統(tǒng)一管理了。

remote_call

<?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"> 
????<parent> 
????????<artifactId>spring_cloud</artifactId> 
????????<groupId>org.example</groupId> 
????????<version>1.0-SNAPSHOT</version> 
????</parent> 
????<modelVersion>4.0.0</modelVersion> 

????<artifactId>remote_call</artifactId> 
????<packaging>pom</packaging> 
????<modules> 
????????<module>server_a</module> 
????</modules> 

????<properties> 
????????<maven.compiler.source>17</maven.compiler.source> 
????????<maven.compiler.target>17</maven.compiler.target> 
????</properties> 
</project>

spring_cloud(后面的測試都是要用這個作為父模塊)

<?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</artifactId> 
????<packaging>pom</packaging> 
????<version>1.0-SNAPSHOT</version> 
????<modules> 
????????<module>product</module> 
????????<module>eureka</module> 
????????<module>order</module> 
????????<module>remote_call</module> 
????</modules> 
????<!-- ???管理版本統(tǒng)一管理和spring相關(guān)的依賴-->
????<parent> 
????????<artifactId>spring-boot-starter-parent</artifactId> 
????????<groupId>org.springframework.boot</groupId> 
????????<version>2.6.7</version> 
????</parent> 
????<properties> 
????????<maven.compiler.source>17</maven.compiler.source> 
????????<maven.compiler.target>17</maven.compiler.target> 
????</properties> 
????<dependencies> 
????????<dependency> 
????????????<groupId>org.springframework.boot</groupId> 
????????????<artifactId>spring-boot-starter-web</artifactId> 
????????</dependency> 
????????<dependency> 
????????????<groupId>org.springframework.boot</groupId> 
????????????<artifactId>spring-boot-starter-logging</artifactId> 
????????</dependency> 
????????<dependency> 
????????????<groupId>org.springframework.boot</groupId> 
????????????<artifactId>spring-boot-starter-test</artifactId> 
????????</dependency> 
????????<dependency> 
????????????<groupId>org.projectlombok</groupId> 
????????????<artifactId>lombok</artifactId> 
????????????<version>1.18.24</version> 
????????????<scope>provided</scope> 
????????</dependency> 
????</dependencies> 
????<dependencyManagement> 
????????<dependencies> 
????????????<dependency> 
????????????????<groupId>org.springframework.cloud</groupId> 
????????????????<artifactId>spring-cloud-dependencies</artifactId> 
????????????????<version>2021.0.3</version> 
????????????????<type>pom</type> 
????????????????<scope>import</scope> 
????????????</dependency> 
????????</dependencies> 
????</dependencyManagement> 
????<repositories> 
????????<repository> 
????????????<id>spring-snapshots</id> 
????????????<name>Spring Snapshots</name> 
????????????<url>http://repo.spring.io/libs-snapshot-local</url> 
????????????<snapshots> 
????????????????<enabled>true</enabled> 
????????????</snapshots> 
????????</repository> 
????????<repository> 
????????????<id>spring-milestones</id> 
????????????<name>Spring Milestones</name> 
????????????<url>http://repo.spring.io/libs-milestone-local</url> 
????????????<snapshots> 
????????????????<enabled>false</enabled> 
????????????</snapshots> 
????????</repository> 
????????<repository> 
????????????<id>spring-releases</id> 
????????????<name>Spring Releases</name> 
????????????<url>http://repo.spring.io/libs-release-local</url> 
????????????<snapshots> 
????????????????<enabled>false</enabled> 
????????????</snapshots> 
????????</repository> 
????</repositories> 
????<pluginRepositories> 
????????<pluginRepository> 
????????????<id>spring-snapshots</id> 
????????????<name>Spring Snapshots</name> 
????????????<url>http://repo.spring.io/libs-snapshot-local</url> 
????????????<snapshots> 
????????????????<enabled>true</enabled> 
????????????</snapshots> 
????????</pluginRepository> 
????????<pluginRepository> 
????????????<id>spring-milestones</id> 
????????????<name>Spring Milestones</name> 
????????????<url>http://repo.spring.io/libs-milestone-local</url> 
????????????<snapshots> 
????????????????<enabled>false</enabled> 
????????????</snapshots> 
????????</pluginRepository> 
????</pluginRepositories> 

????<build> 
????????<plugins> 
????????????<plugin> 
????????????????<groupId>org.springframework.boot</groupId> 
????????????????<artifactId>spring-boot-maven-plugin</artifactId> 
????????????</plugin> 
????????</plugins> 
????</build> 
</project>

2、創(chuàng)建子模塊server_a

1、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"> 
????<parent> 
????????<artifactId>remote_call</artifactId> 
????????<groupId>org.example</groupId> 
????????<version>1.0-SNAPSHOT</version> 
????</parent> 
????<modelVersion>4.0.0</modelVersion> 

????<artifactId>server_a</artifactId> 

????<properties> 
????????<maven.compiler.source>17</maven.compiler.source> 
????????<maven.compiler.target>17</maven.compiler.target> 
????</properties> 
</project>

2、application.yml

server:
??port:?9001
spring:
??application:
????name:?server_a

3、啟動類

import?org.springframework.boot.SpringApplication;
import?org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public?class?server_a_ApplicationStarter {
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(server_a_ApplicationStarter.class,args);
????}
}

4、controller

import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.ResponseBody;
import?org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("server_a")
public?class?controller {

????@RequestMapping(value =?"sendMessageToServerB",method =?RequestMethod.GET)
????@ResponseBody
????public?String?sendMessage(){
????????return?"hello,server_b! i am server_a";
????}

}

3、創(chuàng)建子模塊server_b

1、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"> 
????<parent> 
????????<artifactId>remote_call</artifactId> 
????????<groupId>org.example</groupId> 
????????<version>1.0-SNAPSHOT</version> 
????</parent> 
????<modelVersion>4.0.0</modelVersion> 

????<artifactId>server_b</artifactId> 

????<properties> 
????????<maven.compiler.source>17</maven.compiler.source> 
????????<maven.compiler.target>17</maven.compiler.target> 
????</properties> 

</project>

2、application.yml

server:
??port:?9002
spring:
??application:
????name:?server_b

3、啟動類

@SpringBootApplication
public?class?server_b_ApplicationStarter {

????@Bean
????public?RestTemplate RestTemplate(){
????????return?new?RestTemplate();
????}

????public?static?void?main(String[]?args)?{
????????SpringApplication.run(server_b_ApplicationStarter.class,args);
????}
}

4、controller

import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.RequestMethod;
import?org.springframework.web.bind.annotation.RestController;
import?org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("server_b")
public?class?controller {
????@Autowired
????private?RestTemplate restTemplate;

????@RequestMapping(value =?"remote_server_a",method =?RequestMethod.GET)
????public?String?remoteCallServerA(){
????????return?restTemplate.getForObject("http://127.0.0.1:9001/server_a/sendMessageToServerB",String.class);
????}
}

4、測試結(jié)果:

訪問http://localhost:9002/server_b/remote_server_a得到結(jié)果如下:

5、總結(jié):

成功實(shí)現(xiàn)兩個模塊之間的遠(yuǎn)程調(diào)用,那么這種方式我是通過這樣一行代碼實(shí)現(xiàn)的:

restTemplate.getForObject("http://127.0.0.1:9001/server_a/sendMessageToServerB",String.class);

我們不難發(fā)現(xiàn)其中的地址信息是硬編碼,后續(xù)如果server_a這個模塊掛掉了,就算它有別的結(jié)點(diǎn)服務(wù),我也訪問不到了,能不能有一個通訊錄記錄這個微服務(wù)的電話呢?因?yàn)槲覀冎婪植际郊軜?gòu)的多結(jié)點(diǎn)特性是它高可用性的體現(xiàn)依賴,那么一個微服務(wù)可能出現(xiàn)在多個主機(jī)結(jié)點(diǎn)中運(yùn)行,掛了一個我們還能夠使用別的結(jié)點(diǎn)中的這一塊微服務(wù)。但是如果沒有一個中間的通訊錄,采取硬編碼的方式,顯然無法實(shí)現(xiàn)這樣一個系統(tǒng)的需求。于是,優(yōu)質(zhì)的程序員們設(shè)計出了服務(wù)注冊中心這一個概念。

原文鏈接:https://blog.csdn.net/m0_59588838/article/details/127286398

欄目分類
最近更新