微架构 springcloud-10. Eureka 心跳管理

常见配置

心跳检测

客户端(Client):

  1. 注册服务收起发送:>> 每隔n(n=30,默认)秒向Eureka服务端发送信息,刷新注册服务,
  2. 客户端告知服务端:若在n秒内没有向服务器发送信息,则服务端将其从服务列表中删除

客户端添加如下配置:

#客户端每隔n秒向服务端发送数据包
eureka.instance.leaseRenewalIntervalInSeconds=5
#客户端告知服务端:若在n秒内没有向服务器发送信息,则服务端将其从服务列表中删除
eureka.instance.leaseExpirationDurationInSeconds=10
#配置日志级别
logging.level.com.netflix:DEBUG

服务端(Server):

  1. 关闭自我保护
  2. 注册服务周期检测:>> 每隔n(n=90,默认)秒检测服务端是否重新注册服务,否则将服务从服务列表中清除

相关配置如下:

#关闭Eureka服务自我保护
eureka.server.enable-self-preservation=false
#服务端每隔n秒刷新依次服务列表,将无效服务剔除
eureka.server.eviction-interval-timer-in-ms=5000

接下来做的都是单节点测试,故关闭Eureka作为客户端相关的配置,否则启动会报错:

#eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
# 关闭默认注册到eureka服务中心(该项目本身就是服务中心,无需自己注册自己)
eureka.client.register-with-eureka=false
# 关闭自动抓取服务端,该工程本身就是服务端
eureka.client.fetch-registry=false

重启Eureka服务 8761:

2018-03-16 11:47:38.507 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-16 11:47:38.507 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-16 11:47:38.507 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-16 11:47:38.515 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-16 11:47:38.515 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-16 11:47:38.515 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-16 11:47:38.515 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-16 11:47:38.515 DEBUG 70716 --- [tbeatExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP PUT http://localhost:8761/eureka//apps/APPTWO/192.168.198.2:AppTwo:8083; statusCode=200
2018-03-16 11:47:38.516 DEBUG 70716 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_APPTWO/192.168.198.2:AppTwo:8083 - Heartbeat status: 200
2018-03-16 11:47:43.519 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-16 11:47:43.519 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-16 11:47:43.519 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-16 11:47:43.528 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-16 11:47:43.529 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-16 11:47:43.529 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-16 11:47:43.529 DEBUG 70716 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-16 11:47:43.529 DEBUG 70716 --- [tbeatExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP PUT http://localhost:8761/eureka//apps/APPTWO/192.168.198.2:AppTwo:8083; statusCode=200
2018-03-16 11:47:43.529 DEBUG 70716 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient 

## 服务端每隔5秒刷新服务列表
2018-03-19 15:44:05.760  INFO 17660 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2018-03-19 15:44:10.761  INFO 17660 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms

重启客户端服务 8081:

2018-03-20 15:51:15.353 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-20 15:51:15.353 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-20 15:51:15.353 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-20 15:51:15.356 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-20 15:51:15.356 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-20 15:51:15.357 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-20 15:51:15.357 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-20 15:51:15.357 DEBUG 15556 --- [tbeatExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP PUT http://localhost:8761/eureka//apps/APPONE/192.168.198.2:AppOne:8081; statusCode=200
2018-03-20 15:51:15.357 DEBUG 15556 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_APPONE/192.168.198.2:AppOne:8081 - Heartbeat status: 200


2018-03-20 15:51:20.358 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-20 15:51:20.358 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-20 15:51:20.358 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP PUT http://localhost:8761/eureka//apps/APPONE/192.168.198.2:AppOne:8081; statusCode=200
2018-03-20 15:51:20.361 DEBUG 15556 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_APPONE/192.168.198.2:AppOne:8081 - Heartbeat status: 200


客户端每隔5秒向服务端发送信息!

强制停止客户端,查看服务端信息,打印:

2018-03-20 15:51:43.523  INFO 13276 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Evicting 1 items (expired=1, evictionLimit=1)
2018-03-20 15:51:43.523  WARN 13276 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : DS: Registry: expired lease for APPONE/192.168.198.2:AppOne:8081
2018-03-20 15:51:43.524  INFO 13276 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Cancelled instance APPONE/192.168.198.2:AppOne:8081 (replication=false)

服务端已将无效服务 AppOne:8081 剔除出服务列表

一个客户端(App2)要访问另一个客户端(App1)的服务,App2在启动过程中就会首先读取服务列表,将App1服务存储到自己(App2)上,App2 访问时则根据此路由访问App1的服务,那么App2如何确保App1服务一直是有效的呢?比如App1异常中断服务;所以,各App本身也会定时的向Eureka确认,刷新自己的可用的服务列表,默认是每隔 30s 向Eureka服务中心确认,此配置更改如下:

# 定时的向Eureka确认,刷新自己的可用的服务列表,修改为5s
eureka.client.registry-fetch-interval-seconds=5

#将原有注册相关配置时间间隔增大:

# 客户端每隔n秒向服务端发送数据包
eureka.instance.leaseRenewalIntervalInSeconds=60
# 客户端告知服务端:若在n秒内没有向服务器发送信息,则服务端将其从服务列表中删除
eureka.instance.leaseExpirationDurationInSeconds=600

重启App2,后台会没间隔5秒打印打印如下信息:

2018-03-21 09:42:59.080 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-21 09:42:59.080 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-21 09:42:59.080 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP GET http://localhost:8761/eureka//apps/delta?; statusCode=200
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Got delta update with apps hashcode UP_1_
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Added instance 192.168.198.2:AppTwo:8083 to the existing apps in region null
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Deleted instance 192.168.198.2:AppOne:8081 to the existing apps 
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : The total number of instances fetched by the delta processor : 2
2018-03-21 09:42:59.085 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : The total number of all instances in the client now is 1
2018-03-21 09:42:59.086 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Completed cache refresh task for discovery. All Apps hash code is Local region apps hashcode: UP_1_, is fetching remote regions? false 



2018-03-21 09:43:04.087 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://localhost:8761, timeout = 5000
2018-03-21 09:43:04.087 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : [{}->http://localhost:8761] total kept alive: 1, total issued: 0, total allocated: 1 out of 200
2018-03-21 09:43:04.087 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Getting free connection [{}->http://localhost:8761][null]
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.MonitoredConnectionManager  : Released connection is reusable.
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://localhost:8761][null]
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Pooling connection [{}->http://localhost:8761][null]; keep alive indefinitely
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] n.d.s.t.j.AbstractJerseyEurekaHttpClient : Jersey HTTP GET http://localhost:8761/eureka//apps/delta?; statusCode=200
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Got delta update with apps hashcode UP_1_
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Deleted instance 192.168.198.2:AppOne:8081 to the existing apps 
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : The total number of instances fetched by the delta processor : 1
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : The total number of all instances in the client now is 1
2018-03-21 09:43:04.091 DEBUG 19496 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Completed cache refresh task for discovery. All Apps hash code is Local region apps hashcode: UP_1_, is fetching remote regions? false 

将App1 /sayMesg/{word} 业务逻辑代码更改如下:

@RequestMapping(value = "/sayMesg/{word}")
public @ResponseBody String sayMesg(@PathVariable String word){
    if(word==null){
        return "未接收到参数!";
    }
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < word.length(); i++) {
        int acii = word.charAt(i);
        buffer.append(acii + ",");
    }
    return active + buffer.toString() ;
}

# 即返回参数world 的Ascii码

回顾App2 /getAppOneMesg/{mesg} 代码:

@RequestMapping("/getAppOneMesg/{mesg}")
public @ResponseBody String getAppOneMesg(@PathVariable String mesg){
    String strMesg=restTemplate.getForObject("http://APPONE/sayMesg/" + mesg, String.class);
    return "访问App2,从App1 收到信息:“"+strMesg+"”";
}

重新梳理逻辑:重启Eureka、App1、App2,待启动完成,访问 http://192.168.198.2:8083/getAppOneMesg/123456,页面打印:

访问App2,从App1 收到信息:“808149,50,51,52,53,54,“

强制停止App1服务,观察App2 控制台:

##其中打印:
2018-03-21 10:33:24.061 DEBUG 6636 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Deleted instance 192.168.198.2:AppOne:8081 to the existing apps 

App1 服务停止,那么Eureka服务端在扫描规则下会将App1从服务列表中剔除,App2 刷新本地服务列表,将不存在于服务端的App1从本地剔除

再访问:http://192.168.198.2:8083/getAppOneMesg/123456,页面打印:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Mar 21 10:36:43 CST 2018
There was an unexpected error (type=Internal Server Error, status=500).
No instances available for APPONE

# App1 已经停止服务,且本地(App2)已剔除该服务信息,故无法访问

重启App1,观察App2 客户端:

# 其中打印
2018-03-21 10:39:07.162 DEBUG 21960 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Added instance 192.168.198.2:AppOne:8081 to the existing apps in region null

# 说明App2已经将App1服务添加到本地

再访问:http://192.168.198.2:8083/getAppOneMesg/123456,页面打印:

访问App2,从App1 收到信息:“808149,50,51,52,53,54,“

# 应用恢复正常

客户端获取本地服务信息,以下示例以App2为列

  1. 注入DiscoveryClient
@Autowired
private DiscoveryClient discoveryClient;
  1. 获取服务名称,即:App1、App2
@GetMapping("/discoveryClientList")
public List discoveryClientList(){
    /*获取Eureka 中的服务名称列表*/
    List<String> services = discoveryClient.getServices();
    return services;
}
  1. 获取服务具体实例
@GetMapping("/discoveryClientInstanceList")
public List<Map> discoveryClientInstanceList(){
    /*获取客户端实例列表*/

    List<Map> list = new ArrayList<Map>();
    Map<String, Object> map = new HashMap<String, Object>();
    List<String> servicesNames = discoveryClient.getServices(); //获取名称
    for (String name : servicesNames) {
        map = new HashMap<String, Object>();
        List<ServiceInstance> instanceList = discoveryClient.getInstances(name);
        Map objs = new HashMap();
        for (ServiceInstance instance : instanceList) {
            objs.put("host", instance.getHost());
            objs.put("port", instance.getPort());
            objs.put("serviceId",instance.getServiceId());
            objs.put("uri", instance.getUri());
        }
        map.put(name, objs);
        list.add(map);
    }
    return list;
}

访问:http://192.168.198.2:8083/discoveryClientList 页面响应:

["appone","apptwo"]

# 只是服务名

访问:http://192.168.198.2:8083/discoveryClientInstanceList 页面响应:

[
    {"appone":{"port":8081,"host":"192.168.198.2","serviceId":"APPONE","uri":"http://192.168.198.2:8081"}},
    {"apptwo":{"port":8083,"host":"192.168.198.2","serviceId":"APPTWO","uri":"http://192.168.198.2:8083"}}
]

# 各服务名实例包括:端口、地址、ID、URI 等

配置元数据,App2 配置文件添加如下配置:

# 配置元数据:metadata
eureka.instance.metadata-map.companename:PersonJack
eureka.instance.metadata-map.address:chongqing

从DiscoveryClient 获取元数据,其实也是从ServiceInstance 中获取的,配置文件中spring.application.name即为实例名,故相关Controller 书写如下:

@GetMapping("/metaMap")
public @ResponseBody List metaMap(){
    List<ServiceInstance> instanceList = discoveryClient.getInstances("AppTwo");
    List list = new ArrayList();
    for (ServiceInstance instance : instanceList) {
        Map map=instance.getMetadata();
        list.add(map);
    }
    return list;
}

访问:http://192.168.198.2:8083/metaMap 页面响应如下:

[{"companename":"PersonJack","address":"chongqing"}]

# 元数据成功获取
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容