Zoopeeker介紹

1 方法遠程調(diào)用代碼的對比

// 使用遠程方法調(diào)用框架
@Controller
public class HelloController {
    // 將封裝了遠程服務(wù)功能的接口類型的bean裝配到當前組件
    @Autowired
    private EmpRemoteService empRemoteService;
    @RequestMapping("/aaa/bbb/ccc")
    public String doXxx(){
        // 像調(diào)用本地方法一樣調(diào)用遠程方法
        List<Emp> list = empRemoteService.getEmpList();
        // ...
    }
}
// 不使用遠程方法調(diào)用框架
// 1.創(chuàng)建HttpClient實例
CloseableHttpClient client = HttpClientBuilder.create().build();
try {
    // 2.聲明服務(wù)器端URL地址
    String url = "http://[服務(wù)器端實際IP]:54321/bookManager/book/getBook/23?requestParam=AAA";
    // 3.創(chuàng)建具體請求方式實例
    HttpGet get = new HttpGet(url);
    // 4.調(diào)用客戶端對象執(zhí)行請求,進而獲得響應(yīng)對象
    CloseableHttpResponse response = client.execute(get);
    // 5.從響應(yīng)結(jié)果中獲取封裝響應(yīng)數(shù)據(jù)的Entity對象
    HttpEntity entity = response.getEntity();
    // 6.借助工具類將HttpEntity中包含的數(shù)據(jù)轉(zhuǎn)換成可識別的字符串
    String responseData = EntityUtils.toString(entity, "UTF-8");
    // 7.處理響應(yīng)結(jié)果
    System.out.println(responseData);
    //Ensures that the entity content is fully consumed and the content stream, if exists, is closed.
    //確認entity的內(nèi)容已經(jīng)完全被consume了,而且如果內(nèi)容的流存在缠诅,確認其已經(jīng)關(guān)閉了枣抱。
    EntityUtils.consume(entity);
} catch (ClientProtocolException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace(); 
} finally {
    // 8.釋放連接,無論操作是否成功都必須釋放連接
    if(client != null) {try {client.close();} catch (IOException e) {e.printStackTrace();}}
}

2. 遠程方法調(diào)用框架和注冊中心工作機制

2.1 技術(shù)方案一

Dubbo作為遠程方法調(diào)用框架+Zookeeper作為注冊中心

2.2 技術(shù)方案二

SpringBoot+SpringCloud

→Eureka作為注冊中心

→Feign作為遠程方法調(diào)用框架

3. Zookeeper

3.1 簡介

ZooKeeper是用于維護配置信息,命名,提供分布式同步和提供組服務(wù)的集中式服務(wù)。所有這些類型的服務(wù)都以某種形式或由分布式應(yīng)用程序使用灸拍。每次實施它們時,都會進行很多工作來修復(fù)不可避免的錯誤和競爭條件砾省。
由于難以實現(xiàn)這類服務(wù)鸡岗,因此應(yīng)用程序通常最初會在其上跳過,從而使它們在存在更改的情況下變得脆弱并且難以管理编兄。即使部署正確轩性,當部署應(yīng)用程序時,這些服務(wù)的不同實現(xiàn)也會導(dǎo)致管理復(fù)雜狠鸳。

3.2 樹形目錄結(jié)構(gòu)

ZooKeeper使用樹形結(jié)構(gòu)管理數(shù)據(jù)揣苏。而且以“/”作為樹形結(jié)構(gòu)的根節(jié)點悯嗓。樹形結(jié)構(gòu)中的每一個節(jié)點都稱為“znode”。文件系統(tǒng)中的目錄可以存放其他目錄和文件卸察,znode中可以存放其他znode脯厨,也可以對應(yīng)一個具體的值。znode和它對應(yīng)的值之間是鍵值對的關(guān)系坑质。

每一個znode上同時還有一套狀態(tài)信息合武,稱為:stat。

3.3 異步通知機制

在分布式項目中隨著業(yè)務(wù)功能越來越多涡扼,具體的功能模塊也會越來越多稼跳,一個大型的電商項目能達到幾十個模塊甚至更多。這么多業(yè)務(wù)模塊的工程有可能需要共享一些信息吃沪,這些信息一旦發(fā)生變化岂贩,在各個相關(guān)模塊工程中手動逐一修改會非常麻煩,甚至可能發(fā)生遺漏巷波,嚴重的可能導(dǎo)致系統(tǒng)崩潰,造成經(jīng)濟損失卸伞。

使用ZooKeeper的通知機制后抹镊,各個模塊工程在特定znode上設(shè)置Watcher(觀察者)來監(jiān)控當前節(jié)點上值的變化。一旦Watcher檢測到了數(shù)據(jù)變化就會立即通知模塊工程荤傲,從而自動實現(xiàn)“一處修改垮耳,處處生效”的效果。

3.4 leader-follower集群

4. Zookeeper安裝

4.1 環(huán)境準備

Zookeeper需要在JVM虛擬機上運行遂黍,所以一定要保證有JDK支持终佛。

  1. 上傳JDK到linux虛擬機
  1. 到該路徑下
  1. 解壓jdk

tar -zxvf jdk-8u231-linux-x64.tar.gz

  1. 編輯etc/profile文件

    在文件末尾加上

    JAVA_HOME=/opt/jdk1.8.0_231
    PATH=$JAVA_HOME/bin:$PATH
    export JAVA_HOME PATH
    
  2. 接著進入到j(luò)dk文件中輸入命令

即JKD環(huán)境搭建成功

4.2 上傳Zookeeper

zookeeper-3.4.9.tar.gz

4.3 解壓

tar -zxvf /opt/zookeeper-3.4.9.tar.gz

4.4 準備配置文件

cp /opt/zookeeper-3.4.9/conf/zoo_sample.cfg /opt/zookeeper-3.4.9/conf/zoo.cfg

Zookeeper要求配置文件的文件名必須是:zoo.cfg

4.5 創(chuàng)建數(shù)據(jù)目錄

mkdir /opt/zookeeper-3.4.9/data

4.6 在zoo.cfg中配置數(shù)據(jù)目錄的位置

dataDir=/opt/zookeeper-3.4.9/data

5 Zookeeper服務(wù)器端操作

5.1 zoo.cfg文件解讀

tickTime
    通信心跳數(shù),ZooKeeper服務(wù)器心跳時間,單位毫秒
    ZooKeeper使用的基本時間雾家,服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時間間隔铃彰,也就是每個tickTime時間就會發(fā)送一個心跳,時間單位為毫秒芯咧。
    用于心跳機制牙捉,并且設(shè)置最小的session超時時間為兩倍心跳時間(session的最小超時時間是2*tickTime)。
initLimit
    LF初始通信時限
    集群中的Follower跟隨者服務(wù)器(F)與Leader領(lǐng)導(dǎo)者服務(wù)器(L)之間初始連接時能容忍的最多心跳數(shù)(tickTime的數(shù)量)敬飒。
    投票選舉新Leader的初始化時間邪铲,F(xiàn)ollower在啟動過程中,會從Leader同步所有最新數(shù)據(jù)无拗,然后確定自己能夠?qū)ν夥?wù)的起始狀態(tài)带到。
    Leader允許Follower在initLimit時間內(nèi)完成這個工作。
syncLimit
    LF同步通信時限
    集群中Leader與Follower之間的最大響應(yīng)時間單位英染,假如響應(yīng)超過syncLimit * tickTime揽惹,Leader認為Follwer死掉被饿,從服務(wù)器列表中刪除Follwer。
    在運行過程中永丝,Leader負責與ZooKeeper集群中所有機器進行通信锹漱,例如通過一些心跳檢測機制,來檢測機器的存活狀態(tài)慕嚷。
    如果L發(fā)出心跳包在syncLimit之后哥牍,還沒有從F那收到響應(yīng),那么就認為這個F已經(jīng)不在線了喝检。
dataDir
    數(shù)據(jù)文件目錄+數(shù)據(jù)持久化路徑
    保存內(nèi)存數(shù)據(jù)庫快照信息的位置嗅辣,如果沒有其他說明,更新的事務(wù)日志也保存到數(shù)據(jù)庫挠说。
clientPort
    客戶端連接端口

5.2 常用命令

5.2.1 ZooKeeper服務(wù)器與客戶端

  • 啟動服務(wù)器:./zkServer.sh start
  • 停止服務(wù)器:./zkServer.sh stop
  • 啟動客戶端:./zkCli.sh
  • 退出客戶端:[zk: localhost:2181(CONNECTED) 6] quit

5.2.2 ls

查看當前znode中所包含的內(nèi)容

5.2.3 ls2

查看當前節(jié)點數(shù)據(jù)并能看到更新次數(shù)等數(shù)據(jù)

5.2.4 stat

查看節(jié)點狀態(tài)

5.2.5 create

  • create [-s] [-e] path data acl
  • 普通創(chuàng)建:不帶有-s澡谭、-e參數(shù)
  • -s:含有序列
  • -e:臨時(重啟或者超時消失)

5.2.6 set

設(shè)置節(jié)點的具體值

set 節(jié)點 value值

5.2.7 get

獲得節(jié)點的值

get節(jié)點

5.2.8 delete

可以刪除指定znode,當該znode擁有子znode時损俭,必須先刪除其所有子znode蛙奖,否則操作將失敗。

5.2.9 rmr

rmr命令可用于代替delete命令杆兵,rmr是一個遞歸刪除命令雁仲,如果發(fā)生指定節(jié)點擁有子節(jié)點時,rmr命令會首先刪除子節(jié)點琐脏。

5.3 Zookeeper節(jié)點類型

  1. PERSISTENT-持久化目錄節(jié)點

    客戶端與zookeeper斷開連接后攒砖,該節(jié)點依舊存在

  2. PERSISTENT_SEQUENTIAL-持久化順序編號目錄節(jié)點

    客戶端與zookeeper斷開連接后,該節(jié)點依舊存在日裙,只是Zookeeper給該節(jié)點名稱進行順序編號

  3. EPHEMERAL-臨時目錄節(jié)點

    客戶端與zookeeper斷開連接后吹艇,該節(jié)點被刪除

  4. EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節(jié)點

    客戶端與zookeeper斷開連接后,該節(jié)點被刪除昂拂,只是Zookeeper給該節(jié)點名稱進行順序編號

5.4 Zookeeper節(jié)點狀態(tài)

5.4.1 介紹

znode維護了一個stat結(jié)構(gòu)受神,這個stat包含數(shù)據(jù)變化的版本號、訪問控制列表變化政钟、還有時間戳路克。版本號和時間戳一起,可讓ZooKeeper驗證緩存和協(xié)調(diào)更新养交。每次znode的數(shù)據(jù)發(fā)生了變化精算,版本號就增加。

例如:無論何時客戶端檢索數(shù)據(jù)碎连,它也一起檢索數(shù)據(jù)的版本號灰羽。并且當客戶端執(zhí)行更新或刪除時,客戶端必須提供他正在改變的znode的版本號。如果它提供的版本號和真實的數(shù)據(jù)版本號不一致廉嚼,更新將會失敗玫镐。

5.4.2 屬性

  • czxid:引起這個znode創(chuàng)建的zxid,創(chuàng)建節(jié)點的事務(wù)的zxid(ZooKeeper Transaction Id)

  • ctime:znode被創(chuàng)建的毫秒數(shù)(從1970年開始)

  • mzxid:znode最后更新的zxid

  • mtime:znode最后修改的毫秒數(shù)(從1970年開始)

  • pZxid:znode最后更新的子節(jié)點zxid

  • cversion:znode子節(jié)點變化號怠噪,znode子節(jié)點修改次數(shù)

  • dataversion:znode數(shù)據(jù)變化號

  • aclVersion:znode訪問控制列表的變化號

  • ephemeralOwner:如果是臨時節(jié)點恐似,這個是znode擁有者的session id。如果不是臨時節(jié)點則是0傍念。

  • dataLength:znode的數(shù)據(jù)長度

  • numChildren:znode子節(jié)點數(shù)量

    5.5 四字命令

5.5.1 介紹

ZooKeeper支持某些特定的四字命令矫夷,他們大多是用來查詢ZooKeeper服務(wù)的當前狀態(tài)及相關(guān)信息的,使用時通過telnet或nc向ZooKeeper提交相應(yīng)命令憋槐。

[root@right bin]# echo ruok | nc localhost 2181
imok[root@right bin]#

5.5.2 nc命令

nc命令需要安裝對應(yīng)的程序才可以使用双藕。

yum install -y nc

5.5.3 常用四字命令

  • ruok:測試服務(wù)是否處于正確狀態(tài)。如果確實如此阳仔,那么服務(wù)返回“imok ”忧陪,否則不做任何響應(yīng)
  • stat:輸出關(guān)于性能和連接的客戶端的列表
  • conf:輸出相關(guān)服務(wù)配置的詳細信息
  • cons:列出所有連接到服務(wù)器的客戶端的完全的連接 /會話的詳細信息。包括“接受 / 發(fā)送”的包數(shù)量近范、會話id 嘶摊、操作延遲、最后的操作執(zhí)行等等信息
  • dump:列出未經(jīng)處理的會話和臨時節(jié)點
  • envi:輸出關(guān)于服務(wù)環(huán)境的詳細信息(區(qū)別于conf命令)
  • reqs:列出未經(jīng)處理的請求
  • wchs:列出服務(wù)器watch的詳細信息
  • wchc:通過session列出服務(wù)器watch的詳細信息评矩,它的輸出是一個與watch相關(guān)的會話的列表
  • wchp:通過路徑列出服務(wù)器 watch的詳細信息更卒。它輸出一個與 session相關(guān)的路徑

6 Java客戶端

6.1 依賴信息

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.9</version>
</dependency>

6.2 修改節(jié)點數(shù)據(jù)操作

public class ZkTest {
    private ZooKeeper zooKeeper;
    {
        String connectString = "192.168.56.150:2181";
        int sessionTimeout = 5000;
        Watcher watcher = new Watcher() {
            @Override
            public void process(WatchedEvent event) {}
        };
        try {
            zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testUpdateNodeData() throws KeeperException, InterruptedException {
        // 要操作的節(jié)點的路徑
        String path = "/animal/cat";
        // 獲取節(jié)點當前值
        byte[] resultByteArray = zooKeeper.getData(path, false, new Stat());
        // 將字節(jié)數(shù)組封裝為字符串
        String result = new String(resultByteArray);
        // 打印舊值
        System.out.println("old value="+result);
        // 獲取新值字符串對應(yīng)的字節(jié)數(shù)組
        byte[] newValueByteArray = new String("miaomiao").getBytes();
        // 指定當前操作所基于的版本號,如果不確定可以使用-1
        int version = -1;
        // 執(zhí)行節(jié)點值的修改
        Stat stat = zooKeeper.setData(path, newValueByteArray, version);
        // 獲取最新版本號
        int newVersion = stat.getVersion();
        System.out.println("newVersion="+newVersion);
        // 獲取節(jié)點新值
        resultByteArray = zooKeeper.getData(path, false, new Stat());
        result = new String(resultByteArray);
        System.out.println("new value="+result);
    }
}

7. 異步通知機制

7.1 工作機制介紹

客戶端注冊監(jiān)聽它關(guān)心的目錄節(jié)點稚照,當目錄節(jié)點發(fā)生變化(數(shù)據(jù)改變、被刪除俯萌、子目錄節(jié)點增加刪除)時果录,zookeeper會通知客戶端。

ZooKeeper支持Watch(觀察)機制咐熙,客戶端可以在每個znode結(jié)點上設(shè)置一個Watcher(觀察者)弱恒。如果被觀察服務(wù)端的znode結(jié)點有變更,那么Watcher就會被觸發(fā)棋恼,這個Watcher所屬的客戶端將接收到一個通知包被告知結(jié)點已經(jīng)發(fā)生變化返弹,這就是把相應(yīng)的事件通知給設(shè)置過Watcher的Client端。

ZooKeeper里的所有讀取操作:getData(),getChildren()和exists()都有設(shè)置Watch的選項爪飘。

總結(jié)成一句話:ZooKeeper的觀察機制是一種異步回調(diào)的觸發(fā)機制义起。

當數(shù)據(jù)有了變化時zkServer向客戶端發(fā)送一個Watch通知,這是個一次性動作师崎,觸發(fā)一次就失效了默终。

如果想繼續(xù)Watch的話,需要客戶端重新設(shè)置Watcher。因此如果你得到了一個Watch事件齐蔽,并且在將來繼續(xù)得到節(jié)點變化通知两疚,那么就必須另外設(shè)置一個新的Watcher繼續(xù)觀察。

節(jié)點有不同的改動方式含滴∮詹常可以認為ZooKeeper維護兩個觀察列表:數(shù)據(jù)觀察和子節(jié)點觀察。getData()和exists()設(shè)置數(shù)據(jù)觀察谈况。getChildren()設(shè)置子節(jié)點觀察勺美。此外,還可以認為不同的返回數(shù)據(jù)有不同的觀察鸦做。getData()和exists()返回節(jié)點的數(shù)據(jù)励烦,而getChildren()返回子節(jié)點列表。所以泼诱,setData()將為znode觸發(fā)數(shù)據(jù)觀察坛掠。成功的create()將為新創(chuàng)建的節(jié)點觸發(fā)數(shù)據(jù)觀察,為其父節(jié)點觸發(fā)子節(jié)點觀察治筒。成功的delete()將會為被刪除的節(jié)點觸發(fā)數(shù)據(jù)觀察以及子節(jié)點觀察(因為節(jié)點不能再有子節(jié)點了)屉栓,為其父節(jié)點觸發(fā)子節(jié)點觀察。如果一個節(jié)點設(shè)置存在觀察時尚未創(chuàng)建耸袜,并且在斷開連接后執(zhí)行節(jié)點創(chuàng)建以及刪除操作友多,那么這個節(jié)點上設(shè)置的觀察事件客戶端接收不到,事件會丟失堤框。

7.2 一次性通知

@Test
public void testNoticeOnce() throws KeeperException, InterruptedException {
    String path = "/animal/cat";
    Watcher watcher = new Watcher() {
        @Override
        // 當前Watcher檢測到節(jié)點值的修改域滥,會調(diào)用這個process()方法
        public void process(WatchedEvent event) {
            System.err.println("接收到了通知!值發(fā)生了修改蜈抓!");
        }
    };
    byte[] oldValue = zooKeeper.getData(path, watcher, new Stat());
    System.out.println("old value="+new String(oldValue));
    while(true) {
        Thread.sleep(5000);
        System.err.println("當前方法原本要執(zhí)行的業(yè)務(wù)邏輯");
    }
}

7.3 持續(xù)通知

@Test
public void testNoticeForever() throws KeeperException, InterruptedException {
    String path = "/animal/cat";
    getDataWithNotice(zooKeeper, path);
    while(true) {
        Thread.sleep(5000);
        System.err.println("當前方法原本要執(zhí)行的業(yè)務(wù)邏輯 線程名稱:"+Thread.currentThread().getName());
    }
}
public void getDataWithNotice(ZooKeeper zooKeeper, String path) throws KeeperException, InterruptedException {
    byte[] resultByteArray = zooKeeper.getData(path, new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            // 以類似遞歸的方式調(diào)用getDataWithNotice()方法實現(xiàn)持續(xù)監(jiān)控
            try {
                getDataWithNotice(zooKeeper, path);
                System.err.println("通知 線程名稱:"+Thread.currentThread().getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }, new Stat());
    String result = new String(resultByteArray);
    System.err.println("當前節(jié)點值="+result);
}

8 集群

8.1 數(shù)據(jù)通信機制

  • 同一臺服務(wù)器上:IP地址一樣启绰,端口號必須得不一樣
  • 不同的服務(wù)器上:IP地址不一樣,端口號可以用同一個

8.2 搭建步驟

第1步:創(chuàng)建集群所在目錄

mkdir /opt/cluster-zk

第2步:重新解壓tar包到集群目錄

tar -zxvf /opt/zookeeper-3.4.9.tar.gz -C /opt/cluster-zk/

第3步:復(fù)制新的解壓目錄

cp -r /opt/cluster-zk/zookeeper-3.4.9/ /opt/cluster-zk/zkone

第4步:配置zkone

i:創(chuàng)建zoo.cfg配置文件

cp /opt/cluster-zk/zkone/conf/zoo_sample.cfg /opt/cluster-zk/zkone/conf/zoo.cfg

ii:創(chuàng)建數(shù)據(jù)目錄

mkdir /opt/cluster-zk/zkone/data

iii:在數(shù)據(jù)目錄中創(chuàng)建編號文件

vim /opt/cluster-zk/zkone/data/myid

touch myid

iv:編輯編號文件沟使,內(nèi)容就是當前服務(wù)器實例的編號

1

v:配置zoo.cfg

dataDir=/opt/cluster-zk/zkone/data

clientPort=1000

server.1=127.0.0.1:1001:1002

server.2=127.0.0.1:2001:2002

server.3=127.0.0.1:3001:3002

格式解釋:server.服務(wù)器實例編號=IP地址:數(shù)據(jù)通信端口號:選舉端口號

第5步:配置zktwo

i:把zktwo復(fù)制出來

cp -r /opt/cluster-zk/zkone /opt/cluster-zk/zktwo

ii:修改myid文件中編號值

vim /opt/cluster-zk/zktwo/data/myid

將1改成2

iii:修改zoo.cfg

dataDir=/opt/cluster-zk/zktwo/data

clientPort=2000

第6步:配置zkthree

i:把zkthree復(fù)制出來

cp -r /opt/cluster-zk/zkone /opt/cluster-zk/zkthree

ii:修改myid文件中編號值

vim /opt/cluster-zk/zkthree/data/myid

將1改成3

iii:修改zoo.cfg

dataDir=/opt/cluster-zk/zkthree/data

clientPort=3000

8.3 創(chuàng)建操作服務(wù)器的可執(zhí)行腳本

8.3.1 創(chuàng)建文件

  • /opt/cluster-zk/start.sh
  • /opt/cluster-zk/stop.sh
  • /opt/cluster-zk/status.sh

8.3.2 編輯啟動服務(wù)器命令

  • /opt/cluster-zk/zkone/bin/zkServer.sh start
  • /opt/cluster-zk/zktwo/bin/zkServer.sh start
  • /opt/cluster-zk/zkthree/bin/zkServer.sh start

8.3.3 編輯停止服務(wù)器命令

  • /opt/cluster-zk/zkone/bin/zkServer.sh stop
  • /opt/cluster-zk/zktwo/bin/zkServer.sh stop
  • /opt/cluster-zk/zkthree/bin/zkServer.sh stop

8.3.4 編輯查看服務(wù)器狀態(tài)命令

  • /opt/cluster-zk/zkone/bin/zkServer.sh status
  • /opt/cluster-zk/zktwo/bin/zkServer.sh status
  • /opt/cluster-zk/zkthree/bin/zkServer.sh status

8.3.5 給腳本文件設(shè)置可執(zhí)行權(quán)限

  • chmod 755 /opt/cluster-zk/start.sh
  • chmod 755 /opt/cluster-zk/stop.sh
  • chmod 755 /opt/cluster-zk/status.sh

8.3.6 執(zhí)行腳本

  • /opt/cluster-zk/start.sh
  • /opt/cluster-zk/stop.sh
  • /opt/cluster-zk/status.sh

8.3.7 客戶端登錄

  • /opt/zookeeper-3.4.9/bin/zkCli.sh -server 127.0.0.1:1000
  • /opt/zookeeper-3.4.9/bin/zkCli.sh -server 127.0.0.1:2000
  • /opt/zookeeper-3.4.9/bin/zkCli.sh -server 127.0.0.1:3000

8.4 集群中服務(wù)器數(shù)量

  • 結(jié)論:一般來說委可,集群中服務(wù)器數(shù)量最好設(shè)置為單數(shù)。

  • 原則:集群中有超過一半的服務(wù)器正常工程腊嗡,則整個集群判斷為正常工作着倾。對外提供服務(wù)時大致滿足預(yù)期。

  • 推導(dǎo):

    共2實例:宕機1實例燕少,剩下1=2/2卡者,沒有超過一半。死亡容忍度為0客们。

    共3實例:宕機1實例虎眨,剩下2>3/2蟋软,超過一半。死亡容忍度為1嗽桩。

    共4實例:宕機1實例岳守,剩下3>4/2,超過一半碌冶。死亡容忍度為1湿痢。

    共5實例:宕機2實例,剩下3>5/2扑庞,超過一半譬重。死亡容忍度為2。

    共6實例:宕機2實例罐氨,剩下4>6/2臀规,超過一半。死亡容忍度為2栅隐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末塔嬉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子租悄,更是在濱河造成了極大的恐慌谨究,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泣棋,死亡現(xiàn)場離奇詭異胶哲,居然都是意外死亡,警方通過查閱死者的電腦和手機潭辈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門鸯屿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人把敢,你說我怎么就攤上這事碾盟。” “怎么了技竟?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屈藐。 經(jīng)常有香客問我榔组,道長,這世上最難降的妖魔是什么联逻? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任搓扯,我火速辦了婚禮,結(jié)果婚禮上包归,老公的妹妹穿的比我還像新娘锨推。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布换可。 她就那樣靜靜地躺著椎椰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沾鳄。 梳的紋絲不亂的頭發(fā)上慨飘,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音译荞,去河邊找鬼瓤的。 笑死,一個胖子當著我的面吹牛吞歼,可吹牛的內(nèi)容都是我干的圈膏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼篙骡,長吁一口氣:“原來是場噩夢啊……” “哼稽坤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起医增,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤慎皱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后叶骨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茫多,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年忽刽,在試婚紗的時候發(fā)現(xiàn)自己被綠了天揖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡跪帝,死狀恐怖今膊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伞剑,我是刑警寧澤斑唬,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站黎泣,受9級特大地震影響恕刘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抒倚,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一褐着、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧托呕,春花似錦含蓉、人聲如沸频敛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斟赚。三九已至,卻和暖如春岂嗓,著一層夾襖步出監(jiān)牢的瞬間汁展,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工厌殉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留食绿,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓公罕,卻偏偏與公主長得像器紧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子楼眷,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容