架构大图-全局架构治理的未来

序言

该篇文章由我的好朋友飞哥完成,倾注了公司全局架构组以及各个领域专家、技术专家以及业务负责人的建设性理念。本人很荣幸参与到架构大图讨论之中。也希望这篇文章在大家架构建设及治理上贡献一份力量。

一、现状

  • 随着微服务架构貌似不可回头的发展、以及业务加速的前进,本地生活的系统架构越来越复杂。原到家业务已有数百个服务组成,服务治理、稳定性保障、业务交付效率的挑战不言而喻。
  • 面对越来越庞大的架构和业务,组织越来越希望有更多具有全局视角的全局架构师,来做保大促、产品架构方案、中台架构融合方案等,这些都需要全局视角能力。
  • 到目前为止没有一个元系统或者一个架构师,能够从整个业务视角进行全局架构层面的掌控。而架构往往需要从整体上下文去考虑业务的运转机制,不能掌控全局,这意着架构发展的正确性、稳定性有可能依靠的是运气、某些突出的个体,而不是体系。

二、愿景

无论是全局架构师、垂直领域架构师,他们都需要一把利剑:架构大图。之前没人做出来过,而现在我们要做。

  • 架构大图不是告诉我们架构怎么设计(DDD、SLOID原则设计模式、系统边界问题不在本文探讨范围内,但是后面会稍微扯一下_),而是告诉我们商业背后的支撑能力是什么,现状是什么,从而做到对架构未来的可见和可控。
  • 现在一个业务的架构文档有几个问题:无沉淀、非最新、分散在各种wiki空间,文档之间没有关联性。架构大图来解这个。
  • 需要以商业视角去看架构。做到两个能力:可见、可控。
    注意:可见是可控的前提。
    大图的能力围绕可见、可控两点展开。

1、 可见

可见分为四个关键子能力

  • 架构元数据可见
  • 变更可见
  • 服务级别可见
  • 服务目标、服务协议可见

1.1、架构元数据"可见"

架构元数据"可见"是后面变更可见、服务级别可见、服务目标可见的基础。分为两个关键:元数据结构和浏览方式


1.1.1 元数据结构由来

怎么才能跟上时代的变化,架构的变化,从互联网到移动互联网,从传统零售到新零售...现在我们思考的是:究竟什么才是隐藏在诸多变化背后不变的东西?什么才是支配着万千变化的那双看不见的手?
追随前者会让我们疲惫不堪,迷失不断变化的幻象当中;而找到后者,则能让我们拥有一颗坚定的心,并拥有长期主义的心态。
架构大图追求的是长期主义,并使用基于领域的概念来结构化元数据。为什么用领域,先来唠叨下几个变和不变:

  • 架构的变和不变
    只要世界一直存在,架构所支持的组织、KPI、商业、规则都会一直发生变化,不变的是架构的辩论及自我批判:扩展性、边界、复用性、稳定性等,架构的辩论和演化是没有终点的,这是不变的。

  • 商业的变和不变
    所谓技术支撑商业,在商业这个层面,很多东西都在瞬息万变,但至少有两件事是永远不会变的:第一,一切商业的起点永远都是消费者获利;第二,人性是不变的。

  • 行业的变和不变
    再来看看下面三个行业的变和不变:

    • 零售行业:阿里投资或合作了联华、百联、大润发、银泰和三江购物,腾讯则选择了沃尔玛、永辉和家乐福。很多传统零售行业的从业者都发出了“被时代抛弃”的感慨。同时,盒马、天猫小店等又涌了出来。整个零售行业让我们看到了非常大的变化。但其实,从传统零售到新零售有一点是一直不曾改变的:那就是所有消费者都希望买到的产品更加便宜、品质更好、选择更多、送货更快。所以,不论线上电商,还是线下零售,这个核心都是不变的。
    • 媒体行业:虽然现在传统媒体已经式微,但有一点是不变的,那就是消费者对好的内容的需求---消费者永远希望媒体提供内容更全面、更有趣、更深入透彻、更通熟易懂,同时内容的传递速度更快。所以不论是传统媒体,还是新媒体,这个核心都不曾改变。
    • 互联网行业:一直在日新月异地飞速发展,从互联网到移动互联网,从博客到微博再到微信,从APP时代到5年后的可能出现Non Ui 时代。可有什么不变的吗?至少有一样不变,那就是人们对互联网的核心需求不变---人们希望通过互联网能够高效便捷地实现现实生活中所需要的一切。比如,通过互联网满足阅读、社交、娱乐、学习、消费、理财、约X等需求,以及通过互联网处理生活中各种事务。
  • 行业+商业的不变
    上面把商业的变和不变、行业的变和不变分别讲了下,那么它们两者当中共同不变的就是都需要”业务主角“和”价值链“,
    比如外卖行业的务主角:

    • 消费者

      • 希望能在自己所在地域(3公里内)内,快速精准地找到需要的商品和服务(外卖、堂食、娱乐、洗浴、电影、咖啡茶饮等)。
      • 如果到家需要送货快,到店需要服务好。
    • 商家:

      • 提升业务范围:希望自己的业务范围从原来的1000米内扩展到3公里内。
      • 短路经济:外卖到家业务,需要有高效的物流服务。
      • 增加流量:提高品牌的曝光度,增加客流和订单转化。
      • 提升人效和坪效:有效提高生产和出货效率、餐厅业务提高翻台率等。
      • 供应链:降低采购成本、提高运输效率、标准化货物标准,库存流程、提升食品安全、选品、选址等。
      • 客户服务:通过数字化运营能力确保客诉的有效处理、从而提升消费者体验和商品复购率。
    • 骑手:

      • 希望到店后,商家有及时的出餐效率。
      • 希望精准的目的地路径规划,提高运输效率。
      • 在骑手接单、送货、和商户、消费者沟通的同时,解放骑手的大脑、双手、双脚。

看了上面的内容就能明白商业压根就不关心后面是不是分表分库、是否使用了设计模式、是否写了100多个分支的if else。业务最关心的是用什么能力来支撑“业务的运转机制”。这个“业务运转机制”就能够帮助业务主角产生价值,而这个产生价值的过程就是价值链:

  • 招商入住:外卖平台招募符合要求的餐饮商户入驻。
  • 商品维护:餐饮商户将合适的商品上传至平台进行销售。
  • C端需求:消费者产生外卖需求,寻求供给。
  • 导购投放:外卖平台面向消费者进行导购、商品曝光等。
  • 交易下单:消费者对某一商品产生兴趣进行选购、交易、支付。
  • 商户备货:商户接受订单、开始备货、出餐。
  • 物流履约:骑手到店取餐、送餐。
  • 业务完成:消费者确认收货。

以上就是业务价值链的业务环节,每个业务环节都可以用一个或多个领域去支撑。架构大图的顶层结构我们按照领域来划分。


1.1.2 元数据结构说明

  • 分层原则:

    • 任何一层的内容都是下层内容的总结。打个比方,如果下一层是油麦菜、青菜等,那么上一层就是应该是对他们的总结—蔬菜,而不是蛋白质
    • 同一层的内容必须具有相同的特征。打个比方,如果上一层的内容是蔬菜,那么下一层的内容就是油麦菜、菠菜等。不能把香蕉放进来。因为香蕉并不是蔬菜,与菠菜、油麦菜等并不具有相同的蔬菜特征
    • 同一层的内容必须按照一定的逻辑排序排列。打个比方:比如说交易领域的模块,你可以按照业务上的先后顺序去定义排列,或者根据SLA的等级来排列,排列规则是可以定义的。
    • 每一层的元素之间不能有交叉、也不能有遗漏。比如:我们把性别分为男性和女性,这个世界上除了男性就是女性,如果我们将人分为男人和小孩,因此就出现了交叉。
      (肯定的是:现状总是那么的不完美)
  • 每层定义

    • 领域
      有五个特点:

      • 领域和组织架构没有层的关系,恰恰相反,组织架构尽量来反映领域。
      • 一个领域可以支撑一个或多这个业务环节,一个业务环节由一个或多个领域来支撑。
      • 领域的划分追求业务环节够用原则,不追求100%完美定义。(架构的变和不变)
      • 每一个领域都有一个核心的问题目标,这个目标将层层拆解到这个领域下面的所有模块,比如交易领域,是来解决买卖双方商品货币交换问题的。
      • 领域和行业线没有必然关系,比如交易领域:他可以支持外卖、到家、新零售,如果外卖和到家目前是烟囱就是两个领域。
    • 子领域
      为什么有了领域还要有子领域呢?两个原因:

      • 因为大部分领域还是信息太过庞大,老办法我们需要继续切分,比如交易领域分:正向交易、逆向交易、交易分析查询等子领域。 营销领域分:场景营销、营销中台、商业营销等子领域。
      • 也就是说一个领域可能会支撑某个业务环节下的多个子场景或者多个业务环节,就可能会拆分到多个子领域。每个业务环节的子场景的目的不同,每个业务环节的目的也不同。


    • 模块

      • 模块是用户能够完成一系列业务操作完整功能。比如购物车模块、下单模块。在功能模块设计过程中,需要确保用户能通过一个功能模块完整的完成一项工作,而不是半个工作。


      • 用于体现实际上支撑模块的appid,一个模块有一个或者多个服务组成。


    • 用例
      和UML 的use case一个意思,一个或者多个用例来解释模块。因为一个模块里会有多个操作的.比如购物车模块就有三个用例:添加购物车、减少购物车、查询购物车。

    • 调用链路
      某个use case里面的case,比如说触发添加购物车操作,后面接口是一系列调用链路的,架构图采用trace的离线计算方式将链路关系沉淀起来,并且把业务元数据和技术元数据给关联起来了。

      链路关系有个特点,就是它经常会发生变化,需要架构大图系统自动离线去感知 并且提示到领域owner。


    • 技术元数据
      到了架构图的最底层,将技术,链路时序图上的节点分为:SOA 服务appid、缓存、消息队列、DB等内容。

1.1.3 元数据浏览方式

浏览方式需要做到像高德地图那样的体验,分为以下三点:

  • Zoom in:从业务环节—>到支撑这个业务环节的领域-->子领域-->模块—>用例->链路。(像高德地图的zoom in功能)。
  • Zoom out:是Zoom in的逆顺序。
  • Context Search:你可以根据领域Owner、SOA服务名Appid、接口名、用例名、领域名、Redis集群名或者db instance Name 去找到这个元素所在的位置,然后根据这个元素位置再 做Zoom in 、Zoom out 操作。

1.2 变更"可见"

不是指所有的变更记录可存储可查询,因为这些都有了。而是在"架构元数据"搭建完的基础上把运营、代码、中间件等变更都串起来,把变更影响哪些业务、业务环节、业务用例、业务主角,以及影响到什么程度都可视化出来,否则一个变更窗口出现故障,那么多变更怎么去缩小影响呢?goc得拉个故障群问一堆人到底是怎么回事?但这个过程直接影响到1/5/30的指标。

1.3 服务级别"可见"

  • 业务影响
    • A级:涉及关键业务,如导购、交易、资金、物流、红包、履约等。
    • B级:涉及非关键业务,如:hr系统、稳定性工具平台等。
    • C级:业务量很低将被迁移,将要下线的系统

由于业务影响的定义,B、C类里面是不需要分级的,A级对于交易影响进行再分级。

  • 交易影响
    • 1级:如系统down了影响交易量比20%以上。
    • 2级:如系统down了影响交易量比2%~20%。
    • 3级:如系统down了影响交易量比2%一下。

1.4 服务目标、服务协议"可见"

有一个大佬说过:"如果你无法量化一件事,你就无法改进它"。Google SRE 里面定义了三个名词,SLO、SLI、SLA,这里的SL是service level,服务级别,而I、O 、A分别是indicator、object与agreement。和架构大图关联后可以做到业务链路覆盖率精准检查。

  • 服务目标(SLO)
    SLI 是服务状况体现最直观的数字,比如 Request latency、Error rate、Cpu rate等,你不需要收集监控面板里所有的metric,尽可能少但这些SLI能说明服务是否健康。 而服务目标SLO是一组值的范围,自然的SLO定义就是,某SLI再正常情况下需要小于某个值或者处于某个大小值之间。选择一个SLO不是件容易的事,当然我们并不需要一开始就设定好这个范围,比如QPS,这个指标取决用户流量,而我们无法预先做出准确的判断的。
  • 服务协议(SLA)
    服务级别的协议是如果服务时效、或者不达到预期的效果,该怎么做。一般是赔偿、退款,一般来说,技术是不参与SLA的制定,因为SLA更靠近商务层面,比如搜索服务,并没有暴露给用户的SLI,但是却有和全世界都签订的协议,也就是SLA。(你注册账号时,一大推文字条款。外卖没有按时送到公司就要赔钱等)。

2、可控

在可见建设完以后,才有能力去做可控。可控能力分为两个关键

  • 架构可控
  • 稳定性可控

1、架构"可控"

架构大图可见以后,我们是不是有"自信地"引入架构评审机制,为什么是"有自信"呢? 因为架构不可见之前,架构师面对评审,时常两眼一抹黑。有三个问题:

  • 服务定位不清晰:某领域开发申请一个新appid,架构评审后这个appid可能进入大海,有了架构大图后,评审时通过zoom in 、zoom out浏览整个架构,就能知道这个appid 在什么模块,这个模块所在的业务上下文。
  • 重复造轮子:在评审的时候,感觉这个appid做的事情已有appid做了,但是就是想不起来,对应不上,评审会时间又有限,md算了就过了吧。有了架构大图后,你就知道这个appid所在的业务位置和有无重复。
  • 架构文档不集中并且不一致:无论是新增appid、架构变更。评审过的架构大图元素、分类自动形成了架构文档,能够使文档和现实始终保持一致,解决文档非最新、散落在各种wiki空间的问题。

2、稳定性"可控"

稳定性一般都有一套技术风险体系,但是大家还是觉得很难做,两个关键原因:

  • 与业务易脱节、跟不上业务:稳定性同学有技术风险的工具和套路,但是他们有可能没有产品研发那么快跟上业务。另外分析链路经常是没有沉淀的,要去trace里抓然后在写到wiki里,之后又发现变了。心好累。最后需要定期和业务团队对下关键链路监控和预案,因为这两点的有效性可能会发生变化。
  • SLO一杆子打死:只有一套SLO,无法明确到每个领域模块的SLO(每个业务是有区别的),目标没有细分,稳定性工作没有明细支点,虽然有套路有工具,但是不知道每个业务的详细分级、SLO是什么,从而无法有针对性的巡检、演练。
  • 稳定性KPI管理需要人工整合而且有遗漏:原来故障预算指标、风险覆盖率指标、过程指标达成情况需要从不同的文档、系统去整合。还会有遗漏,比如说关键路径覆盖率100%,那么哪些是关键路径会有遗漏,有了架构大图之后KPI的目标设定和实际情况(故障管理、巡检、演练)都是捆绑在一块的,做到了实时跟踪、无遗漏。

为了解决这两个难做,在实现了架构大图"可见"之后,来说下如何做到稳定性可控,一共有三项:

  • SLO风险巡检
  • 预案体系
  • 链路风险报告

2.1 SLO风险巡检

  • 巡检的范围是什么?当然是各自SRE负责的领域-->子领域-->模块-->use case-->调用链路。
  • 健康程度目标是什么?是架构大图"可见"里的服务目标、服务协议。有详细的目标拆解,才有之后的稳定性策略和行动。每个业务都有自己的目标,就在架构大图的服务目标、服务协议"可见"里。
  • 巡检演练结果如何和业务场景挂钩?SLO、SLI定好了,就要和监控系统项挂钩,这样在巡检系统扫描后,能够比较当前系统的监控值是否符合SLO,如果没有达标的,系统巡检系统将其变成一个优化项报表里进行跟踪。



    在架构大图的基础上设置目标->计划->行动->结果 ,形成一个持续性的循环流程:


2.2 预案体系

故障快速定位和止损的理想处理方式是故障业务定位(架构大图协助)和预案执行打通,当发生故障时,能够判断出故障业务定位、影响、以及对应的预案,并触发预案进行执行。当然实际的故障处理过程中有很多地方需要考虑,虽然并不是所有故障都能提前建立响应的预案,但我们可以根据历史故障和一些先验知识将故障进行归类,建立相应的预案。另外建立预案时,要方便预案执行和触发。如果不方便的话很难短时间内处理故障,最关键的问题是判断预案触发的时机,以及当前是否应该执行预案。

线上服务故障大体可以归类为如下原因:

  • 80%的故障是变更引起的故障
  • 流量和容量的变化引起的故障
  • 依赖故障
  • 机房、网络等硬件和环境故障
  • 其他:比如ID生成益处导致的故障

2.3 链路风险报告

在架构大图可见中的元数据结构中每个用例的case就对应一个调用链路,这为链路风险分析报告提供了基础,让我们清晰看到哪些业务场景下面有链路风险。

链路风险分析就是从链路通信的历史数据出发,分析出链路当前存在的风险,减少链路通信的隐患,提高系统的整体稳定性。链路风险分析可以解决的问题域很多,如超时时间设置是否合理、重试次数设置是否合理、服务SLA指标设置是否合理、服务强弱依赖关系是否符合预期,服务通讯相关的一大部分问题是由于链路风险导致的,可以通过链路风险分析的方式提前发现和解决,避免故障发生。

链路风险分析的基础是链路实时trace指标,我们把这些数据离线抽取过来做分析。

下面介绍四种典型链路风险项:

  • 超时和SLA风险:

    客户端访问服务端超时时间的设置,和实际访问情况不符。是非常常见的链路风险。上游服务的超时设置太 小,会导致本来以为可以正常返回的请求超时,影响服务的SLA和正常的服务体验;超时设置过大,会导致下游服务故障时上游服务超时等待时间太长,严重时把整个系统拖垮。因此,超时设置直接关系到系统的稳定性,需要有相应的机制指导服务超时设置。

    超时风险分两种:一种超时时间和实际不符。还有一种是上下游的超时时间不匹配,比如有A、B、C3个服 务,服务A访问服务B,服务B再访问服务C,但实际业务当中经常会遇到A访问B的超时比B访问C的超时要小。

上述两种超时风险均可以通过链路风险分析来解决。思路其实很简单,离线收集trace指标数据,通过trace数据分析当前服务访问的各分位耗时,比如99.99分位耗时是50ms,把要求的分位耗时和超时配置进行比较,如果差异过大,就存再超时配置风险。实际超时配置修复时,可以使用上述分析分位耗时作为基数,然后加上一个偏移Buffer。基数较小时,可以加上固定偏移(如5~50ms),如果基较大时,可以使用固定倍数的偏移(如1.1~1.5倍)

  • 强弱依赖或重试风险:

    服务之间进行通信,如果链路通信失败会导致整个系统失败,一般将这两个服务之间的关系称为强依赖,反之是弱依赖。我们可以基于服务的强弱关系进行降级、熔断等操作。强弱依赖服务风险是指链路通信之间的关系和预期不符,比如,服务A调用服务B链路是弱依赖,但是随着需求迭代业务逻辑发生了变化,可能不经意间服务A调用服务B变成强依赖,可是大家还是按照之前的认知,把他当成弱依赖,这就是一个很大的风险点。特别是链路故障时,基于弱依赖的前提进行了降级,就可能酿成悲剧~。导致整个系统不可用。因为需要有相应的机制,定期检查出当前链路关系的风险点。

    强弱依赖分析可以采用故障注入的思路,但与直接线上系统进行故障注入和演练不同,为了不影响线上服务的稳定性,可以通过线下环境进行强弱依赖风险检测。具体思路是通过架构大图元数据沉淀的调用链路关系,针对这个调用链路,通过故障注入的方式让链路调用返回失败,构造一个测试用例,在该测试用例基础上执行正常的自动化测试。如果自动化测试成功,证明链路失败对整个系统没有影响,说明该链路是弱依赖,反之是强依赖。通过这种方式,可以判断出每个链路最新的链路关系,然后和基础链路关系进行比较,如果有差异,说明链路关系发生了变化,产生了新的链路依赖风险。

    重试风险也可以采用同样的思路进行分析,这里不详细展开。

  • 链路调用风险:

    架构大图元数据结构里的调用链路是一个宝藏,可以从中慢慢挖掘出链路调用层面的很多风险。比如,当前服务调用超过20个下游服务,扇出过大,不太符合微服务的设计准则,可以考虑是否进一步的分析。服务化当中,单个请求的链路特别长时,会带来一定的性能问题,因此可以从架构大图元数据当中将TOP10的长链路,或者深度超过6的链路列出来,反馈给业务owner,看看有必要进行架构层面的调整。微服务拆分和设计当中,建议不要出现两个服务相互依赖的场景,可以通过调用链路查找当前是否存在有环的链路,如果成环,说明服务之间产生了相互依赖,可以将类似风险反馈给业务人员进行整改。

  • 集群或拓扑风险:

    集群或者拓扑风险是链路风险的一个主要来源,之前工作当中遇到过不少集群和单元机房风险相关的案例。比如,某线上集群的一批机器因为保修要下线一段时间,但机器修好后遗漏挂载,导致部分机器白白闲置;服务A调用服务B本来是同机房调用,由于故障或者流量切换演练等原因临时将调用关系切换到其他机房的服务B,但是事后没有切回来,导致服务A调用服务B一致跨机房调用,影响用户体验和稳定性,这种部署风险没用通用解决思路,需要针对具体的风险增加相应的措施。


最后总结下架构大图的能力

可见

  • 架构元数据可见
  • 变更可见
  • 服务级别可见
  • 服务目标、协议可见

可控

  • 架构可控
  • 稳定性可控


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

推荐阅读更多精彩内容