主頁 > 軟體設計 > SpringCloud 微服務分布式 筆記(一)

SpringCloud 微服務分布式 筆記(一)

2021-01-25 11:07:54 軟體設計

SpringCloud 微服務分布式

軟體行業分類:

傳統軟體行業
互聯網軟體行業
在這里插入圖片描述

軟體架構分類:

微服務
單體架構

單體應用

一個歸檔包(可以是JAR、WAR、EAR或其它歸檔格式)包含所有功能的應用程式,通常稱為單體應用,
在這里插入圖片描述
優點

  • 便于共享: 單個歸檔檔案包含所有功能,便于在團隊之間以及不同的部署階段之間共享,
  • 易于測驗:
    單體應用一旦部署,所有的服務或特性就都可以使用了,這簡化了測驗程序,
    因為沒有額外的依賴,每項測驗都可以在部署完成后立刻開始,
  • 易于部署: 只需將單個歸檔檔案復制到單個目錄下,

缺點

  • 復雜性高:
    由于是單個歸檔檔案,所以一個檔案 等于 整個專案,檔案包含的模塊非常多,導致模塊的邊界模糊,
    依賴關系不清晰、代碼的質量參差不齊,混亂的堆在一起,使得整個專案非常復雜,
    以致每次修改代碼,都非常小心,可能添加一個簡單的功能,或者修改一個Bug都會帶來隱藏的缺陷,
  • 技術債務:
    隨著時間的推移、需求的變更和技術人員的更替,會逐漸形成應用程式的技術債務,并且越積越多,
  • 擴展能力受限:
    單體應用只能作為一個整體進行擴展,無法根據業務模塊的需要進行伸縮,
    (為了提高專案性能可以, 將一個專案復制多份部署多臺服務器~)
  • 阻礙技術創新:
    對于單體應用來說,技術是在開發之前經過慎重評估后選定的,
    每個團隊成員都必須使用相同的開發語言、持久化存盤及訊息系統,

微服務

2014 ,martin fowler馬丁·福勒
提出的:微服務架構風格 常聽的:分布式微服務

優點:
一個應用拆分為一組小型服務
每一個服務: 運行在自己的行程內,也就是可獨立部署和升級,擁有自己獨立的資料庫,通過HTTP的方式進行互通;
? 優點
? 服務圍繞業務功能拆分
? 可以由全自動部署機制獨立部署
? 微服務能夠被小團隊單獨開發,這個小團隊是2到5人的開發人員組成,
? 微服務是松耦合的,是有功能意義的服務,無論是在開發階段或部署階段都是獨立的,
? 去中心化,服務自治,服務可以使用不同的語言、不同的存盤技術; 只要實作功能即可~
? 微服務只是業務邏輯的代碼,不會和HTML,CSS 或其他界面組件混合,
? 每個微服務都有自己的存盤能力,可以有自己的資料庫,也可以有統一資料庫,
在這里插入圖片描述
上圖:微服務分布式架構,每一個點表示一個功能, 使用時只需要呼叫需要的功能模塊組合即可!
缺點:

  • 運維要求高: 更多的服務意味著要投入更多的運維,
  • 分布式固有的復雜性:
    使用微服務構建的是分布式系統,對于一個分布式系統,系統容錯、網路延遲、
    分布式事務等都會帶來巨大的問題,
  • 介面調整成本高:
    微服務之間通過介面進行通信,
    如果修改某一個微服務的API,可能所有用到這個介面的微服務都需要進行調整,
    遠程呼叫、服務發現、負載均衡、服務容錯、配置管理、服務監控、鏈路追蹤、日志管理、任務調度……

相關概念

Provider和Consumer

分布式微服務架構中,把一個應用差分為多個 功能模塊; 每個功能模塊專注做自己的事情…
當需要實作某一功能時候, 只需要對多個需要的 功能模塊直接相互呼叫即可…
那么每個模塊即是 Provider也是Consumer(提供者和呼叫者)…

RPC和Restful

什么叫RPC

  • RPC【Remote Procedure Call】是指遠程程序呼叫
    是一種行程間通信方式,他是一種技術的思想,而不是規范,
    它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的程序或函式,
    而不用程式員顯式編碼這個遠程呼叫的細節,
    即程式員無論是呼叫本地的還是遠程的函式,本質上撰寫的呼叫代碼基本相同,即網路通信

什么是REST

  • REST是一種架構風格,指的是一組架構約束條件和原則,
  • 滿足這些約束條件和原則的應用程式或設計就是 RESTful,
  • REST規范把所有內容都視為資源,網路上一切皆資源,
  • REST并沒有創造新的技術,組件或服務,只是使用Web的現有特征和能力,
  • 可以完全通過HTTP協議實作,使用 HTTP 協議處理資料通信,
  • REST架構對資源的操作包括獲取、創建、修改和洗掉資源的操作
    正好對應HTTP協議提供的GET、POST、PUT和DELETE方法,
  • 這個之前學MVC時候學習過…

分布式

一個應用拆分為多個不同的功能模塊,做不同的事情

集群

一臺服務器,承受不住某個作業,為了減輕服務器壓力,做集群 負載均價…多個設備做同一見事情!

選擇SpringCloud作為微服務

選型依據

  1. 整體解決方案和框架成熟度
  2. 社區熱度
  3. 可維護性
  4. 學習曲線

當前各大IT公司用的微服務架構有哪些?

  1. 阿里Dubbo/HSF
  2. 京東JSF
  3. 新浪微博Motan
  4. 當當網DubboX

各微服務框架對比

在這里插入圖片描述

分布式基礎理論

什么是分布式系統?

《分布式系統原理與范型》定義:
“分布式系統是若干獨立計算機的集合,這些計算機對于用戶來說就像單個相關系統”
分布式系統(distributed system)是建立在網路之上的軟體系統,

發展演變

單一應用架構——垂直應用架構——分布式服務架構——流動計算架構
在這里插入圖片描述

單一應用架構

當網站流量很小時,只需一個應用,將所有功能都部署在一起,
以減少部署節點和成本,此時,用于簡化增刪改查作業量的資料訪問框架(ORM)是關鍵,
在這里插入圖片描述
適用于小型網站,小型管理系統,將所有功能都部署到一個功能里,簡單易用,
缺點:
性能擴展比較難 協同開發問題 不利于升級維護...

垂直應用架構

當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用
以提升效率,此時,用于加速前端頁面開發的Web框架(MVC)是關鍵,
在這里插入圖片描述
通過切分業務來實作各個模塊獨立部署:
降低了維護和部署的難度,團隊各司其職更易管理,性能擴展也更方便,更有針對性,
缺點: 公用模塊無法重復利用,開發性的浪費

分布式服務架構

當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,
作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的回應多變的市場需求,
此時,用于提高業務復用及整合的分布式服務框架(RPC)是關鍵,
在這里插入圖片描述

流動計算架構

當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,
此時需增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率,
提高機器利用率的資源調度 和 治理中心(SOA)[ Service Oriented Architecture]是關鍵,
在這里插入圖片描述

springClond入門 應用開發

SpringBoot和SpringCloud的區別

  • SpringBoot專注于快速方便的開發單個個體微服務,
  • SpringCloud是關注全域的微服務協調整理治理框架
    它將SpringBoot開發的一個個單體微服務整合并管理起來: 為各個微服務之間提供
    配置管理、服務發現、斷路器、路由、微代理、事件總線、全域鎖、決策競選、分布式會話等等集成服務…
  • SpringBoot可以離開SpringCloud獨立使用開發專案,但是SpringCloud離不開SpringBoot,屬于依賴的關系
  • SpringBoot專注于快速、方便的開發單個微服務個體
  • SpringCloud關注全域的服務治理框架,

搭建springcloud工程 分布式服務架構

在這里插入圖片描述

創建一個普通的Maven專案

為了方便開發使用 Maven高級應用...開發專案:
當然你也可以不用Maven來測驗,多起幾個專案工程…
刪掉主工程的src (反之也用不上

主工程的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>org.example</groupId>
    <artifactId>SpringCloudBJ</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    
    <!-- Maven父工程包含管理的子工程... -->
    <modules>
        <module>common_api</module>
        <module>common_orderService</module>
        <module>common_userService</module>
    </modules>

    <!-- SpringBoot父依賴 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <!-- 統一設定Maven專案編碼 jdk環境 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- spring-boot的web依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring-boot的應用日志依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!-- spring-boot的單元測驗依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- lombok的依賴組件,別忘了要下載Idea  lombok的插件哦~ -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <!-- 指定SpringCloud配置必要!! -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>                <!-- 版本... -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- maven的默認下載資源.. -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

關于SpringCloud版本:Greenwich

SpringCloud版本更新非常快!A B C D E F G H目前最高已經到H了我湊!!
2021年初
在這里插入圖片描述

創建Maven子工程common_api物體模塊

主要存放專案開發所需要的物體類…
在這里插入圖片描述
這里只有一個物體類…沒有什么太復雜的操作
Order.Java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data
@AllArgsConstructor
@RequiredArgsConstructor
//創建一個物體類: 并根據lombok 及其注解生產對應的 建構式,toString(); get/set...
public class Order {
    private Integer id;
    private String title;
    private Double price;
    private Integer uid;
}

pom.xml 不用任何添加或改動…看一下我其它Maven子工程如果呼叫;

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

創建Maven子工程common_orderService訂單模塊

撰寫訂單模塊相對于的代碼…
在這里插入圖片描述
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>SpringCloudBJ</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common_orderService</artifactId>

    <!-- 關鍵!! -->
    <dependencies>
        <!-- common_orderService工程引入common_api -->
        <dependency>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
            <artifactId>common_api</artifactId>
        </dependency>
    </dependencies>
</project>

OrderService.Java

import com.wsm.entity.Order;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class OrderService {
    //模擬假訂單集合...
    private static List<Order> orders = new ArrayList<>();
    //類加載時候默認獲取一些資料..模擬假訂單..
    static {
        orders.add(new Order(1, "訂單11", 10.0, 1));
        orders.add(new Order(2, "訂單21", 10.0, 2));
        orders.add(new Order(3, "訂單31", 10.0, 1));
        orders.add(new Order(4, "訂單41", 10.0, 2));
    }
    //根據輸入用戶id獲取當然用訂單集合..
    public List<Order> findOrderByUser(Integer uid) {
        List<Order> myorders = new ArrayList<>();
        //遍歷集合從中獲取 uid一致的資料存放在集合中回傳...
        for (Order order : orders) {
            if (order.getUid() == uid) {
                myorders.add(order);
            }
        }
        return myorders;
    }
}

OrderController.Java

import com.wsm.entity.Order;
import com.wsm.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class OrderController {
    @Autowired
    private OrderService os;
    //REST風格進行請求..
    @GetMapping("/findOrderByUser/{uid}")   //引數是以 /請求名/{引數1}/{引數2} 進行訪問的...
    public List<Order> findOrderByUser(@PathVariable Integer uid){
        //REST風格引數需要使用 @PathVariable獲取!!
        return  os.findOrderByUser(uid);
    }
}

SpringBoot的主工程類:MyOrderServer.Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyOrderServer {
    public static void main(String[] args) {
        SpringApplication.run(MyOrderServer.class, args);
    }
}

SpringBoot application.yml組態檔

server:
  port: 6001            #設定埠6001 當有多個微服務時候注意埠號可別沖突了..
spring:
  application:
    name: order-server  #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;

在這里插入圖片描述

創建Maven子工程common_userService 用戶模塊

撰寫用戶模塊相對于的代碼…
在這里插入圖片描述
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>SpringCloudBJ</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>common_userService</artifactId>

    <dependencies>
        <!-- common_userService工程引入common_api -->
        <dependency>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
            <artifactId>common_api</artifactId>
        </dependency>
    </dependencies>
</project>

UserService.Java

@Service
@Slf4j                  //加載lo4g使用...
public class UserService {
    @Autowired
    private RestTemplate restTemplate;
    //通過restTemplate進行網路通信,回傳..其它遠程模塊的資料(雖然現在都是本地的不過就是模擬了..)

    public List<Order> currentUserOrder(Integer uid) {
        log.info("用戶服務呼叫訂單服務");
        //硬編碼的呼叫!! 這里的請求都寫死的...這好嗎?這不好...后面修改;
        String myurl = "http://localhost:6001/findOrderByUser/" + uid;
        log.info(myurl
        );
        List<Order> list = restTemplate.getForObject(myurl, List.class);
        return list;
    }
}

UserController.Java

//編程控制層,接受請求回應結果
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/showUserOrder")
    public List<Order> showUserOrder(Integer uid){
        return userService.currentUserOrder(uid);   //呼叫Service層
        //Service又是通過網路呼叫  訂單模塊來回應的結果,因此在此基礎上要缺點訂單模塊是運行中的...
    }
}

SpringBoot的主工程類:MyUserServer.java

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

    @Bean
    //實體化 RestTemplate 方便Service
    //可別忘了@SpringBootApplication復合注解底層可以有@SpringBootConfiguration 它也是一個Spring的配置類!
    public RestTemplate createRestTemplate() {
        return new RestTemplate();
    }
}

SpringBoot application.yml組態檔

server:
  port: 6002            #設定埠6002 當有多個微服務時候注意埠號可別沖突了..
spring:
  application:
    name: user-server   #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;

在這里插入圖片描述

服務呼叫

前文已經撰寫了三個基礎的微服務,在用戶下單時需要呼叫商品微服務獲取商品資料,
商品微服務提供了供人呼叫的HTTP介面

  • 所以可以再下定單的時候使用http請求的相關工具類完成,
    如常見的HttpClient,OkHttp,當然也可以使用Spring提供的RestTemplate

RestTemplate介紹

Spring框架提供的RestTemplate類可用于在應用中呼叫rest服務
它簡化了與http服務的通信方式,統一了RESTful的標準,封裝了http鏈接

  • 我們只需要傳入url及回傳值型別即可,相較于之前常用的HttpClient,
  • RestTemplate是一種更優雅的呼叫RESTful服務的方式,
  • RestTemplate類的設計原則與許多其他Spring 模板類(例如JdbcTemplate、JmsTemplate)相同
    為執行復雜任務提供了一種具有默認行為的簡化方法,
  • RestTemplate默認依賴JDK提供http連接的能力(HttpURLConnection)
    如果有需要的話也可以通過setRequestFactory方法替換為例如
    Apache HttpComponents、Netty或OkHttp等其它HTTP library,
  • 考慮到RestTemplate類是為呼叫REST服務而設計的,因此它的主要方法與REST的基礎緊密相連就不足為奇了
    后者是HTTP協議的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS,
    RestTemplate類具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法,
    在這里插入圖片描述

硬編碼存在的問題

至此已經可以通過RestTemplate呼叫商品微服務的RESTFul API介面,
但是我們把提供者的網路地址(ip,埠)等硬編碼到了代碼中,這種做法存在許多問題:

  • 應用場景有局限
  • 無法動態調整

  • 那么應該怎么解決呢,就需要通過:注冊中心動態的對服務注冊和服務發現

總結

以上就是一個典型的分布式模塊架構 多模塊業務之間的相互呼叫 但↓↓↓↓
因為是用戶模塊—參考—訂單模塊
訂單是提供者provide 用戶是呼叫者Consumer

  • 而如果訂單模塊服務未開啟的情況下,會影響用戶模塊的使用!注意!
  • 而對應大量的模塊之間的呼叫, 隨著專案業務擴大…模塊之間的參考也會越來越復雜!!
  • 而對于 A模塊服務停止 B模塊服務受影響…如果加劇呢 C模塊 D模塊…
    B依賴A C依賴B D依賴C 而這時候A沒了會之間的造成服務的崩塌!!

為了解決這種問題, 注冊中心就出現了

服務注冊Eureka基礎

注冊中心可以說是微服務架構中的 ”通訊錄“,它記錄了服務和服務地址 映射關系在分布式架構中
服務會注冊到這里,當服務需要呼叫其它服務時,就這里找到服務的地址,進行呼叫,

注冊中心的主要作用

服務注冊中心是微服務架構非常重要的一個組件,在微服務架構里主要起到了協調者的一個作用,
注冊中心一般包含如下幾個功能:

  • 服務發現:
    提供者/呼叫者需要注冊宣告在注冊中心中才可以相互使用.
    服務注冊/反注冊:保存服務提供者和服務呼叫者的資訊
    服務訂閱/取消訂閱:服務呼叫者訂閱服務提供者的資訊,最好有實時推送的功能
    服務路由(可選):具有篩選整合服務提供者的能力,
  • 服務配置:
    代碼上, 服務提供者/調度者需要配置注冊中心
    配置訂閱:服務提供者和服務呼叫者訂閱微服務相關的配置
    配置下發:主動將配置推送給服務提供者和服務呼叫者
  • 服務健康檢測
    服務要定時的向注冊中心提供心跳?告訴注冊中心我還在能干活
    當然注冊中心一般都有自我保護機制…
    檢測服務提供者的健康情況

常見的注冊中心

  • **Zookeeper **
    zookeeper它是一個分布式服務框架,是Apache Hadoop 的一個子專案
    它主要是用來解決分布式應用中經常遇到的一些資料管理問題,
    如:統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等,
    簡單來說zookeeper=檔案系統+監聽通知機制,
  • Eureka
    Eureka是在Java語言上,基于Restful Api開發的服務注冊與發現組件,Springcloud Netflflix中的重要組件
  • Consul
    Consul是由HashiCorp基于Go語言開發的支持多資料中心分布式高可用的服務發布和注冊服務軟體
    采用Raft演算法保證服務的一致性,且支持健康檢查
  • Nacos
    Nacos是一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺,
    簡單來說 Nacos 就是注冊中心 + 配置中心的組合,提供簡單易用的特性集
    幫助我們解決微服務開發必會涉及到的服務注冊與發現,服務配置,服務管理等問題,
    **Nacos 還是 Spring Cloud Alibaba 組件之一,負責服務注冊與發現, **

在這里插入圖片描述

Eureka的基本架構

在這里插入圖片描述

Spring Cloud 封裝了 Netflix 公司開發的 Eureka
Eureka 采用了 C-S 的設計架構,Eureka Server 作為服務注冊功能的服務器,它是服務注冊中心,

  • 使用 Eureka 的客戶端連接到 Eureka Server并維持心跳連接,
  • 這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行,
  • Eureka包含兩個組件:Eureka ServerEureka Client
  • Eureka Server提供服務注冊服務
    各個節點啟動后,會在EurekaServer中進行注冊,
    這樣EurekaServer中的服務注冊表中將會存盤所有可用服務節點的資訊,
    服務節點的資訊可以在界面中直觀的看到
  • EurekaClient是一個Java客戶端,用于簡化Eureka Server的互動
    客戶端同時也具備一個內置的、使用輪詢(round-robin)負載演算法的負載均衡器,
    在應用啟動后,將會向Eureka Server發送心跳(默認周期為30秒),
    如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer將會從服務注冊表中把這個服務節點移除(默認90秒)

三大角色

  1. Eureka Server 提供服務注冊和發現
  2. Service Provider服務提供方將自身服務注冊到Eureka,從而使服務消費方能夠找到
  3. Service Consumer 服務消費方從Eureka獲取注冊服務串列,從而能夠消費服務
    使用時先啟動注冊中心——Provider提供者——Consumer呼叫者

重構SpringCloud工程 流動計算架構

基于上面的SpringCloud的分布式服務架構開發

創建Maven子工程eureka-server 注冊中心

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>SpringCloudBJ</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>eureka-server</artifactId>
    <!-- Eureka-server服務依賴,必須!  -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 7001                #設定注冊中心的 埠;
spring:
  application:
    name: eureka-server     #注冊中心應用名稱;
#配置注冊中心....
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/   #注冊中心對外暴漏的注冊地址...
    #要不要去注冊中心獲取其他服務的地址,默認為true  (目前只有一個注冊中心而且,當前就是注冊中心..)
    fetch-registry: false
    #是否將允許自己注入注冊中心,默認為true   (目前只有一個注冊中心而且,當前就是注冊中心..自己注冊自己?)
    register-with-eureka: false        #如果一個應用中有兩個注冊中心可以開啟,達到集群注冊中心的目的...

主程式類MyEurekaServer.Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer            //注解主程式開啟 Eureka服務
public class MyEurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(MyEurekaServer.class, args);
    }
}

@EnableEurekaServer

啟動注冊中心的服務, 表示當前專案作為SpringCloud中的注冊中心

現在啟動程式就可以訪問當前的注冊中心了…

在這里插入圖片描述

修改上面SpringBoot微服務 注冊到注冊中心中去!

common_orderService/userService注冊到注冊中心去:

加載注冊服務依賴

pom.xml

	<!--- 注冊服務的依賴.. -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

主程式中加入 @EnableEurekaClient 注入注冊中心

以訂單的主程式為例子, 其它也都這么做
MyOrderServer.Java

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

@EnableEurekaClient 啟動注冊中心客戶端
表示當前主程式注冊到注冊中心去…

@EnableDiscoveryClient與@EnableEurekaClient區別

@EnableDiscoveryClient,一種為@EnableEurekaClient,用法上基本一致,

  • @EnableEurekaClient是針對于 Eureka注冊中心專門的啟動注冊注解
  • @EnableDiscoveryClient在包含了@EnableEurekaClient
    它是對于所以注冊中心的一個統一開啟注解…

SpringBoot .yml檔案的Eureka的配置

組態檔配置注冊中心 Eureka (以業務order的為例子)
application.yml

server:
  port: 6001            #設定埠6001 當有多個微服務時候注意埠號可別沖突了..
spring:
  application:
    name: order-server  #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/    #指定服務注冊的注冊中心;
  instance:
    prefer-ip-address: true                         #在Eureka上使用ip號..
    instance-id: ${spring.cloud.client.ip-address}:${server.port}	#在Eureka上顯示ip號..

最后別忘了把 common_userService中硬編碼解決了

UserService.Java

import com.wsm.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;      //這個DiscoveryClient別搞錯
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
@Slf4j                  //加載lo4g使用...
public class UserService {
    @Autowired
    private RestTemplate restTemplate;
    //通過restTemplate進行網路通信,回傳..其它遠程模塊的資料(雖然現在都是本地的不過就是模擬了..)

    @Autowired              //實作動態呼叫...
    private DiscoveryClient discoveryClient;

    public List<Order> currentUserOrder(Integer uid) {
        //獲取注冊中心上的微服模塊實體                                                根據服務名;
        //回傳一個集合: 有可能這個服務在多個注冊中心上存在,`負載均衡~` 所以是一個集合;
        List<ServiceInstance> instances = discoveryClient.getInstances("order-server");
        ServiceInstance serviceInstance = instances.get(0); //而本次只有一個...
        log.info("用戶服務呼叫訂單服務");
        //動態呼叫服務                服務的host                         服務埠號                 這個就是服務controller請求    給其引數uid
        String myurl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/findOrderByUser/" + uid;

        log.info(myurl);
        List<Order> list = restTemplate.getForObject(myurl, List.class);
        return list;
    }
}

在這里插入圖片描述
在這里插入圖片描述
動態的從注冊中心Eureka上獲取ip
在這里插入圖片描述
查看這里的 ip 192.168.1.1

  • windows+r
  • cmd
  • 輸入ipconfig
  • 在這里插入圖片描述
  • 如果是在同一個網段下, 可以實作不同電腦通過同一個注冊中心進行使用…
  • 但我這個不上無線局域網配置器...

Eureka的服務剔除問題

在服務客戶端Client 配置的~
在這里插入圖片描述
默認 30秒心跳💓 90秒續約時間…
.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/    #指定服務注冊的注冊中心;
  instance:
    prefer-ip-address: true                         #在Eureka上顯示ip號..
    instance-id: ${spring.cloud.client.ip-address}:${server.port}	#在Eureka上顯示ip號..
    lease-renewal-interval-in-seconds: 5            #客戶端向注冊中心發送心跳時間
    lease-expiration-duration-in-seconds: 10        #如果沒有發送心跳的延遲續約時間...

如果客戶端的服務因為某些原因關閉了,Eureka會根據心跳檢測到你沒了而移除你的服務…

  • 客戶端定時向 注冊中心發送心跳如果超過時間沒有發送 默認30秒
  • 會有一個延遲等待時間. 默認90秒兩分鐘~ 如果還沒有啟動Eureka會把服務剔除…
  • 但, 因為 Eureka自我保護機制 服務并不會真的 移除…而是會給你一個時間如果還沒有回來~則報錯!
  • 在這里插入圖片描述

Eureka自我保護機制

一般不會關閉自我保護機制,因為如果服務又好了又可以立刻注冊會來使用...
在服務端即 注冊中心關閉保護機制,,,
注冊中心的.yml

#配置注冊中心....
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/   #注冊中心對外暴漏的注冊地址...
    #要不要去注冊中心獲取其他服務的地址,默認為true  (目前只有一個注冊中心而且,當前就是注冊中心..)
    fetch-registry: false
    #是否將允許自己注入注冊中心,默認為true   (目前只有一個注冊中心而且,當前就是注冊中心..自己注冊自己?)
    register-with-eureka: false        #如果一個應用中有兩個注冊中心可以開啟,達到集群注冊中心的目的...
  server:
    enable-self-preservation: false      #默認是ture 開啟的
    eviction-interval-timer-in-ms: 4000  #默認是0 從不剔除!

保護機制只要關閉就會報錯!
在這里插入圖片描述
而且只要服務失效就會移除…

nice 終于寫完了,建議三聯!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252115.html

標籤:其他

上一篇:XXL-JOB

下一篇:給產品經理的9千字總結:系統間資料傳輸關注這些就夠了:介面、otter、log4j、SFTP、MQ……

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more