Thrift入門(mén)及Java實(shí)例演示【轉(zhuǎn)】

概述

Thrift是一個(gè)軟件框架苟径,用來(lái)進(jìn)行可擴(kuò)展且跨語(yǔ)言的服務(wù)的開(kāi)發(fā)案站。它結(jié)合了功能強(qiáng)大的軟件堆棧和代碼生成引擎,以構(gòu)建在 C++、Java蟆盐、Python承边、PHP、Ruby石挂、Erlang博助、Perl、Haskell痹愚、C#富岳、Cocoa、JavaScript拯腮、Node.js窖式、Smalltalk、and OCaml 等等編程語(yǔ)言間無(wú)縫結(jié)合的动壤、高效的服務(wù)萝喘。

Thrift最初由facebook開(kāi)發(fā),07年四月開(kāi)放源碼琼懊,08年5月進(jìn)入Apache孵化器阁簸。Thrift允許你定義一個(gè)簡(jiǎn)單的定義文件中的數(shù)據(jù)類(lèi)型和服務(wù)接口。以作為輸入文件哼丈,編譯器生成代碼用來(lái)方便地生成RPC客戶(hù)端和服務(wù)器通信的無(wú)縫跨編程語(yǔ)言启妹。

官網(wǎng)地址:thrift.apache.org

下載配置

到官網(wǎng)下載最新版本,截止今日(2016-04-23)最新版本為0.9.3

  • 如果是Maven構(gòu)建項(xiàng)目的醉旦,直接在pom.xml 中添加如下內(nèi)容:
<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.9.3</version>
</dependency>
  • 如果自己編譯lib包饶米,把下載的壓縮包解壓到X:盤(pán),然后在X:\thrift-0.9.3\lib\java 目錄下運(yùn)行ant進(jìn)行自動(dòng)編譯髓抑,會(huì)在X:\thrift-0.9.3\lib\java\build\ 目錄下看到編譯好的lib包:libthrift-0.9.3.jar

基本概念

數(shù)據(jù)類(lèi)型

  • 基本類(lèi)型:
    bool:布爾值咙崎,true 或 false,對(duì)應(yīng) Java 的 boolean
    byte:8 位有符號(hào)整數(shù)吨拍,對(duì)應(yīng) Java 的 byte
    i16:16 位有符號(hào)整數(shù)褪猛,對(duì)應(yīng) Java 的 short
    i32:32 位有符號(hào)整數(shù),對(duì)應(yīng) Java 的 int
    i64:64 位有符號(hào)整數(shù)羹饰,對(duì)應(yīng) Java 的 long
    double:64 位浮點(diǎn)數(shù)伊滋,對(duì)應(yīng) Java 的 double
    string:utf-8編碼的字符串,對(duì)應(yīng) Java 的 String

  • 結(jié)構(gòu)體類(lèi)型:
    struct:定義公共的對(duì)象队秩,類(lèi)似于 C 語(yǔ)言中的結(jié)構(gòu)體定義笑旺,在 Java 中是一個(gè) JavaBean

  • 容器類(lèi)型:
    list:對(duì)應(yīng) Java 的 ArrayList
    set:對(duì)應(yīng) Java 的 HashSet
    map:對(duì)應(yīng) Java 的 HashMap

  • 異常類(lèi)型:
    exception:對(duì)應(yīng) Java 的 Exception

  • 服務(wù)類(lèi)型:
    service:對(duì)應(yīng)服務(wù)的類(lèi)

服務(wù)端編碼基本步驟

  1. 實(shí)現(xiàn)服務(wù)處理接口impl
  2. 創(chuàng)建TProcessor
  3. 創(chuàng)建TServerTransport
  4. 創(chuàng)建TProtocol
  5. 創(chuàng)建TServer
  6. 啟動(dòng)Server

客戶(hù)端編碼基本步驟

  1. 創(chuàng)建Transport
  2. 創(chuàng)建TProtocol
  3. 基于TTransport和TProtocol創(chuàng)建Client
  4. 調(diào)用Client的相應(yīng)方法

數(shù)據(jù)傳輸協(xié)議

  1. TBinaryProtocol 二進(jìn)制格式
  2. TCompactProtocol 壓縮格式
  3. TJSONProtocol JSON格式
  4. TSimpleJSONProtocol 提供JSON只寫(xiě)協(xié)議,生成的文件很容易通過(guò)腳本語(yǔ)言解析

提示:客戶(hù)端和服務(wù)端的協(xié)議要一致

實(shí)例演示

Thrift生成代碼

創(chuàng)建Thrift文件馍资,比如G:\thrift\test\HelloWorld.thrift ,內(nèi)容如下:

namespace java com.thrift.demo
 
service HelloWorldService {
    string sayHello(1:string username)
}

使用從官網(wǎng)提供下載的thrift-0.9.3.exe筒主,運(yùn)用這個(gè)工具生成相關(guān)代碼:

thrift-0.9.3.exe -r -gen java ./HelloWorld.thrift

將生成的HelloWorldService.java 文件復(fù)制到自己測(cè)試的工程中,我的工程是用Maven構(gòu)建的,故在pom.xml中增加如下內(nèi)容:

<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.9.3</version>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.7.5</version>
</dependency>

實(shí)現(xiàn)接口Iface

Java代碼:HelloWorldImpl.java

package com.thrift.demo;

import org.apache.thrift.TException;

public class HelloWorldImpl implements HelloWorldService.Iface {

 public HelloWorldImpl() {
 }

 @Override
 public String sayHello(String username) throws TException {
 return "Hi," + username + " welcome to thrift demo world";
 }

}

TSimpleServer服務(wù)端

簡(jiǎn)單的單線(xiàn)程服務(wù)模型乌妙,一般用于測(cè)試使兔。
編寫(xiě)服務(wù)端server代碼:ThriftServer.java

package com.thrift.demo.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.TTransportFactory;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.impl.HelloWorldServiceImpl;

/**
 ************************************************************
 * @類(lèi)名 ThriftServer
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class ThriftServerDemo {

    public void startServer() {
        try {
            System.out.println("Starting Thrift Server......");

            TProcessor processor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

            TServerSocket serverTransport = new TServerSocket(8191);

            TTransportFactory transportFactory = new TFramedTransport.Factory();

            Factory factory = new TBinaryProtocol.Factory();

            TServer.Args tArgs = new TServer.Args(serverTransport);
            tArgs.protocolFactory(factory);
            tArgs.transportFactory(transportFactory);
            tArgs.processor(processor);

            // 簡(jiǎn)單的單線(xiàn)程服務(wù)模型,一般用于測(cè)試
            TServer server = new TSimpleServer(tArgs);

            server.serve();

        } catch (TTransportException e) {
            System.out.println("Starting Thrift Server......Error!!!");
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        ThriftServerDemo server = new ThriftServerDemo();
        server.startServer();
    }

}

編寫(xiě)客戶(hù)端Client代碼:ThriftClientDemo.java

package com.thrift.demo.client;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.HelloWorldService.Client;

/**
 ************************************************************
 * @類(lèi)名 ThriftClient
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class ThriftClientDemo {

    public static void main(String[] args) {
        try {
            TTransport transport = new TFramedTransport(new TSocket("127.0.0.1", 8191, 5000));
            // 協(xié)議要和服務(wù)端一致
            TProtocol protocol = new TBinaryProtocol(transport);

            Client client = new HelloWorldService.Client(protocol);

            transport.open();

            String string = client.sayHello("Neo");

            System.out.println(string);

            transport.close();

        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        }
    }

}

先運(yùn)行服務(wù)端程序藤韵,日志如下:

Starting Thrift Server......

再運(yùn)行客戶(hù)端調(diào)用程序虐沥,日志如下:

Hello World,Hello Thrift!!! Hi:Neo

測(cè)試成功,和預(yù)期的返回信息一致泽艘。

TThreadPoolServer 服務(wù)模型

線(xiàn)程池服務(wù)模型欲险,使用標(biāo)準(zhǔn)的阻塞式IO,預(yù)先創(chuàng)建一組線(xiàn)程處理請(qǐng)求匹涮。
編寫(xiě)服務(wù)端代碼:HelloServerDemo.java


package com.thrift.demo.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.impl.HelloWorldServiceImpl;

/**
 ************************************************************
 * @類(lèi)名 HelloServerDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloServerDemo {
    public static final int SERVER_PORT = 8191;

    public void startServer() {
        try {
            System.out.println("HelloWorld TThreadPoolServer start ....");

            TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

            TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
            TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(serverTransport);
            ttpsArgs.processor(tprocessor);
            ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());

            // 線(xiàn)程池服務(wù)模型天试,使用標(biāo)準(zhǔn)的阻塞式IO,預(yù)先創(chuàng)建一組線(xiàn)程處理請(qǐng)求焕盟。
            TServer server = new TThreadPoolServer(ttpsArgs);
            server.serve();

        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        HelloServerDemo server = new HelloServerDemo();
        server.startServer();
    }

}

客戶(hù)端Client代碼和之前的一樣秋秤,只要數(shù)據(jù)傳輸?shù)膮f(xié)議一致即可宏粤,客戶(hù)端測(cè)試成功脚翘,結(jié)果如下:

Hello World,Hello Thrift!!! Hi:Neo

TNonblockingServer 服務(wù)模型

使用非阻塞式IO,服務(wù)端和客戶(hù)端需要指定 TFramedTransport 數(shù)據(jù)傳輸?shù)姆绞健?br> 編寫(xiě)服務(wù)端代碼:HelloServerDemo.java

package com.thrift.demo.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.impl.HelloWorldServiceImpl;

/**
 ************************************************************
 * @類(lèi)名 HelloServerDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloServerDemo {
    public static final int SERVER_PORT = 8191;

    public void startServer() {
        try {
            System.out.println("HelloWorld TNonblockingServer start ....");

            TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
            TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
            tnbArgs.processor(tprocessor);
            tnbArgs.transportFactory(new TFramedTransport.Factory());
            tnbArgs.protocolFactory(new TCompactProtocol.Factory());

            // 使用非阻塞式IO绍哎,服務(wù)端和客戶(hù)端需要指定TFramedTransport數(shù)據(jù)傳輸?shù)姆绞?            TServer server = new TNonblockingServer(tnbArgs);
            server.serve();

        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        HelloServerDemo server = new HelloServerDemo();
        server.startServer();
    }
}

編寫(xiě)客戶(hù)端代碼:HelloClientDemo.java

package com.thrift.demo.client;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

import com.thrift.demo.service.HelloWorldService;

/**
 ************************************************************
 * @類(lèi)名 HelloClientDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloClientDemo {

    public static final String SERVER_IP = "127.0.0.1";

    public static final int SERVER_PORT = 8191;

    public static final int TIMEOUT = 30000;

    public void startClient(String userName) {
        TTransport transport = null;
        try {
            transport = new TFramedTransport(new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT));
            // 協(xié)議要和服務(wù)端一致
            TProtocol protocol = new TCompactProtocol(transport);
            HelloWorldService.Client client = new HelloWorldService.Client(protocol);
            transport.open();
            String result = client.sayHello(userName);
            System.out.println("Thrify client result =: " + result);
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }

    public static void main(String[] args) {
        HelloClientDemo client = new HelloClientDemo();
        client.startClient("Neo");

    }
}

客戶(hù)端的測(cè)試成功来农,結(jié)果如下:

Thrify client result =: Hello World,Hello Thrift!!! Hi:Neo

THsHaServer服務(wù)模型

半同步半異步的服務(wù)端模型,需要指定為: TFramedTransport 數(shù)據(jù)傳輸?shù)姆绞健?br> 編寫(xiě)服務(wù)端代碼:HelloServerDemo.java

package com.thrift.demo.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.impl.HelloWorldServiceImpl;

/**
 ************************************************************
 * @類(lèi)名 HelloServerDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloServerDemo {

    public static final int SERVER_PORT = 8191;

    public void startServer() {
        try {
            System.out.println("HelloWorld THsHaServer start ....");

            TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
            THsHaServer.Args thhsArgs = new THsHaServer.Args(tnbSocketTransport);
            thhsArgs.processor(tprocessor);
            thhsArgs.transportFactory(new TFramedTransport.Factory());
            thhsArgs.protocolFactory(new TBinaryProtocol.Factory());

            // 半同步半異步的服務(wù)模型
            TServer server = new THsHaServer(thhsArgs);
            server.serve();

        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        HelloServerDemo server = new HelloServerDemo();
        server.startServer();
    }
}

客戶(hù)端代碼和上一個(gè)服務(wù)模型的Client中的類(lèi)似崇堰,只要注意傳輸協(xié)議一致以及指定傳輸方式為T(mén)FramedTransport沃于。

異步客戶(hù)端

編寫(xiě)服務(wù)端代碼:HelloServerDemo.java

package com.thrift.demo.client;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.impl.HelloWorldServiceImpl;

/**
 ************************************************************
 * @類(lèi)名 HelloServerDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloServerDemo {

    public static final int SERVER_PORT = 8191;

    public void startServer() {
        try {
            System.out.println("HelloWorld TNonblockingServer start ....");

            TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
            TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
            tnbArgs.processor(tprocessor);
            tnbArgs.transportFactory(new TFramedTransport.Factory());
            tnbArgs.protocolFactory(new TCompactProtocol.Factory());

            // 使用非阻塞式IO,服務(wù)端和客戶(hù)端需要指定TFramedTransport數(shù)據(jù)傳輸?shù)姆绞?            TServer server = new TNonblockingServer(tnbArgs);
            server.serve();

        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        HelloServerDemo server = new HelloServerDemo();
        server.startServer();
    }
}

編寫(xiě)客戶(hù)端Client代碼:HelloAsynClientDemo.java

package com.thrift.demo.client;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;

import com.thrift.demo.service.HelloWorldService;
import com.thrift.demo.service.HelloWorldService.AsyncClient.sayHello_call;

/**
 ************************************************************
 * @類(lèi)名 HelloAsynClientDemo
 * 
 * @AUTHOR Neo
 ************************************************************
 */
public class HelloClientDemo {

    public static final String SERVER_IP = "127.0.0.1";

    public static final int SERVER_PORT = 8191;

    public static final int TIMEOUT = 30000;

    public void startClient(String userName) {
        try {
            TAsyncClientManager clientManager = new TAsyncClientManager();
            TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP, SERVER_PORT, TIMEOUT);

            TProtocolFactory tprotocol = new TCompactProtocol.Factory();
            HelloWorldService.AsyncClient asyncClient = new HelloWorldService.AsyncClient(tprotocol, clientManager, transport);
            System.out.println("Client start .....");

            CountDownLatch latch = new CountDownLatch(1);
            AsynCallback callBack = new AsynCallback(latch);
            System.out.println("call method sayHello start ...");
            asyncClient.sayHello(userName, callBack);
            System.out.println("call method sayHello .... end");
            boolean wait = latch.await(30, TimeUnit.SECONDS);
            System.out.println("latch.await =:" + wait);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("startClient end.");
    }

    public class AsynCallback implements AsyncMethodCallback<sayHello_call> {

        private CountDownLatch latch;

        public AsynCallback(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void onComplete(sayHello_call response) {
            System.out.println("onComplete");
            try {
                // Thread.sleep(1000L * 1);
                System.out.println("AsynCall result =:" + response.getResult().toString());
            } catch (TException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        }

        @Override
        public void onError(Exception exception) {
            System.out.println("onError :" + exception.getMessage());
            latch.countDown();
        }
    }

    public static void main(String[] args) {
        HelloAsynClientDemo client = new HelloAsynClientDemo();
        client.startClient("Neo");
    }
    
}

先運(yùn)行服務(wù)程序海诲,再運(yùn)行客戶(hù)端程序繁莹,測(cè)試結(jié)果如下:

Client start .....
call method sayHello start ...
call method sayHello .... end
onComplete
AsynCall result =:Hello World,Hello Thrift!!! Hi:Neo
latch.await =:true
startClient end.

設(shè)計(jì)思路

  • Thrift的Server類(lèi)型有TSimpleServer、TNonblockingServer特幔、THsHaServer咨演、TThreadedSelectorServer、TThreadPoolServer
  • TSimpleServer是單線(xiàn)程阻塞IO的方式蚯斯,僅用于demo
  • TNonblockingServer是單線(xiàn)程非阻塞IO的方式薄风,通過(guò)java.nio.channels.Selector的select()接收連接請(qǐng)求,但是處理消息仍然是單線(xiàn)程拍嵌,吞吐量有限不可用于生產(chǎn)
  • THsHaServer使用一個(gè)單獨(dú)的線(xiàn)程處理IO遭赂,一個(gè)獨(dú)立的worker線(xiàn)程池處理消息, 可以并行處理所有請(qǐng)求
  • TThreadPoolServer使用一個(gè)專(zhuān)用連接接收connection横辆,一旦接收到請(qǐng)求就會(huì)放入ThreadPoolExecutor中的一個(gè)worker里處理撇他,當(dāng)請(qǐng)求處理完畢該worker釋放并回到線(xiàn)程池中,可以配置線(xiàn)程最大值,當(dāng)達(dá)到線(xiàn)程最大值時(shí)請(qǐng)求會(huì)被阻塞困肩。TThreadPoolServer性能表現(xiàn)優(yōu)異募疮,代價(jià)是并發(fā)高時(shí)會(huì)創(chuàng)建大量線(xiàn)程
  • TThreadedSelectorServer是thrift 0.8引入的實(shí)現(xiàn),處理IO也使用了線(xiàn)程池僻弹,比THsHaServer有更高的吞吐量和更低的時(shí)延阿浓,與TThreadPoolServer比性能相近且能應(yīng)對(duì)網(wǎng)絡(luò)IO較多的情況
  • 對(duì)于客戶(hù)端較少的情況,TThreadPoolServer也有優(yōu)異的性能表現(xiàn)蹋绽,但是考慮到未來(lái)SOA可能的高并發(fā)芭毙,決定采用TThreadedSelectorServer
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市卸耘,隨后出現(xiàn)的幾起案子退敦,更是在濱河造成了極大的恐慌,老刑警劉巖蚣抗,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侈百,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡翰铡,警方通過(guò)查閱死者的電腦和手機(jī)钝域,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锭魔,“玉大人例证,你說(shuō)我怎么就攤上這事∶耘酰” “怎么了织咧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)漠秋。 經(jīng)常有香客問(wèn)我笙蒙,道長(zhǎng),這世上最難降的妖魔是什么庆锦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任捅位,我火速辦了婚禮,結(jié)果婚禮上肥荔,老公的妹妹穿的比我還像新娘绿渣。我一直安慰自己,他們只是感情好燕耿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布中符。 她就那樣靜靜地躺著,像睡著了一般誉帅。 火紅的嫁衣襯著肌膚如雪淀散。 梳的紋絲不亂的頭發(fā)上右莱,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音档插,去河邊找鬼慢蜓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛郭膛,可吹牛的內(nèi)容都是我干的晨抡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼则剃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耘柱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起棍现,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤调煎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后己肮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體士袄,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年谎僻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娄柳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戈稿,死狀恐怖西土,靈堂內(nèi)的尸體忽然破棺而出讶舰,到底是詐尸還是另有隱情鞍盗,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布跳昼,位于F島的核電站般甲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鹅颊。R本人自食惡果不足惜敷存,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堪伍。 院中可真熱鬧锚烦,春花似錦、人聲如沸帝雇。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)尸闸。三九已至彻亲,卻和暖如春孕锄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背苞尝。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工畸肆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宙址。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓轴脐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親抡砂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子豁辉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 轉(zhuǎn)自:http://blog.csdn.net/kesonyk/article/details/50924489 ...
    晴天哥_王志閱讀 24,784評(píng)論 2 38
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)舀患,斷路器徽级,智...
    卡卡羅2017閱讀 134,628評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法聊浅,內(nèi)部類(lèi)的語(yǔ)法餐抢,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法低匙,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,597評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在旷痕,面了一些公司,掛了不少顽冶,但最終還是拿到小米欺抗、百度、阿里强重、京東绞呈、新浪、CVTE间景、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,207評(píng)論 11 349
  • 在面對(duì)這個(gè)問(wèn)題的時(shí)候倘要,其實(shí)我們應(yīng)該首先解決幾個(gè)問(wèn)題:1.什么是真正的藝術(shù)圾亏?2.什么是藝術(shù)家?3.什么是真正的藝術(shù)家...
    六戈島夫閱讀 3,550評(píng)論 0 0