Java面試題_第四階段


1.1 電商行業特點

1.分布式

  垂直拆分:根據功能模塊進行拆分

  水平拆分:根據業務層級進行拆分

2.高並發

     用戶單位時間內訪問服務器數量,是電商行業中面臨的主要問題

3.集群

  抗擊高兵發的有效手段,同時集群內部實現高可用

4.海量數據處理

  隨着公司數據的不斷積累.自身的數據量很龐大.如果高效的處理數據/分析

1.2 框架調用流程

 

1.3 EasyUI后台調用流程

 

1.4 分布式項目的設計思想

為了實現架構之間的松耦合,將項目根據分布式的思想進行拆分.

1.項目的垂直拆分

根據功能模塊的不同將項目進行拆分.

2.項目的水平拆分

在大型項目中,由於開發的人數眾多,項目復雜度高.為了保證項目開發的耦合性低.實現項目的水平拆分.

將一個大型項目根據層級模塊進行拆分.Controller項目/Service項目Mapper項目

項目創建時采用聚合項目的方式進行管理

 

1.5 分布式項目的jar包如何管理

將項目中用到公共的jar包使用服務支撐項目jt-parent進行添加,其他的項目只需要繼承jt-parent后獲取對應的jar包全部依賴.從而實現了jar包的統一管理

1.6 介紹一下通用Mapper

  1. 早期使用JDBC操作數據庫.該操作特別的繁瑣,並且所有的數據需要自己手動的封裝.
  2. JPA:java持久化的API(用面向對象的方式操作數據庫)思想
User user = new User(); setXXXX 
User.setId(1);
User.setName(tom);
工具API.insert(user);  JPA內部將對象自動轉化為sql語句
Insert into …….

  3.Haibernate框架.號稱是自動化的(ORM)

程序員只需要操作對象,從而完成了對數據庫的操作.

缺點:

  1. 做新增/刪除/修改會產生一些冗余的sql(出於安全性性考慮)
  2. 如果做多表關聯操作(CRUD) ,需要裝備配置文件,通過配置文件進行數據關聯設定.同時需要學習Hql(語句)
  3. 早期數據庫容量是有限,超過500萬后查詢效率開始變低.

4.Mybatis,優點:繼承ORM,擯棄了冗余的sql(自己手寫),

  5.通用Mapper插件基於mybaits效果,可以實現單表CRUD使用對象操作.(反射機制)

1.7 Nginx是什么,有什么作用?

Nginx (engine x) 是一個輕量級的是一個高性能的HTTP和反向代理服務器,其特點是占有內存少,並發能力強

主要是用來反向代理和實現負載均衡.

1.8 談一下反向代理和負載均衡

說明:

  1. Nginx首先需要監聽特定的域名.
  2. 當用戶根據域名進行資源訪問時.首先會訪問nginx
  3. 之后nginx代替請求者根據內部的配置文件,實現反向代理.將請求轉化為特定的請求路徑進行資源訪問.
  4. Nginx獲取資源后將數據返回給用戶.完成請求的正確的響應.

負載均衡:訪問量高時,可以讓服務器盡量分攤壓力,

實現策略:輪詢,權重,IP_HASH(一般不用)

1.9 Nginx的健康監測機制

當后台的服務器出現宕機的現象,當時nginx中的配置文件並沒有改變時,請求依然會發往故障的機器.需要人為的維護配置文件,這樣的操作不智能.那么采用健康檢測機制.可以實現故障的自動的遷移.

屬性介紹:

1.max_fails=1  當檢測服務器是否正常時,如果檢測失敗的次數達到規定的次數時,則斷定該服務器故障,在規定的時間周期內,不會將請求發往該機器.

2.fail_timeout=60s定義時鍾周期

 

1.10 Nginx如何保證請求參數不丟

nginx中添加請求頭的參數,表示每次請求時,攜帶請求者的請求頭信息,訪問服務器.

proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

1.11 數據庫數據如何備份(數據備份策略)

  1. 冷備份:定期將數據庫中的文件進行轉儲,定期進行數據備份.
  2. 熱備份:搭建數據庫主從結構,當主庫數據發生改變時,從庫根據主庫的二進制日志文件進行備份.
  3. 雙機熱備:數據庫互為主從,數據庫代理服務器對主庫進行心跳檢測,實現數據的高可用,為了防止主庫宕機后發生雪崩現象

1.12 數據庫壓力大時,怎么實現高可用

1.用數據庫代理服務器搭建數據庫的讀寫分離進行分流.讀取從庫數據,寫數據在主庫

可用的數據庫代理服務器有AmoebaMycat

由於大量的用戶的數據庫操作都需要通過數據庫來完成.造成數據庫負載過高.因為數據庫操作中查詢的操作占很大的比重.

2.數據庫實現雙機熱備.

1.13 數據庫的優化策略

  1. 優化sql語句(多表操作)  where 左連接 右連接 內連接

原則:盡可能根據主鍵查詢,盡可能少用關聯查詢.

  1. 創建索引(對經常查詢的數據創建索引)
  2. 添加緩存(Redis/MemCache)
  3. 定期進行數據轉儲(將一些查詢較少的數據保存到歷史表,讓當前表維護可控的數據量)
  4. 分庫分表(需要大量的數據庫服務器)

1.14 什么是Mycat

是一個數據庫中間件,實現讀寫分離,分庫分表和數據庫故障遷移.

1.15 什么是Redis,運行在哪里

開源的內存中的數據結構存儲系統,可以用做數據庫,緩存和消息中間件

基於C語言開發,運行時在內存中,運行速度很快

https://mp.weixin.qq.com/s/0Fqp2aGq7c_x_bEK9pOeeg

1.16 Redis中的數據持久化策略

如果使用時允許丟失部分數據(少量的)則使用RDB模式,它的效率高,也是redis默認的策略,如果不允許丟失數據則采用AOF模式,它的安全性高,但是效率較低.

1.17 Redis中的內存維護策略

問題:如果數據都存儲到redis,如果內存占滿了,redis如何維護?

解決方案:

  1. 動態的擴容redis節點(不科學)
  2. 為數據設定超時時間
  3. 動態的將不用的數據刪除.(LRU算法)

  算法介紹:

內存管理的一種頁面置換算法,對於在內存中但又不用的數據塊(內存塊)叫做LRU,操作系統會根據哪些數據屬於LRU而將其移出內存而騰出空間來加載另外的數據。

1.18 redis為什么要分片

特點:實現動態內存擴容

數據存儲機制:

 

1.19 Hash一致性

1.均衡性:盡可能均勻分片節點中的數據

2.單調性:實現數據的動態遷移

3.分散性:由於分布式原因,導致不能獲取全部節點信息,使得一個key有多個位置

4.負載:是分散性另一種表現形式.表現為一個位置有多個key

1.20 知道哨兵機制嗎,怎么實現的,實現了什么功能

功能:實現redis高可用

機制:心跳檢測

 

1.21 哨兵和分片的優缺點

優點:

  1. 分片可以使redis動態內存擴容.
  2. 分片可以將數據均勻的分配到不同的節點中,使數據分散保存.
  3. 哨兵可以實現redis高可用.

  缺點:

  1. 分片如果有一個節點出現宕機則整個分片都不能正常使用.
  2. 哨兵如果發生宕機現象,則影響整個redis服務.

升級:

  1. 使用多台redis實現內存空間的動態擴容.
  2. 實現在redis內存實現高可用(不再使用哨兵機制)使用組件(ruby)

搭建集群,實現分片和高可用的全部功能.

1.22 Redis集群

使用ruby工具創建集群.集群中全部的節點相互之間互相通訊.redis內部實現高可用.redis集群是分片和哨兵的集合體.

1.23 偽靜態技術

動態頁面不能被搜索引擎收錄.為了保證搜索引擎的友好性.則以.html的靜態頁面形式展現動態頁面數據

1.24 跨域問題

說明:www.jt.com調用manage.jt.com時訪問不成功.原因該操作是一個跨域請求.

 

瀏覽器不允許進行跨域請求.會將成功返回的數據進行攔截.不予顯示.一切出於安全性的考慮.

1.25 同源策略

規則:請求協議/域名/端口號是否相同,如果三者都一致,那么是同域訪問.(即同源策略)瀏覽器可以正常執行.除此之外的全部的請求都是跨域請求.

1.26 怎么解決跨域問題?

利用javascriptsrc屬性實現跨域.

客戶端定義回調函數 callback=hello

服務端程序封裝特定的JSON格式   callback(JSON)  執行回調函數

 

JSONP就是基於這個原理實現的.

JSONP(JSON with Padding)JSON的一種使用模式,可用於解決主流瀏覽器的跨域數據訪問的問題。由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的服務器溝通,而 HTML <script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析

 

1.27 JQuery中怎么使用JSONP

跨域的缺點:回調的函數需要提前定義.程序員自己定義.

解決方案采用jQuery中的JSONP實現跨域的請求.

語法:

        $.ajax({
            url:"http://manage.jt.com/web/testJSONP",
            type:"get",
            dataType:"jsonp",       //返回值的類型 JSONP必須添加否則不能回調 函數
            jsonp: "callback",   //指定參數名稱
            jsonpCallback: "hello",  //指定回調函數名稱
            success:function (data){
                alert(data.id);
                alert(data.name);
                //轉化為字符串使用
                //var obj = eval("("+data+")");
                //alert(obj.name);
            }    
        });

1.28 HttpClient

HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK java net包中已經提供了訪問 HTTP 協議的基本功能,但是對於大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,並且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus  HTMLUnit 都使用了 HttpClient。現在HttpClient最新版本為 HttpClient 4.5 (GA) 2015-09-11

總結:HttpClientjava為了遠程請求開發的http請求工具包.

1.29 HttpClientJSONP的區別

  1. JSONP是基於瀏覽器的,解決跨域問題的.httpClient是基於代碼.模擬http請求.獲取服務端的參數的,功能上類似,但是經過的環節不同.
  2. 安全性不同:JSONP的全部信息都可以通過瀏覽器進行監控.但是HttpClient瀏覽器不能監控.

  3.代碼調用層級不同:Jsonp需要調用服務端業務邏輯,最多3層,HttpClient需要調用5

適用場景:如果從服務端獲取數據,js可以直接解析.使用JSONP,如果服務端的程序的返回值,需要進一步處理.這時使用HttpClient

1.30 你的單點登錄是怎么調用的

流程圖:

 

原理:

實現步驟:

當用戶登陸時,通過nginx訪問jt-web中任意的服務器之后輸入用戶名和密碼訪問JT-SSO單點登錄服務器.

獲取用戶的登陸信息查詢數據庫,校驗用戶名和密碼是否正確.如果用戶名和密碼是正確的,將用戶信息轉化為JSON.之后生成加密的秘鑰TOKEN(MD5(鹽值+隨機數)).token:userJSON保存redis.並且將token信息返回給客戶端(jt-web).

Jt-web接收到服務端數據時首先校驗數據是否有效.如果數據准確無誤,token信息寫入到瀏覽器的Cookie(4K)

當用戶再次訪問jt-web,首先應該獲取用戶的Token信息,之后查詢redis緩存服務器獲取userJSON數據,之后將userJSON轉化為User對象進行使用.實現免密登錄.如果token數據為null,那么則讓用戶訪問登陸頁面.

1.31 同一線程內的數據怎么實現共享(ThreadLocal)

名稱:本地線程變量

作用:在同一線程內實現數據共享.

原理:

 

說明:ThreadLocal是線程安全的,在同一個線程內實現數據的共享.

注意:使用完成后,切記銷毀threadLocal對象,否則gc不能回收.導致JVM內存泄漏.

public class UserThreadLocal {
    //如果保存數據有多個,則使用Map集合
    private static ThreadLocal<User> userThread = new ThreadLocal<User>();
    public static void set(User user){
        userThread.set(user);
    }
    public static User get(){
        return userThread.get();
    }
    //線程銷毀方法
    public static void remove(){
        userThread.remove();
    }
}

 

1.32 如何實現的單點登錄SSO

問題:因為后台的服務器采用的是集群的部署方式,肯定有多台服務器.如果將用戶的登陸信息保存到服務器端,因為多個服務器之間不能共享session.所以相互之間不同實現Session共享.導致用戶頻繁登陸.

初級:使用Nginx提供的IP_Hash

高級:

  1. 當用戶登陸操作時,首選訪問時單點登錄服務器.進行登錄操作.
  2. 如果登錄正確.則生成用戶的秘鑰token.將用戶信息轉化為JSON串和token一起保存到redis緩存中.

3.token信息返回給客戶端.將數據保存到客戶端瀏覽器中的cookie.

4.當用戶進行其他操作需要用到用戶信息時,首先檢測Cookie中是否有token,第二步檢測redis中的數據是否為null.如果一切正確,則允許跳轉到指定頁面中.如果其中有一項有誤,則表示用戶登陸異常.讓用戶重新登陸.

 

1.33 zk如果宕機后,消費者能否正確消費?????

說明:

答案:可以

因為zk會動態的向客戶端更新服務列表信息.zk宕機后,由於之前已經同步了zk的服務列表信息,所以客戶端可以按照自己已經緩存的清單進行訪問.如果在這個期間服務端程序發現宕機現象,那么則訪問故障機時由於不能通信,則等待超時時間,則訪問下一台服務器.

如果這時,所有的服務端程序都宕機,則整個服務陷入癱瘓.

1.34 微服務治理方案(ZooKeeper)

說明:增加服務器或者減少服務器都是自動完成

 

業務邏輯說明:

  1. 當服務的提供者啟動時,會將服務的名稱:IP:端口會寫入注冊中心.
  2. 注冊中心內部會維護服務列表
  3. 當消費者需要訪問服務時,需要先訪問注冊中心獲取服務列表信息.之后將服務列表保存到本地緩存中.方便后續的訪問.在客戶端內部有負載均衡的算法,篩選出一台服務器,之后進行訪問.
  4. 如果后台服務器出現宕機現象.這時注冊中心通過心跳檢測的方式判斷服務器是否宕機.如果服務器宕機則會將該服務器信息從服務列表中刪除.之后將新的服務列表發送消費者(客戶端)進行更新.

1.35 你怎么理解SOA(面向服務)

面向服務的架構SOA是一個組件模型,它將應用程序的不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的,它應該獨立於實現服務的硬件平台、操作系統和編程語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行交互。

 

1.36 知道RPC協議嗎

總結:RPC調用的規則可以傳輸java對象.底層實現時將數據轉化流,並且該流經過加密處理.並且rpc內部使用UTF-8編碼格式

要求:傳輸的java對象必須序列化

 

1.37 什么是Dubbo框架

Dubbo [1]  阿里巴巴公司開源的一個高性能優秀的服務框架(SOA),使得應用可通過高性能的RPC實現服務的輸出和輸入功能可以和Spring框架無縫集成

1.38 NginxZK的區別

 Nginx:

  1. Nginx主要是為了反向代理(Http)
  2. 負載均衡
  3. Nginx主要搭建在公司網關服務器上

Zk:通過RPC進行遠程方法調用,是服務端程序

主要作用是實現服務端的高可用.搭建在內網中.

1.39 知道什么是消息隊列嗎,並說出幾種常用的

消息隊列可以緩解服務器的訪問壓力,請求在在訪問服務器時,先寫入消息隊列中,可以實現請求的異步操作,起到平峰削骨的作用

但是缺點是消耗了用戶的實際等待時間.

常見的消息隊列產品有activeMQ(apache),RabbitMQ(愛立信的)

1.40 消息隊列有幾種工作模式

1.簡單模式2.工作模式3.發布訂閱模式4.路由模式

5.主題模式 6.RPC模式

1.41 倒排索引

倒排索引源於實際應用中需要根據屬性的來查找記錄。這種索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的地址。由於不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置,因而稱為倒排索引(inverted index)。帶有倒排索引的文件我們稱為倒排索引文件,簡稱倒排文件(inverted file)

 

1.42 Solr介紹/ES

Solr是一個獨立的企業級搜索應用服務器,它對外提供類似於Web-serviceAPI接口。用戶可以通過http請求,向搜索引擎服務器提交一定格式的XML文件,生成索引;也可以通過Http Get操作提出查找請求,並得到XML格式的返回結果.

基於Lucene的全文搜索服務器。同時對其進行了擴展,提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴展並對查詢性能進行了優化,並且提供了一個完善的功能管理界面,是一款非常優秀的全文搜索引擎

特點:

  1. solr可以根據數據庫表自動生成索引文件.
  2. Solr可以動態的定期自動更新索引(對更新的數據進行索引的修改)

1.43 Docker介紹

 

Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的Linux機器上,也可以實現虛擬化,容器是完全使用沙箱機制,相互之間不會有任何接口。

一個完整的Docker有以下幾個部分組成:

DockerClient客戶端        

Docker Daemon守護進程   客戶端和Docker容器交互的媒介

Docker Image鏡像        應用程序的模板

DockerContainer容器     啟動后的應用程序

1.44 Docker調用原理

 

模塊描述:

1.docker

Docker客戶端程序

2.daemon

一般在宿主主機的后台運行,作為服務端接收客戶端的請求,並且處理這些請求(創建/運行/分發容器).

    客戶端和服務器既可以運行在一個主機中,也可以通過socket/RESTful來實現通信

3.image:

Docker中的鏡像文件, 為應用程序的模板,一般都是只讀的不允許修改

Docker的鏡像文件來源有兩種:

  1.Docker官網中的鏡像文件

  2.本地的鏡像文件

 

4.Container:

Docker容器,通過image鏡像創建容器后,在容器中運行應用程序(類似於new一個對象)

5.Repository:

管理鏡像的倉庫,類似於Maven倉庫管理jar包文件

調用原理:

1.Docker客戶端通過Daemon請求創建Docker容器

2.Daemon接收請求后,Repository中查找需要的Image鏡像文件

3.找到對應的鏡像文件后,創建Docker容器

4.調用容器完成具體任務(redis/nginx/tomcat/mysql)

1.45 Docker鏡像拉取過程

 

1.當客戶端獲取鏡像文件時,會向服務器發起請求.

2.Docker引擎首先會檢查本地是否含有鏡像文件,如果沒有則會聯網下載鏡像文件

3.從共有雲中獲取Image鏡像文件后,保存到本地

4.當用戶需要使用該應用是,通過鏡像文件創建容器,為用戶提供服務

Dockerfile

1.46 京淘項目人員分配

開發周期:開發4個月但是不停的更新迭代

  購物車商品展現頁面 商品規格

  評價系統

  訂單物流系統  京東物流/調用菜鳥裹裹 調用第三方接口獲取數據進行展現(http)

  支付系統:銀行接口/第三方支付 http

  推薦系統:….

產品經理:3人,確定需求以及給出產品原型圖

項目經理:1人,項目管理。

前端團隊:5人,根據產品經理給出的原型制作靜態頁面。

后端團隊:20人,實現產品功能。

測試團隊:5人,測試所有的功能。2 3 腳本 shell

運維團隊:3人,項目的發布以及維護。

1.47 日活量/並發量

 

日活量:200萬
並發量:1500-2300左右
單點並發壓力 18台tomcat服務器
服務器划分
Mysql                        2
Mycat服務器                   1
Solr                         3
Redis                        3
圖片服務器                     2
Nginx                        2
注冊中心                      3
RabbitMQ                     2
18台服務器

Jt-manage                    5
Jt-web                       10
Jt-sso                       3
Jt-cart                      5
Jt-order                     5
Jt-search                    5
33台tomcat

1.48 SpringBoot全新開發方式特點

創建獨立的Spring應用程序

嵌入的Tomcat,無需部署WAR文件

簡化Maven配置

自動配置Spring

l 提供生產就緒型功能,如指標,健康檢查和外部配置

1.49 什么是微服務架構?

“微服務”源於Martin Fowler的博文 Microservices

Martin說:微服務是系統架構上的一種設計風格,它的主旨是將一個原本獨立的系統拆成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間通過基於HTTPRESTful API進行通信協作。被拆分成的每一個小型服務都圍繞着系統中的某一項或者某些耦合度較高的業務功能進行構建,並且每個服務都維護着自身的數據存儲、業務開發、自動化測試案例以及獨立部署機制。由於有了輕量級的通信協作基礎,所以這些微服務可以使用不同的語言來編寫。

1.50 核心功能

l configuration management 配置中心

l service discovery 服務發現

l circuit breakers 斷路器

l intelligent routing 智能路由

l micro-proxy 微代理

l control bus 控制總線

l one-time tokens 一次性令牌

l global locks 全局鎖

l leadership election 選舉算法

l distributed sessions 分布式會話

l cluster state 集群狀態

1.51 核心組件架構圖

 

1.52 拓展:CAP定理

 

CAP原則又稱CAP定理,指的是在一個分布式系統中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。它是分布式系統中最核心最重要的理論。

分布式系統的CAP理論:理論首先把分布式系統中的三個特性進行了如下歸納:

一致性(C:在分布式系統中的所有數據備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的數據副本)

可用性(A:在集群中一部分節點故障后,集群整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)

分區容錯性(P:以實際效果而言,分區相當於對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須就當前操作在CA之間做出選擇。

CAP理論就是說在分布式系統中,最多只能實現上面的兩點。而由於當前的網絡硬件肯定會出現延遲丟包等問題,所以分區容忍性是我們必須需要實現的。所以我們只能在一致性和可用性之間進行權衡,要么選擇CP要么選擇AP,沒有分布式系統能同時保證這三點。

1.53 ZooKeeperEureka對比

Eureka本身是Netflix開源的一款提供服務注冊和發現的產品,並且提供了相應的Java封裝。在它的實現中,節點之間相互平等,部分注冊中心的節點掛掉也不會對集群造成影響,即使集群只剩一個節點存活,也可以正常提供發現服務哪怕是所有的服務注冊節點都掛了,Eureka Clients(客戶端)上也會緩存服務調用的信息。這就保證了我們微服務之間的互相調用足夠健壯。

Zookeeper主要為大型分布式計算提供開源的分布式配置服務、同步服務和命名注冊。曾經是Hadoop項目中的一個子項目,用來控制集群中的數據,目前已升級為獨立的頂級項目。很多場景下也用它作為Service發現服務解決方案。

對比

根據著名的CAP定理(C-數據一致性;A-服務可用性;P-服務對網絡分區故障的容錯性CAP這三個特性在任何分布式系統中不能同時滿足,最多同時滿足兩個CP或者AP)。

ZooKeeper

Zookeeper是基於CP來設計的,即任何時刻對Zookeeper的訪問請求能得到一致的數據結果,同時系統對網絡分割具備容錯性,但是它不能保證每次服務請求的可用性。從實際情況來分析,在使用Zookeeper獲取服務列表時,如果zookeeper正在選主,或者Zookeeper集群中半數以上機器不可用,那么將無法獲得數據。所以說,Zookeeper不能保證服務可用性。

誠然,在大多數分布式環境中,尤其是涉及到數據存儲的場景,數據一致性應該是首先被保證的,這也是zookeeper設計成CP的原因。但是對於服務發現場景來說,情況就不太一樣了:針對同一個服務,即使注冊中心的不同節點保存的服務提供者信息不盡相同,也並不會造成災難性的后果。因為對於服務消費者來說,能消費才是最重要的——拿到可能不正確的服務實例信息后嘗試消費一下,也好過因為無法獲取實例信息而不去消費。(嘗試一下可以快速失敗,之后可以更新配置並重試)所以,對於服務發現而言,可用性比數據一致性更加重要——AP勝過CP 

Eureka

Spring Cloud Netflix在設計Eureka時遵守的就是AP原則。Eureka Server也可以運行多個實例來構建集群,解決單點問題,但不同於ZooKeeper的選舉leader的過程,Eureka Server采用的是Peer to Peer對等通信這是一種去中心化的架構,無master/slave區分,每一個Peer都是對等的。在這種架構中,節點通過彼此互相注冊來提高可用性,每個節點需要添加一個或多個有效的serviceUrl指向其他節點。每個節點都可被視為其他節點的副本。

如果某台Eureka Server宕機,Eureka Client的請求會自動切換到新的Eureka Server節點,當宕機的服務器重新恢復后,Eureka會再次將其納入到服務器集群管理之中。當節點開始接受客戶端請求時,所有的操作都會進行replicateToPeer(節點間復制)操作,將請求復制到其他Eureka Server當前所知的所有節點中。

一個新的Eureka Server節點啟動后,會首先嘗試從鄰近節點獲取所有實例注冊表信息,完成初始化。Eureka Server通過getEurekaServiceUrls()方法獲取所有的節點,並且會通過心跳續約的方式定期更新。默認配置下,如果Eureka Server在一定時間內沒有接收到某個服務實例的心跳,Eureka Server將會注銷該實例(默認為90秒,通過eureka.instance.lease-expiration-duration-in-seconds配置)。Eureka Server節點在短時間內丟失過多的心跳時(比如發生了網絡分區故障),那么這個節點就會進入自我保護模式

 

總結

ZooKeeper基於CP,不保證高可用,如果zookeeper正在選主,或者Zookeeper集群中半數以上機器不可用,那么將無法獲得數據。Eureka基於AP,能保證高可用,即使所有機器都掛了,也能拿到本地緩存的數據。作為注冊中心,其實配置是不經常變動的只有發版(發布新的版本)和機器出故障時會變對於不經常變動的配置來說,CP是不合適的,而AP在遇到問題時可以用犧牲一致性來保證可用性,既返回舊數據,緩存數據

所以理論上Eureka是更適合作注冊中心。而現實環境中大部分項目可能會使用ZooKeeper,那是因為集群不夠大,並且基本不會遇到用做注冊中心的機器一半以上都掛了的情況。所以實際上也沒什么大問題。

1.54 拓展:分布式對關系型數據庫的沖擊

對於web網站來說,關系數據庫的很多主要特性卻往往無用武之地

數據庫事務一致性需求

很多web實時系統並不要求嚴格的數據庫事務,對讀一致性的要求很低,有些場合對寫一致性要求並不高。允許實現最終一致性

l 數據庫的寫實時性和讀實時性需求

對關系數據庫來說,插入一條數據之后立刻查詢,是肯定可以讀出來這條數據的,但是對於很多web應用來說,並不要求這么高的實時性,比方說發一條消息之后,過幾秒乃至十幾秒之后,我的訂閱者才看到這條動態是完全可以接受的。如:MQ消息隊列機制,意義,可以解決瞬時的高並發,消峰填谷作用。

對復雜的SQL查詢,特別是多表關聯查詢的需求

任何大數據量的web系統,都非常忌諱多個大表的關聯查詢,以及復雜的數據分析類型的報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免了這種情況的產生。往往更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。

SNS:全稱Social Networking Services,專指社交網絡服務,包括了社交軟件和社交網站。例如:臉譜facebook、騰訊QQ、微信等。

1.55 自我保護模式

 

什么是自我保護模式?默認配置下,如果Eureka Server每分鍾收到心跳續約的數量低於一個閾值instance的數量(60/每個instance的心跳間隔秒數)自我保護系數),並且持續15分鍾,就會觸發自我保護。在自我保護模式中,Eureka Server會保護服務注冊表中的信息,不再注銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式。它的設計哲學前面提到過,那就是寧可保留錯誤的服務注冊信息,也不盲目注銷任何可能健康的服務實例。該模式可以通過eureka.server.enable-self-preservation = false來禁用,同時eureka.instance.lease-renewal-interval-in-seconds可以用來更改心跳間隔。

1.56 Ribbon

Feignnetflix開發的聲明式、模板化的http客戶端,在使用時就像調用本地(服務消費者自己)的方法一般,幫助我們更加優雅的調用服務提供者的APIFeign自身支持springMVC,還整合了EurekaRibbon,極大的簡化了Feign的使用。就整合Euraka而言,只需和普通的服務配置Eureka server的信息即可。整合Ribbon,就意味着不再需要通過標注@LoadBalanced的實例化后的RestTemplate去調用服務提供者方法了。Feign只需通過簡單的定義一個接口即可實現負載均衡。

nginx不同,它是客戶端側負載均衡。

 

1.57 負載均衡策略

常見提供的負載均衡算法有三種:

l 第一種也是默認為輪詢

第二種為random隨機

l 第三種為WeightedResponseTimeRule,響應時間

1.58 Feigh概念

Feigh是一個聲明式web服務客戶端。它能讓開發web服務變得容易。使用Feign需要創建一個接口並注解它。它擁有包括Feign注解和JAX-RS注解的可插拔支持。它還支持可插拔的編碼器和解碼器。Spring Cloud擁有Spring MVC支持,並使用Spring Web中默認同樣的HttpMessageConverters。在使用Feign時,Spring Cloud集成了RibbonEureka來提供負載均衡的HTTP客戶端。

總結:Feign簡化HttpClient開發,封裝了JAX-RSSprinMVC的注解,學習成本很低。

1.59 微服務設計引發新的問題

微服務的設計,服務分散在多個服務器上,服務之間互相調用,要調用的服務由於跨網絡跨服務器調用,響應速度明顯比傳統項目單機調用慢很多,甚至由於網絡涌動的不穩定的現象發生導致調用超時;還有類似級聯失敗、雪崩效應(依賴的基礎服務宕機,關聯的服務導致失敗甚至宕機,就像滾雪球一樣層層失敗。)

如何解決這類新的問題呢?傳統的機制就是超時機制。

1.60 熔斷機制

家里電表都有個斷路器(俗稱電閘),當使用的電器很多,用電巨大(例如功率過大、短路等),當電流過載時,電路就會升溫,甚至燒斷電路,引起火災。有了這個斷路器,我們及時拉閘,就不會造成嚴重后果了。

斷路器可以實現快速失敗,如果它在一段時間內檢測到許多失敗,如超時,就會強迫其以后的多個調用快速失敗,不再請求所依賴的服務,從而防止應用程序不斷地嘗試執行可能會失敗的操作,這樣應用程序可以繼續執行而不用等待修正錯誤,或者浪費CPU時間去等待長時間的超時。斷路器也可以使應用程序能夠診斷錯誤是否已經修正,如果已經修正,應用程序會再次嘗試調用操作。

斷路器模式像是那些容易導致錯誤的操作的一種代理。這種代理能夠記錄最近調用發生錯誤的次數,然后決定使用允許操作繼續,或者立即返回錯誤。

 

ending...

 


免責聲明!

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



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