分散式-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
集成了大量常用的第三方庫配置(例如Redis
、MongoDB
、RabbitMQ
等),SpringBoot
應用中這些第三方庫幾乎可以零配置的開箱即用。
SpringBoot
的優點:
- 為所有
Spring
開發者更快的入門; - 開箱即用,即提供各種預設配置來簡化專案配置;
- 內嵌式容器簡化
web
專案; - 沒有冗餘程式碼生成和
XML
配置的要求。
3、微服務概念介紹
3.1 什麼是微服務?
微服務是一種架構風格,它要求我們開發一個應用的時候,這個應用必須構建成一系列子服務的組合,可以通過http
或者RPC
的方式進行服務間的通訊。
3.2 單體應用服務
所謂單體應用架構(all in one)是指,我們將一個應用中的所有應用服務都封裝在一個應用中,比如把資料庫訪問、web訪問等功能都放到一個war包裡。
單體應用架構的優點是:易於開發和測試,也十分方便部署,當需要擴充套件是,只需將war包複製多份,然後放到多臺伺服器上,再做個負載均衡即可。
單體應用架構的缺點是:哪怕要修改一個十分微小的地方,都需要停掉整個服務,重新打包,部署這個應用的war包,各服務的部署升級等可能依賴其他服務,不夠靈活。特別是對於一個大型應用,我們不可能把所有內容都放在一個應用中。
3.3 微服務架構
所謂微服務架構,就是打破之前單體應用服務的架構方式,把每個功能元素獨立出來抽象成一個模組,不同的應用程式可能是不同的模組組合而成的,每個模組就稱為一個微服務,微服務間可以獨立地打包部署升級。
這樣做的好處是:
- 節省了呼叫資源;
- 每個微服務都是一個可替換的,可獨立升級的軟體程式碼。
有關微服務的文章部落格,可以參考:
- 原文地址:http://martinfowler.com/articles/microservices.html
- 翻譯:https://www.cnblogs.com/liuning8023/p/4493156.html
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文字給使用者呈現最終的網站頁面,流程如下:
Thymeleaf
是SpringBoot
推薦的模板引擎,此外FreeMarker
也是使用較多的模板引擎。
SpringBoot
使用Thymeleaf
模板引擎,需要引入Thymeleaf
的maven
依賴:
<!--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實現服務間的通訊呢?