互聯網面試知識技術總結(javacore、jvm、redis、kafka、zookeeper、mysql、hystrix)-第三章

39,mybatis 一級緩存和二級緩存 1,一級緩存是SqlSession級別的緩存。在操做數據庫時須要構造sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不一樣的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。若是中間sqlSession去執行commit操做(執行插入、更新、刪除),則會清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。我的認爲一級緩存不是線程安全的,對於同一行數據,另一個線程寫入數據(不使用mybatis組件),會致使session數據沒法正常更新。   2,二級緩存是mapper級別的緩存,多個SqlSession去操做同一個Mapper的sql語句,多個SqlSession能夠共用二級緩存,二級緩存是跨SqlSession的。 3,二級緩存默認是不開啓的。html

40, MySQL 中的行級鎖、表級鎖和頁級鎖前端

InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,若是加排他鎖可使用select ...for update語句,加共享鎖可使用select ... lock in share mode語句。因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select ...from...查詢數據,由於普通查詢沒有任何鎖機制。java

在數據庫的鎖機制中,能夠按照鎖的粒度把數據庫鎖分爲行級鎖(InnoDB引擎)、表級鎖(MyISAM引擎)和頁級鎖(BDB引擎)。 行級鎖:MySQL中鎖定粒度最細的一種鎖,表示只針對當前操做的行進行加鎖。行級鎖能大大減小數據庫操做的衝突,其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分爲共享鎖和排他鎖。 特色:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。node

表級鎖:MySQL中鎖定粒度最大的一種鎖,表示對當前操做的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MyISAM與InnoDB 都支持表級鎖定。表級鎖定分爲表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。 特色:開銷小,加鎖快,不會出現死鎖;鎖定粒度大,發出鎖衝突的機率最高,併發度最低。mysql

頁級鎖:MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以,採起了折衷的頁級鎖,一次鎖定相鄰的一組記錄。BDB支持頁級鎖。 特色:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常。web

MySQL 經常使用存儲引擎的鎖機制 MyISAM和Memory採用表級鎖(table-level locking) BDB採用頁級鎖(page-level locking)或表級鎖,默認爲頁級鎖; InnoDB支持行級鎖(row-level locking)和表級鎖,默認爲行級鎖。面試

在InnoDB 引擎中既支持行鎖也支持表鎖,那麼何時會鎖住整張表?何時只鎖住一行呢? InnoDB 行鎖是經過給索引上的索引項加鎖來實現的,InnoDB行鎖實現的特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖。 在實際應用中,要特別注意 InnoDB 行鎖的這一特性,否則的話,可能致使大量的鎖衝突,從而影響併發性能。 在不經過索引條件查詢的時候,InnoDB 確實使用的是表鎖,而不是行鎖redis

行級鎖又分共享鎖和排他鎖。     共享鎖:       名詞解釋:共享鎖又叫作讀鎖,全部的事務只能對其進行讀操做不能寫操做,加上共享鎖後在事務結束以前其餘事務只能再加共享鎖,除此以外其餘任何類型的鎖都不能再加了。       用法:SELECT id FROM table WHERE id in(1,2) LOCK IN SHARE MODE 結果集的數據都會加共享鎖     排他鎖:       名詞解釋:若某個事物對某一行加上了排他鎖,只能這個事務對其進行讀寫,在此事務結束以前,其餘事務不能對其進行加任何鎖,其餘進程能夠讀取,不能進行寫操做,需等待其釋放。       用法:SELECT id FROM mk_user WHERE id=1 FOR UPDATE算法

行級鎖與死鎖 MyISAM中是不會產生死鎖的,由於MyISAM老是一次性得到所需的所有鎖,要麼所有知足,要麼所有等待。而在InnoDB 中,鎖是逐步得到的,就形成了死鎖的可能。 在 MySQL 中,行級鎖並非直接鎖記錄,而是鎖索引。索引分爲主鍵索引和非主鍵索引兩種,若是一條 SQL 語句操做了主鍵索引,MySQL 就會鎖定這條主鍵索引;若是一條 SQL 語句操做了非主鍵索引,MySQL 就會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。 在進行UPDATE、DELETE操做時,MySQL 不只鎖定WHERE條件掃描過的全部索引記錄,並且會鎖定相鄰的鍵值,即所謂的next-key locking 當兩個事務同時執行,一個鎖住了主鍵索引,在等待其餘相關索引;另外一個鎖定了非主鍵索引,在等待主鍵索引。這樣就會發生死鎖。 發生死鎖後,InnoDB通常均可以檢測到,並使一個事務釋放鎖回退,另外一個獲取鎖完成事務。spring

避免死鎖的方法 <1>若是不一樣程序會併發存取多個表,儘可能約定以相同的順序訪問表,能夠大大下降發生死鎖的可能性; <2>在同一個事務中,儘量作到一次鎖定所須要的全部資源,減小死鎖產生機率; <3>對於很是容易產生死鎖的業務部分,能夠嘗試使用升級鎖定顆粒度,經過表級鎖定來減小死鎖產生的機率。

行鎖優化 1 儘量讓全部數據檢索都經過索引來完成,避免無索引行或索引失效致使行鎖升級爲表鎖。 2 儘量避免間隙鎖帶來的性能降低,減小或使用合理的檢索範圍。 3 儘量減小事務的粒度,好比控制事務大小,而從減小鎖定資源量和時間長度,從而減小鎖的競爭等,提供性能。 4 儘量低級別事務隔離,隔離級別越高,併發的處理能力越低。

參考:blog.csdn.net/qq_35246620… 41,樂觀鎖和悲觀鎖 悲觀鎖 老是假設最壞的狀況,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖(共享資源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程)。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。Java中synchronized和ReentrantLock等獨佔鎖就是悲觀鎖思想的實現。

樂觀鎖 老是假設最好的狀況,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可使用版本號機制和CAS算法實現。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量,像數據庫提供的相似於write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現方式CAS實現的。

兩種鎖的使用場景 從上面對兩種鎖的介紹,咱們知道兩種鎖各有優缺點,不可認爲一種好於另外一種,像樂觀鎖適用於寫比較少的狀況下(多讀場景),即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是是多寫的狀況,通常會常常產生衝突,這就會致使上層應用會不斷的進行retry,這樣反卻是下降了性能,因此通常多寫的場景下用悲觀鎖就比較合適。

42,索引失效   1.若是條件中有or,即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由)   要想使用or,又想讓索引生效,只能將or條件中的每一個列都加上索引   2.對於多列索引,不是使用的第一部分,則不會使用索引(使用組合索引沒有符合最左原則,致使實際沒能真實使用索引)   3.like查詢以%開頭   4.若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引   5.若是mysql估計使用全表掃描要比使用索引快,則不使用索引 6.索引沒法存儲null值,所以索引中有null,查詢時,採用is null條件時,不能利用到索引,只能全表掃描。 7.not in ,not exist 參考:www.cnblogs.com/shynshyn/p/…

41.內存映射技術 內存映射文件都知道,它比傳統的IO讀寫數據快不少,那麼,它爲何會這麼快,從代碼層面上來看,從硬盤上將文件讀入內存,都是要通過數據拷貝,而且數據拷貝操做是由文件系統和硬件驅動實現的,理論上來講,拷貝數據的效率是一 樣的。其實,緣由是read()是系統調用,其中進行了數據 拷貝,它首先將文件內容從硬盤拷貝到內核空間的一個緩衝區,如圖2中過程1,而後再將這些數據拷貝到用戶空間,如圖2中過程2,在這個過程當中,實際上完成 了兩次數據拷貝 ;而mmap()也是系統調用,如前所述,mmap()中沒有進行數據拷貝,真正的數據拷貝是在缺頁中斷處理時進行的,因爲mmap()將文件直接映射到用戶空間,因此中斷處理函數根據這個映射關係,直接將文件從硬盤拷貝到用戶空間,只進行了 一次數據拷貝 。所以,內存映射的效率要比read/write效率高(通過測試,內存映射技術比常規的io讀取,速度快上6倍左右) (blog.csdn.net/whoamiyang/…

JAVA NIO之淺談內存映射文件原理與DirectMemory 在傳統的文件IO操做中,咱們都是調用操做系統提供的底層標準IO系統調用函數 read()、write() ,此時調用此函數的進程(在JAVA中即java進程)由當前的用戶態切換到內核態,而後OS的內核代碼負責將相應的文件數據讀取到內核的IO緩衝區,而後再把數據從內核IO緩衝區拷貝到進程的私有地址空間中去,這樣便完成了一次IO操做。至於爲何要畫蛇添足搞一個內核IO緩衝區把本來只需一次拷貝數據的事情搞成須要2次數據拷貝呢? 我想學過操做系統或者計算機系統結構的人都知道,這麼作是爲了減小磁盤的IO操做,爲了提升性能而考慮的,由於咱們的程序訪問通常都帶有局部性,也就是所謂的局部性原理,在這裏主要是指的空間局部性,即咱們訪問了文件的某一段數據,那麼接下去極可能還會訪問接下去的一段數據,因爲磁盤IO操做的速度比直接訪問內存慢了好幾個數量級,因此OS根據局部性原理會在一次 read()系統調用過程當中預讀更多的文件數據緩存在內核IO緩衝區中,當繼續訪問的文件數據在緩衝區中時便直接拷貝數據到進程私有空間,避免了再次的低效率磁盤IO操做(其實是預讀機制)

www.cnblogs.com/lyftest/p/6…

42,kafka

典型的kafka集羣中包含若干producer(能夠是web前端產生的page view,或者是服務器日誌,系統CPU、memory等),若干broker(Kafka支持水平擴展,通常broker數量越多,集羣吞吐率越高),若干consumer group,以及一個Zookeeper集羣。Kafka經過Zookeeper管理集羣配置,選舉leader,以及在consumer group發生變化時進行rebalance。producer使用push模式將消息發佈到broker,consumer使用pull模式從broker訂閱並消費消息

1,爲了作到水平擴展,一個topic實際是由多個partition組成的(避免文件尺寸達到單機磁盤的上限,有效提高併發消費的能力),遇到瓶頸時,能夠經過增長partition的數量來進行橫向擴容。單個parition內是保證消息有序,同一個topic在不一樣partition之間是沒法保證有序的(每條消息的偏移量id保證消費有序),這須要業務方根據本身的業務來實現。 2,一個broker有多個topic,每一個topic的分區分散在多個broker之間,而且每一個分區在各個broker有備份(即每一個partition的非leader備份),可是每一個分區只有一個leader 3,異步複製,只要leader寫完就算髮送完成了,同步複製,得要全部follower寫完纔算發送完成 4,每一個topic將被分紅多個partition,每一個partition在存儲層面是append log文件。任何發佈到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱爲offset(偏移量),offset爲一個long型數字,它是惟一標記一條消息,所以在一個partition內能夠保證消息是順序消費的。kafka並無提供其餘額外的索引機制來存儲offset,由於在kafka中幾乎不容許對消息進行「隨機讀寫」。對於consumer而言,它須要保存消費消息的offset(一個partition可能對應多個多個consumer,分佈在多個consume_group裏面,爲每一個consumer分配一個offset,就能夠保證線性消費了,實際上這個offset是存在zk裏面,每一個consumer一個offset),對於offset的保存和使用,有consumer來控制;當consumer正常消費消息時,offset將會"線性"的向前驅動,即消息將依次順序被消費。 4,在kafka中,一個partition中的消息只會被group中的一個consumer消費 5,一個partition最多隻能對應一個consumer(一個consumer可能對應多個partition)

broker: 每一個正在運行的kafka節點 producer:消息生產者 consumer:消息的消費者 consumer group:消費者組,同一個消費者組只能有一個consumer能消費消息 kafka server :也叫做broker, 已部署kafka的服務器, 以broker.id來區分不一樣的服務器 topic:主題, 主題中的每條消息包括key-value和timestamp。能夠定義多個topic,每一個topic又能夠劃分爲多個分區 partition:topic下的消息分區,經過key取哈希後把消息映射分發到一個指定的分區,每一個分區都映射到broker上的一個目錄。通常每一個分區存儲在一個broker上 replica:副本, 每一個分區按照生產者的消息達到順序存放。每一個分區副本都有一個leader leader replica:leader角色的分區副本,leader角色的分區處理消息的讀寫請求. Leader和follower位於不一樣的broker. follower replica:follower角色的分區副本,負責從Leader拉取數據到本地,實現分區副本的建立 zookeeper:嚴格來講這不是kafka的組件。可是在Kafka集羣中, 頗有必要經過Zookeeper管理kafka集羣的配置、選舉leader(每一個topic對應的partition的leader),以及在Consumer Group發生變化時進行rebalance。下面說一下kafka的哪些組件須要註冊到zookeeper 爲何要註冊到zk集羣? 1,Kafka集羣經過Zookeeper來管理kafka的配置,選舉leader; 2,在Consumer Group發生變化時進行rebalance 3,全部的topic與broker的對應關係都由zk維護

kafka的哪些組件須要註冊到zookeeper? (1)Broker註冊到zk(所以Broker和zk之間保持心跳,若是無意跳,broker意味着掛掉) 每一個broker啓動時,都會註冊到zk中,把自身的broker.id通知給zk。待zk建立此節點後,kafka會把這個broker的主機名和端口號記錄到此節點

(2)Topic註冊到zk 當broker啓動時,會到對應topic節點下注冊本身的broker.id到對應分區的isr列表中;當broker退出時,zk會自動更新其對應的topic分區的ISR列表,並決定是否須要作消費者的rebalance

(3)Consumer註冊到zk 一旦有新的消費者組註冊到zk,zk會建立專用的節點來保存相關信息。若是zk發現消費者增長或減小,會自動觸發消費者的負載均衡。 (注意,producer不註冊到zk)

消息如何被消費的? Producer使用push模式將消息發佈到broker,Consumer使用pull模式從broker訂閱並消費消息;producer經過聯繫zk獲取leader角色的消息分區碼,把消息寫到leader Producer使用push模式將消息發佈到broker +————+ | broker | +————+ | | / PULL | | / Consumer使用pull模式從broker訂閱並消費消息

參考:www.cnblogs.com/liyanbin/p/… www.cnblogs.com/likehua/p/3… www.jianshu.com/p/d3e963ff8… blog.csdn.net/dshf_1/arti…

leader選舉(容災) controller會在Zookeeper的/brokers/ids節點上註冊Watch,一旦有broker宕機,它就能知道。當broker宕機後,controller就會給受到影響的partition選出新leader。controller從zk的/brokers/topics/[topic]/partitions/[partition]/state中,讀取對應partition的ISR(in-sync replica已同步的副本)列表,選一個出來作leader。

kafka的數據存儲 其實是以文件的形式存儲在文件系統的。topic下有partition,partition下有segment,segment是實際的一個個文件,topic和partition都是抽象概念。 在目錄/{topicName}-{partitionid}/下,存儲着實際的log文件(即segment),還有對應的索引文件。 每一個segment文件大小相等,文件名以這個segment中最小的offset命名,文件擴展名是.log;segment對應的索引的文件名字同樣,擴展名是.index。有兩個index文件,一個是offset index用於按offset去查message,一個是time index用於按照時間去查

kafka中的zookeeper做用(consumer鏈接到哪一個broker,是由zk決定的,所以kafka的負載均衡是由zk完成的) 管理broker、consumer 建立Broker後,向zookeeper註冊新的broker信息,實如今服務器正常運行下的水平拓展。具體的,經過註冊watcher,獲取partition的信息。 Topic的註冊,zookeeper會維護topic與broker的關係,經過/brokers/topics/topic.name節點來記錄。 Producer向zookeeper中註冊watcher,瞭解topic的partition的消息,以動態瞭解運行狀況,實現負載均衡。Zookeepr是沒有管理producer,只是可以提供當前broker的相關信息。 Consumer可使用group形式消費kafka中的數據。全部的group將以輪詢的方式消費broker中的數據,具體的按照啓動的順序。Zookeeper會給每一個consumer group一個ID,即同一份數據能夠被不一樣的用戶ID屢次消費。所以這就是單播與多播的實現。以單個消費者仍是以組別的方式去消費數據,由用戶本身去定義。Zookeeper管理consumer的offset跟蹤當前消費的offset.

kafka的leader選舉:www.cnblogs.com/aspirant/p/…

新版本的kafka對leader的選舉是這樣的:在Kafka集羣中會有一個或者多個broker,其中有一個broker會被選舉爲控制器(Kafka Controller),它負責管理整個集羣中全部分區和副本的狀態。當某個分區的leader副本出現故障時,由控制器負責爲該分區選舉新的leader副本。當檢測到某個分區的ISR集合發生變化時,由控制器負責通知全部broker更新其元數據信息。當使用kafka-topics.sh腳本爲某個topic增長分區數量時,一樣仍是由控制器負責分區的從新分配

在Kafka的早期版本中,並無採用Kafka Controller這樣一個概念來對分區和副本的狀態進行管理,而是依賴於Zookeeper,每一個broker都會在Zookeeper上爲分區和副本註冊大量的監聽器(Watcher)。當分區或者副本狀態變化時,會喚醒不少沒必要要的監聽器,這種嚴重依賴於Zookeeper的設計會有腦裂、羊羣效應以及形成Zookeeper過載的隱患。在目前的新版本的設計中,只有Kafka Controller在Zookeeper上註冊相應的監聽器,其餘的broker極少須要再監聽Zookeeper中的數據變化,這樣省去了不少沒必要要的麻煩。不過每一個broker仍是會對/controller節點添加監聽器的,以此來監聽此節點的數據變化(參考ZkClient中的IZkDataListener),簡單理解就是舊版本的leader和follower partition都在zk註冊,致使zk變得沉重

Zookeeper羊羣效應:若是有1000個客戶端watch 一個znode的exists調用,當這個節點被建立的時候,將會有1000個通知被髮送。這種因爲一個被watch的znode變化,致使大量的通知須要被髮送,將會致使在這個通知期間的其餘操做提交的延遲,所以,只要可能,咱們都強烈建議不要這麼使用watch。僅僅有不多的客戶端同時去watch一個znode比較好,理想的狀況是隻有1個。 解決思路:使用zookeeper時,儘可能避免大量節點監控一個節點的行爲

策略就是每一個client去建立一個順序的znode /lock/lock-.ZooKeeper 會自動添加順序號/lock/lock-xxx.咱們能夠經過/lock getChildren 去拿到最小的順序號。若是client不是最小的序列號,就再比本身小一點的znode上添加watch,因爲序列號最小(最早建立的node)纔是得到鎖的,所以去通知下一個次小的便可,不用所有通知。 參考:www.cnblogs.com/bnbqian/p/4…

Kafka的消息讀取爲何不從follower讀取? 1,mysql不用於高qps的讀取,而且容許有延遲(能夠在從庫讀取,信息存在不許確性)。可是kafka是爲了低延遲和高吞吐量,只同步到部分的follower就完成消息的投遞。 2,一個consumer對應一個partition的leader,若是對應多個,就出現了一條數據重複消息屢次。(除非消費一次leader,同時修改全部的follower的offset)

43,零拷貝技術(消除多餘的拷貝次數,並不是一次都沒拷貝) 因爲數據實際上仍然由磁盤複製到內存,再由內存複製到發送設備,有人可能會聲稱這並非真正的"零拷貝"。然而,從操做系統的角度來看,這就是"零拷貝",由於內核空間內不存在冗餘數據。應用"零拷貝"特性,出了避免複製以外,還能得到其餘性能優點,例如更少的上下文切換,更少的CPU cache污染以及沒有CPU必要計算校驗和。

步驟一:mmap系統調用致使文件的內容經過DMA模塊被複制到內核緩衝區中,該緩衝區以後與用戶進程共享,這樣就內核緩衝區與用戶緩衝區之間的複製就不會發生。 步驟二:write系統調用致使內核將數據從內核緩衝區複製到與socket相關聯的內核緩衝區中。 步驟三:DMA模塊將數據由socket的緩衝區傳遞給協議引擎時,第3次複製發生。 參考:www.cnblogs.com/pengdonglin…

44,kafka若是作到百萬級高吞吐量的(參考:blog.csdn.net/u010039929/…

生產端 1,能夠將消息buffer起來,當消息的條數達到必定閥值時,批量發送給broker,即批量寫入磁盤(批量寫入,避免零碎寫入屢次io的打開和關閉)。 2,消息寫入到磁盤是順序寫入,充分利用磁盤的順序讀寫性能。 3,多個partition同時寫入,提升數據的併發寫入效率。

broker端 基於內存映射技術實現的零拷貝,sendfile系統調用能夠潛在的提高網絡IO的性能:將文件的數據映射到系統內存中,socket直接讀取相應的內存區域便可,而無需進程再次copy和交換. 其實對於producer/consumer/broker三者而言,CPU的開支應該都不大,所以啓用消息壓縮機制是一個良好的策略;壓縮須要消耗少許的CPU資源,不過對於kafka而言,網絡IO更應該須要考慮.能夠將任何在網絡上傳輸的消息都通過壓縮。 kafka支持gzip/snappy等多種壓縮

消費端 批量fetch多條消息,避免屢次pull操做過程當中的io操做帶來的性能損耗。

另一種解讀: 1、接收數據時寫得快 (1)消息順序寫入磁盤 (2)消息集合批量發送 (3)採用由Producer,broker和consumer共享的標準化二進制消息格式,這樣數據塊就能夠在它們之間自由傳輸,無需轉換,下降了字節複製的成本開銷。 (4)採用了MMAP(Memory Mapped Files,內存映射文件)技術。 (5)利用操做系統的頁緩存來實現文件到物理內存的直接映射。完成映射以後對物理內存的操做在適當時候會被同步到硬盤上。 2、推送數據時發得快 (1)在生產端和消費端分別採起的push和pull的方式,也就是你生產端能夠認爲KAFKA是個無底洞,有多少數據可使勁往裏面推送,消費端則是根據本身的消費能力,須要多少數據,你本身過來KAFKA這裏拉取,KAFKA能保證只要這裏有數據,消費端須要多少,都盡能夠本身過來拿。 (2)採用頁緩存和sendfile組合,意味着KAFKA集羣的消費者大多數都徹底從緩存消費消息,而磁盤沒有任何讀取活動。 (3)批量壓縮,支持Gzip和Snappy壓縮協議。 (4)採用多分區設計,併發讀寫,加快讀寫速度。

kafka面試題:blog.csdn.net/linke118398…

45,單點登陸原理 單點登陸全稱Single Sign On(如下簡稱SSO),是指在多系統應用羣中登陸一個系統,即可在其餘全部系統中獲得受權而無需再次登陸,包括單點登陸與單點註銷兩部分,sso須要一個獨立的認證中心,只有認證中心能接受用戶的用戶名密碼等安全信息,其餘系統不提供登陸入口,只接受認證中心的間接受權。間接受權經過令牌實現,sso認證中心驗證用戶的用戶名密碼沒問題,建立受權令牌,在接下來的跳轉過程當中,受權令牌做爲參數發送給各個子系統,子系統拿到令牌,即獲得了受權,能夠藉此建立局部會話,局部會話登陸方式與單系統的登陸方式相同

46,如何擴展spring 1,自定義註解或者自定義解析器。 2,BeanFactoryPostProcessor(調用時機是全部bean的定義信息都已經初始化好)和BeanPostProcessor(針對bean初始化提供擴展) 3,spring aop

47,zookeeper在工做中常見的做用:它是分佈式系統中的協調系統,可提供的服務主要有:配置中心(像lion)、分佈式同步(分佈式鎖)、rpc服務註冊管理(rpc註冊中心) Apache ZooKeeper是由集羣(節點組)使用的一種服務,用於在自身之間協調,並經過穩健的同步技術維護共享數據。ZooKeeper自己是一個分佈式應用程序,爲寫入分佈式應用程序提供服務。

Zookeeper的角色:leader(負責進行投票的發起和決議,數據變動),follower(接受client讀取請求,參與選舉),observer(ZooKeeper集羣的讀取負載很高,能夠設置一些observer服務器,以提升讀取的吞吐量,不參與選舉和投票),follower和Observer都是Learner。

ZooKeeper提供的常見服務以下 : 命名服務 - 按名稱標識集羣中的節點。它相似於DNS,但僅對於節點。 配置管理 - 加入節點的最近的和最新的系統配置信息。 集羣管理 - 實時地在集羣和節點狀態中加入/離開節點。 選舉算法 - 選舉一個節點做爲協調目的的leader。 鎖定和同步服務 - 在修改數據的同時鎖定數據。此機制可幫助你在鏈接其餘分佈式應用程序(如Apache HBase)時進行自動故障恢復。 高度可靠的數據註冊表 - 即便在一個或幾個節點關閉時也能夠得到數據。

zookeeper入門:www.cnblogs.com/felixzh/p/5… zookeeper實際上以文件形式對節點進行管理,所以同一級目錄下不存在重複節點

zookeeper選主流程(basic paxos) 當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式須要從新選舉出一個新的leader,讓全部的Server都恢復到一個正確的狀態。Zk的選舉算法有兩種:一種是基於basic paxos實現的,另一種是基於fast paxos算法實現的。系統默認的選舉算法爲fast paxos。

ZooKeeper如何解決"腦裂" 3種可行的思路 (1) Quorums(法定人數,通常只有過半投票才能認可選主成功)法: 經過設置法定人數, 進而肯定集羣的容忍度, 當集羣中存活的節點少於法定人數, 集羣將不可用.(或者限制全局至少一半以上節點投票才行) 好比: 3個節點的集羣中, Quorums = 2 —— 集羣能夠容忍 (3 - 2 = 1) 個節點失敗, 這時候還能選舉出leader, 集羣仍然可用; 4個節點的集羣中, Quorums = 3 —— 集羣一樣能夠容忍 1 個節點失敗, 若是2個節點失敗, 那整個集羣就不可用了. (2) Redundant communications(冗餘通訊): 集羣中採用多種通訊方式, 防止一種通訊方式失效致使集羣中的節點沒法通訊. (3) Fencing(共享資源): 經過共享資源的方式, 將全部共享資源添加到集羣中, 能對共享資源進行寫操做(即加鎖)的節點就是leader節點. 原文:blog.csdn.net/ma_shou_fen…

48,zookeeper面試題(segmentfault.com/a/119000001… 1.ZooKeeper是什麼? ZooKeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務 2,ZooKeeper提供了什麼? 文件系統和通知機制 3,Zookeeper通知機制 client端會對某個znode創建一個watcher事件,當該znode發生變化時,這些client會收到zk的通知,而後client能夠根據znode變化來作出業務上的改變等。 4,zookeeper是如何保證事務的順序一致性的? zookeeper採用了遞增的事務Id來標識,全部的proposal(提議)都在被提出的時候加上了zxid,zxid其實是一個64位的數字,高32位是epoch(時期; 紀元; 世; 新時代)用來標識leader是否發生改變,若是有新的leader產生出來,epoch會自增,低32位用來遞增計數。當新產生proposal的時候,會依據數據庫的兩階段過程,首先會向其餘的server發出事務執行請求,若是超過半數的機器都能執行而且可以成功,那麼就會開始執行 5,機器中爲何會有leader? 在分佈式環境中,有些業務邏輯只須要集羣中的某一臺機器進行執行,其餘的機器能夠共享這個結果,這樣能夠大大減小重複計算,提升性能,因而就須要進行leader選舉 6,部署方式?集羣中的機器角色都有哪些?集羣最少要幾臺機器 單機,集羣,僞集羣。Leader、Follower、Observer。集羣最低3(2N+1)臺,保證奇數,主要是爲了選舉算法。 7,集羣若是有3臺機器,掛掉一臺集羣還能工做嗎?掛掉兩臺呢? 過半存活便可用。

8,zookeeper如何保證數據的一致性,而且如何進行leader和follower的選舉? ZooKeeper使用的是ZAB協議做爲數據一致性的算法, ZAB(ZooKeeper Atomic Broadcast ) 全稱爲:原子消息廣播協議。zab有兩種工做模式:恢復模式和廣播模式。zab如何保證數據的一致性:全部事務請求必須由一個全局惟一的服務器(Leader)來協調處理,其餘的服務器則成爲Follower。Leader會將一個客戶端的事務請求轉換爲一個Proposal(提議),而後分發爲集羣中全部的Follower。當有過半數的Follower進行了正確的反饋以後,Leader會向全部的Follower發出Commit消息,而後返回客戶端成功。 Zab保證數據的一致性是典型的兩階段提交策略。

選舉流程:找出一批zxid最大follower,開始投票(paxos算法),投票過半的節點就會成爲leader。

Zab協議特色: 1)Zab 協議須要確保那些已經在 Leader 服務器上提交(Commit)的事務最終被全部的服務器提交。 2)Zab 協議須要確保丟棄那些只在 Leader 上被提出而沒有被提交的事務。

參考:www.jianshu.com/p/2bceacd60…

9,ZK目錄樹中每一個節點對應一個Znode。每一個Znode維護這一個屬性,當前版本、數據版本(zxid)、創建時間和修改時間等。znode的數據操做是原子性的(實際仍是樂觀鎖機制,node有版本號)。 zxid在leader和follower選舉時頗有意義(找出全部zxid爲最大的follower,就是全部follower中數據最新的,此時它能夠做爲leader),zookeeper每次的節點新增、刪除,數據修改都會影響zxid遞增。

10,zk的節點類型, 持久節點:該數據節點被建立後,就會一直存在於zookeeper服務器上,直到有刪除操做來主動刪除這個節點,使用場景:常見的配置中心(如點評的lion) 臨時節點:臨時節點的生命週期和客戶端會話綁定在一塊兒,客戶端會話失效,則這個節點就會被自動清除。使用場景:①分佈式鎖(客戶端掛掉沒法保證心跳,超時致使會話結束,臨時節點會被自動刪除,鎖能夠被其它客戶端使用),②服務註冊中心:服務提供者在ZooKeeper的/dubbo/com.XXX.UserService/providers節點下建立子節點(機器),服務消費者在/dubbo/com.XXX.UserService/consumers建立臨時節點 順序節點:在建立臨時或者永久節點時,能夠給節點加上遞增編號,能夠很好解決分佈式鎖的羊羣效應,當鎖釋放時,只須要通知同一級別的下一個最小節點獲取鎖,不須要所有通知。 參考:segmentfault.com/a/119000001…

48,分佈式鎖的實現方式(blog.csdn.net/u010963948/…) 背景:分佈式環境下,保證某一段業務邏輯只能被某一臺機器執行 實現方式: 1,基於數據庫樂觀鎖的版本號機制實現分佈式鎖(讀取一行記錄的版本號,根據版本號去修改,若是修改爲功,就表明搶鎖成功)。原理:基於行級鎖實現,優勢:操做簡單,容易理解。缺點:不適合高併發場景。 2,基於redis的setnx實現鎖建立和釋放。原理:基於redis寫入操做的原子性(由於redis是單線程),優勢:是全部分佈式鎖中性能最好的(基於內存操做),缺點:因爲redis的master-slave同步不是絕對可靠,可能出現鎖寫入主節點,還沒同步到slave(在cluster集羣下,客戶端加鎖能夠強制去slave讀取一遍,校驗鎖是否同步成功,不成功就自旋等待) 3,基於zookeeper的臨時節點建立實現鎖建立和釋放,缺點:有羊羣效應,須要調用方本身去優化邏輯。

使用redis做爲分佈式鎖注意的問題,cloud.tencent.com/developer/a… 舉例:記得給鎖加上超時時間,避免執行邏輯過程當中發生異常,致使鎖沒法被顯式釋放,鎖就會被永久佔用,致使其它線程沒法再次使用。獲取鎖時,最好加上本身的線程id,以便在刪除鎖時,再次判斷是否是當前線程的鎖(若是不是,須要回滾當前事務)。 備註:setnx有潛在風險,先調用setnx設置鎖,再調用expire設置超時,這一連串的操做非原子操做,可能超時未設置成功就發生異常,致使引起鎖沒法釋放,應該調用set方法,鎖和超時一塊執行。

49,分佈式事務的解決方案 分佈式事務的應用場景(soa服務化的系統裏對數據的操做在不一樣的數據庫,即保證業務數據在關聯的系統中的流轉正確性) 一、支付 最經典的場景就是支付了,一筆支付,是對買家帳戶進行扣款,同時對賣家帳戶進行加錢,這些操做必須在一個事務裏執行,要麼所有成功,要麼所有失敗。而對於買家帳戶屬於買家中心,對應的是買家數據庫,而賣家帳戶屬於賣家中心,對應的是賣家數據庫,對不一樣數據庫的操做必然須要引入分佈式事務。 二、在線下單 買家在電商平臺下單,每每會涉及到兩個動做,一個是扣庫存,第二個是更新訂單狀態,庫存和訂單通常屬於不一樣的數據庫,須要使用分佈式事務保證數據一致性。

解決方案 1,兩階段提交,須要中間協調器的參與,在prepare階段,協調器向參與方(如支付寶和餘額寶的相互轉帳)向發起請求,而且開始執行任務,全部參與方執行成功給協調器回覆yes,若是全部參與方都回復yes,協調器再通知業務方commit操做(完成事務提交),不然通知全部參與方回滾。

缺點: <1>同步阻塞問題。執行過程當中,全部參與節點都是事務阻塞型的。 當參與者佔有公共資源時,其餘第三方節點訪問公共資源不得不處於阻塞狀態。 <2>單點故障。因爲協調者的重要性,一旦協調者發生故障。 參與者會一直阻塞下去。尤爲在第二階段,協調者發生故障,那麼全部的參與者還都處於鎖定事務資源的狀態中,而沒法繼續完成事務操做。(若是是協調者掛掉,能夠從新選舉一個協調者,可是沒法解決由於協調者宕機致使的參與者處於阻塞狀態的問題) <3>數據不一致。在二階段提交的階段二中,當協調者向參與者發送commit請求以後,發生了局部網絡異常或者在發送commit請求過程當中協調者發生了故障,這回致使只有一部分參與者接受到了commit請求。 而在這部分參與者接到commit請求以後就會執行commit操做。可是其餘部分未接到commit請求的機器則沒法執行事務提交。因而整個分佈式系統便出現了數據部一致性的現象。

2,3階段提交須要中間協調器進行協調,第一階段協調器向全部的參與方發出執行任務的請求(cancommit),若是迴應能夠,協調器通知參與方進入prepare,並執行任務。執行成功迴應協調器,協調器通知全部參與方進入commit,否着回滾,中間還加入了超時機制

3.TCC模式,也是兩階段提交的一個變種。TCC提供了一個編程框架,將整個業務邏輯分爲三塊:Try、Confirm和Cancel三個操做。以在線下單爲例,Try階段會去扣庫存,Confirm階段則是去更新訂單狀態,若是更新訂單失敗,則進入Cancel階段,會去恢復庫存。總之,TCC就是經過代碼人爲實現了兩階段提交,不一樣的業務場景所寫的代碼都不同,複雜度也不同,所以,這種模式並不能很好地被複用。 (下單tryLock庫存,confirm(下單成功),cancel(下單失敗還原庫存))

4,消息驅動的方式,消息方案從本質上講是將分佈式事務轉換爲兩個本地事務,而後依靠下游業務的重試機制達到最終一致性。基於消息的最終一致性方案對應用侵入性也很高,應用須要進行大量業務改造,成本較高。(好比下單成功(預約中),消息投遞給庫存扣減系統,若是庫存扣減失敗,回調給上游的訂單系統)

參考:www.cnblogs.com/jiangyu666/…

49,dubbo rpc原理,參考:www.cnblogs.com/panxuejun/p… <1>服務註冊、服務發現 ①服務提供者 服務提供者會在初始化啓動時,首先在ZooKeeper的/dubbo/com.jeiker.UserService/providers節點下建立一個子節點(機器ip),寫入本身的URL地址,這就表明了「com.jeiker.UserService」這個服務的一個提供者。 ②服務消費者 服務消費者會在啓動時,讀取並訂閱ZooKeeper上/dubbo/com.jeiker.UserService/providers節點下的全部子節點(機器ip,這些機器ip會緩存在服務消費者端,防止zk掛掉,消費者仍能持續訪問提供者),解析出全部提供者的URL地址來做爲該服務地址列表,而後發起正常調用,同時,服務消費都還會在 ZooKeeper 的 /dubbo/com.jeiker.UserService/consumers節點下建立一個臨時節點,並寫入本身的URL地址,這就表明了com.jeiker.UserService這個服務的一個消費者。

<2>zookeeper在rpc框架中的模型 dubbo /
/
com.XX.service1 com.XX.service2 /
providers consumers /\ /
10.0.11.11 10.0.11.12 10.0.11.11 10.0.11.12

參考:blog.csdn.net/jeikerxiao/…

歡迎讚揚

相關文章
相關標籤/搜索