乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      大型網(wǎng)站系統(tǒng)與 Java 中間件的“情緣”

       萬皇之皇 2018-01-11

      轉(zhuǎn)載聲明:本文轉(zhuǎn)自【ImportNew】
      原文鏈接:http://mp.weixin.qq.com/s/qtKcJZkcq26nsFln3OYj6A

      第一章 分布式系統(tǒng)介紹

      分布式系統(tǒng)的定義:組件分布在網(wǎng)絡計算機上,組件間僅僅通過消息傳遞來通信并協(xié)調(diào)行動。

      分布式系統(tǒng)的意義:

      • 升級單機處理能力的性價比越來越低

      • 單機處理能力存在瓶頸

      • 處于穩(wěn)定性和可用性的考慮

      摩爾定律:當價格不變時,每隔 18 個月,集成電路上可容納的晶體管數(shù)目會增加一倍,性能也將提升一倍。

      線程與進程的執(zhí)行模式

      馮諾依曼結(jié)構(gòu):輸入設備、輸入設備、運算器、控制器、存儲器。

      基于共享容器協(xié)同的多線程模式:經(jīng)典如生產(chǎn)者消費者問題,對于存儲數(shù)據(jù)的容器或?qū)ο?,有線程安全和不安全之分,對于不安全的容器或?qū)ο?,一般可以通過加鎖或者通過 Copy On Write 的方式控制并發(fā)。

      通過事件協(xié)同的多線程模式:避免死鎖

      多進程模式:

      • 線程是屬于進程的,一個進程內(nèi)的多個線程共享了進程的內(nèi)存空間;而多個進程間的內(nèi)存空間是獨立的,因此多個進程間通過內(nèi)存共享、交換數(shù)據(jù)的方式與多個線程間就有所不同

      • 此外,進程間通信、協(xié)調(diào),以及通過一些事件通知或者等待一些互斥鎖的釋放方面也不一樣

      • 多進程相對于單進程多線程來說,資源控制會更容易實現(xiàn);多進程中單個進程出現(xiàn)問題,不會造成整體的不可用

      • 多進程之間可以共享數(shù)據(jù),但其代價較大,會涉及序列化和反序列化的開銷

      網(wǎng)絡通信基礎知識

      OSI 七層模型與 TCP/IP 模型:

      Socket 套接字進行網(wǎng)絡通信開發(fā)時,用到的三種方式:BIO、NIO 和 AIO

      BIO:Blocking IO,采用阻塞的方式實現(xiàn),一個線程處理一個 Socket,發(fā)生建立連接、讀數(shù)據(jù)、寫數(shù)據(jù)的操作時,都可能會阻塞。

      NIO:Nonblocking IO,基于時間驅(qū)動思想,采用 Reactor 模式,可以在一個線程中處理多個 Socket 套接字

      AIO:AsynchronousIO,異步 IO,采用 Proactor 模式,與 NIO 的差別是,AIO 在進行讀寫操作時,只需要調(diào)用響應的 read/write 方法,并且需要傳入 CompletionHandler,在動作完成后會調(diào)用。

      如何把應用從單機擴展到分布式

      • 輸入設備的變化

      • 輸出設備的變化

      • 控制器的變化

      方式 1 和 2,透明代理:對發(fā)起方和處理方都是透明的

      • 使用硬件負載均衡

      • 使用 LVS(或其他軟件負載均衡系統(tǒng))

      缺點:

      • 會增加網(wǎng)絡的開銷,一方面指流量,另一方面指延遲

      • 這個透明代理處于請求的必經(jīng)之路,如果代理出現(xiàn)問題,所有請求都會受到影響。我們需要考慮代理服務器的熱備份

      方式 3,采用名稱服務器直連的方式:

      請求發(fā)起方和處理方直接沒有代理服務器,而是直接連接。外部多了一個“名稱服務”的角色,作用有:

      • 收集提供請求處理的服務器的地址信息

      • 提供這些地址信息給請求發(fā)起方

      名稱服務只是起到一個地址交換的作用,在發(fā)起請求的機器上,需要根據(jù)從名稱服務得到的地址進行負載均衡的工作。

      優(yōu)點如下:

      • 名稱服務器出現(xiàn)問題,有辦法可以保證處理正常

      • 發(fā)起方和處理方直連,減少中間路徑和帶寬小號

      缺點就是代碼升級較復雜

      方式 4,采用規(guī)則服務器控制路由的請求直連調(diào)用

      與名稱服務器不同的是,規(guī)則服務器并不和請求處理的機器交互,只負責把規(guī)則提供給請求發(fā)起的機器。

      方式 5,Master+Worker 的方式

      存在一個 Master 節(jié)點來管理任務,由 Master 把任務分配給不同的 Worker 進行處理。

      運算器的變化

      通過 DNS 服務器進行調(diào)度和控制

      增加負載均衡設備,DNS 返回的永遠是負載均衡地址

      存儲器的變化

      同控制器的變化,加代理服務器、or 名稱服務器、or 規(guī)則服務器

      分布式系統(tǒng)的難點

      • 缺乏全局時鐘

      • 面對故障獨立性

      • 處理單點故障,如果不能把單點變?yōu)榧?,則需要給單點做好備份,降低單點故障影響范圍

      • 事務的挑戰(zhàn):2PC、最終一致、BASE、CAP、Paxos 等

      第二章 大型網(wǎng)站及其架構(gòu)演進過程

      大型網(wǎng)站:訪問量(PV)、數(shù)據(jù)量、業(yè)務復雜度

      單機負載告警,數(shù)據(jù)庫與應用分離

      應用服務器負載告警,走向集群

      • 服務器選擇問題:DNS、集群前加負載均衡設備

      • Session 的問題

      Session 保存會話狀態(tài),在 Web 服務器上,各個會話獨立存儲,多臺服務器不能保證每次請求都落在同一邊的服務器上。解決方案如下:

      1、Session Sticky:負載均衡根據(jù)會話標識進行轉(zhuǎn)發(fā),讓同樣的 Session 請求每次都發(fā)送到同一個服務器端處理

      缺點:

      • 如果一臺 Web 服務器宕機或重啟,會話數(shù)據(jù)會丟失,用戶要重新登錄

      • 會話標識是應用層信息,則負載均衡要在應用層進行解析,開銷比在第四層大

      • 負載均衡變?yōu)榱擞袪顟B(tài)的節(jié)點,要將會話保存到具體 Web 服務器的映射。內(nèi)存消耗會變大,容災更麻煩

      2、Session Replication:會話在多態(tài)服務器上復制同步

      缺點:

      • 同步 Session 數(shù)據(jù)造成了網(wǎng)絡帶寬的開銷

      • 每臺 Web 服務器都要保存所有的 Session 數(shù)據(jù),數(shù)據(jù)量容易很大

      3、Session 數(shù)據(jù)集中存儲

      Session 數(shù)據(jù)不再 Web 服務器上,而是放在另一個集中存儲的地方。

      缺點:

      • 讀寫 Session 數(shù)據(jù)引入了網(wǎng)絡操作,存在時延和不穩(wěn)定性

      • 如果集中存儲 Session 的機器或者集群有問題,就會影響我們的應用

      4、Cookie Based:把 Session 數(shù)據(jù)放在 Cookie 中

      缺點:

      • Cookie 長度的限制

      • 安全性:外部訪問和修改

      • 帶寬消耗

      • 性能影響:每次 HTTP 請求都帶有 Session 數(shù)據(jù)

      數(shù)據(jù)讀壓力變大,讀寫分離

      1、采用數(shù)據(jù)庫作為讀庫

      缺點:

      • 數(shù)據(jù)復制問題;

      • 應用對于數(shù)據(jù)源的選擇問題:寫操作和事務走主庫,考慮從庫相對主庫的延遲

      2、搜索引擎其實是一個讀庫

      3、加速數(shù)據(jù)讀取的利器——緩存

      • 數(shù)據(jù)緩存,Key-Value,“熱數(shù)據(jù)”,容量不夠時清除緩存

      • 頁面緩存,ESI 標簽頁面緩存

      彌補關系型數(shù)據(jù)庫的不足,引入分布式存儲系統(tǒng)

      分布式文件系統(tǒng),解決小文件和大文件的存儲問題

      分布式 key-value 系統(tǒng),提供高性能的半結(jié)構(gòu)化支持

      分布式數(shù)據(jù)庫提供一個支持大數(shù)據(jù)、高并發(fā)的數(shù)據(jù)庫系統(tǒng)

      讀寫分離后,數(shù)據(jù)庫又遇到瓶頸

      盡管讀寫分離以及分布式存儲系統(tǒng),能夠降低主庫的壓力,但是交易、商品、用戶的數(shù)據(jù)都還在一個數(shù)據(jù)庫中,壓力還在繼續(xù)增加,我們有數(shù)據(jù)垂直拆分和水平拆分兩種選擇;

      1、專庫專用,數(shù)據(jù)垂直拆分

      垂直拆分即把不同的業(yè)務數(shù)據(jù)分到不同的數(shù)據(jù)庫中。

      問題:

      • 應用需要多個數(shù)據(jù)源,帶來的是每個數(shù)據(jù)庫連接池的隔離

      • 單機跨業(yè)務事務,一種方法是使用分布式事務,性能較低;另一種辦法就是去掉事務

      2、單表達到瓶頸,數(shù)據(jù)水平拆分

      水平拆分就是把同一個表的數(shù)據(jù)拆到兩個數(shù)據(jù)庫中。

      問題:

      • SQL 路由問題,選擇哪個數(shù)據(jù)表

      • 主鍵處理等機制不同,如自增主鍵

      • 一些查詢需要從兩個數(shù)據(jù)庫中取數(shù)據(jù),加上分頁操作,比較難處理

      數(shù)據(jù)庫問題解決后,應用面對的新挑戰(zhàn)

      拆分應用

      • 根據(jù)業(yè)務特性,還可以根據(jù)用戶注冊、登陸、用戶信息維護等再拆分。

      • 走服務化的路,共享代碼放在各個服務中心,如商品中心、用戶中心、交易中心

      初識消息中間件

      消息中間件是在分布式系統(tǒng)中完成消息發(fā)送和接收的基礎軟件。兩個明顯好處:異步、解耦。

      第三章 構(gòu)建 Java 中間件

      三個領域的中間件:

      • 遠程過程調(diào)用和對象訪問中間件:主要解決分布式環(huán)境下應用的互相訪問問題。是支撐應用服務化的基礎

      • 消息中間件:解決應用之間的消息傳遞、解耦、異步的問題

      • 數(shù)據(jù)訪問中間件:解決應用訪問數(shù)據(jù)庫的共性問題

      構(gòu)建 Java 中間件的基礎知識

      JVM 中堆分為三塊:Young/Tenured/Perm,新生代 / 年老代 / 持久代

      一般來說,新對象分配在新生代的 Eden 區(qū),也可能直接分配在年老代,在進行新生代垃圾回收時,Eden 區(qū)存活的對象被復制到空的 Survivor 區(qū),在下次新生代回收時,Eden 區(qū)存活的對象和這個 Survivor 存活的對象被復制到另外那個 Survivor 區(qū),并且清空當前 Survivor 區(qū),經(jīng)過多次新生代垃圾回收,還存活的對象會被移動到年老代。

      線程池

      ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 60, TimeUnit, SECONDS, new LinkedBlockingQueue(count));

      tp.execute(new Runnable(){

      public void run(){}

      });

      使用線程池的方式是復用線程的,不用每次都創(chuàng)建線程。而創(chuàng)建線程的開銷占比較大。

      synchronized

      synchronized 修飾靜態(tài)方法、對象方法、代碼塊

      ReetrantLock

      • ** 提供 tryLock 方法,嘗試調(diào)用,如果鎖被其他線程持有,則 tryLock 立即返回

      • 可以實現(xiàn)公平鎖

      • ReentrantReadWriteLock:讀寫鎖,用于讀多寫少并且讀不需要互斥的場景

      • 可以有多個 Condition

      volatile

      可見性指一個線程修改變量值后,其他線程中能夠看到這個值。volatile 雖然解決了可見性問題,但是不能控制并發(fā)

      Atomics

      原子操作,如 AtomicInteger 內(nèi)部通過 JNI 的方式使用了硬件支持的 CAS 指令

      wait、notify 和 notifyAll

      wait 是等待線程,notify 是喚醒一個等待線程(并不能指定,隨機),notifyAll 是喚醒所有的等待線程。

      CountDownLatch

      java.util.concurrent 包中的一個類,主要提供的機制是當多個線程都到達了預期狀態(tài)或完成預期工作時觸發(fā)事件,其他線程可以等待這個事件來觸發(fā)自己后續(xù)的工作。

      CyclicBarrier

      循環(huán)屏障,可以協(xié)同多個線程,讓多個線程在這個屏障前等待,知道所有線程都到達了這個屏障時,再一起繼續(xù)執(zhí)行后面的動作。

      Semaphore

      Semaphore 是用于管理信號量的,構(gòu)造時傳入可供管理的信號量的數(shù)值。如果信號量只有一個,就退化到互斥鎖了,如果多于一個,則主要用于控制并發(fā)數(shù)。

      Exchanger

      用于兩個線程之間進行數(shù)據(jù)交換,線程會阻塞在 exchange 方法上,知道另外一個線程也到了同一個 Exchanger 的 exchange 方法時,二者進行交換。

      Future 和 FutureTask

      Future 是一個接口,F(xiàn)utureTask 是一個具體實現(xiàn)類

      Future future = getDataFromRemote2();

      ……

      HashMap data = (HashMap) future.get();

      public Future getDataFromRemote2(){

      return threadPool.submit(new Callable(){

      public HashMap call()throws Exception{ return getDataFromRemote();}

      });

      }

      getDataFromRemote2 還是使用率 getDataFromRemote 完成操作,并且用到了線程池:把任務加入線程池中,把 Future 對象返回出去。

      并發(fā)容器

      CopyOnWrite:更改容器時,把容器復制一份進行修改,用于讀多寫少

      Concurrent:盡量保證讀不加鎖,并且修改時不影響讀,所以比讀寫鎖更高的并發(fā)性能

      動態(tài)代理

      繼承 InvocationHandler

      反射

      Java 反射機制是指在運行狀態(tài),對于任意一個類,都能知道這個類所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性。

      Class clazz = Object.getClass();

      String className = clazz.getName();

      Method[] methods = clazz.getDeclaredMethods();

      Field[] fields = clazz.getDeclaredFields();

      // 構(gòu)建對象

      Class.forName(“ClassName”).newInstance();

      // 動態(tài)執(zhí)行方法

      Method method = clazz.getDeclaredMethod(“add”, int.class, int.class);

      method.invoke(this, 1, 1);

      // 動態(tài)操作方法

      Field field = clazz.getDeclaredField(“name”);

      field.set(this, “test”);

      網(wǎng)絡通信的選擇

      BIO、NIO、AIO

      第三方框架,MINA,Netty

      第四章 服務框架

      服務調(diào)用端的設計與實現(xiàn)

      調(diào)用發(fā)起 ==> 尋址路由 ==> 協(xié)議適配和序列化 ==> 網(wǎng)絡傳輸

      ==> 反序列化 協(xié)議解析 ==> 得到結(jié)果返回給調(diào)用方

      1、確定服務框架的使用方式

      2、服務調(diào)用者與服務提供者之間通信方式的選擇

      3、引入基于接口、方法、參數(shù)的路由

      4、多機房場景,避免跨機房調(diào)用,一是在服務注冊中心甄別,二是地址過濾

      5、服務調(diào)用端的流控處理

      6、序列化與反序列化處理,Java 本身的序列化性能問題、跨語言問題、序列化后語言長度

      7、網(wǎng)絡通信實現(xiàn)選擇:BIO、NIO、AIO

      8、支持多種異步服務調(diào)用方式:Oneway,Callback,F(xiàn)uture,可靠異步

      服務提供端的設計與實現(xiàn)

      1、如何暴露遠程服務

      2、服務端對請求處理的流程

      3、執(zhí)行不同服務的線程池隔離

      4、服務提供端的流控處理

      第五章 數(shù)據(jù)訪問層

      分布式事務

      • 兩階段提交:2PC

      • 一致性理論:CAP、BASE

      • Paxos 協(xié)議

      多機自增主鍵問題

      考慮唯一性和連續(xù)性,UUID 生成方式(IP、MAC、時間等)連續(xù)性不好

      實現(xiàn)方案 1:把 ID 集中放在一個地方進行管理,對每個 Id 序列獨立管理,每臺機器使用 Id 時都從這個 Id 生成器上取。

      缺點:

      • 性能問題:每次都去遠程取 Id 會有資源損耗

      • 生成器的穩(wěn)定性問題,作為一個無狀態(tài)的集群,保證可用性

      • 存儲的問題

      實現(xiàn)方案 2:舍掉 Id 生成器,把相關的邏輯放到需要生成 Id 的應用本身。每個生成器讀取可用的 Id,然后給應用使用,但是數(shù)據(jù)的 Id 并不是嚴格按照進入數(shù)據(jù)庫順序而增大的。

      應對多機的數(shù)據(jù)查詢

      跨庫 Join

      • 在應用層把原來數(shù)據(jù)庫的 Join 操作分成多次的數(shù)據(jù)庫操作

      • 數(shù)據(jù)冗余,對常用信息進行冗余

      • 借助外部系統(tǒng),如搜索引擎

      外鍵約束

      外鍵約束比較難解決,不能完全依賴數(shù)據(jù)庫本身來完成之前的功能了。

      跨庫查詢的問題及解決

      一張邏輯表,對應多個數(shù)據(jù)庫的多張數(shù)據(jù)表,在一些場景下比較復雜,如排序、最大最小求和等函數(shù)處理、求平均值、非排序分頁、排序后分頁。

      如何對外提供數(shù)據(jù)訪問層的功能

      1、為用戶提供專有 API

      2、通用的方式,數(shù)據(jù)層 JDBC

      3、基于 ORM 或類 ORM 接口的方式

      直接基于 JDBC 驅(qū)動方式較好 ~

      數(shù)據(jù)層的整體流程

      SQL 解析 ==> 規(guī)則處理 ==>SQL 改寫 ==> 數(shù)據(jù)源選擇 ==>SQL 執(zhí)行 ==> 結(jié)果集返回合并處理

      1、SQL 解析階段

      • SQL 解析并不完備

      • SQL 中不帶有分庫條件,但實際上是可以明確指定分庫的

      2、規(guī)則處理階段

      • 采用固定哈希算法作為規(guī)則,如根據(jù)用戶 id 取模,id mod 2 分庫,再 id mod 4 分表。實現(xiàn)簡單,但是如果擴容的話比較復雜!

      • 一致性哈希,節(jié)點對應的哈希值為一個范圍,分配給現(xiàn)有節(jié)點。如果有節(jié)點加入,會從原有節(jié)點分管一部分范圍的哈希值;如果有節(jié)點退出,會把哈希值交給下一個節(jié)點管理

      • 虛擬節(jié)點對一致性哈希的改進,引入虛擬節(jié)點,如 4 個物理節(jié)點可以變?yōu)槎鄠€虛擬節(jié)點,每個虛擬節(jié)點支持連續(xù)的哈希環(huán)上的一段。

      • 映射表與規(guī)則自定義計算方式,映射表是根據(jù)分庫分表字段的值的查表法來確定數(shù)據(jù)源的方法,一般用于對熱點數(shù)據(jù)的特殊處理。

      3、為什么要改寫 SQL

      分庫分表后,同一個賣家的商品可能會分在多個庫中,查詢就要跨庫。分布的不同數(shù)據(jù)庫中的表的結(jié)構(gòu)雖然一樣,但是表的名字、索引名字未必一樣,所以要修改 SQL。

      還有需要修改 SQL 的地方,如跨庫計算平均值,必須修改 SQL 獲取數(shù)量、總數(shù)后再進行計算。

      4、如何選擇數(shù)據(jù)源,讀寫分析

      5、執(zhí)行 SQL 和結(jié)果處理階段,異常處理和判斷

      第六章 消息中間件

      JMS,Java Message Service 是 Java EE 中關于消息的規(guī)范,ActiveMQ 等是對這個規(guī)范的實現(xiàn)。如果是小型系統(tǒng)直接使用 JMS 是一個經(jīng)濟的選擇,在大型系統(tǒng)中不適合使用 JMS。

      如何解決消息發(fā)送一致性

      消息發(fā)送一致性是指產(chǎn)生消息的業(yè)務動作與消息發(fā)送一致,即如果業(yè)務操作成功了,那么由這個操作產(chǎn)生的消息一定要發(fā)送出去。

      1、發(fā)送消息給消息中間件

      2、消息中間件入庫消息

      3、消息中間件返回結(jié)果

      4、業(yè)務操作

      5、發(fā)送業(yè)務操作結(jié)果給消息中間件

      6、更改存儲中消息狀態(tài)

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多