目录

1、云计算技术中的一股清流:PaaS

2、Docker给PaaS带来的“降维打击”

3、群雄并起

4、Kubernetes的横空出世

5、尘埃落定



研读张磊老师《深入剖析 Kubernetes》课程有感。

Kubernetes 项目为什么会成功,先说答案:
1、它争取到了云计算生态里的绝大多数开发者;
2、“API 为王”的设计思路。(API是连接 Kubernetes 项目和开发者们最重要的纽带); 


1、云计算技术中的一股清流:PaaS

(1)回顾2103年

2013年后端技术已经太久没有出现令人兴奋的东西了,曾经被人们寄予厚望的云计算技术,也已经从当初虚无缥缈的概念蜕变成了实实在在的虚拟机和账单。相比于如日中天的AWS和盛极一时的OpenStack(一个开源的云计算管理平台项目),以Cloud  Foundry(业界第一个开源PaaS云平台)为代表的开源PaaS项目却成为了当时云计算技术中的一股清流。

这一年Foundry项目基本度过了概念普及和用户教育阶段,吸引了一大批国内外技术厂商,开启了以开源PaaS为核心构建平台层服务能力的变革。当然除了Foundry,还有Heroku、Pivotal、Red Hat以及dotCloud这个“低调”的公司。

(2)PaaS到底是什么技术?

PaaS技术到底是什么呢?在当时,虚拟机和云计算已经是比较普遍的技术和服务了,那时主流用户的普遍用法就是租一批AWS或者OpenStack的虚拟机,然后像以前管理物理服务器那样,把本地的应用部署到云上。部署过程会遇到云端虚拟机和本地环境不一致的问题,所以当时的云计算服务,比的就是谁能更好地模拟本地服务器环境,能带来更好的“上云”体验,像Cloud Foundry这样的PaaS项目正是解决这个问题的最佳方案。

Foundry是如何解决这个难题呢?Foundry最核心的组件就是一套应用的打包和分发机制,首先它为每种主流编程语言都定义了一种打包格式,通过cf push把应用的可执行文件和启动脚本打进一个压缩包内,上传到云上存储中;然后Foundry会通过调度器选择一个可以运行这个应用的虚拟机,通知这个机器上的Agent把应用压缩包下载下来启动;最后也是关键,由于需要在一个虚拟机上启动多个来自不同用户的应用,Foundry会调用操作系统的Cgroups和Namespace机制为每一个应用单独创建一个称作“沙盒”的隔离环境(所谓的“容器”),在“沙盒”中启动这些应用进程,这样就实现了把多个用户的应用互不干涉地在虚拟机里批量地、自动地运行起来的目的,这正是PaaS项目最核心的能力。


2、Docker给PaaS带来的“降维打击”

(1)Docker的横空出世

突然那个“低调”的dotCloud公司宣布开源自己的核心引擎:Docker,但并未引起太多人注意,因为Foundry项目中容器也只是其最底层、最没人关注的那一部分,“容器”这个词也不是dotCloud公司发明。Docker项目与Cloud  Foundry的容器在大部分功能和实现原理上一样,可偏偏就是这剩下的一小部分不一样的功能:镜像,使Docker项目迅速崛起。Foundry以及所有的 PaaS社区还没来得及成为它的竞争对手,就直接被宣告出局了,短短几年内迅速地改变了整个云计算领域的发展历程。

(2)PaaS的软肋

Docker的出现为何会对PaaS造成如此大的影响?我们再梳理下用户使用PaaS的流程,看看其“软肋”是什么。第一:用户一旦用上了 PaaS就必须为每种语言、每种框架,甚至每个版本的应用维护一个打好的包,打包过程没有章法可循;第二:在本地运行好好的应用,却需要做很多修改和配置工作才能在PaaS里运行,这些修改和配置没有什么经验可以借鉴,基本上靠不断试错。

(3)Docker的崛起为什么如此迅速?

“cf push”确实能一键部署,但为了实现一键部署,用户为每个应用打包的工作可谓一波三折,而Docker镜像解决了这个打包的软肋。有了Docker镜像你只需要提供一个下载好的操作系统文件与目录,使用docker build制作一个镜像,其次通过docker  run使用Cgroups和Namespace机制创建一个“沙盒”在里面运行应用。用这个镜像在本地开发、测试后直接上传到云端就可以运行,不需要修改任何信息,保证了本地环境和云端环境的高度一致,避免了用户通过“试错”来匹配两种不同运行环境之间差异的痛苦过程,这就是镜像的精髓

Docker项目给PaaS世界带来的“降维打击”,一方面它解决了应用打包和发布这一困扰运维人员多年的技术难题;另一方面它第一次把一个纯后端的技术概念,通过非常友好的设计和封装,交到了最广大的开发者群体手里,坚持把“开发者”群体放在至高无上的位置。

简洁的UI,有趣的demo,“1 分钟部署一个 WordPress 网站”,“3 分钟部署一个 Nginx 集群”,这种同开发者之间与生俱来的亲近关系,使 Docker项目迅速成为了全世界Meetup上最受欢迎的一颗新星,这样一个普通到不能再普通的技术却开启了一个名为“Docker”的全新时代。


3、群雄并起

(1)Docker的错误定位

Docker 项目固然解决了应用打包的难题,但正如前面所介绍的那样,它并不能代替 PaaS 完成大规模部署应用的职责。遗憾的是,考虑到 Docker 公司是一个与自己有潜在竞争关系的商业实体,再加上对Docker项目普及程度的错误判断,Cloud  Foundry 项目并没有第一时间使用 Docker 作为自己的核心依赖,去替换自己那套饱受诟病的打包流程。反倒是一些机敏的创业公司,纷纷在第一时间推出了 Docker 容器集群管理的开源项目,比如 Deis 和 Flynn,它们一般称自己为 CaaS,即 Container-as-a-Service,用来跟“过时”的PaaS们划清界限。

但是,Docker 项目一日千里的发展势头,一直伴随着公司管理层和股东们的阵阵担忧。因为虽然 Docker 项目备受追捧,但用户们最终要部署的,还是他们的网站、服务、数据库,甚至是云计算业务。只有那些能为用户提供平台层能力的工具,才会真正成为开发者们关心和愿意付费的产品。而Docker项目这样一个只能用来创建和启停容器的小工具,最终只能充当这些平台项目的“幕后英雄”。

谈到 Docker的定位问题,就不得不说Docker公司的老朋友和老对手 CoreOS了。CoreOS 是一个基础设施领域创业公司,它的核心产品是一个定制化的操作系统,用户可以按照分布式集群的方式,管理所有安装了这个操作系统的节点。从而,用户在集群里部署和管理应用就像使用单机一样方便了。

Docker 项目发布后,CoreOS 公司很快就认识到可以把“容器”的概念无缝集成到自己的这套方案中,从而为用户提供更高层次的 PaaS 能力。所以,CoreOS 很早就成了 Docker 项目的贡献者,并在短时间内成为了 Docker 项目中第二重要的力量。然而,这段短暂的蜜月期到 2014 年底,CoreOS 公司以强烈的措辞宣布与 Docker 公司停止合作,并直接推出了自己研制的 Rocket(后来叫 rkt)容器。这次决裂的根本原因,正是源于 Docker 公司对 Docker 项目定位的不满足。Docker 公司解决这种不满足的方法就是让 Docker项目提供更多的平台层能力,即向PaaS项目进化,这显然与CoreOS公司的核心产品和战略发生了严重冲突。

(2)Swarm的出现

Docker公司在2014年就定好了平台化的发展方向,并且绝对不会跟CoreOS在平台层面开展任何合作。在2014年底的DockerCon上,Docker公司雄心勃勃地对外发布了自家研发的“Docker 原生”容器集群管理项目Swarm,它最大亮点是完全使用Docker项目原本的容器管理API来完成集群管理。在部署了Swarm的多机环境下,用户只需要使用原先的Docker指令创建一个容器,这个请求就会被 Swarm 拦截下来处理,然后通过具体的调度算法找到一个合适的 Docker Daemon运行起来,操作方式简洁明了。这样一个“原生”的 Docker容器集群管理项目一经发布就受到了已有Docker用户群的热捧。

而相比之下,CoreOS则是依托于一系列开源项目,比如 Container Linux操作系统、Fleet作业调度工具、systemd进程管理和 rkt容器,一层层搭建起来的平台产品。CoreOS的解决方案就显得非常另类,更不用说用户还要去接受完全让人摸不着头脑、新造的容器项目rkt了。

在2014年到2015年这段时间里,Docker项目迅速走红催生出了一个非常繁荣的“Docker 生态”,围绕着Docker在各个层次进行集成和创新的项目层出不穷。Swarm的出现不仅将这波“CaaS”热推向了一个前所未有的高潮,更是寄托了整个Docker公司重新定义PaaS的宏伟愿望。

(3)Compose的出现

接下来不差钱的Docker公司收购了Fig,这个项目在开发者面前第一次提出了“容器编排”(Container Orchestration)的概念,它主要是指用户如何通过某些工具或者配置来完成一组虚拟机以及关联资源的定义、配置、创建、删除等工作,然后由云计算平台按照这些指定的逻辑来完成的过程。

Fig的工作流程简单描述如下:

1)假如现在用户需要部署的是应用容器 A、数据库容器 B、负载均衡容器 C,那么 Fig 就允许用户把 A、B、C 三个容器定义在一个配置文件中,并且可以指定它们之间的关联关系,比如容器 A 需要访问数据库容器 B。

2)接下来,你只需要执行一条非常简单的指令:fig up。Fig 就会把这些容器的定义和配置交给 Docker API 按照访问逻辑依次创建,你的一系列容器就都启动了;而容器 A 与 B 之间的关联关系,也会交给 Docker 的 Link 功能通过写入 hosts 文件的方式进行配置。

3)更重要的是,你还可以在 Fig 的配置文件里定义各种容器的副本个数等编排参数,再加上 Swarm 的集群管理能力,一个活脱脱的 PaaS 呼之欲出。

Fig 项目被收购后改名为 Compose,它成了Docker公司到目前为止第二大受欢迎的项目,一直到今天也依然被很多人使用。接下来Docker还收购了一些开源项目或公司,比如专门负责处理容器网络的 SocketPlane 项目,专门给Docker集群做图形化管理界面和对外提供云服务的 Tutum项目,一时之间整个后端和云计算领域的聪明才俊都汇集在了这个“小鲸鱼”的周围,为Docker生态的蓬勃发展献上了自己的智慧。

(4)Machine的出现

Docker不失时机地发布了Machine,与Docker Compose、Swarm 构成了Docker的“三件套”,在重新定义 PaaS 的方向上走出了最关键的一步。大量围绕着Docker项目的网络、存储、监控、CI/CD,甚至UI项目纷纷出台,也涌现出了很多 Rancher、Tutum 这样在开源与商业上均取得了巨大成功的创业公司。在2014~2015 年间,整个容器社区可谓热闹非凡。


4、Kubernetes的横空出世

(1)“满腹牢骚”

Docker 项目刚刚兴起时,Google 也开源了一个在内部使用多年、经历过生产环境验证的 Linux 容器:lmctfy(Let Me Container That For You),这个对用户没那么友好的容器项目根本没有引起注意。知难而退的 Google 公司向 Docker 公司表示了合作的愿望,Google和 Docker 公司共同推进一个中立的容器运行时(container runtime)库作为 Docker 项目的核心依赖。

Docker 公司并没有认同这个明显会削弱自己地位的提议,不久自己发布了一个容器运行时库 Libcontainer。这次匆忙的、由一家主导的、并带有战略性考量的重构,成了 Libcontainer 被社区长期诟病代码可读性差、可维护性不强的一个重要原因。Docker 公司在容器运行时层面上的强硬态度,以及 Docker 项目在高速迭代中表现出来的不稳定和频繁变更的问题,开始让社区叫苦不迭。

(2)一次无用的“反击”

社区的这种情绪在2015年达到了一个小高潮,容器领域的其他几位玩家开始商议“切割”Docker 项目,“切割”的手段非常经典,那就是成立一个中立的基金会。于是2015年6月22日,由 Docker公司牵头,CoreOS、Google、RedHat等公司共同宣布,Docker公司将 Libcontainer捐出,并改名为RunC项目,由一个完全中立的基金会管理,以RunC为依据大家共同制定一套容器和镜像的标准和规范。这套标准和规范就是OCI( Open Container Initiative )。OCI意在将容器运行时和镜像的实现从 Docker项目中完全剥离出来。这样做,一方面可以改善 Docker公司在容器技术上一家独大的现状,另一方面也为其他玩家不依赖于 Docker 项目构建各自的平台层能力提供了可能。

不过OCI的成立更多的是这些容器玩家出于自身利益进行干涉的一个妥协结果。尽管Docker是OCI的发起者和创始成员,它却很少在 OCI 的技术推进和标准制定等事务上扮演关键角色,也没有动力去积极地推进这些所谓的标准。Docker之所以不担心OCI的威胁,原因就在于它的 Docker项目是容器生态的事实标准,而它所维护的 Docker社区也足够庞大。但是,如果将这场斗争转移到容器之上的平台层或者PaaS层,Docker公司的竞争优势便立刻捉襟见肘了。

(3)揭竿而起

在这个领域里,像Google、RedHat这样的成熟公司都拥有着深厚的技术积累。CoreOS 这样的创业公司也拥有像Etcd这样被广泛使用的开源基础设施项目。Docker公司呢?它却只有一个 Swarm。事实上,很多从业者也都看得明白,Docker 项目此时已经成为 Docker 公司一个商业产品。而开源,只是 Docker 公司吸引开发者群体的一个重要手段。不过这么多年来,开源社区的商业化其实都是类似的思路,无非是高不高调、心不心急的问题罢了。而真正令大多数人不满意的是Docker 公司在 Docker 开源项目的发展上,始终保持着绝对的权威和发言权,并在多个场合用实际行动挑战到了其他玩家(比如,CoreOS、RedHat,甚至谷歌和微软)的切身利益。

2014 年注定是一个神奇的年份,基础设施领域的翘楚 Google 公司突然发力,正式宣告了一个名叫 Kubernetes 项目的诞生。这个项目,不仅挽救了当时的 CoreOS和RedHat,还如同当年 Docker 项目的横空出世一样,再一次改变了整个容器市场的格局。

(4)大名鼎鼎的CNCF成立了

这次Google、RedHat等开源基础设施领域玩家们,共同发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金会。这个基金会的目的以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker公司为核心的容器商业生态。为了打造出一条围绕 Kubernetes 项目的“护城河”,CNCF 社区就需要至少确保两件事情:

第一、Kubernetes 项目必须能够在容器编排领域取得足够大的竞争优势;

第二、CNCF 社区必须以 Kubernetes项目为核心,覆盖足够多的场景。

(5)一骑绝尘

CNCF如何解决Kubernetes项目在编排领域的竞争力的问题?在容器编排领域,Kubernetes 项目需要面对来自 Docker Swarm和 Mesos 社区两个方向的压力。Docker  Swarm 和 Mesos分别从两个不同的方向讲出了自己最擅长的故事:Swarm 擅长的是跟 Docker 生态的无缝集成,而Mesos擅长的则是大规模集群的调度与管理。这两个方向也是大多数人做容器集群管理项目时最容易想到的两个出发点,如果Kubernetes项目继续在这两个方向上做文章就不太明智了。

这一次Kubernetes选择的应对方式是:Borg。如果你看过 Kubernetes 项目早期的 GitHub Issue 和 Feature就会发现它们大多来自于 Borg 和 Omega 系统的内部特性,这些特性落到 Kubernetes 项目上,就是 Pod、Sidecar 等功能和设计模式,这就解释了为什么 Kubernetes发布后很多人“抱怨”其设计思想过于“超前”的原因。Kubernetes 项目的基础特性并不是几个工程师“拍脑袋”想出来的,而是 Google 公司在容器化基础设施领域多年实践经验的沉淀与升华。

于是CNCF 接下来的任务就是如何把这些先进的思想通过技术手段在开源社区落地,并培育出一个认同这些理念的生态。这时RedHat发挥了重要作用。当时,Kubernetes 团队规模很小,能够投入的工程能力也十分紧张,而这恰恰是 RedHat 的长处,而且RedHat是世界上为数不多的、能真正理解开源社区运作和项目研发真谛的合作伙伴。所以,RedHat与Google的联盟,不仅保证了RedHat在 Kubernetes 项目上的影响力,也正式开启了容器编排领域“三国鼎立”的局面。

这时我们再重新审视容器生态的格局就不难发现 Kubernetes、Docker和Mesos社区的关系已经发生了微妙的变化。其中,Mesos 社区与容器技术的关系,更像是“借势”,而不是这个领域真正的参与者和领导者,加上它所属的Apache社区固有的封闭性,导致了Mesos社区虽然技术最为成熟,却在容器编排领域鲜有创新。这也是为何Google 公司很快就把注意力转向了动作更加激进的 Docker,Docker对 Mesos 社区也是类似的看法。

所以从一开始,Docker 公司就把应对 Kubernetes 项目的竞争摆在了首要位置:一方面,不断强调“Docker Native”的“重要性”,另一方面,与 Kubernetes 项目在多个场合进行了直接的碰撞。Kubernetes 项目让人耳目一新的设计理念和号召力,很快就构建出了一个与众不同的容器编排与管理的生态。就这样Kubernetes项目在GitHub上的各项指标开始一骑绝尘,将Swarm远远地甩在了身后。

有了这个基础,CNCF社区就可以放心地解决第二个问题。在已经囊括了容器监控事实标准的 Prometheus 项目之后,CNCF 社区迅速在成员项目中添加了 Fluentd、OpenTracing、CNI 等一系列容器生态的知名工具和项目,大量的公司和创业团队也开始专门针对 CNCF 社区而非 Docker公司制定推广策略。


5、尘埃落定

(1)孤注一掷

面对这样的竞争态势,在2016年Docker突然宣布放弃Swarm项目,将容器编排和集群管理功能全部内置到Docker项目中。Docker认为Swarm 项目目前唯一的竞争优势就是跟Docker项目无缝集成。如何让这种优势最大化呢?那就是把Swarm内置到 Docker 项目当中,从工程角度来看这种做法的风险很大。内置容器编排、集群管理和负载均衡能力固然可以使得 Docker 项目的边界直接扩大到一个完整的 PaaS 项目的范畴,但这种变更带来的技术复杂度和维护难度,长远来看对Docker项目不利。不过在当时的环境下Docker的选择恐怕也带有一丝孤注一掷的意味。

(2)百家争鸣

Kubernetes的应对策略则是反其道而行之,开始在整个社区推进“民主化”架构,即从API到容器运行时的每一层,为开发者暴露出了可以扩展的插件机制,鼓励用户通过代码的方式介入Kubernetes项目的每一个阶段。这个变革的效果立竿见影,很快在整个容器社区中催生出了大量基于Kubernetes API和扩展接口的二次创新工作,比如微服务治理项目Istio和有状态应用部署框架 Operator,以及像 Rook 这样的开源创业项目通过Kubernetes的可扩展接口把Ceph这样的重量级产品封装成了简单易用的容器存储插件。

在这种鼓励二次创新的整体氛围当中,Kubernetes社区在2016年之后得到了空前的发展。更重要的是不同于之前局限于“打包、发布”这样的PaaS化路线,这一次容器社区的繁荣完全以Kubernetes为核心的“百家争鸣”。

(3)落下帷幕

对Kubernetes的崛起和壮大,Docker不得不面对自己豪赌失败的现实,实际上早前Docker拒绝了微软的天价收购之后就已经没有了回旋余地。

从2017年开始Docker公司先是将Docker项目的容器运行时部分 Containerd捐赠给CNCF社区,标志着 Docker 项目已经全面升级成为一个PaaS平台,接着Docker宣布将Docker项目改名为Moby,然后交给社区自行维护,而Docker公司的商业产品将占有Docker这个注册商标。从此Docker公司全面放弃在开源社区同Kubernetes生态的竞争,转而专注于自己的商业业务。

2017 年 10 月,Docker 公司出人意料地宣布,将在自己的主打产品 Docker 企业版中内置 Kubernetes 项目,这标志着持续了近两年之久的“编排之争”至此落下帷幕。

2018 年 1 月 30 日,RedHat 宣布斥资 2.5 亿美元收购 CoreOS。

2018 年 3 月 28 日,这一切纷争的始作俑者Docker公司的 CTO Solomon Hykes 宣布辞职,他表示未来的身份将是 Docker 的董事会成员、主要股东以及 Docker 维护者,不再负责担任公司的日常工作。曾经纷纷扰扰的容器技术圈子,到此尘埃落定。

2019年,容器市场基本趋于稳定,一切都向着优化改进方向发展。Docker公司是底层容器引擎及运行时的。容器的编排进过几轮的激烈竞争,基本是Kubernetes一家独大。

至今,新的战斗已经由容器和编排的战场,逐渐迁移到应用领域。云原生CNCF将引领新的技术方向,微服务、ServcieMesh、Envoy、ServerLess等正在路上。


最后,非常感谢张磊老师的课程(在这里也给磊哥打个广告)


Kubernetes为什么会赢,容器圈的风云变幻!相关推荐

  1. 一场360容器圈的武林大会“360互联网技术训练营第九期—360容器技术解密与实践” (附PPT与视频)...

    女主宣言 周六我们的线下面基,圆满成功.女王大人发现,咱容器圈还是有不少妹子的哇~ PS:丰富的一线技术.多元化的表现形式,尽在"HULK一线技术杂谈",点关注哦! 2018年4月 ...

  2. 一场360容器圈的武林大会“360互联网技术训练营第九期—360容器技术解密与实践” (附PPT与视频)

    女主宣言 周六我们的线下面基,圆满成功.女王大人发现,咱容器圈还是有不少妹子的哇~ PS:丰富的一线技术.多元化的表现形式,尽在"HULK一线技术杂谈",点关注哦! 2018年4月 ...

  3. 《深入剖析Kubernetes》-张磊——白话容器基础(三):深入理解容器镜像

    <深入剖析Kubernetes>-张磊 白话容器基础(三):深入理解容器镜像 写在前面: 张磊的极客时间课程<深入剖析Kubernetes>,是我见过讲docker和k8s最好 ...

  4. Kubernetes(K8s)容器设计模式实践案例 – 分散收集模式

    <Kubernetes与云原生应用>专栏是InfoQ向轻元科技首席架构师王昕约稿的系列 文章.本专栏包含8篇内容,将会从介绍和分析Kubernetes系统以及云原生应用 入手,逐步推出基于 ...

  5. Kubernetes 如何打赢容器之战?

    阿里妹导读:Kubernetes 近几年很热门,在各大技术论坛上被炒的很火.它提供了强大的容器编排能力,与此同时 DevOps 的概念也来到大家身边,广大的开发同学也能简单地运维复杂的商业化分布式系统 ...

  6. 以 Kubernetes 为代表的容器技术,已成为云计算的新界面

    来源 | 阿里巴巴云原生公众号 作者 | 志敏.智清 2020 年 双11,阿里核心系统实现了全面云原生化,扛住了史上最大流量洪峰,向业界传达出了"云原生正在大规模落地"的信号.这 ...

  7. Kubernetes排错:用容器的元数据提供新思路

    本文讲的是Kubernetes排错:用容器的元数据提供新思路[编者的话]本文介绍了Kubernetes的元数据以及如何用于工作的,用好元数据有助于监控和排查系统故障,并且只有在需要的时候才去深入到主机 ...

  8. kubernetes不同的命名空间下的容器能通信吗_在Kubernetes环境中,容器间如何进行网络通信?...

    前 言 随着云计算的兴起,各大平台之争也落下了帷幕,Kubernetes作为后起之秀已经成为了事实上的PaaS平台标准,而网络又是云计算环境当中最复杂的部分,总是让人琢磨不透.本文尝试着围绕在Kube ...

  9. 《深入剖析Kubernetes》-张磊——白话容器基础(二):隔离与限制

    <深入剖析Kubernetes>-张磊 白话容器基础(二):隔离与限制 写在前面: 张磊的极客时间课程<深入剖析Kubernetes>,是我见过讲docker和k8s最好的网络 ...

最新文章

  1. php cookie加密 类,PHP cookie加密类
  2. poj 1830 开关问题
  3. C++类的构造函数 后单冒号加基类 例如:CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
  4. mysql的十进位,MySQL十进制字段的正确默认值是什么?
  5. [转载] [转载] python 中NumPy和Pandas工具包中的函数使用笔记(方便自己查找)
  6. 《Android框架揭秘》——2.4节开发Android应用程序
  7. 同花顺如何切换k线_同花顺k线图怎么切换(aud和人民币的汇率)
  8. Vivado 错误代码 [DRC PDCN-2721] 解决
  9. Qt开发植物大战僵尸第一篇
  10. 舱机器人尾巴毛茸茸_并无卵用的毛茸茸机器人 如此呆萌 设计是为了爱
  11. 可显示上拼音下汉字的 text 格式
  12. python爬虫爬取淘宝美食_python爬虫爬取淘宝商品信息
  13. 电脑显示windows无服务器,win10电脑提示windows似乎未正确加载_网站服务器运行维护...
  14. 腾讯音乐评论审核、分类与排序算法技术
  15. Deepin-TIM或Deepin-QQ调整界面DPI字体大小的方法
  16. 查看网站服务器版本,查看网站为TLS或SSL及其版本
  17. 去除滚动条 去除滚动条样式 css修改滚动条样式
  18. 又来了!10分钟实现微信 “炸屎“大作战
  19. Java工程师薪资究竟有多高?
  20. QPrinter设置页面(pageSize)铺满纸张(paperSize)问题

热门文章

  1. 喜报!Stratifyd获评“北京市用户满意企业”荣誉称号
  2. Java常用类(时间)
  3. 二手数码产品以旧换新评测
  4. 雅腾php怎么样_浅谈PHP发展前景及就业
  5. 微信新玩法,这个隐藏福利太爽了!!!
  6. 电视广告时段的收视率评估工具(CPRP Table评估)
  7. 【ubuntu(Linux)安装Vs code并配置c++编译及cmake多文件编译】
  8. java ee考试题_Java-EE考试习题
  9. Hadoop 从HDFS中删除文件夹命令
  10. struct termios结构体【转】