Spring-Cloud-Netflix-系統架構


系統架構

概述

隨着互聯網的發展,網站應用的規模不斷擴大。需求的激增,帶來的是技術上的壓力。 系統架構也因此也不斷的演進、升級、迭代。
從單一應用,到垂直拆分,到分布式服務,到SOA,以及現在火熱的微服務架構

集中式架構

概述

當網站流量很小時,只需一個應用 將所有功能都部署在一起,以減少部署節點和成本 從頭到尾就一個工程,部署的時候 , 只需要打成一個war包

特點

  1. 代碼耦合,開發維護困難
  2. 無法針對不同模塊進行針對性優化
  3. 無法水平擴展
  4. 單點容錯率低,並發能力差

垂直拆分

概述

當訪問量逐漸增大,單一應用無法滿足需求,此時為了應對更高的並發和業務需求,我們根據業務功能對系統進行拆分

特點

  1. 系統拆分實現了流量分擔,解決了並發問題
  2. 可以針對不同模塊進行優化
  3. 方便水平擴展,負載均衡,容錯率提高
  4. 系統間相互獨立,會有很多重復開發工作,影響開發效率

系統架構分類

微服務

微服務就是把原本臃腫的一個項目的所有模塊拆分開來並做到互相沒有關聯,甚至可以不使用同一個數據庫

微服務的特點:

  1. 單一職責微服務中每一個服務都對應唯一的業務能力,做到單一職責
  2. 服務拆分粒度很小例如一個用戶管理就可以作為一個服務
  3. 面向服務面向服務是說每個服務都要對外暴露服務接口API,並不關心服務的技術實現,做到與平台和語言無關,不限定用什么技術實現,只要提供Rest的接口即可
  4. 自治自治是說服務間互相獨立,互不干擾

分布式服務:

概述:

當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務
分布式,就是將偌大的系統划分為多個模塊(這一點和微服務很像)部署到不同機器上 因為一台機器可能承受不了這么大的壓力
各個模塊通過接口進行數據交互,其實 分布式也是一種微服務。

特點:

  1. 將基礎服務進行了抽取,系統間相互調用,提高了代碼復用和開發效率
  2. 系統間耦合度變高,調用關系錯綜復雜,難以維護

微服務和分布式的區別:

微服務與分布式都是把模塊拆分開來變為獨立的單元,提供接口來調用

他們本質的區別在於目標的不同:

  1. 分布式的目標是:一台機器承受不了的,或者是成本問題 , 不得不使用多台機器來完成服務的部署
  2. 微服務的目標 :只是讓各個模塊拆分開來,不會被互相影響,比如模塊的升級亦或是出現BUG等等...

微服務要面臨的問題:

  1. 服務治理(SOA)
    概述:

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

問題:

服務越來越多,需要管理每個服務的地址 調用關系錯綜復雜,難以理清依賴關系 服務過多,服務狀態難以管理,無法根據服務情況動態管理

服務治理要做什么:

服務注冊中心,實現服務自動注冊和發現,無需人為記錄服務地址 服務自動訂閱,服務列表自動推送,服務調用透明化,無需關心依賴關系
動態監控服務狀態監控報告,人為控制服務狀態

  1. 監聽服務有沒有宕機:部署很多服務后 ,如果監聽到服務有沒有宕機
  2. 負載均衡:一個服務吃不消,要部署多個服務,部署的多個服務均衡調用
  3. 熔斷:服務出現了問題,不能讓程序卡在那里
  4. 限流:限流就是針對超過預期的流量,通過預先設定的限流規則選擇性的對某些請求進行限流“熔斷”
  5. 降級:當服務器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心交易正常運作或高效運作
  6. 網關:統一管理API的一個網絡關口、通道,是整個微服務平台所有請求的唯一入口

springClould是什么

微服務只是一種項目的架構方式,或者說是一種概念
Spring-Cloud便是對這種技術的實現
對微服務面臨的問題進行統一的封裝處理

遠程調用方式:

RPC:

  1. Remote Produce Call遠程過程調用,類似的還有RMI。自定義數據格式,基於原生TCP通信,速度快,效率高
  2. 早期的webservice,現在熱門的dubbo,都是RPC的典型
  3. 限制了平台,只能是Java平台

Http:

  1. http其實是一種網絡傳輸協議,基於TCP,規定了數據傳輸的格式
  2. 現在客戶端瀏覽器與服務端通信基本都是采用Http協議。也可以用來進行遠程服務調用。缺點是消息封裝臃腫
  3. 不限制平台

模擬微服務:

  1. 創建一個普通父工程,刪除src目錄,保留pom文件
    在這里插入圖片描述
    在這里插入圖片描述
  2. 在父工程當中添加springboot依賴
    在這里插入圖片描述
    代碼:
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.3.RELEASE</version>
    </parent>
  1. 創建子模塊user
    在這里插入圖片描述
    在這里插入圖片描述
  2. 添加springboot-web啟動器依賴
    在這里插入圖片描述
    代碼:
	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  1. 創建user工程啟動類UserApplication
    在這里插入圖片描述
    代碼:
@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}

  1. 創建util包,把ResponseResult工具類復制到該包中
    在這里插入圖片描述
    代碼:
public class ResponseResult extends HashMap {
    public static String SUCCESS_CODE = "200";
    public static String ERROR_CODE = "500";
    public static String DATA_KEY = "data";
    public static String MSG_KEY = "msg";

    private ResponseResult() {
    }

    public ResponseResult set(String key, Object object) {
        super.put(key, object);
        return this;
    }

    private static ResponseResult newResponseResult() {
        return new ResponseResult();
    }

    public static ResponseResult success() {
        return ResponseResult.newResponseResult()
                .set("code", ResponseResult.SUCCESS_CODE)
                .set(ResponseResult.MSG_KEY, "操作成功");
    }

    public static ResponseResult success(String msg) {

        return ResponseResult.newResponseResult()
                .set("code", ResponseResult.SUCCESS_CODE)
                .set(ResponseResult.MSG_KEY, msg);
    }

    public static ResponseResult success(String msg, Object object) {

        return ResponseResult.newResponseResult()
                .set("code", ResponseResult.SUCCESS_CODE)
                .set(ResponseResult.MSG_KEY, msg)
                .set(ResponseResult.DATA_KEY, object);
    }

    public ResponseResult data(Object obj) {
        return this.set("data", obj);
    }

    public static ResponseResult error() {
        return ResponseResult.newResponseResult()
                .set(ResponseResult.MSG_KEY, "操作失敗")
                .set("code", ResponseResult.ERROR_CODE);
    }

    public static ResponseResult error(String msg) {
        return ResponseResult.newResponseResult()
                .set(ResponseResult.MSG_KEY, msg)
                .set("code", ResponseResult.ERROR_CODE);
    }

    public static ResponseResult error(String msg, Object object) {
        return ResponseResult.newResponseResult()
                .set(ResponseResult.MSG_KEY, msg)
                .set(ResponseResult.DATA_KEY, object)
                .set("code", ResponseResult.ERROR_CODE);
    }

}
  1. 創建子包controller,在controller當中創建UserController
    在這里插入圖片描述
    代碼:
@RestController
public class UserController {
    @RequestMapping("/getUser.do")
    public ResponseResult getUser() {
        return ResponseResult.success("返回成功","myUser");
    }
}
  1. 在resources目錄下創建application.yml
    在這里插入圖片描述
  2. 啟動訪問http://localhost:5000/getUser.do
    10.
  3. 創建子模塊goods
    在這里插入圖片描述
  4. 配置和user一樣,修改server-port端口為:5001
    在這里插入圖片描述
    在這里插入圖片描述
  5. 啟動訪問http://localhost:5001/getGoods.do
    在這里插入圖片描述
  6. user工程調用goods工程當中的接口
    在UserApplication中添加RestTemplate的Bean
    在這里插入圖片描述
    代碼:
 @Bean
    public RestTemplate restTemplate(){
        return  new RestTemplate();
    }

在user工程的UserController當中注入restTemplate
在這里插入圖片描述
通過restTemplate實現工程之間的接口調用
在這里插入圖片描述
同時運行兩個工程, 訪問http://localhost:5000/getGoods.do
在這里插入圖片描述
以上操作就實現了兩個工程之間的調用

使用nginx實現集群搭建

  1. 下載nginx 網址:nginx下載地址
    在這里插入圖片描述
    下載后解壓:注意解壓目錄不要帶有中文
  2. 創建一個新的goods1工程 和goods一模一樣 只需要改端口號即可,用於搭建集群。
    在這里插入圖片描述
  3. 修改nginx的配置文件
    在這里插入圖片描述
    把之前的server的代碼刪掉,替換成這樣
    在這里插入圖片描述
    代碼:
  upstream mServer {
		server localhost:5001;
		server localhost:5002;
	}
	
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
	    proxy_pass http://mServer;
        }
  1. 配置完成后啟動nginx.exe
    在這里插入圖片描述
    啟動會一閃而過 屬於正常情況

  2. 把user中調用方的端口號改為80
    在這里插入圖片描述

  3. 啟動user,goods,goods1 訪問user的地址:http://localhost:5000/getGoods.do
    在這里插入圖片描述
    在這里插入圖片描述
    會發現每次刷新訪問,都會返回兩個不同的工程的controller,完成集群的搭建。

存在問題, 如果其中的一個服務停止了, 當訪問的時候 , 會出現有時會很慢的情況
解決方案:用到SpringCloud的Eureka注冊中心來管理我們的服務
在這里插入圖片描述
下次更新 Spring-Cloud-Netflix-Eureka的使用方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM