Nacos服務(wù)發(fā)現(xiàn)-一弧械、概覽

上一篇 Nacos服務(wù)發(fā)現(xiàn)-零、導(dǎo)學(xué)

1.1 從單體架構(gòu)到微服務(wù)

1.1.1 單體架構(gòu)

Web應(yīng)用程序發(fā)展的早期空民,大部分web工程師將所有的功能模塊打包到一起并放在一個(gè)Web容器中運(yùn)行刃唐,所有功能模塊使用同一個(gè)數(shù)據(jù)庫(kù)羞迷,同時(shí),它還提供API或者UI訪問(wèn)的Web模塊等画饥。

3201048542,3330451989.jpg

盡管也是模塊化邏輯衔瓮,但是最終還是會(huì)打包并部署為單體式應(yīng)用,這種將所有功能部署在一個(gè)Web容器中運(yùn)行的系統(tǒng)就叫做單體架構(gòu)(也稱:巨石型應(yīng)用)

優(yōu)點(diǎn):

  • 開發(fā)效率高:模塊之間交互采用本地方法調(diào)用抖甘,并節(jié)省微服務(wù)之間的交互討論時(shí)間與開發(fā)成本热鞍。
  • 容易測(cè)試:IDE都是為開發(fā)單個(gè)應(yīng)用設(shè)計(jì)的、容易測(cè)試---在本地就可以啟動(dòng)完整的系統(tǒng)衔彻。
  • 容易部署:運(yùn)維成本小薇宠,直接打包為一個(gè)完整的包,拷貝到Web容器的某個(gè)目錄下即可運(yùn)行米奸。

但是昼接,上述的好處是有條件的,它適用于小型簡(jiǎn)單應(yīng)用悴晰,對(duì)于大規(guī)模的復(fù)雜應(yīng)用,就會(huì)展現(xiàn)出來(lái)以下的不足:

缺點(diǎn):

  • 復(fù)雜性逐漸變高逐工,可維護(hù)性逐漸變差 :所有業(yè)務(wù)模塊部署在一起铡溪,復(fù)雜度越來(lái)越高,修改時(shí)牽一發(fā)動(dòng)全身泪喊。
  • 版本迭代速度逐漸變慢:修改一個(gè)地方就要將整個(gè)應(yīng)用全部編譯棕硫、部署、啟動(dòng)時(shí)間過(guò)長(zhǎng)袒啼、回歸測(cè)試周期過(guò)長(zhǎng)哈扮。
  • 阻礙技術(shù)創(chuàng)新:若更新技術(shù)框架,除非你愿意將系統(tǒng)全部重寫蚓再,無(wú)法實(shí)現(xiàn)部分技術(shù)更新滑肉。
  • 無(wú)法按需伸縮:通過(guò)冗余部署完整應(yīng)用的方式來(lái)實(shí)現(xiàn)水平擴(kuò)展,無(wú)法針對(duì)某業(yè)務(wù)按需伸縮摘仅。

1.1.2 微服務(wù)

許多大型公司靶庙,通過(guò)采用微服務(wù)架構(gòu)解決了上述問(wèn)題。其思路不是開發(fā)一個(gè)巨大的單體式的應(yīng)用娃属,而是將應(yīng)用分解為小的六荒、互相連接的微服務(wù)。

一個(gè)微服務(wù)一般完成某個(gè)特定的功能矾端,比如訂單服務(wù)掏击、用戶服務(wù)等等。每一個(gè)微服務(wù)都是完整應(yīng)用秩铆,都有自己的業(yè)務(wù)邏輯和數(shù)據(jù)庫(kù)砚亭。一些微服務(wù)還會(huì)發(fā)布API給其它微服務(wù)和應(yīng)用客戶端使用。

比如,根據(jù)前面描述系統(tǒng)可能的分解如下:

image-20210109180611020.png

每一個(gè)業(yè)務(wù)模塊都使用獨(dú)立的服務(wù)完成钠惩,這種微服務(wù)架構(gòu)模式也影響了應(yīng)用和數(shù)據(jù)庫(kù)之間的關(guān)系柒凉,不像傳統(tǒng)多個(gè)業(yè)務(wù)模塊共享一個(gè)數(shù)據(jù)庫(kù),微服務(wù)架構(gòu)每個(gè)服務(wù)都有自己的數(shù)據(jù)庫(kù)篓跛。

優(yōu)點(diǎn):

  • 分而治之膝捞,職責(zé)單一;易于開發(fā)愧沟、理解和維護(hù)蔬咬、方便團(tuán)隊(duì)的拆分和管理
  • 可伸縮;能夠單獨(dú)的對(duì)指定的服務(wù)進(jìn)行伸縮
  • 局部容易修改沐寺,容易替換林艘,容易部署,有利于持續(xù)集成和快速迭代
  • 不會(huì)受限于任何技術(shù)棧

1.2 什么是服務(wù)發(fā)現(xiàn)

在微服務(wù)架構(gòu)中混坞,整個(gè)系統(tǒng)會(huì)按職責(zé)能力劃分為多個(gè)服務(wù)狐援,通過(guò)服務(wù)之間協(xié)作來(lái)實(shí)現(xiàn)業(yè)務(wù)目標(biāo)。這樣在我們的代碼中免不了要進(jìn)行服務(wù)間的遠(yuǎn)程調(diào)用究孕,服務(wù)的消費(fèi)方要調(diào)用服務(wù)的生產(chǎn)方啥酱,為了完成一次請(qǐng)求,消費(fèi)方需要知道服務(wù)生產(chǎn)方的網(wǎng)絡(luò)位置(IP地址和端口號(hào))厨诸。

我們的代碼可以通過(guò)讀取配置文件的方式讀取服務(wù)生產(chǎn)方網(wǎng)絡(luò)位置镶殷,如下:

image-20210114224629773.png

我們通過(guò)Spring Boot技術(shù)很容易實(shí)現(xiàn):

(1) 新建Maven項(xiàng)目

父工程pom.xml

<?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>net.zhi365</groupId>
    <artifactId>nacosdiscover</artifactId>
    <packaging>pom</packaging>
    <version>1.0</version>

    <modules>
        <module>service-provider</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <!--    這個(gè)問(wèn)題太坑了,是boot-maven中間那個(gè)【-】的問(wèn)題微酬,重新輸入就好用了 -->
                <!--<artifactId>spring-boot‐maven-plugin</artifactId>-->
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

(2) ServiceProvider(服務(wù)生產(chǎn)者)

ServiceProvider是服務(wù)的生產(chǎn)方绘趋,暴露/service服務(wù)地址,實(shí)現(xiàn)代碼如下:

pom.xml

<?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>nacosdiscover</artifactId>
        <groupId>net.zhi365</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

ServiceProviderApplication.java

/**
 * @author Xin.li
 * @date 2021-01-14 23:38
 */
@SpringBootApplication
public class ServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }
}

ServiceController.java

package net.zhi365.serviceprovider.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Xin.li
 * @date 2021-01-14 23:44
 */
@RestController
public class ServiceController {

    @GetMapping( value = "/service")
    public String service() {
        return "provider invoke";
    }
}

application.yml

server:
  port: 56010

(3) Service A(服務(wù)消費(fèi)者)

實(shí)現(xiàn)代碼:

pom.xml

<?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>nacosdiscover</artifactId>
        <groupId>net.zhi365</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-rest-consumer-bootstrap</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

SpringRestConsumerBootStrapApplication.java

package net.zhi365.springrestconsumerbootstrap;

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

/**
 * @author Xin.li
 * @date 2021-01-15 0:03
 */
@SpringBootApplication
public class SpringRestConsumerBootStrapApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringRestConsumerBootStrapApplication.class, args);
    }
}

ConsumerController.java

package net.zhi365.springrestconsumerbootstrap.web;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author Xin.li
 * @date 2021-01-15 0:08
 */
@RestController
public class ConsumerController {

    @Value("${provider.address}")
    private String providerAddress;

    @GetMapping(value = "/service")
    public String service(){
        RestTemplate restTemplate = new RestTemplate();
        //  調(diào)用服務(wù)
        String providerResult = restTemplate.getForObject("http://" + providerAddress +"/service", String.class );

        return "consumer invoke | " + providerResult;
    }
}

application.yml

server:
  port: 56020
  # 服務(wù)生產(chǎn)方地址
provider:
  address: 127.0.0.1:56010

看上去很完美颗管,但是陷遮,仔細(xì)考慮以下,此方案對(duì)于微服務(wù)應(yīng)用而言行不通忙上。

首先拷呆,微服務(wù)可能是部署在云環(huán)境的,服務(wù)實(shí)例的網(wǎng)絡(luò)位置或許是動(dòng)態(tài)分配的疫粥。另外茬斧,每一個(gè)服務(wù)一般會(huì)有多個(gè)實(shí)例來(lái)做負(fù)載均衡,由于宕機(jī)或升級(jí)梗逮,服務(wù)實(shí)例網(wǎng)絡(luò)地址會(huì)經(jīng)常動(dòng)態(tài)改變项秉。再者,每一個(gè)服務(wù)也可能應(yīng)對(duì)臨時(shí)訪問(wèn)壓力增加新的服務(wù)節(jié)點(diǎn)慷彤。

如下圖所示:

image-20210115001646505.png

基于以上的問(wèn)題参滴,服務(wù)之間如何相互感知?服務(wù)如何管理失乾?這就是服務(wù)發(fā)現(xiàn)的問(wèn)題了。如下圖:

image-20210114233006747.png

上圖中服務(wù)實(shí)例本身并不記錄服務(wù)生產(chǎn)方的網(wǎng)絡(luò)地址锚沸,所有服務(wù)實(shí)例內(nèi)部都會(huì)包含服務(wù)發(fā)現(xiàn)客戶端。

(1)在每個(gè)服務(wù)啟動(dòng)時(shí)會(huì)向服務(wù)發(fā)現(xiàn)中心上報(bào)自己的網(wǎng)絡(luò)位置涕癣。這樣哗蜈,在服務(wù)發(fā)現(xiàn)中心內(nèi)部會(huì)形成一個(gè)服務(wù)注冊(cè)表,服務(wù)注冊(cè)表是服務(wù)發(fā)現(xiàn)的核心部分坠韩,是包含所有服務(wù)實(shí)例的網(wǎng)絡(luò)地址的數(shù)據(jù)庫(kù)距潘。

(2)服務(wù)發(fā)現(xiàn)客戶端會(huì)定期從服務(wù)發(fā)現(xiàn)中心同步服務(wù)注冊(cè)表 ,并緩存在客戶端只搁。

(3)當(dāng)需要對(duì)某服務(wù)進(jìn)行請(qǐng)求時(shí)音比,服務(wù)實(shí)例通過(guò)該注冊(cè)表,定位目標(biāo)服務(wù)網(wǎng)絡(luò)地址氢惋。若目標(biāo)服務(wù)存在多個(gè)網(wǎng)絡(luò)地址洞翩,則使用負(fù)載均衡算法從多個(gè)服務(wù)實(shí)例中選擇出一個(gè),然后發(fā)出請(qǐng)求焰望。

總結(jié)一下菱农,在微服務(wù)環(huán)境中,由于服務(wù)運(yùn)行實(shí)例的網(wǎng)絡(luò)地址是不斷動(dòng)態(tài)變化的柿估,服務(wù)實(shí)例數(shù)量的動(dòng)態(tài)變化 ,因此無(wú)法使用固定的配置文件來(lái)記錄服務(wù)提供方的網(wǎng)絡(luò)地址陷猫,必須使用動(dòng)態(tài)的服務(wù)發(fā)現(xiàn)機(jī)制用于實(shí)現(xiàn)微服務(wù)間的相互感知秫舌。各服務(wù)實(shí)例會(huì)上報(bào)自己的網(wǎng)絡(luò)地址,這樣服務(wù)中心就形成了一個(gè)完整的服務(wù)注冊(cè)表绣檬,各服務(wù)實(shí)例會(huì)通過(guò)服務(wù)發(fā)現(xiàn)中心來(lái)獲取訪問(wèn)目標(biāo)服務(wù)的網(wǎng)絡(luò)地址足陨,從而實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)的機(jī)制。

下一篇 Nacos服務(wù)發(fā)現(xiàn)-二娇未、Nacos服務(wù)發(fā)現(xiàn)快速入門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末墨缘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子零抬,更是在濱河造成了極大的恐慌镊讼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件平夜,死亡現(xiàn)場(chǎng)離奇詭異蝶棋,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)忽妒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門玩裙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)兼贸,“玉大人,你說(shuō)我怎么就攤上這事吃溅∪艿” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵决侈,是天一觀的道長(zhǎng)螺垢。 經(jīng)常有香客問(wèn)我,道長(zhǎng)颜及,這世上最難降的妖魔是什么甩苛? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮俏站,結(jié)果婚禮上讯蒲,老公的妹妹穿的比我還像新娘。我一直安慰自己肄扎,他們只是感情好墨林,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著犯祠,像睡著了一般旭等。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衡载,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天搔耕,我揣著相機(jī)與錄音,去河邊找鬼痰娱。 笑死弃榨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梨睁。 我是一名探鬼主播鲸睛,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坡贺!你這毒婦竟也來(lái)了官辈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤遍坟,失蹤者是張志新(化名)和其女友劉穎拳亿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體政鼠,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡风瘦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了公般。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片万搔。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胡桨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞬雹,到底是詐尸還是另有隱情昧谊,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布酗捌,位于F島的核電站呢诬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胖缤。R本人自食惡果不足惜尚镰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哪廓。 院中可真熱鬧狗唉,春花似錦、人聲如沸涡真。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)哆料。三九已至缸剪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間东亦,已是汗流浹背杏节。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留典阵,地道東北人拢锹。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像萄喳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹋半,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容