1. 程式人生 > 實用技巧 >分散式-springboot基礎入門

分散式-springboot基礎入門

B站播放地址:https://www.bilibili.com/video/BV1PE411i7CV?t=51

部落格地址:https://www.cnblogs.com/hellokuangshen/p/12516870.html

狂神參考雷鋒陽的視訊講的,建議視訊還是看雷鋒陽的
1、學習路線

2、什麼是SpringBoot

SpringBoot是一個Javaweb的開發框架,和SpringMVC類似,相比其他Javaweb框架,SpringBoot簡化開發,約定大於配置,能迅速地開發web應用,幾行程式碼開發一個http介面。

隨著Spring不斷的發展,涉及的領域越來越多,專案整合開發需要配合各種各樣的檔案,使Spring

框架的使用變得沒那麼簡單,人稱“配置地獄”。SpringBoot正是在這樣的背景下被抽象出來的開發框架,目的是為了讓大家更容易地使用Spring、更容易地整合各種常用的中介軟體和開源框架。

SpringBoot是基於Spring開發,SpringBoot本身並不提供Spring框架的核心特性以及擴充套件功能,只是用於快速、敏捷地開發新一代基於Spring框架的應用程式。也就是說,SpringBoot並不是用來替代Spring的解決方案,而是和Spring框架緊密結合用於提升Spring開發者體驗的工具。SpringBoot****以約定大於配置的核心思想,預設幫我們進行了很多配置,多數SpringBoot

應用只需要很少的Spring配置。同時,SpringBoot集成了大量常用的第三方庫配置(例如RedisMongoDBRabbitMQ等),SpringBoot應用中這些第三方庫幾乎可以零配置的開箱即用。

SpringBoot的優點:

  • 為所有Spring開發者更快的入門;
  • 開箱即用,即提供各種預設配置來簡化專案配置;
  • 內嵌式容器簡化web專案;
  • 沒有冗餘程式碼生成和XML配置的要求。

3、微服務概念介紹

3.1 什麼是微服務?

微服務是一種架構風格,它要求我們開發一個應用的時候,這個應用必須構建成一系列子服務的組合,可以通過http或者RPC的方式進行服務間的通訊。

3.2 單體應用服務

所謂單體應用架構(all in one)是指,我們將一個應用中的所有應用服務都封裝在一個應用中,比如把資料庫訪問、web訪問等功能都放到一個war包裡。

單體應用架構的優點是:易於開發和測試,也十分方便部署,當需要擴充套件是,只需將war包複製多份,然後放到多臺伺服器上,再做個負載均衡即可。

單體應用架構的缺點是:哪怕要修改一個十分微小的地方,都需要停掉整個服務,重新打包,部署這個應用的war包,各服務的部署升級等可能依賴其他服務,不夠靈活。特別是對於一個大型應用,我們不可能把所有內容都放在一個應用中。

3.3 微服務架構

所謂微服務架構,就是打破之前單體應用服務的架構方式,把每個功能元素獨立出來抽象成一個模組,不同的應用程式可能是不同的模組組合而成的,每個模組就稱為一個微服務,微服務間可以獨立地打包部署升級。

這樣做的好處是:

  • 節省了呼叫資源;
  • 每個微服務都是一個可替換的,可獨立升級的軟體程式碼。

有關微服務的文章部落格,可以參考:

4、第一個SpringBoot程式

  • 可以在官網直接下載後,匯入IDEA開發(https://start.spring.io/);
  • 直接使用IDEA建立一個springboot專案(一般開發直接在IDEA中建立);

目錄結構:

Main:

package com.jerry;

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

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

Controller:

package com.jerry.controller;

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

@RestController
@RequestMapping("/hello")
public class HelloController {
    @GetMapping("hello")
    @ResponseBody
    public String hello()
    {
        return "byte dance";
    }
}

使用方法:

開啟瀏覽器,輸入 http://localhost:8080/hello/hello,會返回一個網頁,網頁顯示byte dance字串。

5、SpringBoot自動裝配原理

5.1 啟動器

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

啟動器:就是SpringBoot的啟動場景,有多種啟動器,比如spring-boot-starter-web,就會幫我們自動匯入web環境所有的依賴,springboot將每一個功能場景都生成一個對應的啟動器,我們需要什麼樣的功能和場景,只需要引入對應的starter即可。

5.2 主程式

// 標註這個類是一個springboot應用
@SpringBootApplication
public class Springboot01HelloworldApplication {
    public static void main(String[] args) {
        // 將springboot應用啟動
        SpringApplication.run(Springboot01HelloworldApplication.class, args);
    }
}

我們可以把 @SpringBootApplication看作是 @Configuration@EnableAutoConfiguration@ComponentScan 註解的集合。

根據 SpringBoot 官網,這三個註解的作用分別是:

  • @EnableAutoConfiguration:啟用 SpringBoot 的自動配置機制;
  • @ComponentScan: 掃描被@Component@Service@Controller註解修飾的 bean,註解預設會掃描該類所在的包下所有的類;
  • @Configuration:允許在 Spring 上下文中註冊額外的 bean 或匯入其他配置類。

5.3 自動裝配原理

總結:springboot所有自動配置都是在啟動的時候掃描並載入,spring.factories所有的自動配置都在這裡面,但是不一定生效,要判斷條件是否成立,只有匯入了對應的starter,就有對應的啟動器了,有了啟動器,我們自動裝配就會生效,配置就會成功。

TMD還沒講怎麼用呢就開始講底層是不是撒比???

6、主啟動類如何執行(後續補充)

7、Yaml

7.1 Springboot配置檔案

Springboot的配置檔案一般位於resource目錄下,配置檔案的作用:修改SpringBoot自動配置的預設值,因為SpringBoot在底層都給我們配置好了。

Springboot使用一個全域性的配置檔案,配置檔名稱是固定的

  • application.properties

  • 語法結構:key=value

  • 不推薦使用

  • application.yml

  • 語法結構:key:空格 value

7.2 Yaml語法

7.2.1 Yaml概述

Yaml全稱:“Yet Another Markup Language”,仍然是一種標記語言。

以前的配置檔案,大多數使用xml來配置,比如一個簡單的埠配置,對比一下xml和yaml配置:

<server>
  <port>8080</port>
</server>
server:
  port: 8080	

7.2.2 yaml基本語法

  • yaml大小寫敏感
  • 使用縮排表示層級關係
  • 縮排不允許用tab,只允許用空格
  • '#'表示註釋,沒有多行註釋

yaml支援普通的k-v、陣列/列表、對映(map)和自定義類的例項。

(1)普通的k-v

name: zhangjian

(2)陣列/列表

意思是陣列和列表都是一樣的寫法,有兩種格式:不寫成一行和寫成一行。

不寫成一行:

  hobbies:
    - code
    - music

寫成一行:

hobbies: [code, music]

注意:code和music逗號後面的空格可有可不有。

(3)對映(map)

資料結構就是Java裡的map結構,同樣有兩種格式:不寫成一行和寫成一行。

不寫成一行:

  scoreMap:
    - Math: 100
    - English: 100

寫成一行:

scoreMap: {Math: 100, English: 100}

注意:key和value中間的:後面一定要有空格,不同的k-v對,即逗號後面的空格可有可不有。

(4)自定義類的例項

Bean如下:

public class Dog {
    private String name;
    private int age;
}

Bean對應的yml寫法如下:

  dog:
    name: miumiu
    age: 1

Student的成員屬性有Dog的例項,yml寫法如下:

student:
  name: zhangjian
  age: 17
  isMarry: false
  birthday: 1993/05/16
  scoreMap: {Math: 100, English: 100}
  hobbies: [code,music]
  
  dog:
    name: miumiu
    age: 1

7.2.3 佔位符

${}

person:
    name: qinjiang${random.uuid} # 隨機uuid
    age: ${random.int}  # 隨機int
    happy: false
    birth: 2000/01/01
    maps: {k1: v1,k2: v2}
    lists:
      - code
      - girl
      - music
    dog:
      name: ${person.hello:other}_旺財
      age: 1

8、給屬性賦值的幾種方式

8.1 通過Yaml配置檔案賦值

application.yml配置檔案中將類的屬性值配好,在要配置屬性的類中,通過註解@ConfigurationProperties(prefix = "XXX")將yml配置檔案中的配置項和實體類相關聯,@ConfigurationProperties作用:將配置檔案中配置的每一個屬性的值,對映到這個類中,告訴SpringBoot將本類中的所有屬性和配置檔案中相關的配置進行繫結,舉例如下:

Student類:

package com.jerry.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
    private String name;
    private Integer age;
    private Date birthday;
    private Boolean isMarry;
    private Map<String, Integer> scoreMap;
    private List<String> hobbies;
    private Dog dog;
}

注意Student類被註解@ConfigurationProperties(prefix = "student")修飾。

Dog類:

package com.jerry.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Dog {
    private String name;
    private int age;
}

yml配置檔案:

student:
  name: zhangjian
  age: 17
  isMarry: false
  birthday: 1993/05/16
  scoreMap: {Math: 100, English: 100}
  hobbies: [code,music]

  dog:
    name: miumiu
    age: 1

Student類被註解@ConfigurationProperties(prefix = "student")修飾,其中prefix="student",這個student對應的就是yml配置檔案裡的student。

測試類:

package com.jerry;

import com.jerry.pojo.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot01HelloworldApplicationTests {
    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        System.out.println(student);
    }
}

注意@Autowired自動將student屬性注入到Springboot01HelloworldApplicationTests類中。

8.2 @PropertySource載入指定的配置檔案

不推薦

8.3 @Value配置(推薦,公司基本都用這個)

還需搭配@Autowired@Component註解使用。

8.4 小結

  • 如果我們在某個業務中,只需要獲取配置檔案中的某個值,可以使用一下 @value;
  • 如果說,我們專門編寫了一個JavaBean來和配置檔案進行一一對映,就直接@configurationProperties,不要猶豫!

9、JSR303校驗

見SpringBoot常用註解 6、引數校驗部分:https://www.yuque.com/docs/share/5e853752-a1ba-4d24-ad6f-6c7ec5147dbc?#

10、多環境配置及配置檔案位置

實際開發過程中可能有多種環境,比如研發環境、類生產環境、現網環境等,每一類環境對應的配置檔案都不一樣,比如不同的環境對接不同的資料來源,因此就存在這種場景:需要靈活地切換不同的配置檔案供Spring載入。

SpringBoot提供兩種方式進行多環境配置:

  • properties
  • yml

10.1 properties多環境配置

我們在主配置檔案編寫的時候,檔名可以是 application-{profile}.properties/yml , 用來指定多個環境版本,例如:

  • application-test.properties,代表測試環境配置
  • application-dev.properties,代表開發環境配置

當上述配置檔案同時存在於resource目錄下時,它****預設使用application.properties主配置檔案

當我們需要切換成test環境或者dev環境的配置時,只需要在application.properties主配置檔案中加入:

spring.profiles.active=測試級別(dev or test)

可通過在不同的配置檔案中配置不同的埠號驗證。

10.2 yml多環境配置

和properties配置檔案中一樣,但是使用yml去實現多環境配置不需要建立多個配置檔案,更加方便了 !

server:
  port: 8081
#選擇要啟用哪個環境塊
spring:
  profiles:
    active: test

---
server:
  port: 8083
spring:
  profiles: dev #配置環境的名稱


---
server:
  port: 8084
spring:
  profiles: myEnv  #配置環境的名稱

如果yml和properties同時對dev或者test環境編寫了配置檔案 , 預設會使用dev或者test環境的properties配置檔案。

11、SpringBoot進行web開發

用SpringBoot進行web開發要解決的問題:

  • 靜態資源的匯入
  • 首頁
  • 模板引擎(Thymeleaf)
  • 裝配SpringMVC
  • 增刪改查
  • 攔截器
  • 國際化(實現中英文切換)

12、靜態資源匯入

12.1 web靜態資源和動態資源

靜態資源和動態資源的概念

  • 靜態資源:一般客戶端傳送請求到web伺服器,web伺服器從記憶體在取到相應的檔案,返回給客戶端,客戶端解析並渲染顯示出來。
  • 動態資源:一般客戶端請求的動態資源,先將請求交於web容器,web容器連線資料庫,資料庫處理資料之後,將內容交給web伺服器,web伺服器返回給客戶端解析渲染處理。

靜態資源和動態資源的區別

  • 靜態資源一般都是設計好的html頁面,而動態資源依靠設計好的程式來實現按照需求的動態響應;
  • 靜態資源的互動性差,動態資源可以根據需求自由實現;
  • 在伺服器的執行狀態不同,靜態資源不需要與資料庫參於程式處理,動態資源可能需要多個數據庫的參與運算。

12.2 靜態資源匯入的幾種方式

12.2.1 webjars + jQuery

沒啥實際意義。

12.2.2 靜態資源對映規則

將靜態資源放在以下目錄,可以被SpringBoot識別到:

"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"

其中classpath為resource目錄:

我們可以在resources根目錄下新建對應的資料夾,都可以存放我們的靜態檔案,一般遵循以下規則:

  • static存放靜態資源;
  • public存放公共的資源;
  • resource存放上傳的圖片等資源。

優先順序:resource > static > public。

12.3 自定義資源路徑

我們也可以自己指定特定目錄來存放靜態資源,在application.properties中配置:

spring.resources.static-locations=classpath:/coding/,classpath:/kuang/

其中classpath為上面截圖中的resource目錄,/coding和/kuang是我們自定義存放靜態資源的目錄,一旦自己定義了靜態檔案目錄的路徑,原來的自動配置就都會失效了,不推薦自己再自定義一個資源路徑。

13、首頁定製

首頁就是我們訪問一個網站首先出現的頁面,比如百度,我們將首頁對應的index.html(檔名必須是這個,springboot原始碼寫死的)檔案放在上面講的靜態資源目錄下,比如public或者static目錄下,如下:

重新執行springboot,開啟瀏覽器,如圖:

我們可以精心編寫首頁對應的html檔案,瀏覽器渲染index.html後,會為我們呈現絢麗的網站首頁畫面!

14、Thymeleaf模板引擎

14.1 什麼是web的模板引擎

模板引擎(這裡特指用於Web開發的模板引擎)是為了使使用者介面與業務資料(內容)分離而產生的,是用於前端指令碼簡化字串拼接的。模板引擎提供一個模板,後端傳來的資料來源(json或者字串格式)通過這個模板引擎的處理生成一個html文字,瀏覽器再通過渲染這個html文字給使用者呈現最終的網站頁面,流程如下:

ThymeleafSpringBoot推薦的模板引擎,此外FreeMarker也是使用較多的模板引擎。

SpringBoot使用Thymeleaf模板引擎,需要引入Thymeleafmaven依賴:

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

此外,還需要在html文本里引入Thymeleaf的名稱空間:

<html lang="en" xmlns:th="http://www.thymeleaf.org">

14.2 Thymeleaf語法

15、SpringMVC自動配置

X、分散式 Dubbo + Zookeeper + SpringBoot

X.1 分散式理論

分散式系統是若干獨立計算機的集合,這些計算機對於使用者來說就像單個相關係統。分散式系統是由一組通過網路進行通訊,為了完成共同的任務而協調工作的計算機節點組成的系統。分散式系統的出現是為了用廉價的、普通的機器完成單個計算機無法完成的計算、儲存任務。其目的是利用更多的機器、處理更多的資料。

分散式系統是建立在網路之上的軟體系統。

首先需要明確的是,只有當單個節點的處理能力無法滿足日益增長的計算、儲存任務的時候,且硬體的提升(比如加記憶體、加磁碟、使用更好的CPU)高昂到得不償失的時候,應用程式也不能進一步優化的時候,我們才需要考慮分散式系統。因為,分散式系統要解決的問題本事就是和單機系統一樣的,而由於分散式系統多節點、通過網路通訊的拓撲結構,會引入很多單機系統沒有的問題,為了解決這些問題又會引入更多的機制、協議,帶來更多的問題...

可以參考Dubbo官網的背景介紹:http://dubbo.apache.org/zh-cn/docs/user/preface/background.html

以下摘自上面的連線(感覺很濃縮很高度,但是憑我現在的開發經驗還不能領會...):

隨著網際網路的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。

單一應用架構

當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的資料訪問框架(ORM)是關鍵。

垂直應用架構

當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,提升效率的方法之一是將應用拆成互不相干的幾個應用,以提升效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。

分散式服務架構

當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用於提高業務複用及整合的分散式服務框架(RPC)是關鍵。

流動計算架構

當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率。此時,用於提高機器利用率的資源排程和治理中心(SOA)是關鍵。

Todo:上面四種模式需要網上查資料弄清楚,最好每種模式對應一個結構圖,需要總結!

X.2 RPC框架

參考:https://www.yuque.com/zhangjian-mbxkb/uxqnxx/ag2a4f

X.2.1 什麼是RPC?

RPC(Remote Procedure Call)是遠端過程呼叫,是一種程序間通訊的方式,RPC是一種技術的思想,而不是規範。它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的過程或函式,而不用程式設計師顯示編碼這個遠端呼叫的細節。即程式設計師無論是呼叫本地的還是遠端的函式,本質上編寫的呼叫程式碼基本相同。

舉個例子,兩臺伺服器A、B,一個應用a部署在伺服器A上,另一個應用b部署在伺服器B上,應用a想要呼叫伺服器B上的應用b提供的方法,由於應用a和應用b不在一個記憶體空間,需要通過網路來表達呼叫的語義和傳達呼叫的資料。為什麼要用RPC呢?就是因為無法在一個程序內,甚至一臺計算內通過本地呼叫的方式完成的需求,比如不同系統間的通訊,甚至不同的組織間的通訊,由於計算能力需要橫向擴充套件,需要在多臺機器組成的叢集上部署應用。RPC就是要像呼叫本地函式一樣去調遠端函式。

推薦閱讀文章:https://www.jianshu.com/p/2accc2840a1b

X.2.2 RPC基本原理

Todo:補圖!需要花時間至少知道個大概流程。

RPC兩大核心模組:通訊、序列化。

X.2.3 http和RPC的區別和聯絡

既然有了http,為什麼還需要RPC實現服務間的通訊呢?