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

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

    • 分享

      關(guān)于命名服務(wù)的知識點都在這里了

       鳳凰苑兇真 2017-05-25

      命名服務(wù),顧名思義,就是幫助我們對資源進行命名的服務(wù),命名的目的當然是為了更好的定位了。這里所提到的資源在不同場景中包括但不限于計算機(主機)名和地址、應(yīng)用提供的服務(wù)的地址或者遠程對象等。

      本文主要介紹Java中的命名服務(wù)、簡單的命名服務(wù)的實現(xiàn)策略以及在分布式場景中如何實現(xiàn)命名服務(wù)。

      JNDI

      要介紹命名服務(wù),不得不提 Java 命名和目錄接口(Java Naming and Directory Interface,JNDI),他是J2EE中重要的規(guī)范之一,標準的J2EE容器都提供了對JNDI規(guī)范的實現(xiàn)。

      在沒有JNDI的場景中,我們要配置一個JDBC驅(qū)動鏈接數(shù)據(jù)庫時我們需要做以下操作:

      Class.forName("com.mysql.jdbc.Driver");  
      Connection conn=DriverManager.getConnection("jdbc:mysql://DBName?user=hollis&password=hollischuang"); 

      上面的代碼中,把數(shù)據(jù)庫鏈接相關(guān)的字符串直接寫到了代碼中,這不是一個好的做法。有過web開發(fā)經(jīng)驗的人都知道,在真正的web開發(fā)中我們并不需要這樣定義JDBC的連接,我們一般都是把哪些固定的字符串配置到配置文件中,然后在代碼中直接從配置中讀取。甚至有很多數(shù)據(jù)庫處理的框架(Hibernate\mybatis)會幫我們把創(chuàng)建數(shù)據(jù)庫鏈接等操作全部都封裝好。

      使用 JNDI 得到數(shù)據(jù)源:

      Context ctx=new InitialContext();
      Object datasourceRef=ctx.lookup("java:comp/env/jdbc/mydatasource");
      DataSource ds=(Datasource)datasourceRef;
      Connection c=ds.getConnection();  

      為了讓 JNDI 解析 java:comp/env/jdbc/mydatasource 引用,部署人員必須把 標簽插入 web.xml 文件(Web 應(yīng)用程序的部署描述符)。 標簽的意思就是“這個組件依賴于外部資源”。

      <resource-ref>
        <description>Dollys DataSource</description>
        <res-ref-name>jdbc/mydatasource</res-ref-name>
        <res-ref-type>javax.sql.DataSource</res-ref-type>
        <res-auth>Container</res-auth>
      </resource-ref>

      上面介紹的JNDI是一種Java的命名服務(wù)。他充分的反映出命名服務(wù)的特點——對某一資源進行命名,然后通過名稱來定位唯一的資源。

      到這里,我們可以確定的是:命名服務(wù)的目的是定義一個唯一的名字。這個名字的作用是可以用來定義唯一的資源。那么,我們想一想,在日常開發(fā)中我們?nèi)绾谓o一組資源中的每一個某一個進行一個唯一的命名呢?在數(shù)據(jù)庫開發(fā)中,通常有兩種方案:自增的IDUUID

      數(shù)據(jù)庫自增ID

      在數(shù)據(jù)庫中,為了標識唯一記錄,可以使用自增ID,只要指定某個字段是自增的,那么數(shù)據(jù)庫就會幫我們維護這個字段的自增。不同數(shù)據(jù)庫的實現(xiàn)原理不一樣,即使是MySql數(shù)據(jù)庫,不同的引擎的實現(xiàn)方式也不盡相同。InnoDB 中AUTO_INCREMENT的實現(xiàn)原理可以參考:innodb-auto-increment-handling

      但是,無論如何,自增ID的實現(xiàn)都是基于單庫單表的。也就是說一旦涉及到分庫分表及分布式環(huán)境,就不能依賴數(shù)據(jù)庫的自增字段來唯一標識一條記錄了。也就是說,他生成的ID也就不再能保證是唯一的了。

      UUID

      UUID(Universally Unique Identifier)全局唯一標識符,是指在一臺機器上生成的數(shù)字,它保證對在同一時空中的所有機器都是唯一的。按照開放軟件基金會(OSF)制定的標準計算,用到了以太網(wǎng)卡地址、納秒級時間、芯片ID碼和許多可能的數(shù)字。由以下幾部分的組合:當前日期和時間(UUID的第一個部分與時間有關(guān),如果你在生成一個UUID之后,過幾秒又生成一個UUID,則第一個部分不同,其余相同),時鐘序列,全局唯一的IEEE機器識別號(如果有網(wǎng)卡,從網(wǎng)卡獲得,沒有網(wǎng)卡以其他方式獲得),UUID的唯一缺陷在于生成的結(jié)果串會比較長。

      UUID是由一組32位數(shù)的16進制數(shù)字所構(gòu)成,也就是說若每納秒產(chǎn)生1兆個UUID,要花100億年才會將所有UUID用完。

      在Java中,可以通過java.util.UUIDUUID.randomUUID();來生成一個UUID。

      UUID是可以保證唯一性的,因為在這個長度為32位的ID中包含了時間、時鐘序列、全局唯一IEEE機器識別號等。但是,他有兩個比較明顯的缺點,那就是長度過長和沒有任何含義。長度自然不必說,他有32位16進制數(shù)字。對于『550e8400-e29b-41d4-a716-446655440000』這個字符串來說,我想任何一個程序員都看不出其表達的含義。一旦使用它作為全局唯一標識,就意味著在日后的問題排查和開發(fā)調(diào)試過程中會遇到很大的困難。


      上面介紹了兩種傳統(tǒng)的數(shù)據(jù)庫中生成唯一標識的方法:自增ID和UUID。他們的優(yōu)缺點正好相反:

      • 自增ID的優(yōu)點是語義比較明確,至少我們可以知道他是第幾個生成的,而且,在很多場景中我們需要ID的自增性。但是他無法在分布式環(huán)境中保證其唯一性。
      • UUID的優(yōu)點是可以在分布式環(huán)境中保證其唯一性,但是沒有明確的語義。

      那么,有沒有一種方法可以在分布式環(huán)境生成一組自增的、唯一的ID呢?

      Zookeeper的命名服務(wù)

      Zookeeper是一個開放源碼的分布式服務(wù)協(xié)調(diào)組件,是Google Chubby的開源實現(xiàn)。是一個高性能的分布式數(shù)據(jù)一致性解決方案。他將那些復(fù)雜的、容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并提供一系列簡單易用的接口給用戶使用。(http://www./archives/tag/zookeeper)

      Zookeeper 的命名服務(wù)與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結(jié)構(gòu)關(guān)聯(lián)到一定資源上,但是 Zookeeper 的命名服務(wù)更加是廣泛意義上的關(guān)聯(lián),也許你并不需要將名稱關(guān)聯(lián)到特定資源上,你可能只需要一個不會重復(fù)名稱,就像數(shù)據(jù)庫中產(chǎn)生一個唯一的數(shù)字主鍵一樣。

      Zookeeper可以實現(xiàn)命名服務(wù)有兩個重要的前提

      一、節(jié)點類似于文件系統(tǒng)中的目錄結(jié)構(gòu)

      二、可以創(chuàng)建順序節(jié)點


      上面說過,我們想在分布式環(huán)境生成一組自增的、唯一的ID,那么看看zookeeper如何保證這兩點。

      • 唯一性

        • 由于zookeeper中的節(jié)點的結(jié)構(gòu)和文件系統(tǒng)中的目錄結(jié)構(gòu)是類似的,想想我們自己的電腦,我們使用一個全路徑是不是可以唯一定位到某個目錄中的某個文件。如 /home/admin/hollis.txt是可以唯一定位到一個文件的。
      • 自增性

        • 在zookeeper中可以創(chuàng)建順序節(jié)點,在ZooKeeper中,每個父節(jié)點會為他的第一級子節(jié)點維護一份時序,會記錄每個子節(jié)點創(chuàng)建的先后順序?;谶@個特性,在創(chuàng)建子節(jié)點的時候,可以設(shè)置這個屬性,那么在創(chuàng)建節(jié)點過程中,ZooKeeper會自動為給定節(jié)點名加上一個數(shù)字后綴,作為新的節(jié)點名。如 /home/admin/hollis1 /home/admin/hollis2 /home/admin/hollis3

      下面是一個用開源客戶端ZKClient實現(xiàn)的命名服務(wù)的例子:

      ZkClient client = new ZkClient(server, 5000, 5000, new BytesPushThroughSerializer());
      final String fullNodePath = root.concat("/home/admin").concat("hollis");
      final String ourPath = client.createPersistentSequential(fullNodePath, null);
      client.delete(ourPath);
      sout(ourPath);

      以上代碼就可以在/home/admin節(jié)點下創(chuàng)建出順序的hollis節(jié)點,節(jié)點名稱hollis-0000000001 hollis-0000000002 hollis-0000000003那么,我們就可以通過/home/admin/hollis-0000000001來唯一定位到一個節(jié)點了,那么我們直接用這個名稱給其他的資源命名了。

      總結(jié)

      一些比較常見的分布式框架(RPC、RMI)等都需要用到命名服務(wù),如何解決分布式場景中的統(tǒng)一命名是一個至關(guān)重要的話題。

      通過本文的介紹,可以知道Zookeeper可以解決分布式場景中的統(tǒng)一命名問題。通過本文,讀者不必立刻很深入的理解其中的原理,只需要知道zookeeper是可以做分布式的命名服務(wù)的就可以了,在以后的工作中遇到類似的場景可以想到zookeeper就夠了。

      【公告】版權(quán)聲明

      (全文完)
      歡迎關(guān)注HollisChuang微信公眾賬號

      如未加特殊說明,此網(wǎng)站文章均為原創(chuàng),轉(zhuǎn)載必須注明出處。HollisChuang's Blog ? 關(guān)于命名服務(wù)的知識點都在這里了

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多