十问蚂蚁金服:关于Service Mesh和Kubernetes的最前沿思考

百家 作者:聊聊架构 2018-07-29 02:29:32

7 月 6 日 ArchSummit 全球架构师峰会 2018 深圳站,我们采访到了蚂蚁金服平台数据技术部的杨冰、Service Mesh 布道师敖小剑、蚂蚁金服技术专家毛小云和来自阿里大文娱 UC 基础部的曾彬,并与四位技术专家围绕着 Service Mesh 和 Kubernetes 领域最前沿的问题展开了深度的讨论。本文是此次采访实录。









嘉宾组成背景: 蚂蚁金服中间件团队和阿里大文娱 UC 基础部,在云原生 /K8S/Service Mesh 等多个共同领域都有长期探索和深度积累,在双方的共同推动下,在基于 Kubernetes 的 PaaS 及周边基础设施、Service Mesh 大规模落地实践、中间件和应用云原生探索方向上展开合作共建。

Q1:蚂蚁金服近期在对外发布的文章和线下活动中频频提到 Service Mesh 的概念,能否介绍一下?

敖小剑:  Service Mesh 是最近引入的一个新名词。它的官方定义是这样的:Service Mesh 是一个基础设施层,负责服务间通讯,主要目标是保证请求的正确传递。它在部署时表现为轻量级的网络代理,通常是跟应用一起部署,但是它对应用程序是透明的。



Q2: 蚂蚁金服内部服务化体系的现状,以及在 Service Mesh 方面的规划?

杨冰: 首先,蚂蚁金服内部的服务化从 2007 年就开始建设了。蚂蚁金服经历了四代架构:第一代相对来说是单体化的 Monolithic 的架构;到 2007 年开始做微服务架构,经过四代演进到现在已经变为一个相对比较成熟的云平台架构。但到了现在这个阶段,也遇到了一些问题。比如为了支撑业务的快速发展,整个基础架构需要快速演进。但在实际上,基础架构的演进、升级、迭代速度都非常慢,往往以年为周期的,每一年大促往前推进一代。因为系统规模很大,架构复杂度也很高,大量的工作被消耗在客户端升级和基础设施灰度验证上。所以我们认为支撑全局架构的一些逻辑应该往下沉,编程基础设施,尽可能与业务系统解耦,这样才能使我们的推进交付的速度更快。



第二个是整个基础设施的发展趋势也是不断下沉和标准化的过程,从 Linux 开始到 K8S,现在再到 Service Mesh 或者是 Serverless,这是一个大的趋势,所以我们也在跟进这些方向。

第三个是蚂蚁技术的开放过程中遇到的新问题。在技术开放的过程当中,我们遇到了很多传统 IT 系统,这些系统仍然发挥着重要作用,我们的客户或者合作伙伴,一方面期望进行整体服务化改造,一方面又期望保留或者是复用现有的 IT 资产,但希望能够整体跟微服务的体系进行对接,这时候我们发现 Service Mesh 是一个很好的解决方案。

第四,我们内部虽然大部分是 Java 系统,内部也有一个统一的开发框架叫 SOFA,大部分系统是在同一套架构上的。但随着业务的发展,还是存在很多异构的体系,比如 Web 开发的繁荣引入了 Node.js 体系,还有 AI 的遍地开花引入了 C++ 和 Python 的体系,还有很多用 C/C++ 开发的基础设施。现在我们正在将这些多元的体系整体用 Service Mesh 对接起来,让他们不再需要重复实现融入到异地多活单元化架构体系的逻辑。在运维层面,我们也在探索落地方向和更多技术红利,注入增强精细化流量控制的能力,透明的植入服务访问控制能力等。

Q3: Service Mesh 落地最大挑战是什么?目前进展如何?

敖小剑:  目前我们的 Service Mesh 落地的一个基本条件是要在蚂蚁金服主站这样一个规模场景下落地。所以我们的关注点可能就会跟开源社区不太一样:必须要考虑到在这样的规模下,我们能够真真切切地落地下来。最大的挑战在性能方面。目前,Service Mesh(比如像典型的 Istio)的性能表现不是特别理想。如果直接落到蚂蚁金服上的话,在性能上很难承受我们这样的规模。

然后,涉及到另外的实际场景,比如我们内部现有的一些非常成熟而且基本上已经铺开的框架,比如 SOFARPC。这些框架在迁移到 Service Mesh 的过程中,就会有平滑过渡的要求。因为我们必须要保证我们这些海量应用,它们的迁移过程在业务上必须是平滑的,而且期间的工作量、改动量最好不要太大。这对我们是一个比较大的挑战。

另外还会涉及到平台的问题。比如说现在的 Istio,其实它比较关注的是 K8S 这样一个比较理想化的平台,确实 K8S 的支持会让 Istio 的很多事情变得比较轻松。但是落地的实际情况是, 蚂蚁金服目前在 K8S 上还没有完全普及,还有一部分应用暂时还在非 K8S 的环境中运行。在这种情况下,需要在往 Service Mesh 技术的迁移过程中,可以提供对非 K8S 环境的支持,以便完成过渡。

再有就是私有协议支持,比如我们的 SOFARPC,这个已经在内部大规模使用,那么我们需要在标准的 Service Mesh 解决方案里加入这些协议的支持。

这是目前几个比较大的挑战。

大家可能比较关心现在内部的进度。目前我们 Mesh 最基本的 Proxy 部分基本上已经开发完成,我们会用它来替换原有的一些多语言客户端,比如说 C++ 的客服端、nodejs 的客户端。这样,我们会先完成最基本的对多语言的支持。

在这个基础上,我们目前正在实现对 Envoy 的 XDSAPI 的支持,为后面对接 Istio 做准备,这个工作正在开发过程中。后面我们也正在做一些私有协议的支持,包括特殊场景的支持。比如说我们对 Pilot 的改造,这些目前都正在开发当中。

曾彬: 我来补充一下,其实集团现在在 Service Mesh 有挺多团队,都是在一个探索的过程。UC 的特点就是 K8S 做的相对早一些,所以 K8S 落地相对比较完整,应用往上迁移的程度也是比较高的。然后在成本或在效率上拿到了一些红利,也从社区、CNCF、项目里看到了未来我们可能的一些方向。所以我们很看好 Service Mesh 这个方向,这算是一个背景吧。

Q4: 几位老师一直提到 K8S,那可以具体聊聊 K8S 和 Service Mesh 两种技术之间的关系吗?

曾彬: 首先,先从复杂度层面来说,我觉得 Service Mesh 由于有 Sidecar 的引入,肯定会带来运维上的复杂度。K8S 的 Pod 作为一种基础设施,里面可以天然地支持多个 Container,来支持这种 Sidecar 技术,对运维是非常大的帮助。然后再加上它对资源细粒度的控制,比如说 CPU、内存资源的控制,以及像权限控制 RBAC 方面的一些功能,我们觉得这些都对简化复杂度有很大的帮助。

第二点就比较通用一点,原来的应用程序如果没有跑在 K8S 的话,它的元数据信息对整个外部系统是不可见的。如果把这个程序放到 Pod 里面之后,因为 Pod 是在 K8S 上运行,本身是带有元数据的,比如说 label,如果我们把这些元数据对外部可见,让它开放了,这样不仅对于 Service Mesh,而是面向整个上层的 K8S 生态开放了,应用本身能拿到更多的红利,这是我的两点看法。

敖小剑: 我稍微补充一下,昨天晚上我们夜话活动的时候,讨论到 Service Mesh,当时有很多同学也谈到这个问题,就是说——上 Service Mesh 之前,是不是一定要先上 K8S?这个话题当时有过讨论,大家的一致想法是:从技术上讲是不限制的,因为 Service Mesh 从理论上讲,底下可以不是 K8S。但是从长期的发展上说,K8S 可以给 Service Mesh 提供非常大的支持。所以,从远景上说,K8S 跟 Service Mesh 未来长期的发展路线是必然结合着使用的。

Q5:那 K8S 在落地的过程中,有什么问题和挑战吗?

毛小云: 这个我来回答一下,刚刚小剑和曾彬也提到了,K8S 是支持 Service Mesh 比较理想的方案。但是落地 K8S 会有比较多的问题跟挑战,我就分享一下蚂蚁在这方面的一些经验。

要落地 K8S,比如说蚂蚁在 Docker 化之前,其实蚂蚁内部的虚拟化技术基本上可以分成两种。一种是基于 VM 的或者是基于 LXC 这种形式的,然后基于这种 LXC 和 VM 的形式,我们也建立了一整套相应的运维体系。我们面临的一个比较明显的挑战是,我们原有的这些运维体系,如何比较平滑地迁移到这种容器化的体系上来。在迁移到容器化体系的过程中,我们会遇到各种各样的问题,比如像类似于镜像的问题。还有比如一些有状态的应用,Dockerfile 的问题,Dockerfile 的运维模式,其实跟我们原有的运维模式是相冲突的。蚂蚁金服在这方面,比如镜像方面,做了蛮多的工作。比如说有一些 P2P 的加速方案,以及有一些做了镜像云化的这种能力,去加速镜像。在这个 Dockerfile 的运维上面,我们也做了一些适配,能够降低研发成本的复杂度,这是第一个阶段的挑战,相当于是容器化的挑战。

第二个挑战是我们要真正把 K8S 在蚂蚁落地,还会面临各种各样的具体落地上面的一些问题。比如像集群部署、网络或者是存储方面的问题。如果说到集群部署,蚂蚁可能跟其它公司要面临的集群环境更加复杂。比如说它是跨 IDC 的,甚至跨国的,还有是这种多云的环境,那么怎么管理这些集群,怎么样去解决刚刚说的这几种复杂场景里面的运维和发布,其实这些都是挑战。在网络层面上,其实整个 K8S 社区的网络插件生态还是比较丰富的。比如说产品化做得较好的 weave 或者是提供 overlay 的 flannel,或者是 BGP 的 calico,这些方案都是在社区里面比较有影响力的,但是在蚂蚁的场景中这些方案都有自己的局限性。所以我们蚂蚁自己也研发了相对来说比较多的网络技术方案,以适用于蚂蚁自己的这些场景。这些方案包括了网络加速方案,或者 SRIOV 的加速方案。

最后提一下存储,K8S 的存储这一块相对于 K8S 的其它模块进化是相对比较慢的,所以我们在落地存储方案时会经历一些方案上的变化,或者是痛点。比如说像我们之前有一些 Data Container 的方案,迁移到 K8S 上面去之后,其实这些方案都会给我们带来比较多的工作量。第二块是指真正落地 K8S 的具体挑战,针对蚂蚁的场景,我们有一些可能是特有的场景。比如说蚂蚁集群的规模都比较大。K8S 官方提供的集群能力是 5000 个节点,但可能推荐的节点是 1000 个节点,而蚂蚁的核心集群基本上都是超过这个数量的。其实这个瓶颈主要还是在 ETCD 上面,官方其实也给了一些推荐方案,比如可以用多 ETCD 集群的管理方式来管理 K8S 的资源。

那蚂蚁可能会从另外的角度,比如说做数据分片这样的方式,去解决这样的问题。另外除了 ETCD 这个方面的问题,蚂蚁在应用的数量上其实也有相当大的规模,那这些应用之间的调度的亲和关系以及规则,事实上已经远远超出了目前 K8S 的能力。在蚂蚁的另外一个场景里面,做得比较超前的事情,比如在线和离线混布、提高 CPU 的利用率,目前来说 K8S 里面是相对来说 cover 比较少的,我们也需要投入更多的研发精力在里面,为了支持我们的大促双 11 这种场景。

最后一个就是蚂蚁金服其实是金融属性比较强一点,所以我们会特别关注安全问题,容器的安全或者是说容器里面的数据的安全、网络的安全,怎么给用户的应用提供一个比较安全的应用运行环境,对我们来说是非常重要的。所以在内核,或者是在一些更加高级的基础上,比如说像研究安全容器这方面,我们也做了一些深入的研究。最后就是在网络安全方面,刚刚也提到了 K8S 是 Service Mesh 落地比较好的一个选择,结合 Service Mesh,其实 K8S 在网络安全上可以做更多的事情。

曾彬: 刚刚蚂蚁那边提到了 K8S 落地的问题,UC 这边历史包袱方面可能相对简单一些,但是有一些相对通用的问题。比如 UC 这边在 K8S 落地上,首先要解决网络的问题,包括容器 IP 段规划,先解决容器之间网络互通的问题,以及基础运维,包括装机、集群搭建,还有要跟四层负载、七层负载,甚至 DNS,这些系统都要打通。以及后面的业务运维方式其实也发生了挺大的变化,甚至整个 Devops 流程的变化,因为后面镜像作为载体了,用户需要一个熟悉的过程。其实昨天张磊(K8S 的维护者),他也提到了一个观点,大家认为 K8S 复杂,但他认为其实 K8S 的 API 本来就不是面向最终用户的,应该是面向开发者的。

所以在 K8S 之上,我们应该再分装一个 PaaS 平台出来,让这个 PaaS 平台去面向最终用户,我们觉得这是落地上非常重要的一点。要让用户去接受这个东西,他要能够非常低成本地使用整个这个平台。参考 UC 这边的经验,我们新做了一套完全以 K8S 为基座的 PaaS 平台,可以理解成是比较薄的一层,但是承载了很多业务需求在上面。比如说像刚才提到的网络相关的、还有四、七层负载相关的、DNS 相关的,应用所有者在这个 PaaS 平台上可以自助提交变更,经过业务运维审核后就可能完成一些工作,面向应用的整体过程是很高效的。还有一点,其实现在 K8S 的主体功能已经相对稳固,它的一个发展趋势是朝着 SDK 化、插件化、可拔插化这个方向在发展。

举个例子,它之前推出了自定义资源、CRD 和 Operator 这种模式,以及张磊提到的 Scheduler 后续完全可拔插化的设计,都能体现出 SDK 化这一点。对于我们,特别是做基础架构的技术团队,带来了不少思考,因为我们有 K8S 这个底座,那我们在做这些基础中间件产品的时候思路就会有所转变,或者说挑战,就是如何把这些基础架构组件或者产品,往 CRD/Operator 的方式去做。比如说我们上线了 Kafka Operator,Kafka 的运维其实挺复杂的,我们把这些复杂性封装在 Operator 之内。比如说容灾、伸缩等等。对应的还有一些 KV 存储服务,现在也是朝这个方向在做。从用户角度看,他能通过我们刚才提到的前端 PaaS 平台,以自助的方式去实现资源申请,甚至完成一些运维的工作,这也是我们看到的收益和变化。

杨冰: 简单补充一下,其实刚才典韦提到的那个点,蚂蚁这边也在实践。尤其是模型标准化这件事情,我们还是非常认同这个方向的。就好比 K8S 这层体给我们开发 PaaS 以及 PaaS 上面的一些基础软件,提供了一个很好的编程模型。另外,因为中间件相比应用来说,会有更多的状态,而且也有不同的系统角色,在处理不同角色的扩容或是宕机恢复的时候,也需要考虑更多状态信息。以前每个中间件基本上是自己要在 PaaS 上去定制这部分的逻辑,复杂度和差异性会比较大。但现在可以由统一的一套模型去做,比方说巡检,启动以后的检查、校验等,或者是自动的一些 Self-Healing 和扩缩容等等机制,我们可以写成通用的模板,这块对于我们来说还是有很大帮助的。

Q6:Service Mesh 也有很多实现,你们在技术选型上有什么样的考虑呢?

敖小剑: 关于我们 Service Mesh 产品的技术选型方案,在这里面我主要讲几个重点。第一个重点,我们的技术选型相对来说是比较慎重的,在这之前我们调研了目前市面上几个主流的 Service Mesh 产品,也包括国内国外一些做前期探索的同行的实际方案,尤其对性能和架构的权衡。我这里简单说一下,主要的技术选型方案是这样的。我们整体上会 follow Istio 的架构和设计,在数据平面上,我们选择的方式比较特殊,我们会用 Golang 重新开发一个新的 Sidecar,然后在 API 上去兼容目前 Istio 和 Envoy 的标准 API,可以做到最终和 Istio 兼容,这是一个比较大的动作。

然后在控制平面上,我们现在会选择跟随整个 Istio 社区,实际上就是刚才说的,我们会兼容 Istio 的整个控制平面。我们有些特殊的诉求,比如说性能方面的,比如我们需要应用程序做平滑的过渡。出于这些方面的考虑,我们会在控制平面上做一些扩展和增强。举例说,比如说在 Pilot 的这个模块上,接下来我们会让 Pilot 支持除 K8S 之外的一些其它的注册方案。比如我们内部支持超大容量的服务注册方案,SOFA Registry。因为我们应用服务的数量比一般的公司数量级上会大一两个等级。

典型的 Istio 的注册方案,比如说它有一个全量拉取过程,对我们来说,肯定是不可取的。类似的,像在 Mixer 里头,我们会做比较大的改动,就是因为 Mixer 对性能的影响特别大。所以我们会考虑把它合并进我们的 Sidecar 来达到性能提升的目标。在 Auth 模块上,我们会尽可能去遵循目前 Istio 的做法,但是在落地的时候,因为金融行业相对来说在安全性上的考虑会更多一些,所以我们会在这方面做比较多的扩展,这是目前主要的选型过程。

细节我们就不详说了,但是在这里可能需要额外指出一点:我们技术选型是在现有社区的开源方案上,跟随整个社区,一起去做演进。所以我们的方案最终选择就是:我们在 Istio 兼容的模式上去做各种增强。一个产品如果要获得持续发展,需要有社区的支持,然后跟随整个社区一起前进。这也是我们做技术选型一个非常重要的考量。

Q7:采用 Service Mesh 会有什么收益?大家可以谈一下感受。

杨冰: 这个其实刚才各位同事也都有提到,就从比较近期来看,蚂蚁是奔着几个方向去的。第一个就是多语言,确实以前是统一的,但是到现在,其实就很难有这样一个大的把控。因为业务的复杂度,还有人员的复杂度,其实小公司也是,可能一开始能招到什么人,就用什么样的语言。第二个,我们内部可能还好一些,但是在外部,确实有不少遗留系统,那我们不期望大家一听到很好的概念,就推翻重来,还是期望能保留已有的资产,复用原有的基础设施,那就可以用 Service Mesh 把这些系统给接进来。

其实传统机构很多用到了 ESB,我听到很多人提到分布式 ESB 或者是分布式网关等概念,本质上其实跟 Mesh 这条路是殊途同归的。第三个就是我刚才提到的,可能像蚂蚁这样的公司会比较看中,就是整个基础设施迭代演化的速度。当然,从长远来看,其实任何一家公司,应该都可以从中受益。至于 Mesh、Istio 等等跟整个生态结合的一些好处,其实也是有挺多想象空间的,这一块就不展开说了。

Q8:各位老师可以展望一下 K8S 的发展吗?

曾彬: 首先短期来看,我们还是要解决性能和稳定性这方面的问题,还有落地的问题。如果长远来看,就是生态这个点。我们畅想一下,后面 Sidecar 在整个生态里面的位置。我们现在对它期望很大,希望它承载很多东西。首先,自底向上看的话,硬件层面,我们希望通过软硬件结合来解决性能问题,比如说利用硬件的 offload,比如说智能网卡 /FPGA,去把一些工作量 offload 到硬件上面去,实现一部分加速。然后再往上面看,在内核这一层,现阶段的 Mesh 技术,在包拦截、包过滤、协议处理上面,都还有提升的空间。

举个例子,包拦截和过滤目前大多是通过 Iptables 实现,是否可以通过 eBPF 的方式,以及使用用户态协议栈绕过内核 TCP/IP 栈,都可以做一些探索。再往上面看,在容器这个层面,如何更好地把 Sidecar 和周边的生态,比如说 metrics 采集 / 计算 / 应用,运维 /PaaS 系统与 Sidecar 的控制交互等。再往上面看,刚刚提到的多协议 /RPC 协议,是很常见的需求,如何通过 Mesh 来支持,可能还有更多的场景需要更多协议,Mesh 的扩展机制如何去支持。最后从应用场景来看, 运维 /PaaS 需要和 Mesh 生态更好地结合起来,比如说蓝绿 / 灰度发布。

敖小剑: 补充一个小点,这一点是昨天晚上我们在现场讨论过程当中比较关注的一点,刚才曾彬也聊到了,就是转发的性能。从架构的角度上说,Service Mesh 这样一个技术,实际上是对性能和架构平衡点的选择:我们牺牲了远程调用的开销,来换取架构上巨大的发挥空间。在 Service Mesh 后续的发展过程当中,我们能看到两个大的方向,有舍有得:一个方向在“得”这一边,我们会把控制平面的各种创新做起来,尽可能在收益方面做一些事情;另外一个方向就是舍,远程调用的开销在技术层面上还有一些改进空间,我们可以尽量将我们损失的这部分性能,通过一些技术手段尽量减少。最终实现用更小的开销去换取更大的收益。

杨冰: 这块我也想补充一下,之前多次提到过多语言这个事情,其实我们发现,在基础架构的演进过程当中,每种语言都要去支持同样的功能做 N 遍,比如说熔断、路由、限流、故障注入等等。这些东西如果往下沉的话,其实对于大家来说是一件好事。但是对于 Mesh 这个架构来说,它跟 K8S 一样要具备极强的可扩展性,方便大家针对架构差异去扩展和定制,我觉得这跟 K8S 这个框架是一样的。它需要往这个方向去发展。甚至在这个过程当中,是不是可以把各家所长集成在一起,变成一种标准,这个也是我们希望去做的事情。

敖小剑: 最早在 2017 年 QCon 上海的时候,当时我讲 Service Mesh,举了一个例子,几十年前的 TCP 技术栈的发展过程。最终 IP/TCP 这个技术栈变成了一个非常非常标准的东西,直接进入到操作系统内核,也许若干年之后,Mesh 这样的技术,在它足够成熟并且标准化之后,可能也会以某种技术栈的方式沉淀下来。应该说,如果 Mesh 技术持续这样发展,是有可能的。



Q9:之前听说蚂蚁金服 Service Mesh 有开源的技术,可以分享一下这方面背后的思考吗?

杨冰: 我简单说一下,这个其实跟整个蚂蚁业务的开放是一脉相承的。我们最早开放的是更偏体验层的一些技术,随着业务更加开放,整个服务端技术也逐步往外走。我们在 4 月份的时候启动 SOFA 开源,这是我们微服务体系的一套框架。开放的另外一个原因,是我们觉得 Service Mesh 这个技术虽然提出来的概念很好,但是蚂蚁金服已经在微服务领域趟了 N 多年的坑了,而且在这个方向上,在不同的规模下,包括在带着金融属性这样的一些要求下迭代了 N 多版本。我们也期望这些东西可以分享出来给大家,而且这些已经是越来越标准化的技术。

另外一方面,虽然我们在内部折腾了这么多,但是在业务跟技术开放的过程中,我们发现很多合作伙伴和客户那里有很多我们没遇到过的场景,其实我们内部的场景还远远不够丰富,有很多需要大家来去补充的部分,所以这也是开源的另外一个初衷,就是期望更多的人参与共建。所以我们期望跟大家以开放的形式去探讨,说得再美好一点,我们希望在标准化上能有所建树,为社区做一些贡献。

敖小剑: 这里我稍微补充一下,因为我们在上周的时候,刚刚放出消息,我们准备在 Mesh 这个领域,尽量开源,跟大家共建。过去这一周,我们也得到了一些反馈,很多同学非常的开心:至少大家看到了,有人愿意在这个领域拉起旗帜说,我们一起来做一些合作。有一部分同学,他们也有力量可以贡献出来,这个也是我们非常期望的。我们开源的一个出发点,就是尽可能地汇集大家的力量,然后共同去把一个优秀的产品做出来,最后让 Service Mesh 技术的水准更高一些,而不是大家分散开在低水平上做重复的事情。

Q10:如果想学习和研究 Service Mesh 技术,有没有什么建议,或者是有没有什么推荐的资料供大家学习?

敖小剑: 因为 Service Mesh 技术相对来说还是比较前沿,在整个技术社区,了解这个技术的人也不是特别多。这方面的资料、书籍非常少,而且大部分停留在相对比较浅一点、早期一点。介绍性的资料会比较多,真的深入学习的资料,目前还是比较难找的。我们在学习调研的过程中,也遇到了一些问题。所以我们后面做了一些事情,比如说我们目前组建了一个 Service Mesh 垂直领域的技术社区。

地址:  http://servicemesher.com

尽可能汇集国内对 Service Mesh 比较感兴趣的同学。我们通过社区的方式,将大家汇总起来,然后收集、汇总这个领域一些比较好的文章,鼓励大家去做一些原创性的工作,包括翻译工作。

说到翻译的话,其实我们这个社区最近也组织了一个翻译组,大概有 70 多位同学,因为国外的资料会更新一些,我们主要的目标是将他们的博客、文章,也包括像 Istio 的官方文档等资料翻译成中文,然后给到大家,这样在学习的时候,可能你能得到的资料会比较齐全,阅读方面也会比较通畅,大家可以关注。

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接