「深度学习福利」大神带你进阶工程师,立即查看>>> 2019天猫双11 96秒成交额破100亿 全球最大流量洪峰 每秒订单峰值54.4万笔 阿里巴巴核心系统 100%上云 我们扛住了! 1心1役 把不可能变成可能 今晚为阿里工程师疯狂打call! 阅读原文 本文为云栖社区原创内容,未经允许不得转载。
「深度学习福利」大神带你进阶工程师,立即查看>>> 有朋友问我说你们公司怎么用上了 云桌面 的,听说它的桌面性能不怎么样的,特别是在处理3D应用这一方面的时候听说效果很不好的,然后我就和他说,我们公司又不用到3D应用这一块的,我们就是一个互联网公司,主要就是正常的office办公,还有浏览网页,然后就是PS这些的,没感觉到它的有什么不好的啊。其实很多人和我一样之所以选择云桌面并不是说它的性能有多么的强大,而是因为其他的原因。 首先低的使用成本,我们之所以选择云桌面,其实一个最主要的原因就是听说云桌面的使用成本很低的,云桌面厂家给我们的方案介绍中,单独硬件的投入就可以比使用PC便宜了30%左右的,而用电成本更是不用说的,100个云终端的功耗也只有500W,也才相当于2台台式机的用电的,每年下来可以省95%左右的电费的,以及还有后期的维护和管理成本。这些对于急需降低运营成本的企业来说是迫切需要的。 其次方便的维护管理,之所以选择云桌面还有一个重要原因就是,它的管理维护包括系统的安装以及软件的升级都可以通过服务器来完成的,100台办公电脑如果使用台式机管理维护虽然也不是太复杂的,但是当需要给所有电脑安装新的操作系统和应用软件的时候,还是需要花费很多时间的,特别是对于经常需要安装使用一些新的应用软件的互联网一起来说更是麻烦的,而使用云桌面后这些都可以在服务器上就可以在线升级安装的。比使用PC节省了很多时间也方便了很多的。 第三可靠的数据安全,传统的台式机性能是很强大,很多人也很喜欢用台式机来办公的,但是对于对数据比较看重的企业来说却不是这样的,数据存储在本地可以随意的被访问和拷贝,硬盘的被盗和故障都能导致数据的泄露和丢失的。而云桌面通数据存储在服务器上,任何终端用户访问数据和拷贝资料都需要授权,确保数据不被泄露。服务器具备磁盘备份功能不用担心硬件故障而造成的数据丢失。 最后灵活的办公应用,作为一家公司来说更换办公位置是一个很正常的事情,而使用云桌面有一个好处就是灵活的办公的,当更换位置时我们只需要人过去就可以,更换到新的办公位置后只需要登录自己的账号密码就可以就像办公的了不需要搬动自己的显示器和终端这些就可以的。 云桌面在某些功能和应用上或许是比不了传统的PC的,但是它也有传统PC所不具备的优点,而这或许就是很多人和我一样选择云桌面的原因。 来源禹龙云
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 倪超(银时) 阿里云开发者工具产品专家 本文整理自 11 月 7 日社群分享,每月 2 场高质量分享, 点击加入 社群。 导读 :Cloud Toolkit 是本地 IDE 插件,帮助开发者更高效地开发、测试、诊断并部署应用。通过插件,可以将本地应用一键部署到任意服务器,甚至云端(ECS、EDAS、Kubernetes 和 小程序云 等);并且还内置了 Arthas 诊断、Dubbo工具、Terminal 终端、文件上传和 MySQL 执行器等工具。 Cloud Toolkit 功能清单 一键部署本地 IDE 内项目到任意远程服务器 一键部署本地 IDE 内项目到阿里云 EDAS、SAE 和 Kubernetes 本地 Docker Image 打包和仓库推送工具 远程服务器实时日志查看 阿里云小程序开发工具 阿里云函数计算开发工具 阿里云 RDS 内置 SQL 执行器 内置 Terminal 终端 文件上传 Apache Dubbo 框架项目模板&代码生成 Java 程序诊断工具 RPC 服务端云联调 知识点 1:提升部署效率 如上图所示,开发者本地编写的应用程序,在图形化界面上进行配置,即可持续便利的部署到任意服务器,或者阿里云的 ECS 服务器上;在 IDEA 或 Eclipse 中完成编码后,无须在 Maven 、Git 以及其他运维脚本和工具的之间切换,借助 Cloud Toolkit,在 IDE 的图形界面上选择一个或若干个实例,即可将应用程序部署至指定目录。 针对阿里云 EDAS 和 SAE 产品的开发者,我们也在插件上打通了本地应用程序和云端部署,在 IDE 中完成编码后,将项目工程关联上 EDAS 和 SAE 的应用,即可实现快速部署。 针对阿里云容器服务 Kubernetes 产品的开发者,我们也在插件上打通了本地应用程序和云端 Kubernetes 部署,在 IDE 中完成编码后,将项目工程关联上容器服务 Kubernetes,即可实现快速部署。 知识点 2:本地 Docker Image 打包和仓库推送工具 Cloud Toolkit 提供了图形化的 Docker Image 打包工具,能够帮助开发者即使在不熟悉 Docker 的情况下,也可以快速打包镜像,并推送到阿里云镜像仓库 ACR 。 知识点 3:内置终端 Terminal IDE 内,开发者可以直接通过内置的终端 Terminal,快速登录远程服务器; 不仅仅用于阿里云服务器 ECS,所有支持标准 SSH 协议的机器都可以。 知识点 4:文件上传 Cloud Toolkit 帮助开发者在 IDE 内,一键将本地或者远程 URL 文件上传到服务器指定目录下去,无需在各种 FTP、SCP 工具之间频繁切换。更为重要的是,文件上传完毕后,还支持命令执行,比如:文件解压缩、程序启动等。 立即点击下载 官网 手把手 1:部署应用到服务器 第一步:安装插件 略过,请读者自行前往各个平台的插件市场下载「Alibaba Cloud Toolkit」。 第二步:添加服务器 上图所示,在菜单 Tools - Alibaba Cloud - Alibaba Cloud View - Host 中打开机器视图界面,如下图: 点击右上角 Add Host 按钮,出现添加机器界面: 第三步:部署 在 IntelliJ IDEA 中,鼠标右键项目工程名,在出现的菜单中点击 【 Alibaba Cloud - Deploy to Host...】 ,会出现如下部署窗口: 在 Deploy to Host 对话框设置部署参数,然后单击 Deploy,即可执行初次部署。 部署参数说明 Deploy File:部署文件包含两种方式; Maven Build:如果当前工程采用 Maven 构建,可以使用 Cloud Toolkit 直接构建并部署; Upload File:如果当前工程并非采用 Maven 构建,或者本地已经存在打包好的部署文件,可以选择并直接上传本地的部署文件; Target Deploy host:在下拉列表中选择 Tag,然后选择要部署的服务器; Deploy Location :输入在 ECS 上部署路径,如 /root/tomcat/webapps; Commond:输入应用启动命令,如 sh /root/restart.sh。表示在完成应用包的部署后,需要执行的命令 —— 对于 Java 程序而言,通常是一句 Tomcat 的启动命令。 手把手 2:部署应用到容器服务 Kubernetes 第一步:配置插件首选项 安装完插件之后,按照路径进行首选项配置: 顶部菜单 - Tools - Alibaba Cloud Toolkit - Preferences。 出现如下界面,配置阿里云账号的 AK 和 SK,即可完成首选项配置。(如果是子账号,则填写子账号的 AK 和 SK) 设置本地 Docker 镜像打包: 顶部菜单 - Tools - Alibaba Cloud Toolkit - Preferences - Alibaba Cloud Toolkit - Docker 第二步:部署 在 Intellij IDEA 中,鼠标右键项目工程名,在出现的菜单中点击 Alibaba Cloud - Deploy to CS Kubernetes... ,可会出现如下部署窗口。 设置说明 1 在 Image 标签页中,选择本地应用程序的 Context Directory 和 Dockerfile(通常会根据您本地的应用工程自动识别并设置); 选择容器镜像服务的地域、命名空间和镜像仓库,然后单击 Container 标签页。 说明 :如果您还没有镜像仓库,在对话框右上角单击 Create a new repository 跳转到容器镜像仓库创建镜像仓库。创建步骤请参考 容器镜像仓库文档 。 设置说明 2 在 Container 标签页,选择容器服务 Kubernetes 的 Clusters(集群)、Namespace(命名空间)和 Deployment(部署),以及其中指定的 Container(容器)。 说明 :如果您还没有创建容器服务 Kubernetes 的 Deployment,在对话框右上角单击 Create a new Kubernetes deployment,跳转到容器服务 Kubernetes 控制台创建 Deployment。创建步骤请参考 容器服务 Kubernetes 版文档 。 点击 Run 按钮之后,即可完成本地应用程序向容器服务 Kubernetes 的部署。 Q & A Q1 :K8s 各组件,比如 etcd,建议部署在容器内还是物理机?有什么区别或者优劣吗? A1 :etcd 可以部署在容器里,物理机的话就是性能更好一点。 Q2 :如果登录是堡垒机,并且是动态密码,那个配置保存必须要密码,所以不方便吧!能动态密码登陆局域网服务器吗? A2 :这是个非常好的建议,我们需要在后续的版本中开发这些能力。 Q3 :如何在本地电脑(如 mac )部署 K8s 玩玩,以及写 Go 代码增删改查 K8s 资源,这块有啥玩一玩的优良经验嘛?目的是想本地开发测试 K8s,更加去熟悉 K8s 内部机制。 A3 :本地 mac 要玩 K8s 可以去搜一下 minikube。 Q4 :K8s 网络组件 calico 和自带的 flannel,请问建议采用哪一个? A4 :简单上手选 flannel,看重功能选 calico。 Q5 :有哪些开源的管理 K8s Web UI 软件,这样可以部署在公司内,所有团队直接在该软件内傻瓜式操作 K8s 资源,自己部署上线代码? A5 :K8s 自带的 dashboard 可以试试。 Q6 :我想深入学 K8s,但是 K8s 内部使用了 etcd/coredns,以及监控这块使用 prometheus,这些技术是不是需要先深入学习下,再去深入学习 K8s 呢?毕竟 K8s 太大了,一上来就深入会容易找不到门路,这块大大有啥经验没? A6 :建议从 K8s 核心开始学习,再学习周边组件,按照从中心到外围的顺序。推荐学习下阿里云和 CNCF 联合开发的免费云原生技术公开课。链接: https://edu.aliyun.com/roadmap/cloudnative Q7 :若 K8s 集群服务器宕机,请问如何快速恢复集群能力(除拉起 kubelet 等待其他组件自动拉起,是否还有其他方式)? A7 :配置 3master 高可用可降低宕机带来的损失,另外备份组件的配置文件。 Q8 :Master 节点如果同时作为 node 节点,请问存在哪些风险? A8 :Master 节点不宜作为 node 节点部署应用,会导致集群不稳定。 Q9 :请问老师,假设升级 K8s 集群版本,有什么地方需要注意的?另外升级过程各个组件先后顺序有要求吗?谢谢。 A9 :做好各个组件的备份,一般先升级 master,再升级 worker。 欢迎加入钉钉交流群 “阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文首发于: Jenkins 中文社区 原文链接 作者:Long Nguyen 译者:wenjunzhangp 我是越南 FPT 大学的 Long Nguyen ,我的 Google Summer of Code 2019 项目是 Remoting over Apache Kafka with Kubernetes features 。这是我第一次为 Jenkins 做贡献,我非常兴奋地宣布在第一阶段已经完成的功能。 项目介绍 当前版本的 Remoting over Apache Kafka plugin 远程处理需要用户手动配置整个系统,包括 zookeeper 、 kafka 和远程处理代理。它也不支持动态代理配置,因此很难实现具有伸缩性的扩展。我的项目旨在解决两个问题: 1. 提供 Apache-Kafka 集群的现成解决方案。 2. Kubernetes 集群中的动态代理配置。 当前状态 支持凭据的 Kubernetes 连接器。 Kubernetes 功能中的 ApacheKafka 预配功能已完全实现。 Helm chart 部分实现。 Kubernetes 中的 Apache-Kafka 配置 此功能是 2.0 版本的一部分,因此尚未正式发布。您可以通过使用 Experimental Update Center 更新到 2.0.0-alpha 版本或直接从 master 分支构建来尝试该功能: git clone https://github.com/jenkinsci/remoting-kafka-plugin.git cd remoting-kafka-plugin/plugin mvn hpi:run 在全局配置页面上,用户可以输入 Kubernetes 服务器信息和凭据。然后他们只需点击一个按钮就可以启动 ApacheKafka 。 当用户点击 Start Kafka on Kubernetes 按钮时, Jenkins 将根据信息创建一个 Kubernetes 客户机,然后从 resources 中应用 zookeeper 和 kafka yaml 规范文件。 Helm Chart Apache-Kafka 插件上远程处理的 Helm 图表基于 stable/jenkins 图表和 incubator/kafka 图表。截至目前,该图表仍在 开发中 ,因为它仍在等待第 2 阶段的 Cloud API 实现。但是,您可以使用一个独立的远程 Kafka 代理查看演示图表: git clone -b demo-helm-phase-1 https://github.com/longngn/remoting-kafka-plugin.git cd remoting-kafka-plugin K8S_NODE= ./helm/jenkins-remoting-kafka/do.sh start 命令 do.sh start 将执行以下步骤: * 安装图表(与 Jenkins 和 Kafka 一起使用)。 * 通过应用下面的 JCasC 在 Jenkins master 上启动一台 Kafka 计算机。 jenkins: nodes: - permanent: name: "test" remoteFS: "/home/jenkins" launcher: kafka: {} 启动单个 Remoting Kafka Agent pod 。 您可以通过运行 kubectl 来检查图表状态,例如: ``` $ kubectl get all -n demo-helm NAME READY STATUS RESTARTS AGE pod/demo-jenkins-998bcdfd4-tjmjs 2⁄2 Running 0 6m30s pod/demo-jenkins-remoting-kafka-agent 1⁄1 Running 0 4m10s pod/demo-kafka-0 1⁄1 Running 0 6m30s pod/demo-zookeeper-0 1⁄1 Running 0 6m30s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demo-0-external NodePort 10.106.254.187 19092:31090/TCP 6m30s service/demo-jenkins NodePort 10.101.84.33 8080:31465/TCP 6m31s service/demo-jenkins-agent ClusterIP 10.97.169.65 50000/TCP 6m31s service/demo-kafka ClusterIP 10.106.248.10 9092/TCP 6m30s service/demo-kafka-headless ClusterIP None 9092/TCP 6m30s service/demo-zookeeper ClusterIP 10.109.222.63 2181/TCP 6m30s service/demo-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 6m31s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/demo-jenkins 1⁄1 1 1 6m30s NAME DESIRED CURRENT READY AGE replicaset.apps/demo-jenkins-998bcdfd4 1 1 1 6m30s NAME READY AGE statefulset.apps/demo-kafka 1⁄1 6m30s statefulset.apps/demo-zookeeper 1⁄1 6m30s ``` 下一阶段计划 实施 Cloud API 来配置 Remoting Kafka Agent 。( JENKINS-57668 ) 将 Cloud API 实施与 Helm 图表集成。( JENKINS-58288 ) 单元测试和集成测试。 发布版本 2.0 和地址反馈。( JENKINS-58289 ) 链接 第一阶段演示视频 第一阶段演示幻灯片 Remoting over Apache Kafka plugin 项目页面 Gitter Channel
「深度学习福利」大神带你进阶工程师,立即查看>>> 来源 丨TechSugar **文︱**Sophia **图︱**网络 什么是“边缘计算”? 想要弄清楚这一概念的含义,我们还得从“云计算”谈起。云计算(cloud computing)指的是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序,然后,通过多部服务器组成的系统进行处理和分析这些小程序得到结果并返回给用户。用户通过网络获得应用所需的资源(硬件、平台、软件)。而提供资源的网络被称为“云”。 传统云计算模型(来源:网络) 举个简单的例子,这就好似我们现在的用电方式一样。每个家庭或企业一般情况下并不自己生产“电”,而是大型发电站进行集中发电,然后通过星罗棋布的电网,将“电”输送到每家每户。人们只需插上插座,按时交纳电费,便可以用上电。“云计算”就类似于这样一种存在。那些提供云计算服务的公司,就好比“大型发电站”。1961 年,网络互联领域专家约翰·麦卡锡就曾预言:“未来电脑运算有可能成为一项公共事业,就像电话系统已成为一项公共事业一样。”然而,正如文章开头所说,庞大的数据量将极易造成网络拥堵,并且随着5G时代的到来,我们对数据的实时性提出了更高的要求。因此我们需要将部分数据在本地进行处理。“边缘计算”便是这样一种模式。 所谓边缘计算就是在网络边缘结点来处理、分析数据,而不是在中央服务器里整理后实施处理。在这里“边缘节点”目前主要包括,通信基站、服务器、网关设备以及终端设备。与云计算相比边缘计算在网络拓扑中的位置更低,即更加靠近“用户”——数据产生的地方。作为对云计算方式的补充,边缘计算弥补了云计算的诸多缺陷。 来源:网络 边缘计算的优势 边缘计算与传统云计算主要性能对比(来源:思科) 1、 低时延 :由于数据是在边缘结点进行分析处理,降低了延迟,提升应用的响应速度。据运营商估计,如若经由部署在接入点的MEC完成处理和转发,则时延有望控制在1ms之内。 2、 更安全 :一些比较敏感的数据直接在边缘进行分析处理,不用全部上传至云计算平台,能够尽可能的避免数据泄露问题。 3、 减少数据传输 :数据不需要全部传输到云端,减少智能设备和数据中心传输的数据量,节省了大量带宽成本,同时还能减小核心网络的拥堵。 4、 提高可用性 :边缘计算分担(offload)了中心服务器的计算任务,并且降低了出现单点故障的可能。另外很多智能终端设备在非工作状态下处于闲置状态,边缘计算可以充分的对其加以利用,提高了资源的利用率。 现状——主要“玩家” 目前,边缘计算产业主要涉及设备、网络、应用和数据四个领域。边缘计算产业联盟提出的边缘计算参考架构1.0指出,设备域支撑现场设备实现实时的智能交互和智能应用;网络域为系统互联、数据聚合与承载提供连接服务;数据域提供全生命周期数据服务并保障数据的安全与隐私;应用域需要实现边缘行业应用,支持边缘业务运营。 从“中信证券研究部”整理的资料来看,边缘计算产业涉及硬件、软件、通信等多个方面的企业。上下游企业紧密联系,通力合作。并加快边缘计算方面的布局。 来源:中信证券研究部 对于上游企业,2019年2月25日,浪潮在世界移动通信大会MWC2019上发布了首款基于OTII标准的边缘计算服务器NE5260M5,该产品专为5G设计,可以承担物联网、MEC和NFV等5G应用场景,适合边缘机房的物理环境。华为发布的华为AR系列敏捷网关,具有高度的适应性,能提供17种以上的物联接口,并广泛兼容各个行业的标准协议。另外,凌华科技推出模块化工业云计算架构MICA和架构级边缘服务器SETO-1000,用以分别应对5G建设的集中式无线接入网(C-RAN)和分布式无线接入网(D-RAN),前者具有模块化设计、工业级特性、云计算核心等特征;后者具有防尘防水、抵抗低温等环境耐性,能适配高带宽下的边缘计算需求。当然作为上游软件提供商,他们也纷纷推出了自己的产品,例如思科IOx平台以及华为Liteos平台。 根据中信证券的分析报告,中游企业在公有云市场上竞争激烈,边缘云服务提供商逐渐在细分领域进行布局。从2015年起,国内公共云市场除阿里云外,大量的中小企业占据了1/3的市场份额,大小厂商展开了激烈的价格竞争。因此部分云服务商积极拓展新的领域。目前已有多家公司涉足边缘计算平台和相关服务。此外,国内三大通信运营商均已制定5G网络商用计划,并加大了对MEC相关基础设施的投入。 对于下游企业而言,边缘计算不仅服务于手机、电脑等常规的智能终端设备。车联网、智能家居概念的提出,为边缘计算创造了新的需求。BAT等巨头公司也纷纷参与到智能硬件产品的开发之中。 应用与前景 根据中国移动发布的《中国移动边缘计算白皮书》,目前智能制造、智慧城市、直播游戏和车联网4个垂直领域对边缘计算的需求最为明确。 边缘计算的典型应用场景(来源:中国移动) 智能制造 在智能制造领域,工厂利用边缘计算智能网关进行本地数据采集,并进行数据过滤、清洗等实时处理。同时边缘计算还可以提供跨层协议转换的能力,实现碎片化工业网络的统一接入。一些工厂还在尝试利用虚拟化技术软件实现工业控制器,对产线机械臂进行集中协同控制,这是一种类似于通信领域软件定义网络中实现转控分离的机制,通过软件定义机械的方式实现了机控分离。 智慧城市 智慧城市,主要包括智慧楼宇、物流和视频监控等多个方面。边缘计算可以实现对城市中运行参数进行采集分析。例如,在城市路面检测中,在道路两侧路灯上安装传感器收集城市路面信息,检测空气质量、光照强度、噪音水平等环境数据,当路灯发生故障时能够及时反馈至维护人员。边缘计算还可以利用本地部署的GPU服务器,实现毫秒级的人脸识别、物体识别等智能图像分析。 虽然当前城市中部署了大量的IP摄像头,但是大部分摄像头都不具备前置的计算功能,而需要将数据传输至数据中心进行处理,或者需要人工的方式来进行数据筛选。然而,安珀警报助手(Amber alert assistant)的开发,使其可以自动化地在边缘设备上部署视频分析程序,并与附近的边缘设备协同实时地对视频进行处理,同时和周边摄像头进行联动,以完成犯罪车辆的实时追踪。 直播游戏 在直播游戏领域,边缘计算可以为CDN提供丰富的存储资源,并在更加靠近用户的位置提供音视频的渲染能力,让云桌面,云游戏等新型业务模式成为可能。特别在AR/VR场景中,边缘计算的引入可以大幅降低AR/VR终端设备的复杂度,从而降低成本,促进整体产业的高速发展。 车联网 随着深度学习和传感器等技术的发展,汽车不再仅仅是传统的出行和运输工具,而是不断智能化,我们称这样新型的汽车为智能网联车(connected and autonomous vehicles, CAVs)智能网联车的出现催生出了一系列新的应用场景,例如自动驾驶、车联网以及智能交通。我们以“自动驾驶”为例,由于它配备了非常多的传感器,汽车可以随时随地感知周围的环境,并也源源不断的产生数据。所以,“自动驾驶汽车”就好似一个“移动的数据中心”。 来源:网络 Intel曾经的一份报告指出,一辆自动驾驶车辆一天产生的数据为4TB,这些数据无法全部上传至云端处理,需要在边缘节点(汽车)中存储和计算,从而形成指令。另一方面,无人驾驶汽车对于“延迟”的要求非常苛刻,尤其是当汽车在高速行驶的过程中,通信延迟需要控制在极短的范围之内,并且网络的可靠性对于安全驾驶也是至关重要的。 挑战 然而,边缘计算现如今还没有完全成熟,并且它也不是一个完美无瑕的计算方式。施巍松教授曾在他的论文《Edge Computing : Vision and Challenges》中表示,“边缘计算具有”编程可行性、命名和数据抽象三方面的问题。 1、编程可行性:在云计算平台编程是非常便捷的,因为云上有特定的编译平台,大部分程序都可以在云上运行。但是在边缘层编程就会面临一个平台异构的问题,每一个网络的边缘都是不一样的,可能是ios系统,也有可能是安卓或者linux等等,不同平台下的编程又是不同的。 2、命名:命名方案对于编程、寻址、事物识别和数据通信非常重要,但是在边缘计算中还没有行之有效的数据处理方式。边缘计算中事物的通信是多样的,可以依靠wifi、蓝牙等通信技术,因此,仅仅依靠tcp/ip协议栈并不能满足这些异构的事物之间进行通信。边缘计算的命名方案需要处理事物的移动性,动态的网络拓扑结构,隐私和安全保护等问题。传统的命名机制如DNS(域名解析服务)、URI(统一资源标志符)都不能很好的解决动态的边缘网络的命名问题。目前正在提出的NDN(命名分发网络)解决此类问题也有一定的局限性。在一个相对较小的网络环境中,我们提出一种解决方案,如下图所示,我们描述一个事物的时间、地点以及正在做的事情,这种统一的命名机制使得管理变得非常容易。当然,当环境上升到城市的高度的时候,这种命名机制可能就不是很合适了。 来源:《Edge Computing:Vision and Challenges》 3、数据抽象:在物联网环境中会有大量的数据生成,并且由于物联网网络的异构环境,生成的数据是各种格式的,把各种各样的数据格式化对边缘计算来说是一个挑战。同时,网络边缘的大部分事物只是周期性的收集数据,定期把收集到的数据发送给网关,而网关中的存储是有限的,他只能存储最新的数据,因此边缘结点的数据会被经常刷新。利用集成的数据表来存储感兴趣的数据,表内部的结构可以如下图所示,用id、时间、名称、数据等来表示数据。 来源:《Edge Computing : Vision and Challenges》 如果筛选掉过多的原始数据,将导致边缘结点数据报告的不可靠,如果保留大量的原始数据,那么边缘结点的存储又将是新的问题;同时这些数据应该是可以被引用程序读写和操作的,由于物联网中事物的异构性,导致数据库的读写和操作会存在一定的问题。
「深度学习福利」大神带你进阶工程师,立即查看>>> 产品概述:物联网中心通过设备连接通信功能,帮助用户将设备数据采集上云;平台提供设备管理功能帮助用户远程管理、控制设备;平台通过规则引擎提供接口将设备数据转发、存储到其他京东云服务,帮助用户集成应用。 产品概述:数据传输 DTS 是京东云提供的数据库迁移服务,支持MySQL、MariaDB、Percona、SQL Server、MongoDB等多种数据库迁移,可以简单快速地将本地自建数据库迁移至京东云。 产品概述:边缘网络隧道是基于电信边缘网络及海量碎片化闲置资源节点构建而成的网络穿透服务。通过该服务获得边缘优质中继线路,实现端与端之间快速连接和内容传输 产品概述:云容灾服务实现与公有云和私有云架构的对接,通过灵活高效的数据复制技术,提供关键数据的实时保护;通过自动化管理平台,提供灾备全环境监控以及一键式切换操作,为业务和数据提供安全可靠的灾难恢复方案。 描述:创建云硬盘是可通过参数指定开通自动续费,实现资源到期时自动使用账户余额对云硬盘实例进行续费,简化续费流程,方便用户维护云硬盘资源。 描述:对于按时间拆分的表,可在原有分库的基础上添加新的分库,扩展表的存储范围和容量。 描述:新增预付费资源包,包含标准存储容量包及外网下行流量包。 描述:支持检测直播流中黑屏、纯色、偏色、晶振、亮度、对比度等影响用户体验的质量问题,客户可针对性检测其中一项或多项问题。 描述:提供给设备厂商,用于集成在设备之上并使之安全连接至京东云物联网引擎或物联网中心进行管理。 描述:1. 消息轨迹页面信息分布更合理,用户可以清晰查询到消息的各个阶段状态。2. 用户可以在一定范围内自定义取出消息隐藏时间、最大重试次数以及是否开启死信队列。 描述:日志管理是京东云微服务平台针对微服务日志类数据的一站式服务,用户无需开发就能快捷完成日志数据采集、解析、存储以及查询分析等功能,提升运维、及故障定位排除效率。 描述:提供自定义监控维度查询监控图和配置报警的功能,满足用户多维度监控数据的统计需求。 描述:根据业务需求在对应的日志主题内创建日志监控配置,筛选出符合条件的日志,并对符合筛选条件的日志中的指定字段进行计数、求和、最大值、最小值、平均值的聚合统计。同时,用户也可以根据自身业务需求设置报警规则,进行报警。 点击” 阅读 “了解更多京东云最新产品消息 点击“ 京东云 ”了解京东云更多精彩内容
「深度学习福利」大神带你进阶工程师,立即查看>>> 云计算、大数据带来的数字化转型赋予了经济发展新的动力。数字经济是随着信息技术发展而产生的一种新的经济形态。在世界范围内,数字经济早已成为全球经济的重要内容,是全球经济发展的主线,并在逐步推动产业界和全社会的数字化转型。在数字化的趋势下,信息技术将会越来越深入到企业业务的方方面面,而低代码搭建应用将是未来企业进入信息化的首要选择。 JEPaaS云平台作为中国领先的低代码开发平台产品与方案提供商,是专为SaaS而生的PaaS开发平台。基于PaaS而生,帮助SaaS企业、咨询公司和企业客户,大幅缩短复杂业务需求响应时间和成本。 JEPaaS可以在公有云或私有云上快速搭建各种工作场景及应用软件,相当于是建立在云基础上的操作系统。快速对接人工智能、物联网,是把人工智能和物联网快速普及到具体工作实践中去的基础平台,也更加符合国内用户的使用习惯和工作场景。平台采用BS架构,可以基于云开发大型软件或者作为大型项目的基础开发平台,可以实现各种复杂应用场景的智能化管理,可以基于低代码开发平台实现在云端的搭建。JEPaaS低代码平台在为客户服务的过程中,也继续形成套件的积累,进而实现为该行业进行深度的服务,从而解决了低代码软件平台不能全行业覆盖的瓶颈,开创了低代码开发平台的新时代。 JEPaaS低代码平台的先进性: 完善的支撑架构 组织机构,扁平、矩阵等架构全支持角色权限,功能、数据、字段全控制SNS,人与人、人与系统全协同工作流,全业务流程驱动任务管理,系统工作实时提醒。 可视化的功能设计 业务表单,可视化配置业务表单;业务流程,图形化设计业务流程;业务报表,多维度数据统计分析。 灵动、全面的业务规则 表单计算逻辑、表单校验规则、业务间关联逻辑、流程流转规则、报表计算逻辑等都通过统一的业务规则引擎灵活定义。 代码级的无限扩展 在线编码,前端后端随您掌控;在线调试,所有问题快速捕捉;SDK控件,第三方应用无缝连接。 丰富应用模板 免费提供大量开箱即用,自由修改的应用模板。 数字化转型不是让企业将现有业务以数字化的形式记录下来,而是利用新的技术去改造业务,以更好服务客户。低代码平台改变的不仅仅是企业的IT,更改变的是企业。它使得企业变成一家敏捷的、数字化企业,从而使得企业具备下一代创新的基础。
「深度学习福利」大神带你进阶工程师,立即查看>>> 台式机一直以来都是以超高的配置和能连接更大的显示器而被很多人喜欢,一直以来它也是很多企业选择办公电脑时的首要选择的,然而随着 云桌面 的出现,向来以超高配置和性价比的台式机仿佛不在这么受欢迎的了,相比于性能更加强大的台式机,很多企业仿佛更喜欢使用云桌面的。这又是什么原因的呢? 1、 台式机配置是很高性能也很强大,但是由于数据都在本地存储,台式机各种端口难以管控,数据可以随意的拷贝,同时本地存储,系统中毒或者硬盘故障后容易导致数据的丢失,而这些对于很多企业来说都是一个重大的损失,而云桌面所有的数据都集中在服务器上,服务器基本磁盘备份和高可用的功能,不用担心硬件故障造成的数据丢失,同时终端不进行数据的存储,用户在访问重要数据和插入U盘等存储工具拷贝时都必须权限才可以,从而保证数据的安全性。 2、随着市场竞争环境的日益激烈,企业除了在通过加强人才建设上来提高竞争力之外,同时也希望通过降低自身的运营成本来提高竞争力的,而云桌面有一个最大的优势就是它的使用成本会比传统PC低的,云终端和台式机相比功耗只有5W,每年可以节省大概95%左右的电费成本的,而这对于拥有几十上百个用户的企业来说,单节省的电费都是不得了的,更不要说后期的管理和维护升级等成本的了。 3、之所以说相比于性能更加强大的台式机很多的企业更喜欢使用云桌面,还有一个重要原因就是,它本身的功能也不弱的,它的CPU核心数,运行内存和存储硬盘等这些一样可以达到高配置台式机性能的,在运行office办公、浏览网页、微信QQ、播放高清视频、Photoshop等应用时都流畅不卡顿的。虽然说台式机在3D应用上会更强大,然而对于大多数的企业来说并不是所有的用户都需要用到3D的,更多的还是普通办公应用这些的。 台式机相对来说性能是很强大,但是对于很多企业来说如何提高数据安全和以及降低成本才是最重要的,在云桌面不影响正常办公的情况下,即使台式机性能更强大,很多企业还是更喜欢使用云桌面的。 来源禹龙云
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者| 阿里云智能事业群技术专家牛秋霖(冬岛) 导读 :从头开发一个Serverless引擎并不是一件容易的事情,今天咱们就从Knative的健康检查说起。通过健康检查这一个点来看看Serverless模式和传统的模式都有哪些不同,以及Knative针对Serverless场景都做了什么思考。 Knative Serving 模块的核心原理如下图所示,图中的 Route 可以理解成是 Istio Gateway 的角色。 当缩容到零时进来的流量就会指到 Activator 上面; 当 Pod 数不为零时流量就会指到对应的 Pod 上面,此时流量不经过 Activator; 其中 Autoscaler 模块根据请求的 Metrics 信息实时动态的扩缩容。 Knative 的 Pod 是由两个 Container 组成的:Queue-Proxy 和业务容器 user-container。架构如下: 咱们以 http1 为例进行说明:业务流量首先进入 Istio Gateway,然后会转发到 Queue-Proxy 的 8012 端口,Queue-Proxy 8012 再把请求转发到 user-container 的监听端口,至此一个业务请求的服务就算完成了。 粗略的介绍原理基本就是上面这样,现在咱们对几个细节进行深入的剖析看看其内部机制: 为什么要引入 Queue-Proxy? Pod 缩容到零的时候流量会转发到 Activator 上面,那么 Activator 是怎么处理这些请求的? Knative 中的业务 Pod 有 Queue-Proxy 和 user-container,那么 Pod 的 readinessProber 和 LivenessProber 分别是怎么做的?Pod 的 readinessProber、 LivenessProber 和业务的健康状态是什么样的关系? Istio Gateway 向 Pod 转发流量的时候是怎么选择 Pod 进行转发的? 为什么要引入 Queue-Proxy Serverless 的一个核心诉求就是把业务的复杂度下沉到基础平台,让业务代码快速迭代并且按需使用资源。不过现在更多的还是聚焦在按需使用资源层面。 如果想要按需使用资源我们就需要收集相关的 Metrics,并根据这些 Metrics 信息来指导资源的伸缩。Knative 首先实现的就是 KPA 策略,这个策略是根据请求数来判断是否需要扩容的。所以 Knative 需要有一个机制收集业务请求数量。除了业务请求数还有如下信息也是需要统一处理: 访问日志的管理; Tracing; Pod 健康检查机制; 需要实现 Pod 和 Activator 的交互,当 Pod 缩容到零的时候如何接收 Activator 转发过来的流量; 其他诸如判断 Ingress 是否 Ready 的逻辑也是基于 Queue-Proxy 实现的。 为了保持和业务的低耦合关系,还需要实现上述这些功能,所以就引入了 Queue-Proxy 负责这些事情。这样可以在业务无感知的情况下把 Serverless 的功能实现。 从零到一的过程 当 Pod 缩容到零的时候流量会指到 Activator 上面,Activator 接收到流量以后会主动“通知”Autoscaler 做一个扩容的操作。扩容完成以后 Activator 会探测 Pod 的健康状态,需要等待第一个 Pod ready 之后才能把流量转发过来。所以这里就出现了第一个健康检查的逻辑: Activator 检查第一个 Pod 是否 ready。 ** 这个健康检查是调用的 Pod 8012 端口完成的,Activator 会发起 HTTP 的健康检查,并且设置 K-Network-Probe=queue Header,所以 Queue Container 中会根据 K-Network-Probe=queue 来判断这是来自 Activator 的检查,然后执行相应的逻辑。 参考阅读 Activator to perform health checks before forwarding real requests Activator: Retry on Get Revision error Retry on Get Revision error? Always pass Healthy dests to the throttler Consolidate queue-proxy probe handlers Queue proxy logging, metrics and end to end traces End to end traces from queue proxy VirtualService 的健康检查 Knative Revision 部署完成后会自动创建一个 Ingress(以前叫做 ClusterIngress), 这个 Ingress 最终会被 Ingress Controller 解析成 Istio 的 VirtualService 配置,然后 Istio Gateway 才能把相应的流量转发给相关的 Revision。 所以每添加一个新的 Revision 都需要同步创建 Ingress 和 Istio 的 VirtualService ,而 VirtualService 是没有状态表示 Istio 的管理的 Envoy 是否配置生效能力。所以 Ingress Controller 需要发起一个 http 请求来监测 VirtualService 是否 ready。这个 http 的检查最终也会打到 Pod 的 8012 端口上。标识 Header 是 K-Network-Probe=probe 。Queue-Proxy 需要基于此来判断,然后执行相应的逻辑。 相关代码如下所示: 图片来源 图片来源 参考阅读 Gateway 通过这个健康检查来判断 Pod 是否可以提供服务 。 New probe handling in Queue-Proxy & Activator Extend VirtualService/Gateway probing to HTTPS Probe Envoy pods to determine when a ClusterIngress is actually deployed ClusterIngress Status Consolidate queue-proxy probe handlers Kubelet 的健康检查 Knative 最终生成的 Pod 是需要落实到 Kubernetes 集群的,Kubernetes 中 Pod 有两个健康检查的机制:ReadinessProber 和 LivenessProber。 其中 LivenessProber 是判断 Pod 是否活着,如果检查失败 Kubelet 就会尝试重启 Container; ReadinessProber 是来判断业务是否 Ready,只有业务 Ready 的情况下才会把 Pod 挂载到 Kubernetes Service 的 EndPoint 中,这样可以保证 Pod 故障时对业务无损。 那么问题来了,Knative 的 Pod 中默认会有两个 Container:Queue-Proxy 和 user-container 。 前面两个健康检查机制你应该也发现了,流量的“前半路径”需要通过 Queue-Proxy 来判断是否可以转发流量到当前 Pod,而在 Kubernetes 的机制中,Pod 是否加入 Kubernetes Service EndPoint 完全是由 ReadinessProber 的结果决定的。而这两个机制是独立的,所以我们需要有一种方案来把这两个机制协调一致。这也是 Knative 作为一个 Serverless 编排引擎时需要对流量做更精细的控制要解决的问题。所以 Knative 最终是把 user-container 的 ReadinessProber 收敛到 Queue-Proxy 中,通过 Queue-Proxy 的结果来决定 Pod 的状态。 另外 这个 Issue 中也提到在启动 istio 的情况下,kubelet 发起的 tcp 检查可能会被 Envoy 拦截,所以给 user-container 配置 TCP 探测器判断 user-container 是否 ready 也是不准的。这也是需要把 Readiness 收敛到 Queue-Proxy 的一个动机。 Knative 收敛 user-container 健康检查能力的方法是: 置空 user-container 的 ReadinessProber; 把 user-container 的 ReadinessProber 配置的 json String 配置到 Queue-Proxy 的 env 中; Queue-Proxy 的 Readinessprober 命令里面解析 user-container 的 ReadinessProber 的 json String 然后实现健康检查逻辑,且这个检查的机制和前面提到的 Activator 的健康检查机制合并到了一起。这样做也保证了 Activator 向 Pod 转发流量时 user-container 一定是 Ready 状态。 参考阅读 Consolidate queue-proxy probe handlers Use user-defined readinessProbe in queue-proxy Apply default livenessProbe and readinessProbe to the user container Good gRPC deployment pods frequently fail at least one health check Fix invalid helloworld example 这里面有比较详细的方案讨论,最终社区选择的方案也是在这里介绍的。 Allow probes to run on a more granular timer. Merge 8022/health to 8012/8013 TCP probe the user-container from the queue-proxy before marking the pod ready. Use user-defined readiness probes through queue-proxy queue-proxy /heatlth to perform TCP connect to user container 使用方法 如下所示可以在 Knative Service 中定义 Readiness。 apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata: name: readiness-prober spec: template: metadata: labels: app: helloworld-go spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4db7 readinessProbe: httpGet: path: / initialDelaySeconds: 3 需要说明两点: 和原生的 Kubernetes Pod Readiness 配置相比,Knative 中 timeoutSeconds、failureThreshold、periodSeconds 和 successThreshold 如果要配置就要一起配置,并且不能为零,否则 Knative webhook 校验无法通过。并且如果设置了 periodSeconds,那么一旦出现一次 Success,就再也不会去探测 user-container(不建议设置 periodSeconds,应该让系统自动处理)。 如果 periodSeconds 没有配置那么就会使用默认的探测策略,默认配置如下: timeoutSeconds: 60 failureThreshold: 3 periodSeconds: 10 successThreshold: 1 从这个使用方式上来看,其实 Knative 是在逐渐收敛 user-container 配置,因为在 Serverless 模式中需要系统自动化处理很多逻辑,这些“系统行为”就不需要麻烦用户了。 小结 前面提到的三种健康检查机制的对比关系: “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文结合HDFS的副本和分块从宏观上描述HDFS存入文件的整个流程。HDFS体系中包含Client、NameNode、DataNode、SeconderyNameode四个角色,其中Client是客户端,NN负责管理,DN负责存储、SN协助管理。 先来看一个官网上的图 # 图 0 -HDFS的体系结构 HDFS的副本存储有如下规则: 1.client将第一副本放到最靠近的一台DN 2.第二副本优先放到另一个机架 3.以此类推,尽量保证副本放在不同的机架 由于副本和分块机制的存在,当从本地文件系统向HDFS上传文件时,其内部的流程相对比较复杂,可以通过下图及步骤说明进行理解。 # 图 1-1 -hdfs副本存储机制(3副本) A.对于可存于单块的小文件: 1.client向NN(NameNode)发起存储请求, 2.NN查找自身是否已有相应的文件, 3.若无则,NN向client返回DN1(DataNode)路径, 4.client向DN1传送副本, 5.DN1通过管道异步向DN2传副本, 6.DN2通过管道异步向DN3传副本, 7.DN3通知DN2接收完成, 8.DN2通知DN1接收完成, 9.DN1通知NN接收完成。 B.对于需要分块的大文件: 大致流程同上,但在步骤3NN还会进行块的划分,随后步骤4client会将各块分别发送到分配的DN执行步骤4~9 从前述可见,在向HDFS传输文件的过程中,NameNode节点至关重要。NN负责掌管元数据。其作用相当于物理硬盘中的文件分配表FAT,NN中的数据如果发生丢失,DN中存储的数据也就没有了意义。 # 图 1-2 -NN元数据存储机制 1.client向NN请求写, 2.NN将分配block写入editslog文件, 3.NN响应client, 4.client向DN写文件, 5.client通知NN写完成, 6.NN将editslog更新到内存。 ps:常用及最新元数据放在内存,最新元数据放editslog,老元数据放fsimage,editslog写满之前将edits log(新元数据)转换并合并到fsimage。 # 图 1-3 -edits log合并机制 当editslog写满: 1.NN通知SecondryNameNode执行checkpoint操作, 2.NN停止向已满editslog写入, 3.NN创建新edits log维持写入, 4.SN下载NN的fsimage和已满editslog, 5.SN执行合并生成fsimage。checkpoint, 6.SN向NN上传fsi。cp, 7.NN将fsi。cp改名fsimage, 8.NN删除已满editslog。 # 图3 -元数据格式:文件全路径,副本数,块编号,块-所在DN的映射。
「深度学习福利」大神带你进阶工程师,立即查看>>> 好程序员云计算培训分享部署网校系统部署 网校系统 edusoho 基础环境 update: [root @aliyun ~]# yum update [root @aliyun ~]# reboot epel: [root @aliyun ~]# yum -y install epel-release env: [root @aliyun ~]# yum -y install bash-completion [root @aliyun ~]# getenforce Disabled [root@aliyun ~]# systemctl restart firewalld [root@aliyun ~]# systemctl enable firewalld.service Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service. Created symlink from /etc/systemd/system/basic.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service. [root@aliyun ~]# firewall-cmd --permanent --add-service=http success [root@aliyun ~]# firewall-cmd --permanent --add-service=https success [root@aliyun ~]# firewall-cmd --permanent --add-port=8080/tcp success [root@aliyun ~]# firewall-cmd --reload success [root@aliyun ~]# firewall-cmd --permanent --list-all LAMP环境 [root@aliyun ~]# yum -y install httpd [root@aliyun ~]# yum -y install php php-cli php-curl php-fpm php-intl php-mcrypt php-mysql php-gd php-mbstring php-xml php-dom [root@aliyun ~]# yum -y install mariadb-server mariadb [root@aliyun ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/m/mod_xsendfile-0.12-10.el7.x86_64.rpm apache: [root@aliyun ~]# rm -rf /etc/httpd/conf.d/welcome.conf [root@aliyun ~]# sed -ri 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf [root@aliyun ~]# systemctl start httpd [root@aliyun ~]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. [root@aliyun ~]# echo "tianyun test" > /var/www/html/index.html [root@aliyun ~]# ss -an |grep :8080 tcp LISTEN 0 128 *:8080 *:* mysql: [root@aliyun ~]# systemctl start mariadb [root@aliyun ~]# systemctl enable mariadb Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service. [root@aliyun ~]# mysql_secure_installation [root@aliyun ~]# mysql -uroot -p MariaDB [(none)]> create database edusoho; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | edusoho | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec) php: [root@aliyun ~]# vim /etc/php.ini post_max_size = 1024M memory_limit = 1024M upload_max_filesize = 1024M date.timezone = Asia/ShangHai [可选]
「深度学习福利」大神带你进阶工程师,立即查看>>> VMware vSphere vCenter Server Appliance (简称为VCSA)中包含一个Platform Service Controller的系列服务。VMware Certificate Authority(简称VMCA)就是其中不可或缺的一员。vCenter Server 核心的身份认证服务包括以下3个组件: 1)VMCA,VMware证书管理服务 2)VMAFD,VMware Authentication Framework Daemon 3)VMDIR,VMware Directory Service,目录服务 1、VMCA VMCA面向VMware环境中的VMware产品提供的电子证书服务,其命令行工具存放在vCenter Server上,见下文: #/usr/lib/vmware-vmca/certificate-manager //运行上述的命令行后,会出现以下内容: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | *** Welcome to the vSphere 6.7 Certificate Manager *** | | | | -- Select Operation -- | | | | 1. Replace Machine SSL certificate with Custom Certificate | | | | 2. Replace VMCA Root certificate with Custom Signing | | Certificate and replace all Certificates | | | | 3. Replace Machine SSL certificate with VMCA Certificate | | | | 4. Regenerate a new VMCA Root Certificate and | | replace all certificates | | | | 5. Replace Solution user certificates with | | Custom Certificate | | | | 6. Replace Solution user certificates with VMCA certificates | | | | 7. Revert last performed operation by re-publishing old | | certificates | | | | 8. Reset all Certificates | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _| Note : Use Ctrl-D to exit. VMCA为以下用户签发证书: 1)系统用户,SAML证书,用于验证身份,存放在VECS(Endpoint Certificate Store ,证书存放点)内,一般来说其证书有效期为2592000秒,即30天 2)ESXi主机,SSL证书,用于通信加密,存放在主机本地磁盘中 3)运行相关服务的服务器,SSL证书,用于通信加密,存放在VECS内 即,VMCA只向同一个域内、想要使用SSO(single sign-on,单点登录)登录的客户端发放证书。VMware产品则使用标准的X.509 version 3 (X.509v3)证书来存放Session证书。这些证书也要通过SSL加密过的网络连接发送。 2019年11月5日,我与其他4人在北京参加ICW,VMware北京公司的寇学旭老师说,vCenter Server两个登录客户的登录端口看上去似乎都是443,但实际上一个是5443,一个9443。我不相信,登录到vCenter Server,看到如下结果: netstat -nlp |grep 443 tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2196/rhttpproxy tcp 0 0 0.0.0.0:9443 0.0.0.0:* LISTEN 2374/vsphere-client tcp 0 0 0.0.0.0:5443 0.0.0.0:* LISTEN 2396/vsphere-ui.lau tcp6 0 0 :::443 :::* LISTEN 2196/rhttpproxy 上面的结果中,负责展示网页的是rhttpproxy,那个叫vsphere-client的是老式的、即将退出历史舞台的、基于Adobe Flex的客户端。vsphere-ui.lau则是那个基于HTML 5的新式客户端。 2、VMAFD /usr/lib/vmware-vmadir-cli, certool, and vecs-cl 3、VMDIR 它提供的是目录服务(Active Directory)。 证书相关命令 Windows C:\Program Files\VMware\vCenter Server\vmafdd\vecs-cli.exe C:\Program Files\VMware\vCenter Server\vmafdd\dir-cli.exe C:\Program Files\VMware\vCenter Server\vmcad\certool.exe C:\Program Files\VMware\VCenter server\VMware Identity Services\sso-config VCENTER_INSTALL_PATH\bin\service-control Linux /usr/lib/vmware-vmafd/bin/vecs-cli # /usr/lib/vmware-vmafd/bin/vecs-cli store list 得到如下结果: MACHINE_SSL_CERT TRUSTED_ROOTS TRUSTED_ROOT_CRLS machine vsphere-webclient vpxd vpxd-extension APPLMGMT_PASSWORD data-encipherment SMS # /usr/lib/vmware-vmafd/bin/vecs-cli entry list --store vpxd /usr/lib/vmware-vmafd/bin/dir-cli /usr/lib/vmware-vmca/bin/certool /opt/vmware/bin 参考资料: https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.psc.doc/GUID-16947630-6378-4021-A5D3-B9F16187EF80.html https://blogs.vmware.com/vsphere/2015/03/vmware-certificate-authority-overview-using-vmca-root-certificates-browser.html https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.psc.doc/GUID-3D0DE463-D0EC-442E-B524-64759D063E25.html https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.psc.doc/GUID-DB55A84F-8405-49AB-89B5-04FE3A5CD03C.html#GUID-DB55A84F-8405-49AB-89B5-04FE3A5CD03C https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.psc.doc/GUID-779A011D-B2DD-49BE-B0B9-6D73ECF99864.html#GUID-779A011D-B2DD-49BE-B0B9-6D73ECF99864 https://docs.vmware.com/en/VMware-Identity-Manager/19.03/idm-administrator/GUID-592CC646-894F-403D-8A96-1851D7DBE598.html
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 肖长军(穹谷)阿里云智能事业群技术专家 导读 :随着云原生系统的演进,如何保障系统的稳定性受到很大的挑战,混沌工程通过反脆弱思想,对系统注入故障,提前发现系统问题,提升系统的容错能力。ChaosBlade 工具可以通过声明式配置执行混沌实验,简单高效。本文将会重点介绍 ChaosBlade 以及云原生相关的实验场景实践。 ChaosBlade 介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌实验模型的混沌实验执行工具,具有场景丰富度高、简单易用等特点,而且可以很方便的扩展实验场景,开源后不久就被加入到 CNCF Landspace 中,成为主流的一款混沌工具。 实验场景 目前支持的实验场景如下: 基础资源场景:CPU 负载、内存占用、磁盘 IO 负载、磁盘占用、网络延迟、网络丢包、网络屏蔽、域名不可访问、shell 脚本篡改、杀进程、进程 Hang、机器重启等; 应用服务场景:支持 Java 应用和 C++ 应用内的实验场景。Java 的场景组件丰富,例如支持 Dubbo、RocketMQ、HttpClient、Servlet、Druid等,而且支持编写 Java 或 Groovy 脚本实现复杂的实验场景; 容器服务场景:支持 Kubernetes 和 Docker 服务,包含 node、pod 和 container 三种资源的实验场景,例如 Pod 网络延迟、丢包等。 混沌实验模型 以上所有的实验场景都遵循混沌实验模型,此模型共分为四层,包含: Target:实验靶点。指实验发生的组件,如容器、应用框架(Dubbo、Redis)等; Scope:实验实施的范围。指具体触发实验的机器或者集群等; Matcher:实验规则匹配器。根据所配置的 Target,定义相关的实验匹配规则,可以配置多个。由于每个 Target 可能有各自特殊的匹配条件,比如 RPC 领域的 Dubbo,可以根据服务提供者提供的服务和服务消费者调用的服务进行匹配,缓存领域的 Redis,可以根据 set、get 操作进行匹配; Action:指实验模拟的具体场景,Target 不同,实施的场景也不一样,比如磁盘,可以演练磁盘满,磁盘 IO 读写高等。如果是应用,可以抽象出延迟、异常、返回指定值(错误码、大对象等)、参数篡改、重复调用等实验场景。 比如一台 IP 是 10.0.0.1 机器上的应用,调用 com.example.HelloService @1.0.0 Dubbo 服务延迟 3s,基于此模型可以描述为对 Dubbo 组件(Target)进行实验,实验实施的范围是 10.0.0.1 主机(Scope),调用 com.example.HelloService @1.0.0 (Matcher)服务延迟 3s(Action),对应的 chaosblade 命令为: blade create dubbo delay --time 3000 --service com.example.HelloService --version 1.0.0 所以此模型很简单清晰的表达出实验场景,易于理解。下文中的云原生实验场景也基于此模型定义。 面向云原生的实验场景 实现方案 将混沌实验场景按照上述的实验模型,定义为 Kubernetes 中的资源,并通过自定义控制器来管理,可以通过 Yaml 配置或者直接执行 blade 命令执行。 ChaosBlade Operator 定义了资源控制器,并且会以 daemonset 的方式,在每个节点上部署一个 chaosblade-tool pod 来执行混沌实验。不同的实验场景内部实现方式不同,比如 Node 实验场景,其上面部署的 chaosblade-tool 内部执行即可,而 Container 内的实验场景,控制器会将 chaosblade 包拷贝到目标 Container 中执行。 使用方式 安装必要组件 安装 ChaosBlade Operator,可通过 地址 下载 chaosblade-operator-0.0.1.tgz,使用以下命令安装: helm install --namespace kube-system --name chaosblade-operator chaosblade-operator-0.0.1.tgz 安装在 kube-system 命令空间下。ChaosBlade Operator 启动后会在每个节点部署 chaosblade-tool Pod 和一个 chaosblade-operator Pod。可通过以下命令查看安装结果: kubectl get pod -n kube-system -o wide | grep chaosblade 执行实验 执行方式有两种: 一种是通过配置 yaml 方式,使用 kubectl 执行; 另一种是直接使用 chaosblade 包中的 blade 命令执行。 下面以指定一台节点,做 CPU 负载 80% 实验举例。 yaml 配置方式 apiVersion: chaosblade.io/v1alpha1 kind: ChaosBlade metadata: name: cpu-load spec: experiments: - scope: node target: cpu action: fullload desc: "increase node cpu load by names" matchers: - name: names value: - "cn-hangzhou.192.168.0.205" - name: cpu-percent value: - "80" 如上所示,配置好文件后,保存为 chaosblade_cpu_load.yaml,使用以下命令执行实验场景: kubectl apply -f chaosblade_cpu_load.yaml 可通过以下命令查看每个实验的执行状态: kubectl get blade cpu-load -o json 查看 更多实验场景配置事例 。 blade 命令执行方式 下载 chaosblade 工具包 ,解压即可使用。还是上述例子,使用 blade 命令执行如下: blade create k8s node-cpu fullload --names cn-hangzhou.192.168.0.205 --cpu-percent 80 --kubeconfig ~/.kube/config 使用 blade 命令执行,会返回实验的执行结果。 修改实验 yaml 配置文件的方式支持场景动态修改,比如将上述的 cpu 负载调整为 60%,则只需将上述 value 的值从 80 改为 60 即可,例如: apiVersion: chaosblade.io/v1alpha1 kind: ChaosBlade metadata: name: cpu-load spec: experiments: - scope: node target: cpu action: load desc: "cpu load" flags: - name: cpu-percent value: "60" - name: ip value: 192.168.0.34 然后使用 kubeclt apply -f chaosblade_cpu_load.yaml 命令执行更新即可。 停止实验 可以通过以下三种方式停止实验: 根据实验资源名停止 比如上述 cpu-load 场景,可以执行以下命令停止实验: kubectl delete chaosblade cpu-load 通过 yaml 配置文件停止 指定上述创建好的 yaml 文件进行删除,命令如下: kubectl delete -f chaosblade_cpu_load.yaml 通过 blade 命令停止 此方式仅限使用 blade 创建的实验,使用以下命令停止: blade destroy 是执行 blade create 命令返回的结果,如果忘记,可使用 blade status --type create 命令查询。 卸载 chaosblade operator 执行 helm del --purge chaosblade-operator 卸载即可,将会停止全部实验,删除所有创建的资源。 总结 ChaosBlade 基于混沌实验模型,友好地将 Kubernetes 资源控制结合,部署简单而且使用简洁,实验可控。除此之外 ChaosBlade 基于实验模型实现了很多领域场景执行器,可以很方便的扩展实验场景,可详见附录中的项目列表。 社区共建 ChaosBlade 自开源以来,共有近 30 多位贡献者加入和很多企业的关注及使用,非常感谢各位。同时非常欢迎更多的人参与进来,使 ChaosBlade 变的更加强大,覆盖更多的场景,成为各个企业稳定的、通用的混沌工程工具。 贡献的形式可以是提 bug、提交代码、编写文档、补充单元测试、参与问题讨论等等。ChaosBlade 相信:开源世界中,任何帮助都是贡献。 附录 项目列表如下: ChaosBlade CLI(调用入口) ChaosBlade 实验模型定义 基础资源场景执行器 Docker 场景执行器 Kubernetes 场景执行器 Java 应用场景执行器 C++ 应用场景执行器 “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 该系列文章总共分为三篇: Linux Capabilities 入门教程:概念篇 Linux Capabilities 入门教程:基础实战篇 待续... 上篇文章 介绍了 Linux capabilities 的诞生背景和基本原理,本文将会通过具体的示例来展示如何查看和设置文件的 capabilities。 Linux 系统中主要提供了两种工具来管理 capabilities: libcap 和 libcap-ng 。 libcap 提供了 getcap 和 setcap 两个命令来分别查看和设置文件的 capabilities,同时还提供了 capsh 来查看当前 shell 进程的 capabilities。 libcap-ng 更易于使用,使用同一个命令 filecap 来查看和设置 capabilities。 1 libcap 安装很简单,以 CentOS 为例,可以通过以下命令安装: $ yum install -y libcap 如果想查看当前 shell 进程的 capabilities,可以用 capsh 命令。下面是 CentOS 系统中的 root 用户执行 capsh 的输出: $ capsh --print Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read Securebits: 00/0x0/1'b0 secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root) 解释一下: Current : 表示当前 shell 进程的 Effective capabilities 和 Permitted capabilities。可以包含多个分组,每一个分组的表示形式为 capability[,capability…]+(e|i|p) ,其中 e 表示 effective, i 表示 inheritable, p 表示 permitted。不同的分组之间通过空格隔开,例如: Current: = cap_sys_chroot+ep cap_net_bind_service+eip 。再举一个例子, cap_net_bind_service+e cap_net_bind_service+ip 和 cap_net_bind_service+eip 等价。 Bounding set : 这里仅仅表示 Bounding 集合中的 capabilities,不包括其他集合,所以分组的末尾不用加上 +... 。 Securebits : 我也没搞清楚这是个什么鬼。 这个命令输出的信息比较有限,完整的信息可以查看 /proc 文件系统,比如当前 shell 进程就可以查看 /proc/$$/status 。其中一个重要的状态就是 NoNewPrivs ,可以通过以下命令查看: grep NoNewPrivs /proc/$$/status NoNewPrivs: 0 根据 prctl(2) 中的描述,自从 Linux 4.10 开始, /proc/[pid]/status 中的 NoNewPrivs 值表示了线程的 no_new_privs 属性。至于 no_new_privs 究竟是干嘛的,下面我单独解释一下。 no_new_privs 一般情况下, execve() 系统调用能够赋予新启动的进程其父进程没有的权限,最常见的例子就是通过 setuid 和 setgid 来设置程序进程的 uid 和 gid 以及文件的访问权限。这就给不怀好意者钻了不少空子,可以直接通过 fork 来提升进程的权限,从而达到不可告人的目的。 为了解决这个问题,Linux 内核从 3.5 版本开始,引入了 no_new_privs 属性(实际上就是一个 bit,可以开启和关闭),提供给进程一种能够在 execve() 调用整个阶段都能持续有效且安全的方法。 开启了 no_new_privs 之后,execve 函数可以确保所有操作都必须调用 execve() 判断并赋予权限后才能被执行。这就确保了线程及子线程都无法获得额外的权限,因为无法执行 setuid 和 setgid,也不能设置文件的权限。 一旦当前线程的 no_new_privs 被置位后,不论通过 fork,clone 或 execve 生成的子线程都无法将该位清零。 Docker 中可以通过参数 --security-opt 来开启 no_new_privs 属性,例如: docker run --security-opt=no_new_privs busybox 。下面通过一个例子来体会一下 no_new_privs 属性的作用。 首先撸一段 C 代码,显示当前进程的有效用户 id: $ cat testnnp.c #include #include #include int main(int argc, char *argv[]) { printf("Effective uid: %d\n", geteuid()); return 0; } $ make testnnp cc testnnp.c -o testnnp 将可执行文件打入 docker 镜像中: FROM fedora:latest ADD testnnp /root/testnnp RUN chmod +s /root/testnnp ENTRYPOINT /root/testnnp 构建镜像: $ docker build -t testnnp . Step 1 : FROM fedora:latest ---> 760a896a323f Step 2 : ADD testnnp /root/testnnp ---> 6c700f277948 Removing intermediate container 0981144fe404 Step 3 : RUN chmod +s /root/testnnp ---> Running in c1215bfbe825 ---> f1f07d05a691 Removing intermediate container c1215bfbe825 Step 4 : ENTRYPOINT /root/testnnp ---> Running in 5a4d324d54fa ---> 44f767c67e30 Removing intermediate container 5a4d324d54fa Successfully built 44f767c67e30 下面来做两个实验,先在没有开启 no-new-privileges 的情况下启动容器: $ docker run -it --rm --user=1000 testnnp Effective uid: 0 从输出结果来看,只要给可执行文件设置了 SUID 标识,即使我们使用普通用户(UID=1000)来运行容器,进程的有效用户也会变成 root。 接着在开启 no-new-privileges 的前提下启动容器,以防止执行设置了 SUID 标识的可执行文件进行 UID 转换: $ docker run -it --rm --user=1000 --security-opt=no-new-privileges testnnp Effective uid: 1000 可以看到,开启了 no_new_privs 属性之后,即使可执行文件设置了 SUID 标识,线程的有效用户 ID 也不会变成 root。这样即使镜像中的代码有安全风险,仍然可以通过防止其提升权限来避免受到攻击。 Kubernetes 也可以开启 no_new_privs ,不过逻辑稍微复杂一点。当 Pod 的 SecurityContext 定义下的 allowPrivilegeEscalation 字段值为 false 时(默认就是 false),如果不满足以下任何一个条件,就会开启 no_new_privs 属性: 设置了 privileged=true 增加了 CAP_SYS_ADMIN capabilities,即 capAdd=CAP_SYS_ADMIN 以 root 用户运行,即 UID=0 例如,当设置了 privileged=true 和 allowPrivilegeEscalation=false 时,就不会开启 no_new_privs 属性。同理,设置了 capAdd=CAP_SYS_ADMIN 和 allowPrivilegeEscalation=false 也不会开启 no_new_privs 属性。 管理 capabilities 可以通过 getcap 来查看文件的 capabilities,例如: $ getcap /bin/ping /usr/sbin/arping /bin/ping = cap_net_admin,cap_net_raw+p /usr/sbin/arping = cap_net_raw+p 也可以使用 -r 参数来递归查询: $ getcap -r /usr 2>/dev/null /usr/bin/ping = cap_net_admin,cap_net_raw+p /usr/bin/newgidmap = cap_setgid+ep /usr/bin/newuidmap = cap_setuid+ep /usr/sbin/arping = cap_net_raw+p /usr/sbin/clockdiff = cap_net_raw+p 如果想查看某个进程的 capabilities,可以直接使用 getpcaps ,后面跟上进程的 PID: $ getpcaps 1234 如果想查看一组相互关联的线程的 capabilities(比如 nginx),可以这么来看: $ getpcaps $(pgrep nginx) 这里你会看到只有主线程才有 capabilities,子线程和其他 workers 都没有 capabilities,这是因为只有 master 才需要特殊权限,例如监听网络端口,其他线程只需要响应请求就好了。 设置文件的 capabilities 可以使用 setcap ,语法如下: $ setcap CAP+set filename 例如,将 CAP_CHOWN 和 CAP_DAC_OVERRIDE capabilities 添加到 permitted 和 effective 集合: $ setcap CAP_CHOWN,CAP_DAC_OVERRIDE+ep file1 如果想移除某个文件的 capabilities,可以使用 -r 参数: $ setcap -r filename 2 libcap-ng 安装也很简单,以 CentOS 为例: $ yum install libcap-ng-utils 用法 libcap-ng 使用 filecap 命令来管理文件的 capabilities。有几个需要注意的地方: filecap 添加删除或查看 capabilities 时,capabilities 的名字不需要带 CAP_ 前缀(例如,使用 NET_ADMIN 代替 CAP_NET_ADMIN ); filecap 不支持相对路径,只支持绝对路径; filecap 不允许指定 capabilities 作用的集合,capabilities 只会被添加到 permitted 和 effective 集合。 查看文件的 capabilities: $ filecap /full/path/to/file 递归查看某个目录下所有文件的 capabilities: $ filecap /full/path/to/dir 例如: $ filecap /usr/bin file capabilities /usr/bin/newgidmap setgid /usr/bin/newuidmap setuid > 注意: filecap 只会显示“capabilities 被添加到 permitted 和 effective 集合中”的文件。所以这里没有显示 ping 和 arping。 递归查看整个系统所有文件的 capabilities: $ filecap / # or $ filecap -a 设置文件的 capabilities 语法如下: $ filecap /full/path/to/file cap_name 例如: $ filecap /usr/bin/tac dac_override 移除某个文件的 capabilities: $ filecap /full/path/to/file none 3 总结 本文通过两种工具演示了如何对可执行文件的 capabilities 进行管理,并以 docker 为例,展现了 no_new_privs 的强大之处。如果条件允许,推荐大家以后尽量用 capabilities 来替代完整的 root 权限或者设置 SUID 标识。 4 参考资料 Added no-new-privileges Security Flag to Docker 关于 no new privs 翻译稿 微信公众号 扫一扫下面的二维码关注微信公众号,在公众号中回复◉加群◉即可加入我们的云原生交流群,和孙宏亮、张馆长、阳明等大佬一起探讨云原生技术
「深度学习福利」大神带你进阶工程师,立即查看>>> 货比三家这是大多数人购买产品时的一种心理,而我们公司在使用 云桌面 时也是这么做的,一开始在网上了解了很多关于云桌面的一些信息和资料,同时也对比了很多的云桌面厂家,既了解像华为、联想这样知名厂家的产品和方案,同时也了解一些专业的小厂家的产品和方案的,而经过多家对比后,我们最终选择了禹龙云这么一个厂家来部署的,而主要原因有这么几点的。 首先专业性强,我们之所以选择禹龙云并不是说它比我们所对比哪些厂家价格都要便宜和功能都要强大的,而是他们的专业性比较强,比如部署云桌面需要用到的服务器、云终端和云桌面虚拟化软件这三大部件都是同一个品牌的,而且针对不同的办公部门都有相应的解决方案,而不像有些厂家提供的服务器、云终端和云桌面软件都是多个厂家组合而成的。 其次性价比高,而在功能应用都可以满足的情况下我们是从性价比考虑的,华为他们的品牌知名度是会大很多,但是同时在功能应用都差不多的情况下,他们的价格还是会比其他厂家的相对高一些的。而禹龙云我们了解到他们做云桌面的时间并不会说比其他厂家晚。而由于云桌面的主要三大组成都是同一个厂家,所以在价格上他们还是比较适中的。不会像有些厂家一样价格高的离谱。 第三维护方便,而在选择云桌面的时候除了考虑它的专业性和价格之外,维护也是我们非常关心的问题,而禹龙云的维护相对来说还是比较方便,所有的维护都只需在服务器上就可完成,终端基本上是不用维护的,即使是不懂IT技术的人员,在厂家工程师的远程协助下也能轻松的进行维护。 最后简单易用,因为考虑到把传统PC更换成云桌面会造成大家使用不习惯的问题,因此我们在选择时还有一个考虑到的是要简单易用,禹龙云虽然说功能在这么多的厂家中不是最多也不是最强的,但是他们有一个好处就是简单易用,不管是操作还是管理维护只需稍微简单的培训下就能轻松上手的。不用担心说因更换IT架构导致很多人使用不习惯这些问题的。 说了这么多并不是说我们选择的云桌面厂家有多好的,要说的是云桌面厂家这么多,我们在选择的适合不一定要选择品牌最大功能最多的,也不一定说要选择价格最便宜的,而是要选择最适合自己的。 来源禹龙云
「深度学习福利」大神带你进阶工程师,立即查看>>> 上周,微软和阿里巴巴共同推出了开放应用模型(OAM),用于定义部署在任何地方的应用模型的一种规范。Rudr是Microsoft基于Kubernetes环境的OAM标准实现。 我用了一个周末来了解OAM试图解决的问题,为此我还以Rudr为基础重构了一些我喜欢的基础微服务的应用程序。本文和以下教程将帮助普通的Kubernetes用户了解OAM背后的动机。 众所周知,Kubernetes是一个复杂的平台,包含许多活动组件。在编排和部署简单的两层Web应用程序时,需要涉及到创建Storage Classes,PVC,PV,Secret,ConfigMap,Service,Deployment和 Ingress。在实际生产部署中还需要健全的日志收集,监控告警,安全性,高可用性和可扩容性,我们将用到StatefulSet(有状态应用),网络策略,RBAC,准入控制,Pod横向自动伸缩等知识。 对于从传统IT环境过渡的开发工程师和运维工程师,Kubernetes强劲的发展势头让人感到害怕。甚至一些熟悉容器化的DevOps专业人员都发现想要完全理解Kubernetes也是个很棘手的事情。 当转换为可部署的文件时,一个简单的两层Web应用程序可能具有十几个YAML文件,里面包含了这个应用程序针对于每个对象的定义描述。 Kubernetes的核心设计原则之一是对象的可解耦性。例如一个服务可以独立于Pod而存在,创建一个PV无需任何使用者,还可以配置一个无需任何后端来处理请求的Ingress。基于一组标签,注释和选择器,这些特点在运行时可以拼凑在一起共同使用。一个服务会将请求转发到符合条件的一个或多个Pod上。Ingress将流量路由到某个服务也是相同的用法。 Kubernetes中的每个对象都是自我治理并且完全独立的。尽管这种设计使Kubernetes具有极高的可扩展性,但其缺点是缺乏应用程序上下文关系。Kubernetes中的一个应用程序是一系列协同工作的自治对象的集合。当转换为可部署的文件时,一个简单的两层Web应用程序可能具有十几个YAML文件,里面包含了这个应用程序针对于每个对象的定义描述。在单一环境下管理和维护这些编排文件是与Kubernetes接触时面临的最大挑战。 Helm工具想要通过图表的概念来解决这个问题。但是即使这样,你往往还是在部署后丢失上下文关系。毕竟Helm只是应用程序运行所需的多个Kubernetes对象定义的集合编排文件生成工具。 Kubernetes的其他挑战之一是开发人员和运维人员之间有个很模糊的界限。为了有效利用平台,开发人员需要对运行时环境有一定的了解。他们需要了解ConfigMap如何对Pod中包装的容器可见。他们需要知道初始化代码的哪一部分应打包为Init容器。运维人员负责确保正确的命名规则来保证服务发现的正常工作。他们需要知道需要传递给Pod的所有环境变量。运维人员应根据应用程序的特性来决定将容器部署为ReplicationController,DaemonSet还是StatefulSet。他们需要在生产环境部署的时候,选择使用ClusterIP还是NodePort。 如上所述,开发人员期望熟悉运行时程序需要哪些必要的决策,并且运维人员应了解软件设计方面的知识。OAM想要通过以下方法解决这些存在的问题: 将应用程序上下文带入微服务部署 在开发人员和运维人员之间明确关注点 与运行时无关的应用程序模型 从更高的层次上来说,OAM是用于定义微服务或一组属于应用程序的微服务组件的规范。每个组件都有一个或多个工作节点,它们可以作为一个服务,或者是个消费者,或者是个需要完成的任务。每个工作节点之间可能具有关联的配置和特征。这些配置转换为传递给工作节点的参数,这些特性会影响组件的运行环境,同一类组件的集合属于一个应用程序。 OAM的核心前提是,开发人员的工作以从源代码在构建容器镜像的时候结束,而运维人员负责的工作正好从此处开始。Ops团队将负责为单个应用程序的一组容器镜像进行配置和部署。 OAM中的组件意在使开发人员能够以与基础结构无关的格式声明,来区分执行单元的操作特性。组件定义了在基础系统结构中的CPU,GPU,内存和磁盘需求。 组件中的每个工作节点类型如下: 配置通常在处理后以参数的形式传递给工作节点。例如在配置中定义了发送到应用程序服务工作节点的连接数据库的字符串。 这些特性定义了工作节点的运行时行为,从而定义了一个应用程序。Rudr就是OAM的参考实现的,并有以下特征: 如果我们仔细观察Workload和Trait的概念描述,它们可以轻松将这些概念对应到到Kubernetes。服务本质上是Deployment,而Singleton服务是具有一个replica的Deployment。它们都要使用ClusterIP或NodePort。Worker和单独的Worker是没有关联服务的Pods。任务是一个可并行化的Kubernetes Job,而单个任务是个单次运行的Job。 同样这些特性也能对应到到Kubernetes的自动扩容,Ingress,Deployment和PVC等概念。 因此使用OAM和Rudr,开发人员可以提交代码并构建可转换为工作节点的容器镜像。运维人通过这些组件的特性进行配置定义,将其组成工作节点。 从技术上讲,OAM这一规范可以适用于虚拟机基础设施平台(IaaS),PaaS和容器管理平台(CaaS)。OAM的每个构建模块都可以映射到相应的环境。就是说OAM定义的YAML文件可以在没有任何修改的情况下部署在任何环境中。 在本系列的下一篇文章中,我将带你逐步了解Rudr的端到端教程,其中展示了以Node.js Web应用程序部署组件,配置其特性所涉及的工作流程。敬请关注~ 作者|Janakiram MSV 翻译|Big dimple 原文链接 https://thenewstack.io/what-does-the-open-application-model-oam-and-rudr-mean-for-kubernetes-developers/ 已获原作者授权翻译转载 “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 孙健波(阿里巴巴技术专家)、赵钰莹 导读 :云原生时代,Kubernetes 的重要性日益凸显。然而,大多数互联网公司在 Kubernetes 上的探索并非想象中顺利,Kubernetes 自带的复杂性足以让一批开发者望而却步。本文中,阿里巴巴技术专家孙健波在接受采访时基于阿里巴巴 Kubernetes 应用管理实践过程提供了一些经验与建议,以期对开发者有所帮助。 在互联网时代,开发者更多是通过顶层架构设计,比如多集群部署和分布式架构的方式来实现出现资源相关问题时的快速切换,做了很多事情来让弹性变得更加简单,并通过混部计算任务来提高资源利用率,云计算的出现则解决了从 CAPEX 到 OPEX 的转变问题。 云计算时代让开发可以聚焦在应用价值本身,相较于以前开发者除了业务模块还要投入大量精力在存储、网络等基础设施,如今这些基础设施都已经像水电煤一样便捷易用。云计算的基础设施具有稳定、高可用、弹性伸缩等一系列能力,除此之外还配套解决了一系列应用开发“最佳实践”的问题,比如监控、审计、日志分析、灰度发布等。原来,一个工程师需要非常全面才能做好一个高可靠的应用,现在只要了解足够多的基础设施产品,这些最佳实践就可以信手拈来了。但是,在面对天然复杂的 Kubernetes 时,很多开发者都无能为力。 作为 Jira 和代码库 Bitbucket 背后的公司,Atlassian 的 Kubernetes 团队首席工程师 Nick Young 在采访中表示: 虽然当初选择 Kubernetes 的战略是正确的(至少到现在也没有发现其他可能的选择),解决了现阶段遇到的许多问题,但部署过程异常艰辛。 那么,有好的解决办法吗? 太过复杂的 Kubernetes “如果让我说 Kubernetes 存在的问题,当然是‘太复杂了’”,孙健波在采访中说道,“不过,这其实是由于 Kubernetes 本身的定位导致的。” 孙健波补充道,Kubernetes 的定位是“platform for platform”。它的直接用户,既不是应用开发者,也不是应用运维,而是“platform builder”,也就是基础设施或者平台级工程师。但是,长期以来,我们对 Kubernetes 项目很多时候都在错位使用,大量的应用运维人员、甚至应用研发都在直接围绕 Kubernetes 很底层的 API 进行协作,这是导致很多人抱怨 “Kubernetes 实在是太复杂了”的根本原因之一。 这就好比一名 Java Web 工程师必须直接使用 Linux Kernel 系统调用来部署和管理业务代码,自然会觉得 Linux “太反人类了”。所以,目前 Kubernetes 项目实际上欠缺一层更高层次的封装,来使得这个项目能够对上层的软件研发和运维人员更加友好。 如果可以理解上述的定位,那么 Kubernetes 将 API 对象设计成 all-in-one 是合理的,这就好比 Linux Kernel 的 API,也不需要区分使用者是谁。但是,当开发者真正要基于 K8s 管理应用、并对接研发、运维工程师时,就必然要考虑这个问题,也必然要考虑如何做到像另一层 Linux Kernel API 那样以标准、统一的方式解决这个问题,这也是 阿里云和微软联合开放云原生应用模型 Open Application Model (OAM) 的原因。 有状态应用支持 除了天然的复杂性问题,Kubernetes 对于有状态应用的支持也一直是众多开发者花费大量时间研究和解决的问题,并不是不可以支持,只是没有相对较优的解决方案。目前,业内主流的针对有状态应用的解法是 Operator,但是编写 Operator 其实是很困难的。 在采访中,孙健波表示,这是因为 Operator 本质上是一个“高级版”的 K8s 客户端,但是 K8s API Server 的设计,是“重客户端”的模型,这当然是为了简化 API Server 本身的复杂度,但也导致了无论是 K8s client 库,还是以此为基础的 Operator,都变的异常复杂和难以理解:它们都夹杂了大量 K8s 本身的实现细节,比如 reflector、cache store、informer 等。这些,并不应该是 Operator 编写者需要关心的,Operator 编写者应该是有状态应用本身的领域专家(比如 TiDB 的工程师),而不应该是 K8s 专家。这是现在 K8s 有状态应用管理最大的痛点,而这可能需要一个新的 Operator 框架来解决这个问题。 另一方面,复杂应用的支持不止编写 Operator 这么简单,这里还需要有状态应用交付的技术支撑,这是目前社区上各种持续交付项目都有意或者无意间忽略掉的事情。事实上,持续交付一个基于 Operator 的有状态应用,跟交付一个无状态的 K8s Deployment 的技术挑战完全不是一个量级的。这也是孙健波所在团队在 CNCF 应用交付领域小组(CNCF SIG App Deliver)倡导“应用交付分层模型”的重要原因:如下图所示,四层模型分别为“应用定义”、“应用交付”、“应用运维与自动化”、“平台层”,只有通过这四个层不同能力的合力协作,才能真正做到高质量和高效率的交付有状态应用。 举个例子,Kubernetes API 对象的设计是“all-in-one”的, 即:应用管理过程中的所有参与者,都必须在同一个 API 对象上进行协作。这就导致开发者会看到,像 K8s Deployment 这样的 API 对象描述里, 既有应用开发关注的字段,也可以看到运维关注的字段,还有一些字段可能还是被多方关注的。 实际上,无论是应用开发、应用运维,还是 HPA 这样的 K8s 自动化能力,它们都有可能需要控制一个 API 对象里的同一个字段。最典型的情况就是副本数(replica)这种参数。但是,到底谁 own 这个字段,是一个非常棘手的问题。 综上,既然 K8s 的定位是云时代的 Linux Kernel,那么 Kubernetes 就必须在 Operator 支持、API 层以及各类接口定义的完善上不断进行突破,使得更多生态参与者可以更好的基于 K8s 构建自己的能力和价值。 阿里巴巴大规模 Kubernetes 实践 如今,Kubernetes 在阿里经济体的应用场景涵盖了阿里方方面面的业务,包括电商、物流、离在线计算等,这也是目前支撑阿里 618、双 11 等互联网级大促的主力军之一。阿里集团和蚂蚁金服内部运行了数十个超大规模的 K8s 集群,其中最大的集群约 1 万个机器节点,而且这其实还不是能力上限。每个集群都会服务上万个应用。在阿里云 Kubernetes 服务(ACK)上,我们还维护了上万个用户的 K8s 集群,这个规模和其中的技术挑战在全世界也是首屈一指的。 孙健波透露,阿里内部早在 2011 年便开始了应用容器化,当时最开始是基于 LXC 技术构建容器,随后开始用自研的容器技术和编排调度系统。整套系统本身没有什么问题,但是作为基础设施技术团队,目标一定是希望阿里的基础技术栈能够支撑更广泛的上层生态,能够不断演进和升级,因此,整个团队又花了一年多时间逐渐补齐了 K8s 的规模和性能短板。总体来看,升级为 K8s 是一个非常自然的过程,整个实践过程其实也很简单: 第一:解决应用容器化的问题,这里需要合理利用 K8s 的容器设计模式; 第二:解决应用定义与描述的问题,这里需要合理的利用 OAM,Helm 等应用定义工具和模型来实现,并且要能够对接现有的应用管理能力; 第三:构建完整的应用交付链,这里可以考虑使用和集成各种持续交付能力。 如上的三步完成,就具备了对接研发、运维、上层 PaaS 的能力,能够讲清楚自己的平台价值。接下来就可以试点开始,在不影响现有应用管理体系的前提下,一步步换掉下面的基础设施。 Kubernetes 本身并不提供完整的应用管理体系,这个体系是整个云原生的生态基于 K8s 构建出来的,可以用下图表示: Helm 就是其中最成功的一个例子,它位于整个应用管理体系的最上面,也就是第 1 层,还有 Kustomize 等各种 YAML 管理工具,CNAB 等打包工具,它们都对应在第 1.5 层。然后有 Tekton、Flagger 、Kepton 等应用交付项目,对应在第 2 层。Operator ,以及 K8s 的各种工作负载组件,比如 Deployment、StatefulSet,对应在第 3 层。最后才是 K8s 的核心功能,负责对工作负载的容器进行管理,封装基础设施能力,对各种不同的工作负载对接底层基础设施提供 API 等。 初期,整个团队最大的挑战来自于规模和性能瓶颈,但这个解法也是最直接的。孙健波表示,随着规模逐渐增大,我们看到规模化铺开 K8s 最大的挑战实际上是如何基于 K8s 进行应用管理和对接上层生态。比如,我们需要统一的管控来自数十个团队、数百个不同目的的 Controller;我们需要以每天近万次的频率交付来自不同团队的生产级应用,这些应用的发布、扩容策略可能完全不同;我们还需要对接数十个更加复杂的上层平台,混合调度和部署不同形态的作业以追求最高的资源利用率,这些诉求才是阿里巴巴 Kubernetes 实践要解决的问题,规模和性能只是其中一个组成部分。 除了 Kubernetes 的原生功能外,在阿里巴巴内部会开发大量的基础设施以 K8s 插件的形式对接到这些功能上,随着规模的扩大,用统一的方式发现和管理这些能力成为了一个关键问题。 此外,阿里巴巴内部也有众多存量 PaaS,这些是为了满足用户不同业务场景上云所构建的,比如有的用户希望上传一个 Java 的 War 包就可以运行,有的用户希望上传一个镜像就可以运行。在这些需求背后,阿里各团队帮用户做了许多应用管理的工作,这也是存量 PaaS 出现的原因,而这些存量 PaaS 与 Kubernetes 对接过程可能会产生各种问题。目前,阿里正在通过 OAM 这个统一标准的应用管理模型,帮助这些 PaaS 向 K8s 底盘进行对接和靠拢,实现标准化和云原生化。 解耦运维和研发 通过解耦,Kubernetes 项目以及对应的云服务商就可以为不同的角色暴露不同维度、更符合对应用户诉求的声明式 API。比如,应用开发者只需要在 YAML 文件中声明”应用 A 要使用 5G 可读写空间“,应用运维人员则只需要在对应的 YAML 文件里声明”Pod A 要挂载 5G 的可读写数据卷“。这种”让用户只关心自己所关心的事情“所带来的专注力,是降低 Kubernetes 使用者学习门槛和上手难度的关键所在。 孙健波表示,现在大多数的解法实际上是“悲观处理”。比如,阿里内部的 PaaS 平台,为了减轻研发使用的负担,长期以来只开放给研发设置 5 个 Deployment 的字段。这当然是因为 K8s YAML "all-in-one"的设计,使得完整的 YAML 对研发来说太复杂,但这也导致 K8s 本身的能力,绝大多数情况下对研发来说是完全没有体感的。而对 PaaS 平台运维来说,他反而觉得 K8s YAML 太简单,不够描述平台的运维能力,所以要给 YAML 文件添加大量 annotation。 此外,这里的核心问题在于,对运维人员而言,这种“悲观处理”的结果就是他自己太“独裁”,包揽了大量细节工作,还费力不讨好。比如扩容策略,目前就是完全由运维一方说了算。可是,研发作为编写代码的实际人员,才是对应用怎么扩容最有发言权的,而且研发人员也非常希望把自己的意见告诉运维,好让 K8s 更加 灵活,真正满足扩容需求。但这个诉求在目前的系统里是无法实现的。 所以,“研发和运维解耦”并不是要把两者割裂,而是要给研发提供一个标准、高效的,同运维进行沟通的方式,这也是 OAM 应用管理模型要解决的问题。孙健波表示,OAM 的主要作用之一就是提供一套研发从自己的角度表达诉求的标准和规范,然后这套标准“你知,我知,系统知”,那么上面这些问题也就迎刃而解了。 具体来说,OAM 是一个专注于描述应用的标准规范。有了这个规范,应用描述就可以彻底与基础设施部署和管理应用的细节分开。这种关注点分离(Seperation of Conerns)的设计好处是非常明显的。举个例子,在实际生产环境中,无论是 Ingress、CNI 还是 Service Mesh,这些表面看起来一致的运维概念,在不同的 Kubernetes 集群中可谓千差万别。通过将应用定义与集群的运维能力分离,我们就可以让应用开发者更专注应用本身的价值点,而不是”应用部署在哪“这样的运维细节。 此外,关注点分离让平台架构师可以轻松地把平台运维能力封装成可被复用的组件,从而让应用开发者专注于将这些运维组件与代码进行集成,从而快速、轻松地构建可信赖的应用。OAM 的目标是让简单的应用管理变得更加轻松,让复杂的应用交付变得更加可控。孙健波表示,未来,团队将专注于将这套体系逐步向云端 ISV 和软件分发商侧推进,让基于 K8s 的应用管理体系真正成为云时代的主流。 嘉宾介绍 :孙健波,阿里巴巴技术专家。Kubernetes 项目社区成员。目前在阿里巴巴参与大规模云原生应用交付与管理相关工作,2015 年参与编写《Docker 容器与容器云》技术书籍。曾任职七牛,参与过时序数据库、流式计算、日志平台等项目相关应用上云过程。 今年 12 月 6-7 日北京 ArchSummit 全球架构师峰会上,孙健波老师会继续分享《阿里巴巴 Kubernetes 应用管理实践中的经验与教训》,会介绍阿里对解耦研发和运维过程中的现有实践,以及实践本身存在的问题;以及实施的标准化、统一化解决的思路,以及对社区的进一步思考。 “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。” 更多详细信息可关注 “阿里巴巴云原生” 。
「深度学习福利」大神带你进阶工程师,立即查看>>> 随着技术的不断发展和完善, 云终端 被大家所接受和普及使用的速度是越来越快的,也许前一段时间你还在和朋友吐槽云终端如何如何,自己是不会去使用它的,然而没过多久自己公司就已经开始使用上云终端的了。而又是什么原因让用户接受使用云终端的速度变得越来越快的呢? 首先功能越来越强大,云终端本身配置并不高的,单独使用的话功能也不强的,但是通过连接服务器使用后,它的功能这些现如今是越来越强的,桌面性能完全可以媲美i3、I5电脑配置性能甚至跟高的,对应office办公、播放高清视频和连接打印机等外设设备都达到使用PC时一样效果的。即使是面对一些软件开发和设计类的应用,云终端也有相应的解决方案的, 其次应用场景越来越广,可以说云终端一开始的应用场景是非常单一的,主要是应用在一些学校的云计算机教室和房地产中介门店这样应用相对单一和简单的场景中的,然而随着功能的越来越强大,它的应用场景也是变得越来越广的,特别是一些对应数据安全比较重视的场景中,如软件开发行业、医院的信息化办公等场景更是需要云终端来加强数据安全建设的。可以说除了一些比较特殊的场景云终端还不是很适用之外,其他的一些应用场景基本都是可以适用的。 最后使用越来越方便,云终端发展到今天不管是在使用上还是维护方面都是越来越方便的,在使用上它既可以通过连接本地服务器使用,同时也可以通过连接阿里云等各种类型的云服务器使用,实现灵活性性办公。而在维护上也是越来越方便的,终端系统故障后无需本地维护的,而终端硬件出现故障也很简单,只需拿一个新的换上即可,不懂电脑的也能轻松掌握的。 可以说随着技术的快速发展,云终端的发展也是越来越快的,正如前面说的一样,也许上个月你还在吐槽它,这个月你的办公电脑就被它所替代了的。 来源禹龙云
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文来自: Rancher Labs 自k3s问世以来,社区里有许多小伙伴都问过这样的问题“除了中间的数字之外,k3s和K8s的区别在哪里?”,“在两者之间应该如何选择?”。本文将简单介绍它们两者的区别。 什么是Kubernetes? 正如大家所了解到的那样,Kubernetes是一个“容器编排平台”,也就是说你可以从一组机器中选择其中之一来运行你所需要使用的容器。 它也处理诸如升级你的容器之类的事情,所以如果你发布网站的新版本,它会逐渐使用新版本来启动容器,并放弃旧版本,这一过程仅需一到两分钟。 那么,究竟什么是K8s? K8s是Kubernetes的缩写,因为在K和s之间有8个字母,故称K8s。然而,通常情况下,无论人们谈论的是Kubernetes还是K8s,他们正在说的是原生上游的Kubernetes,由Google所设计的一个真正高可用且可扩展的平台。 问题是,虽然你可以使用诸如Minikube之类的工具在本地计算机上运行Kubernetes,但是如果要在生产环境中运行它,你将很快获得一些“最佳实践”的建议,如: 将你的节点和master分开,使用你的master运行控制平面,使用你的节点运行工作负载,两者永远也不会见面 在独立的集群上运行etcd,以确保它能够处理负载 理想状态下,分离Ingress节点,以便它们能够轻松处理进入的流量,即便一些底层节点已经十分忙碌 很快,你将拥有3倍的K8S master、3倍的etcd、2倍的Ingress以及你的节点。所以在你到达需要询问“我的站点需要多少个节点”这一阶段之前,实际情况下你至少已经有了8个中型实例。 别误会,我不是在指责这些建议不好。相反,如果你正在运行一个生产工作负载,那么这些建议是十分明智的。毕竟,没有比在星期五晚上调试过载的停机生产集群更糟糕的了! 但是,如果你只是想学习Kubernetes,或者给一些非核心的应用托管一个development/staging集群,那么采纳上述建议就有些“杀鸡用牛刀“的感觉了,不是吗?至少对我来说是这样的。如果我只是想启动集群来查看我的Kubernetes manifest(包括部署配置等等)是否是正确的,我并不愿意每月为此付出几百元。 k3s的优势在哪里? Rancher Labs是业界领先的容器软件提供商,其旗舰产品Rancher是一款开源的企业级Kubernetes管理平台,极为出色地管理和安装Kubernetes集群。他们发布了一系列产品,构成他们的生态,例如,Longhorn是一个轻量级并且可靠的容器化分布式块存储解决方案,可用于Kubernetes中,并在近期被收纳入CNCF沙箱项目中。闲杂让我们回到这篇文章的主题,Rancher Labs也是k3s这款轻量级Kubernetes发行版的创建者。 k3s将安装Kubernetes所需的一切打包进仅有60MB大小的二进制文件中,并且完全实现了Kubernetes API。为了减少运行Kubernetes所需的内存,Rancher删除了很多不必要的驱动程序,并用附加组件对其进行替换。 k3s是一款完全通过CNCF认证的Kubernetes发行版,这意味着你可以编写YAML来对完整版的Kubernetes进行操作,并且它们也将适用于k3s集群。 由于它只需要极低的资源就可以运行,因此它能够在任何512MB RAM以上的设备上运行集群,换言之,我们可以让pod在master和节点上运行。 当然,既然它是一个小型的二进制文件,那么我们可以在短时间内安装它,相比于启动常规Kubernetes集群,安装它仅需一小部时间。通常我们仅需要不到2分钟的时间就能够启动一个带有几个节点的k3s集群,也就是说,你可以一有机会就部署应用程序来学习或者进行测试。 听起来不错,实际如何呢? 当人们提到Kubernetes时,他们想到的是如果节点死亡,容器会自动在其他节点上启动,容器之间的负载均衡、隔离和滚动部署,所有这些优点在完整版的Kubernetes和k3s之间是相同的。 但是,k3s并不总是只有优点,否则的话每个人都会去使用k3s。那么,为什么有些人没有使用k3s呢? 首先,当前k3s的版本(k3s v0.8.1)仅能运行单个master,这意味着如果你的master宕机,那么你就无法管理你的集群,即便已有集群要继续运行。但是在k3s v0.10的版本中,多主模式已经是实验性功能,也许在下一个版本中能够GA。 其次,在单个master的k3s中,默认的数据存储是SQLite,这对于小型数据库十分友好,但是如果遭受重击,那么SQLite将成为主要痛点。但是,Kubernetes控制平面中发生的更改更多是与频繁更新部署、调度Pod等有关,因此对于小型开发/测试集群而言,数据库不会造成太大负载。 结 语 K8s和k3s各有优劣,使用场景也有所区别,因此不能一概而论。如果你要进行大型的集群部署,那么我建议你选择使用K8s;如果你处于边缘计算等小型部署的场景或仅仅需要部署一些非核心集群进行开发/测试,那么选择k3s则是性价比更高的选择。 赶紧试试看吧! 欢迎添加小助手(wx:rancher2),进官方技术群,了解更多Kubernetes使用攻略
「深度学习福利」大神带你进阶工程师,立即查看>>> JEPaaS【7.1.0】版升级发布,本次最新升级版本,更新内容如下: JEPAAS-7.1.0 ChangeList Bug Fix 完善PageOffice支持 增加中英文支持 附件上传大文件超时 Features 重构文档模块,并提供SDK,支持SaaS和集群下单独部署 新版JEAPP发布 支持左部菜单主题设置 NextStep 平台安全性优化 修复现有系统Bug 登陆页面 首页看板 功能列表 欢迎下载使用!
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文作者:yanxin1563 本文作者: 李永会 百度APP 团队长期致力于在移动平台应用人力工智技术,近两年得到快速发展,百度 APP 中的 AI 体验也重新定义了很多行业的用户体验,而这仅是开始。 随着5G商用大规模落地,以及智能手机硬件性能越来越强、AIoT设备的快速普及,基于云-边缘-端算法和算力结构的移动端人工智能,仍有非常大的发展空间,亟待我们快速理解移动端深度学习的原理,掌握如何将其应用到实际业务中。 一.在移动端应用深度学习技术的业界案例 在互联网行业中,在移动端应用深度学习技术的案例越来越多。从深度学习技术的运行端来看,主要可以分为下面两种。 一种是完全运行在移动端,这种方式的优点显而易见,那就是体验好。在移动端高效运行神经网络,用户使用起来会感觉没有任何加载过程,非常流畅。前面的“拾相”和手机百度中的图像搜索都属于这一流派,还有其他一些比较好的应用,典型的如识别植物花卉的App“识花”。 另一种是在服务器端运行深度学习技术,移动端只负责UI展示。在第一种流派出现之前,绝大部分App都是使用这种在服务器端运算、在移动端展示的方式的。这种方式的优点是实现相对容易,开发成本低。 1.1 植物花卉识别 卉识别的App近两年来颇多,“识花”是微软亚洲研究院推出的一款用于识别花卉的 App,如下图所示,用户可以在拍摄后查看花卉信息,App会给出该类花卉的详细相关信息。精准的花卉分类是其对外宣传的一大亮点。 1.2 奇妙的风格化效果 将计算机视觉技术应用在App中,可以为图片实现滤镜效果。使用深度学习技术实现的风格化滤镜效果非常魔幻。例如,Philm这款App就可以提供非常出色的体验,它使用了深度学习技术,有不少风格化滤镜效果,下面第一张图是原图,第二张是增加滤镜效果之后的图。 除此之外,还有许多产品也尝试了在移动端支持视频、图片的风格化,如Prisma和Artisto这两款App也都可以实现风格化的效果。 1.3 视频主体检测技术在App中的应用 深度学习技术在移动端的应用越来越多,视频主体检测技术在App中的应用也在加速。目前,手机使用视频主体检测技术进行身份认证已经是非常普遍的事。视频主体检测技术主要根据物体的特征来进行判别,整个流程(如识别和监测这样的操作)包含大量的神经网络计算。下图是我们团队在2017年做的一个Demo,它通过实时识别视频中的图像主体,再通过该区域进行图像搜索,就可以得到商品、明星等多种垂直分类相关图片的信息。 你可能会问,这一功能的意义是什么?直接来看,我们可以利用此技术为视频动态添加演员注解,并且动态支持“跳转到xxx(某个明星的名字)出现的第一个镜头”这样的命令。扩展来看,我们还可以思考一下这一功能实现商业化的方式可能有哪些。例如,假设某个女士看到视频中出现了她喜欢的包包,但是不知道在哪里能够买到。使用了视频主体检测技术后,可以让用户自行筛选,然后在视频中自动提示包包的产地、品牌等信息,甚至可以让用户直接购买。这样就能扩展出非常多的移动AI场景。 二.在移动端应用深度学习技术的难点 在移动端应用深度学习技术,要考虑各种机型和App指标的限制,因此难点较多。如何使深度学习技术稳定高效地运行在移动设备上是最大的考验。拆解落地过程中的复杂算法问题,就是移动端团队面临的首要挑战。 2.1 在服务器端和移动端应用深度学习技术的难点对比 通过对比服务器端的情况,更容易呈现移动端应用深度学习技术的难点,对比如下表所示。 在移动端App的开发过程中,需要克服以上所有困难,才能在移动端应用相关技术。将Demo的演示效果转化为亿级安装量的App线上效果,并不是一件容易的事情。在移动端和嵌入式设备的App中使用深度学习技术,可以大大提升App给用户带来的体验。但是,只应用深度学习技术还不能实现所有想要的效果,往往还要结合计算机视觉相关的技术,才能解决从实验到上线的难题。工程师需要具备很高的将工程与算法结合的能力,才能综合运用多种技术解决问题。在移动端应用深度学习技术时,往往没有太多可以查阅和参考的资料,需要开发人员活学活用,因地制宜。接下来通过实例看一下,如何使用诸多办法来实现AR实时翻译功能。 2.2 实现AR实时翻译功能 AR实时翻译能够实现所见即所得的翻译效果,什么意思呢?来看下面的实例,在下图中,电脑屏幕上有“实时翻译”四个字,将其放在百度App图像搜索实时翻译框中,就能得到“Real-Time translation”,而且手机上的文字和电脑屏幕上的文字具有同样的背景色和字色。 AR实时翻译功能最早在Google翻译软件中应用并上线,Google使用了翻译和OCR(图片转文本)模型全部离线的方式。翻译和OCR离线的好处是,用户不联网也能使用实时翻译功能,且每帧图像在及时处理运算后实时贴图,以达到即视效果。 但是全部离线的方式也有弊端,那就是OCR和翻译模型体积较大,且需要用户下载到手机中才可以使用。另外离线OCR和离线翻译模型压缩体积后会导致准确率降低,用户体验变差:Google翻译App中的词组翻译效果较好,在翻译整句和整段时表现就不够理想。 2017年下半年,笔者参与并主导了百度App中的实时翻译工作的落地。在开始时,团队面对的首要问题是,翻译计算过程是使用服务器端返回的结果,还是使用移动端的本地计算结果?如果使用移动端的计算结果,用户就不需要等待服务器端返回结果,能够减少不必要的延迟。我们只需要针对移动端的OCR和翻译的计算过程,在移动端做性能调优,即可保证每一帧图像都可以快速贴图。移动端性能优化技术其实是我们更擅长的。这样看来,似乎使用移动端计算结果的优点很多,但是其缺点也不容忽视——长文本可能出现“不说人话”的翻译效果。经过分析和讨论,我们回到问题的本质:AR实时翻译的本质是要给用户更好的翻译效果,而不是看似酷炫的实时贴合技术。 最后,我们选择了使用服务器端的返回结果。下图就是上线第一个版本后的试用效果,左边是原文,右边是融合了翻译结果和背景色的效果。 上图中的效果,如果从头做这件事,应该如何拆解过程? 首先,需要将文本提取和翻译分成两部分;接着,拿到翻译结果后,还需要找到之前的位置,准确地贴图。依次介绍如下: 2.2.1 OCR提取文本 需要把单帧图片内的文本区域检测出来。a. 检测文本区域是典型的深度学习技术范畴,使用检测模型来处理。b. 对文本区域的准确识别决定了贴图和背景色的准确性。 要对文本的内容进行识别,就要知道写的具体是什么。a. 识别文本内容需要将图像信息转化为文本,这一过程可以在移动端进行,也可以在服务器端进行。其原理是使用深度学习分类能力,将包含字符的小图片逐个分类为文本字符。b. 使用的网络结构GRU是LSTM网络的一种变体,它比LSTM网络的结构更加简单,而且效果也很好,因此是当前非常流行的一种网络结构。 2.2.2 翻译获取 如果是在移动端进行文本提取,那么在得到提取的文本后,就要将文本作为请求源数据,发送到服务器端。服务器端返回数据后,就可以得到这一帧的最终翻译数据了。 请求网络进行图像翻译处理,移动端等待结果返回。 2.2.3 找到之前的位置 当翻译结果返回后,很可能遇到一个类似“刻舟求剑”的问题:在移动端发送请求并等待结果的过程中,用户可能移动了手机摄像头的位置,服务器端返回的结果就会和背景脱离关系,从而无法贴合到对应的位置,这是从服务器端提取结果的弊端。解决这一问题需要使用跟踪技术。 需要用一个完整的三维坐标系来描述空间,这样就能知道手机现在和刚才所处的位置。 需要倒推原来文本所在位置和现在的位置之间的偏移量。 在跟踪的同时需要提取文字的背景颜色,以尽量贴近原图效果。文字和背景的颜色提取后,在移动端学习得到一张和原文环境差不多的背景图片。 将服务器端返回的结果贴合在背景图片上,大功告成。 下图是我们团队在初期对AR实时翻译功能进行的技术拆解,从中可以看到,在移动端进行AI创新,往往需要融合使用深度学习和计算机视觉等技术。 如果你看过AR实时翻译的案例后仍然觉得晦涩,请不要着急,等学过移动端的机器学习、线性代数、性能优化等后,就会觉得明朗许多。 三.《移动深度学习》 移动深度学习需要克服模型压缩、编译裁剪、代码精简、多平台支持、汇编优化等诸多挑战,本书正是基于作者在此过程中的实战经验。首先介绍基础的数学原理和深度学习模型,然后深入移动计算设备的体系结构,以及如何在这种体系结构上进行高效的深度学习计算。购书链接: https://item.jd.com/57832791296.html 。 关于内容 本书由浅入深地介绍了如何将深度学习技术应用到移动端运算领域,书中尽量避免罗列公式,尝试用浅显的语言和几何图形去解释相关内容。本书第1章展示了在移动端应用深度学习技术的Demo,帮助读者建立直观的认识;第2章至第4章讲述了如何在移动端项目中应用深度学习技术;第5章至第8章的难度略大,主要讲述如何深入地调整框架,适配并定制自己的框架。本书适合移动端研发工程师阅读,也适合所有对移动端运算领域感兴趣的朋友阅读。 关于作者 李永会,百度App移动研发部资深工程师。2015年起在百度从事图像搜索和语音搜索客户端研发工作,主持了多个重要创新项目,包括百度Lens、实时翻译等。同时负责开源移动端深度学习框架 Paddle -Lite的开发,长期从事移动端AI高性能计算优化工作,在多种软硬件平台上高性能运行深度学习技术。在工作之余有读史、书法等爱好。 --------------------------------- 在微信-搜索页面中输入“ 百度App技术 ”,即可关注微信官方账号。 原文链接地址: https://developer.baidu.com/topic/show/290429
「深度学习福利」大神带你进阶工程师,立即查看>>>
上篇回顾 本文是《docker-compose下的java应用启动顺序两部曲》的终篇,在上一篇 《docker-compose下的java应用启动顺序两部曲之一:问题分析》 中,我们以SpringCloud环境下的注册中心和业务服务为例,展示了docker-compose.yml中
depends_on 参数的不足:即只能控制容器创建顺序,但我们想要的是eureka服务就绪之后再启动业务服务,并且docker官方也认为
depends_on 参数是达不到这个要求的,如下图所示: 针对上述问题,docker给出的解决办法是使用
wait-for-it.sh 脚本来解决问题,地址: https://docs.docker.com/compose/startup-order/ ,如下图:
什么是wait-for-it.sh
wait-for-it.sh 脚本用来访问指定的地址和端口,如果收不到响应就等待一段时间再去重试,直到收到响应后,再去做前面指定好的命令,如上图红框所示
./wait-for-it.sh db:5432 -- python app.py 的意思是:等到
db:5432 这个远程访问能够响应的时候,就去执行
python app.py 命令 wait-for-it.sh文件的链接:
https://raw.githubusercontent.com/zq2599/blog_demos/master/wait-for-it-demo/docker/wait-for-it.sh
环境信息
本次实战的环境如下: 操作系统:CentOS Linux release 7.7.1908 docker:1.13.1 docker-compose:1.24.1 spring cloud:Finchley.RELEASE maven:3.6.0 jib:1.7.0
实战简介
上一篇的例子中,我们用到了eureka和service两个容器,eureka是注册中心,service是普通业务应用,service容器向eureka容器注册时,eureka还没有初始化完成,因此service注册失败,在稍后的自动重试时由于eureka进入ready状态,因而service注册成功。 今天我们来改造上一篇的例子,让service用上docker官方推荐的
wait-for-it.sh 脚本,等待eureka服务就绪再启动java进程,确保service可以一次性注册eureka成功; 为了达到上述目标,总共需要做以下几步: 简单介绍eureka和service容器的镜像是怎么制作的; 制作基础镜像,包含
wait-for-it.sh 脚本; 使用新的基础镜像构建service镜像; 改造docker-compose.yml; 启动容器,验证顺序控制是否成功; wait-for-it.sh方案的缺陷;
接下来进入实战环节;
源码下载
如果您不想编码,也可以在GitHub上获取文中所有源码和脚本,地址和链接信息如下表所示: | 名称 | 链接 | 备注| | :-------- | :----| :----| | 项目主页| https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 | | git仓库地址(https)| https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 | | git仓库地址(ssh)| git@github.com :zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
这个git项目中有多个文件夹,本章的应用在
wait-for-it-demo 文件夹下,如下图红框所示: 源码的结构如下图所示: 接下来开始编码了;
简单介绍eureka和service容器
上一篇和本篇,我们都在用eureka和service这两个容器做实验,现在就来看看他们是怎么做出来的: eureka是个maven工程,和SpringCloud环境中的eureka服务一样,唯一不同的是它的pom.xml中使用了jib插件,用来将工程构建成docker镜像:
4.0.0 com.bolingcavalry eureka 0.0.1-SNAPSHOT jar eureka eureka com.bolingcavalry wait-for-it-demo 0.0.1-SNAPSHOT ../pom.xml UTF-8 UTF-8 1.8 Finchley.RELEASE org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.boot spring-boot-maven-plugin com.google.cloud.tools jib-maven-plugin 1.7.0 openjdk:8-jdk-stretch bolingcavalry/${project.artifactId}:${project.version} -Xms1g -Xmx1g 8080 true compile dockerBuild 上述pom.xml中多了个jib插件,这样在执行
mvn compile 的时候,插件就会用构建结果制作好docker镜像并放入本地仓库; 2. service是个普通的SpringCloud应用,除了在pom.xml中也用到了jib插件来构建镜像,它的配置文件中,访问eureka的地址要写成eureka容器的名称: spring: application: name: service eureka: client: serviceUrl: defaultZone: http://eureka:8080/eureka/ 关于如何将java应用制作成docker镜像,如果您想了解更多请参考以下两篇文章: 《Docker与Jib(maven插件版)实战》 《Jib使用小结(Maven插件版)》
制作基础镜像
从上面的pom.xml可见,我们将Java应用制作成docker镜像时,使用的基础镜像是
openjdk:8-jdk-stretch ,这样做出的应用镜像是不含wait-for-it.sh脚本的,自然就无法实现启动顺序控制了,因此我们要做一个带有wait-for-it.sh的基础镜像给业务镜像用: 把wait-for-it.sh文件准备好,下载地址: https://raw.githubusercontent.com/zq2599/blog_demos/master/wait-for-it-demo/docker/wait-for-it.sh 在wait-for-it.sh文件所在目录新建Dockerfile文件,内容如下: FROM openjdk:8-jdk-stretch ADD wait-for-it.sh /wait-for-it.sh RUN sh -c 'chmod 777 /wait-for-it.sh'
注意: 我这里用的是openjdk:8-jdk-stretch,您可以根据自己的实际需要选择不同的openjdk版本,可以参考: 《openjdk镜像的tag说明》 3. 执行命令
docker build -t bolingcavalry/jkd8-wait-for-it:0.0.2 . 就能构建出名为
bolingcavalry/jkd8-wait-for-it:0.0.2 的镜像了,请您根据自己的情况设置镜像名称和tag,注意命令的末尾有个小数点,不要漏了; 4. 如果您有hub.docker.com账号,建请使用
docker push 命令将新建的镜像推送到镜像仓库上去,或者推送到私有仓库,因为后面使用jib插件构建镜像是,jib插件要去仓库获取基础镜像的元数据信息,取不到会导致构建失败;
使用新的基础镜像构建service镜像
我们的目标是让service服务等待eureka服务就绪,所以应该改造service服务,让它用docker官方推荐的
wait-for-it.sh 方案来实现等待: 修改service工程的pom.xml,有关jib插件的配置改为以下内容:
com.google.cloud.tools jib-maven-plugin 1.7.0 bolingcavalry/jkd8-wait-for-it:0.0.2 bolingcavalry/${project.artifactId}:${project.version} INHERIT 8080 true compile dockerBuild 上述配置有几点需要注意: a. 基础镜像改为刚刚构建好的
bolingcavalry/jkd8-wait-for-it:0.0.2 b. 增加
entrypoint 节点,内容是
INHERIT ,按照官方的说法,entrypoint的值等于INHERIT表示jib插件不构建启动命令了,此时要使用者自己控制,可以在启动时输入,或者写在基础镜像中,这样我们在docker-compose.yml中用command参数来设置service容器的启动命令,就可以把
wait-for-it.sh 脚本用上了 c. 去掉
jvmFlags 节点,按照官方文档的说法,entrypoint节点的值等于INHERIT时,jvmFlags和mainClass参数会被忽略,如下图,地址是: https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin 至此,service工程改造完毕,接下来修改docker-compose.yml,让service容器能用上wait-for-it.sh
改造docker-compose.yml 完整的docker-compose.yml内容如下所示: version: '3' services: eureka: image: bolingcavalry/eureka:0.0.1-SNAPSHOT container_name: eureka restart: unless-stopped service: image: bolingcavalry/service:0.0.1-SNAPSHOT container_name: service restart: unless-stopped command: sh -c './wait-for-it.sh eureka:8080 -t 0 -- java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication' depends_on: - eureka 注意command参数的内容,如下,service容器创建后,会一直等待eureka:8080的响应,直到该地址有响应后,才会执行命令
java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication : sh -c './wait-for-it.sh eureka:8080 -t 0 -- java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication' 对于命令
java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication ,您可能觉得太长了不好写,这里有个小窍门,就是在不使用
entrypoint 节点的时候,用jib插件制作的镜像本身是带有启动命令的,容器运行的时候,您可以通过
docker ps --no-trunc 命令看到该容器的完整启动命令,复制过来直接用就行了;
所有的改造工作都完成了,可以开始验证了;
启动容器,验证顺序控制是否成功 在docker-compose.yml文件所在目录执行命令
docker-compose up ,会创建两个容器,并且日志信息会直接打印在控制台,我们来分析这些日志信息,验证顺序控制是否成功; 如下图,可见service容器中并没有启动java进程,而是在等待eureka:8080的响应: 继续看日志,可见eureka服务就绪的时候,service容器的wait-for-it.sh脚本收到了响应,于是立即启动service应用的进程: 继续看日志,如下图,service在eureka上注册成功: 综上所述,使用docker官方推荐的wait-for-it.sh来控制java应用的启动顺序是可行的,可以按照业务自身的需求来量身定做合适的启动顺序;
wait-for-it.sh方案的缺陷
使用docker官方推荐的
wait-for-it.sh 来控制容器启动顺序,虽然已满足了我们的需求,但依旧留不是完美方案,留下的缺陷还是请您先知晓吧,也许这个缺陷会对您的系统产生严重的负面影响: 再开启一个SSH连接,登录到实战的linux电脑上,执行命令
docker exec eureka ps -ef ,将eureka容器内的进程打印出来,如下所示,
java进程的PID等于1 : [root@maven ~]# docker exec eureka ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 2 07:04 ? 00:00:48 java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.EurekaApplication root 56 0 0 07:25 ? 00:00:00 /bin/bash root 63 0 0 07:31 ? 00:00:00 ps -ef 再来看看service的进程情况,执行命令
docker exec service ps -ef ,将service容器内的进程打印出来,如下所示,
PID等于1的进程不是java,而是启动时的shell命令 : [root@maven ~]# docker exec service ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 07:04 ? 00:00:00 sh -c ./wait-for-it.sh eureka:8080 -t 0 -- java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication root 7 1 1 07:04 ? 00:00:32 java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication root 107 0 0 07:33 ? 00:00:00 ps -ef 通常情况下,在执行命令
docker stop xxx 停止容器时,只有PID=1的进程才会收到"SIGTERM"信号量,所以在使用
docker stop 停止容器时,eureka容器中的java进程收到了"SIGTERM"可以立即停止,但是service容器中的java进程收不到"SIGTERM",因此只能等到默认的10秒超时时间到达的时候,被"SIGKILL"信号量杀死,
不但等待时间长,而且优雅停机的功能也用不上了 ; 您可以分别输入
docker stop eureka 和
docker stop service 来感受一下,前者立即完成,后者要等待10秒。 我的shell技能过于平庸,目前还找不到好的解决办法让service容器中的java进程取得1号进程ID,个人觉得自定义entrypoint.sh脚本来调用wait-for-it.sh并且处理"SIGTERM"说不定可行,如果您有好的办法请留言告知,在此感激不尽; 目前看来,控制容器启动顺序最好的解决方案并非wait-for-it.sh,而是业务自己实现容错,例如service注册eureka失败后会自动重试,但是这对业务的要求就略高了,尤其是在复杂的分布式环境中更加难以实现; docker官方推荐使用wait-for-it.sh脚本的文章地址是: https://docs.docker.com/compose/startup-order/ ,文章末尾显示了顶和踩的数量,如下图,顶的数量是145,踩的数量达到了563,一份官方文档居然这么不受待见,也算是开了眼界,不知道和我前面提到的1号PID问题有没有关系: 至此,java应用的容器顺序控制实战就完成了,希望您在对自己的应用做容器化的时候,此文能给您提供一些参考。
欢迎关注公众号:程序员欣宸
「深度学习福利」大神带你进阶工程师,立即查看>>> 在docker-compose编排多个容器时,需要按实际情况控制各容器的启动顺序,本文是《docker-compose下的java应用启动顺序两部曲》的第一篇,文中会分析启动顺序的重要性,以及启动顺序有问题时会有什么样的影响,再给出临时解决的和官方推荐的两种解决方案,为下一篇的实战做好铺垫。 环境信息 本次实战的环境如下: 操作系统:CentOS Linux release 7.7.1908 docker:1.13.1 docker-compose:1.24.1 spring cloud:Finchley.RELEASE 分布式环境中的依赖关系 在分布式环境中,各服务之间可能存在依赖关系,例如SpringCloud环境中的应用在启动时都会先往注册中心Eurka发起请求,如下图(来自spring官方博客: https://spring.io/blog/2015/07/14/microservices-with-spring ): 从上图可知,如果Eureka的服务不可用,就会影响业务服务的功能; Docker环境中的依赖关系 上述服务如果用docker-compose编排在一起,也面依赖着问题:Eureka容器启动完毕并且能提供http服务以后,业务服务的容器才能在Eureka注册成功并取得服务列表,通常我们都使用depends_on 参数来设定依赖关系; 以下是个docker-compose.yml文件,里面有两个容器:eureka和service,eureka是注册中心,service是业务服务,service启动后要去eureka注册,为了确保启动顺序,service配置了depends_on 参数: version: '3' services: eureka: image: bolingcavalry/eureka:0.0.1-SNAPSHOT container_name: eureka restart: unless-stopped service: image: bolingcavalry/service:0.0.1-SNAPSHOT container_name: service restart: unless-stopped command: sh -c 'java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication' depends_on: - eureka 上述yml文件能解决依赖问题吗?service服务启动时能否成功在eureka注册?来试试吧,在Linux电脑上创建docker-compose.yml文件,内容如上所示; 在docker-compose.yml所在目录执行docker-compose up ,docker服务会先去hub.docker.com下载镜像,然后依次创建容器,控制台会同时打印eureka和service的日志,如下图所示,service注册eureka失败了,请注意图中的文字分析: 为何会注册失败呢?继续看后面的日志,如下图,service注册失败后eureka才初始化完成,所以前面的service注册会失败: 至此可以确定:depends_on 参数可以确保eureka容器启动后再启动service容器,但我们真正想要的,是eureka容器启动后,并且eureka服务初始化完毕进入可用状态后,再启动service容器,显然depends_on 参数达不到我们的要求; docker官方文档也证实了这一点,如下图红框所示: 看来depends_on 参数解决不了我们的问题,需要去寻找其他方法; 另外您可能会说:没关系,service会自动重新注册,但是在真实环境中,不是每个服务都有能力去自己解决依赖不可用的问题,例如spring-cloud-config服务如果起不来,依赖它的服务可能会立即停止; 有一种临时方法(此方法V3版语法不再支持) 如果eureka容器配置了健康检查,那么service容器可以配置健康检查依赖来控制启动时机,具体的做法可以参考官方示例,如下所示,地址是: https://docs.docker.com/compose/compose-file/compose-file-v2/ : version: "2.4" services: web: build: . depends_on: db: condition: service_healthy redis: condition: service_started redis: image: redis db: image: redis healthcheck: test: "exit 0" 从上述编排内容可见:db容器有健康检查,可以确定db容器的服务是否可用,web容器的depends_on 参数内可以配置condition ,这样就做到了只有redis已经启动并且db的健康检查通过,才会启动web容器; 2. 上述配置看起来似乎是个不错的方案,在我们这里,只要给eureka配置要健康检查,再让service容器的depends_on 参数内配置condition: service_healthy 就可以了; 3. 不幸的是:在docker-compose的第三版语法中,取消了condition参数! 文档地址是: https://docs.docker.com/compose/compose-file/ ,如下图红框所示: 4. 因此,condition参数看似好用,但是从V3版开始的docker-compose.yml已经不再支持该参数,不能作为标准的解决方案; 官方推荐的方案 如下图红框所示,docker官方推荐使用wait-for-it.sh 脚本来解决问题,地址: https://docs.docker.com/compose/startup-order/ : 至此,本篇已经分析了docker-compose下容器启动顺序的问题,下一篇文章,我们用SpringCloud应用来做实战,将其做到在docker-compose下有序启动; 参考文章 如果您对docker容器健康检查有兴趣,可以参考以下文章: 《极速体验docker容器健康》 ; 《Java应用在docker环境配置容器健康检查》 ; 欢迎关注公众号:程序员欣宸
「深度学习福利」大神带你进阶工程师,立即查看>>> 1)host-manager(管理虚拟主机) 这个功能主要用来管理虚拟主机的,可以通过这个WEB界面,来停止、启动以及增加虚拟主机。首先要配置用户角色: # vim conf/tomcat-user.xml // 更改或增加 这里的admin-gui和admin-script是两个Tomcat内置的角色,host-manager功能需要这两个角色的支持。其中admin-gui用于控制页面访问权限,admin-script用于控制以简单的文本的形式进行访问host-manager。 此时在浏览器里输入http://ip:8080/host-manager/就可以访问到主机管理界面了,但此时还有点问题,会提示403. 这是因为Tomcat还有一个安全的设置,默认不允许这个客户端IP访问host-manager页面,解决办法是修改配置文件: # vim webapps/host-manager/META-INF/context.xml //在allow那一行增加白名单IP,如果是网段用*表示,例如192.168.100.* allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192\.168\.190.*" 我们可以通过这个WEB界面来增加、停止以及启动虚拟主机,非常方便。增加virtualhost,会在conf/Catalina/目录下生成一个目录,目录永久存在,但virtualhost临时的,重启服务后会消失,可以让其永久保存到server.xml,但需要在server.xml里增加,如下配置 如果出现403,则要新增加角色:admin-gui, admin-script 2) Manager(部署) 其实在host-manager界面里,点击右侧的"Server Status"按钮就会跳转到Manager界面里,要想成功访问同样需要配置tomcat-user.xml以及webapps/manager/META-INF/context.xml两个配置文件: # vim conf/tomcat-user.xml //更改或增加 其中manager-gui用于控制manager页面的访问,manager-script 用于控制以简单的文本的形式进行访问manager,manager-jmx用于控制jmx访问,manager-status用于控制服务器状态的查看。然后编辑webapps/manager/META-INF/context.xml: # vim webapps/manager/META-INF/context.xml //在allow那一行增加白名单IP,如果是网段用*表示,例如192.168.100.* allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192.168.190" 完成以上两步操作后,就可以通过http://ip:8080/manager/ 访问到manager界面了。 tomcat的日志: Tomcat日志在/usr/local/tomcat/logs/目录下,大概有这么几类文件:catalina.out、catalina.xxxx-xx-xx.log、host-manager.xxxx-xx-xx.log、manager.xxxx-xx-xx.log、localhost.xxxx-xx-xx.log、xxx_access_log.xxxx-xx-xx.txt。哇~怎么这么多?遇到问题我们该查哪个? 记住一点即可,遇到问题查catalina.out,这个日志是核心日志,无论正确的信息还是错误的信息,不管是tomcat服务本身的还是tomcat跑的应用(如,zrlog)都会记录到这个日志里。 两个manager日志是管理台相关的日志,不用关注。而access_log是访问日志,记录客户端访问网站的情况,这个日志其实可以不让它记,而是在前端Nginx代理上记录,所以也不用关注。这个带日期的catalina.xxxx-xx-xx.log是catalina引擎相关的日志,可以认为是tomcat服务本身的日志,其实这个也不用关注,因为它和catalina.out是重复的,也就是说这个里面记录的信息在catalina.out里就有。还有个localhost.xxxx-xx-xx.log,它主要是应用初始化(listener, filter, servlet)未处理的异常最后被tomcat捕获而输出的日志,其实也不用怎么关注。 日志配置文件conf/logging.properties,里面主要定义了非访问日志的一些属性,比如日志路径、哪些日志记录到哪个文件(名字)、日志级别、存储周期等信息,这个配置文件我们一般都不会更改,保持默认即可。而访问日志的格式、路径是在server.xml中定义的,如下为访问日志的配置片段: ``` prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> ``` 细心的你也许一经发现,catalina.out文件并没有日期后缀,这样就意味着该文件并不会自动切割,它会越写越大。解决该问题的方法有两个: 1)每隔一段时间清空该文件,比如增加一个计划任务 ``` 0 0 */5 * * echo "" > /usr/local/tomcat/logs/catalina.out ``` 2)用系统自带的logrotate工具切割 ``` # vim /etc/logrotate.d/tomcat //写入如下内容 /usr/local/tomcat/logs/catalina.out { copytruncate # 创建新的catalina.out副本后,截断源catalina.out文件 daily # 每天进行catalina.out文件的轮转 rotate 7 # 至多保留7个副本 missingok # 如果要轮转的文件丢失了,继续轮转而不报错 compress # 使用压缩的方式(节省硬盘空间) size 16M # 当catalina.out文件大于16MB时,就轮转 } FTP服务: 文件传输协议,可以上传和下载文件。比如,我们可以把Windows上的文件上传到Linux上。也可以把Linux上的文件 下载到windows上。当然,反过来也可以,因为FTP也可以安装在Windows上。 CentOS上默认有一个 vsftpd Linux下安装pure-ftpd yum install -y epel-release yum install -y pure-ftpd 配置pure-ftpd vi /etc/pure-ftpd/pure-ftpd.conf PureDB /etc/pure-ftpd/pureftpd.pdb MinUID 1000 useradd ftpuser mkdir /data/ftp chown ftpuser:ftpuser /data/ftp pure-pw useradd user1 -u ftpuser -d /data/ftp pure-pw mkdb pure-pw list systemctl start pure-ftpd firewall-cmd --add-port=21/tcp --permanent firewall-cmd --reload 测试: yum install -y lftp lftp user1 @127.0.0.1 Win测试: 下载filezilla client https://filezilla-project.org/download.php?type=client 安装 SFTP 走的ssh的端口 22 支持SFTP的常用软件:filezilla xftp
「深度学习福利」大神带你进阶工程师,立即查看>>>
我在CentOS 7电脑上安装了VMware Workstation 15 Pro,再里面安装了VMware ESXi主机。今天,我在VMware Workstation里为这台主机添加了一块NVMe的硬盘,大小只有5G。从SSH登录进去运行命令行,看看这个ESXi主机里的操作系统上如何对磁盘进行分区和格式化。 # df -h //看到了如下的结果: Filesystem Size Used Available Use% Mounted on VMFS-6 142.5G 84.8G 57.7G 60% /vmfs/volumes/datastore1 vfat 249.7M 155.2M 94.6M 62% /vmfs/volumes/0ef1c67e-54175993-9656-932280ba9446 vfat 285.8M 172.9M 112.9M 60% /vmfs/volumes/5d653d0f-64439c8c-7b4c-000c298b51e3 vfat 249.7M 146.5M 103.2M 59% /vmfs/volumes/3e062d7e-1ad90a51-07ec-d5b812fdb036 vfat 4.0G 33.2M 4.0G 1% /vmfs/volumes/5d653d15-461dfccc-77a2-000c298b51e3 [root@172:~] fdisk -l *** *** The fdisk command is deprecated: fdisk does not handle GPT partitions. Please use partedUtil *** Found valid GPT with protective MBR; using GPT Disk /dev/disks/mpx.vmhba0:C0:T0:L0: 629145600 sectors, 0 Logical sector size: 512 Disk identifier (GUID): 5e307c8f-fd9c-488d-b3bc-d83d6fbd4321 Partition table holds up to 128 entries First usable sector is 34, last usable sector is 629145566 Number Start (sector) End (sector) Size Name 1 64 8191 4064K 2 7086080 15472639 4095M 3 15472640 314572766 142G 5 8224 520191 249M 6 520224 1032191 249M 7 1032224 1257471 109M 8 1257504 1843199 285M 9 1843200 7086079 2560M Disk /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001: 5120 MB, 5368709120 bytes, 10485760 sectors 652 cylinders, 255 heads, 63 sectors/track Units: sectors of 1 * 512 = 512 bytes Disk /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001 doesn't contain a valid partition table
上面使用fdisk -l查看硬盘分区信息,提示说这个命令已经过时了,要使用partedUtil对磁盘进行格式化。
另外,还看到了那块空白的磁盘,盘符看起来怪怪的。
# partedUtil
Not enough arguments
Usage:
Get Partitions : get
//获取磁盘的信息 Set Partitions : set ["partNum startSector endSector type attr"]* //设置磁盘信息 Delete Partition : delete //删除分区: delete <磁盘名称> <磁盘编号> Resize Partition : resize //重新分区: resize Get Partitions : getptbl //获取分区列表: getptbl Set Partitions : setptbl ["partNum startSector endSector type/guid attr"]* Fix Partition Table : fix Create New Label (all existing data will be lost): mklabel Show commonly used partition type guids : showGuids Get usable first and last sectors : getUsableSectors # partedUtil getUsableSectors /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001 34 10485726 上面的这个命令在获取一个磁盘的可用扇区,34是开始,10485726是结束的扇区。 # partedUtil showGuids //命令显示常见的分区类型及其GUID编号 Partition Type GUID vmfs AA31E02A400F11DB9590000C2911D1B8 vmkDiagnostic 9D27538040AD11DBBF97000C2911D1B8 vsan 381CFCCC728811E092EE000C2911D0B2 virsto 77719A0CA4A011E3A47E000C29745A24 VMware Reserved 9198EFFC31C011DB8F78000C2911D1B8 Basic Data EBD0A0A2B9E5443387C068B6B72699C7 Linux Swap 0657FD6DA4AB43C484E50933C84B4F4F Linux Lvm E6D6D379F50744C2A23C238F2A3DF928 Linux Raid A19D880F05FC4D3BA006743F0F84911E Efi System C12A7328F81F11D2BA4B00A0C93EC93B Microsoft Reserved E3C9E3160B5C4DB8817DF92DF00215AE Unused Entry 00000000000000000000000000000000 Fix GPT Table interactively : fixGpt Show Partition Information : partinfo Add Partition Information : add ["partNum startSector endSector type/guid attr"] # partedUtil add /dev/disks /t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001 gpt "1 2048 10485726 AA31E02A400F11DB9590000C2911D1B8 0" 后面几个参数,partNum startSector endSector type/guid attr。其中: partNum,分区编号是1,实际上这个磁盘只有一个分区 startSector:2048(VMFS 5推荐为这个值) endSector: 10485726(刚才查出来的最大扇区号) type/guid: AA31E02A400F11DB9590000C2911D1B8,即vmfs格式的文件系统 attr: 设为0 接下来,怎样格式化这块新创建的分区? 怎样查看现有分区的block size? # partedUtil partinfo /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001 1 注意上面这条命令,最后有一个1,指查看第1个分区的信息,如下: Partition Number: 1 Start sector: 2048 End sector: 10485726 Partition Type GUID: AA31E02A400F11DB9590000C2911D1B8 Partition Unique GUID: FD3C189755D248B8916446785DCFA72A Partition Filesystem Type: vmfs Partition attributes: 0 格式化: # vmkfstools -C vmfs6 /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1 create fs deviceName:'/dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1', fsShortName:'vmfs6', fsName:'(null)' deviceFullPath:/dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1 deviceFile:t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1 ATS on device /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1: not supported . Checking if remote hosts are using this device as a valid file system. This may take a few seconds... Creating vmfs6 file system on "t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001:1" with blockSize 1048576, unmapGranularity 1048576, unmapPriority default and volume label "none". Successfully created new volume: 5dc2f1b6-5f9057e0-b194-000c298b51e3 查看其block size是不是1M或512M: # vmkfstools -P -v10 /dev/disks/t10.NVMe____VMware_Virtual_NVMe_Disk________________VMWare_NVME2D0000____00000001 Could not retrieve max file size: Function not implemented devfs-1.00 (Raw Major Version: 0) file system spanning 0 partitions. File system label (if any): Mode: private Capacity 512 (1 file blocks * 512), 512 (1 blocks) avail, max supported file size 0 Disk Block Size: 512/512/0 UUID: 00000000-00000000-0000-000000000000 Logical device: Partitions spanned (on "notDCS"): Is Native Snapshot Capable: NO OBJLIB-LIB: ObjLib cleanup done. WORKER: asyncOps=0 maxActiveOps=0 maxPending=0 maxCompleted=0 vmkfstools -P -v10 -h /vmfs/volumes/datastore1 VMFS-6.82 (Raw Major Version: 24) file system spanning 1 partitions. File system label (if any): datastore1 Mode: public Capacity 142.5 GB, 57.7 GB available, file block size 1 MB, max supported file size 64 TB Volume Creation Time: Tue Aug 27 14:24:21 2019 Files (max/free): 16384/16291 Ptr Blocks (max/free): 0/0 Sub Blocks (max/free): 16384/16313 Secondary Ptr Blocks (max/free): 256/255 File Blocks (overcommit/used/overcommit %): 0/86873/0 Ptr Blocks (overcommit/used/overcommit %): 0/0/0 Sub Blocks (overcommit/used/overcommit %): 0/71/0 Large File Blocks (total/used/file block clusters): 285/118/128 Volume Metadata size: 1504681984 Disk Block Size: 512/512/0 UUID: 5d653d15-3352555a-55d3-000c298b51e3 Logical device: 5d653d15-27d81446-5f1d-000c298b51e3 Partitions spanned (on "lvm"): mpx.vmhba0:C0:T0:L0:3 Is Native Snapshot Capable: NO OBJLIB-LIB: ObjLib cleanup done. WORKER: asyncOps=0 maxActiveOps=0 maxPending=0 maxCompleted=0 创建scratch分区 # mkdir /vmfs/volumes/Datastore1/.scratch # vim-cmd hostsvc/advopt/update ScratchConfig.ConfiguredScratchLocation string /vmfs/volumes/Datastore1/.scratch 「深度学习福利」大神带你进阶工程师,立即查看>>> Milestone Maintainers 隶属于 Release Team ,负责维护版本的Milestone。其成员除了来自 Release Team 外,还包括各个 SIG 的代表。本节内容侧重于介绍来自各个 SIG 的milestone maintainer相关信息。 一般来说,能够成为 Milestone Maintainers 的人,都是深度参与社区贡献的人。因为,作为 Milestone Maintainers 你需要识别出某个给定的feature或bug应该在哪个release中合入。另外,还需要了解一些版本发布规则,比如你需要准确的知道每个版本的 code freeze 时间点等关键信息。 Milestone Maintainers 职权 Milestone Maintainer 需要参与到某个社区会议、设计和各种讨论,以便可以识别出哪些issue和PR需要在特定的release解决。 作为Milestone Maintainer,拥有为issue或PR设置 milestone 的权利。 申请成为 Milestone Maintainers 申请成为Milestone Maintainer的流程非常简单,只需三个步骤: 提交PR把自己加入到相应的配置文件中; SIG 主席批准; Release Team 主席批准; 提交PR 在 https://github.com/kubernetes/org 仓库的 config/kubernetes/sig-release/teams.yaml 文件中记录了所有的 milestone maintainers. 申请成为Milestone Maintainer只需要提交PR把自己的GitHub ID加入进去即可。 如果你是Release Team 成员,添加自己到 milestone-maintainers 的maintainers列表; 如果你是某个SIG选派出的代表,添加自己到 milestone-maintainers 的 members列表: 提交PR时请注意,GitHub ID是按字母升序排列的。 SIG 主席批准 通常每个SIG会有2到3名主席,一般需要事前跟某个主席达成一致,至少需要一名主席同意,你的PR才以继续。 Release Team 批准 一般而言,SIG同意加入某位成员后,Release Team不会拒绝,但如果某个SIG 加入了很多milestone maintainer时,Release Team 可能会提出异议,此种情况下,建议增加一些背景信息,解释为什么需要加入。 为PR、Issue添加Milestone 以PR为例,一旦识别出在要某个release合入,可以回复 /milestone v1.xx 以通知机器人为该PR设置milestone,表明该PR需要在v1.xx版本合入: 机器人设置完成后,在PR右侧,则会呈现milestone信息,如下图所示: 获取更多信息 Milestone Maintainer 介绍: https://github.com/kubernetes/sig-release/tree/15d0990857d344f028245b6101e30f3713a258c1/release-team#milestone-maintainers
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 李鹏(壮怀) 阿里云智能事业群高级技术专家 导读 :新的企业负载/智能工作负载容器化、迁云、存储方面遇到的性能、弹性、高可用、加密、隔离、可观测性以及生命周期等方面的问题,不但需要存储产品层次的改进,更需要在云原生的控制/数据平面的改进,推进云原生存储和云存储的演进。本文将介绍一下问题场景,探讨可行的解决方案,最终得出云原生存储以及云存储目前可以做什么和未来还需要做什么。 引言 最近有幸参加了由 Infra Meetup 联合 Kubernetes & Cloud Native Meetup 共同组织的面向云原生持久化应用的 Meetup,结合最近对云存储、开源存储、云原生存储的思考,对云原生存储到底是什么,需要做些什么,云原生存储未来挑战是什么,做了更多的反思和梳理,一家之言,分享了几个初步观点。 随着云原生应用对可迁移性、扩展性和动态特性的需求,相应的,对云原生存储也带来了密度、速度、混合度的要求,所以对云存储基本能力又提出了在效率、弹性、自治、稳定、应用低耦合、GuestOS 优化、安全等方面的诉求。 云原生现状 容器和云原生计算被企业快速接纳 Forrester 预测:到 2022 年, 全球组织/公司在生成环境运行容器化应用,从今天不足 30% 的比例将大幅度提升到超过 75%,企业应用容器化的趋势势不可挡。 另一方面,根据 IDC 对未来企业级存储市场的增长趋势预测:云存储的需求相比于 2015 年,到 2020 将会有 3 倍以上的增长,企业存储市场中,数据管理类企业核心数据消耗的存储所占的比例将从 15% 提升到 23%,结构化数据和 DBMS 数据在企业存储市场中将进一步加强。 对云原生来说,核心企业应用/智能应用,使用云原生存储来部署生产可用的有状态应用,呈现加速上升趋势。海外存储巨头 EMC、NetApp 拥抱云原生,积极布局 REX-Ray flexrex、Trident 等云原生存储编排方案。 Kubernetes 逐渐成为云原生时代的基础设施 过去的一年(2018-2019)中,Kubernetes 逐渐成为云原生时代的基础设施,越来越多的互联网、数据库、消息队列等有状态企业核心应用,逐步迁移到云原生平台 Kubernetes,对不同的云上块存储的性能在时延和吞吐,以及稳定性提出了不同的要求,比如: 毫秒级 NvME SSD 级别的稳定时延,来满足高性能 KVstore 和数据库需求; 随着应用单机部署密度的提升,对块存储单机密度的挑战; 本地块存储共享,对块存储的弹性和隔离性也提出了更高需求。 在云原生环境下,如何以声明方式来满足不同的业务场景,成为了云原生存储在实现控制面和数据面上的挑战。 在智能应用 AI 场景下,高性能计算、流式计算也尝试通过 Kubernetes 云原生平台来部署,使用云存储方式来完成训练、计算、推理等方面的工作,这对云存储在 Kubernetes 环境的选择及使用方面提出了挑战。比如,有证据表明 Spark 生态正在逐步从 Hadoop YARN 向 Kubernetes 原生的调度器以及扩展调度器 e.g. Gang Scheuler 迁移。 在云计算环境中:由于成本和存储计算分离的模型,HDFS 仍然会以存储协议的方式存在,但存储方式会逐步从 HDFS 的 3 副本向对象存储(OSS,S3)迁移;GPU 多机多卡 MPI 计算、Flink 流式计算的 Kubernetes 化已经逐步成为主流,存储访问方式也多以对象存储方式呈现。 但是在使用对象存储过程中,大数据/AI 应用的计算效率仍面临着严峻的挑战: 减少同一节点对同一 Block 的反复拉起产生的网络 IO; 减少数据的 Shuffle 产生的写 IO; 实现计算对数据感知,计算向数据迁移的就近计算。 目前的 Kubernetes 调度器以及云存储特性并未给出好的解决方案,所以这也给云原生存储在加速大数据计算、弥补 IO 吞吐不足方面提供了发挥的舞台。 大数据离线计算比如基因计算,已经通过 Kubernetes 云原生平台来大规模的运行计算任务:对文件存储峰值吞吐 10GBps - 30GBps 的峰值刚性兑付,需要独立的高吞吐的文件存储形态和交付方式在云原生环境下的演进和变革。 容器服务成为云原生时代基础设施 随着企业应用上云越来越多地选择使用容器化方式,容器服务在不同的云厂商中都有大幅度的业务增长,容器服务已经逐步成为云原生时代新的基础设施和最佳使用云资源的入口。云原生存储对云计算/云存储来说也有了新的内涵,有必要重新思考云存储和云原生存储的本质区别和联系。 云原生存储和云存储的思考 Cloud Native Storage vs Cloud Storage: 对立还是统一? 两者之间的联系? 差异和侧重点? 1. 云原生存储 = 云存储 UI,面向应用的申明式应用层存储 + 效率等能力组合 云原生存储声明的六要素: 容量 Size; 性能 IOPS,、吞吐、时延; 可访问性,共享/独享; IO 可观测性; QoS; 多租户隔离。 2. 分层存储,重用基础设施红利,不重新发明轮子,针对新的负载类型部分存储形态上移 3. 在控制平面实现效率、自治方面能力,最大化存储稳定和安全 市场上的云原生存储 为了更好的理解在云环境中如何构建云原生存储,先看几个在 Kubernetes 企业环境中部署主流的云原生存储,以及对比云存储的形态: Ceph on Kubernetes with Rook Portworx OpenEBS Ceph on Kubernetes with Rook Ceph 是圣克鲁兹加利福尼亚大学的 Sage Weil 在 2003 年开发的,也是他博士学位项目中的一部分。Ceph LTS 成熟稳定、高可用、生态强大,在云原生时代和 Kubernets 紧密集成。Ceph 基于 RADOS(Reliable Autonomic Distributed Object Store )的高可用存储,在云原生时代之前 2003 年发行起,已经广泛生产部署的高可用存储,支持最广泛的块存储 RBD、文件 POSIX Cephfs,以及对象存储访问协议。 RedHat/SUSE 目前是 Ceph 最主要的商业化支持者,在多个容器平台落地案例中,RBD、CephFS 都被采用作为容器平台实施的主要存储,用来弥补基础云存储的缺失。 Rook 目前是在 Kubernetes 产品级可用的部署和运维 Ceph 编排工具。 Ceph 的基本架构由数据面 OSDs(RADOS) 和控制面 MON/RBD/RADOSGW/CEPHFS 组成,以 CRUSH Algorithm 作为核心算法处理数据冗余和高可用, 上层的应用存储通过 librados 同数据面 OSDs 直接完成数据的读写,能够支持快照、备份、监控可观测性等能力,可以通过 Rook 直接通过 Kubernetes 输出,RedHat/SUSE 也提供独立的集群安装能力。 Ceph 的一些基本架构特征和能力: 控制面:MON/RBD/RADOSGW/CEPHFS; 数据面:OSDs(RADOS); 快照、备份、支持 IO 监控等存储性能监控,支持 RBD QoS 的服务端限速能力。 Portworx Portworx 以容器服务的方式部署,每个节点称为 PX,向下对接各种公有云的块存储或者裸金属服务器,向上提供块或文件服务。 不绑定硬件形态和厂商,可接入任何一家公有云或者自建服务器集群(只需支持 iSCSI 或 FC 协议),目前 Portworx 主打能力云灾备 DR、多云复制,具备完备的快照(ROW)、多云管理、同步复制(RTO,秒级)异步复制(RPO<=15min),可以通过 Kubernetes CRD 申明方式,优雅实现持久化云下应用带数据自动迁移云上能力。PX 可以独立部署,并不强依赖 Kubernetes 的容器网络。 Portworx 的一些基本功能/性能特征: 弹性扩展, PX 自动识别服务器节点的能力,可动态调度 IO 控制面 支持主流容器编排工具:Kubernetes、Mesos、Swarm 等 支持 IO 级别的性能监控 IO面 数据块和元数据打散到不同的节点 使用了缓存和高性能RPC QOS隔离:不支持 根据底层存储的特性IOPS(4k) 768 - 65024 时延(4k): 0.58ms - 23ms 增值特性 加密(三方秘钥托管,传输加密,落盘加密),支持云厂商KMS集成和Vault 快照(ROW),多云管理,同步复制(RTO,秒级),异步复制(RPO<=15min) 可扩展性 >1000个节点,>10000个Volume 支持拓扑感知计算 OpenEBS OpenEBS 基于 Kubernetes 构建的开源版 EBS,软件定义 PV:将各种介质,包括本地磁盘、云等各种存储统一池化和管理。使用 iSCSI 作为存储协议。没有绑定某一个厂商的存储,可以灵活的接入各种存储的一个原因。从某种意义上也是更加灵活,轻量。但是强依赖容器网络,增加了抽象层 OpenEBS layer, 写入操作要通过抽象层,并且每个卷 PV 都有独立的 controller,增加了额外的开销,虽然可以做到更灵活,但相比于 Portworx、Ceph 来说,其在性能上有比较大的劣势。 OpenEBS 的一些基本功能/性能特征: 控制面:扩展容器编排系统,支持超融合。相比块而言,卷的数量多且卷的大小任意配置,更加灵活; 高可用:每个卷可以有多副本,数据实时同步,数据同步是在不同的存储池间进行同步; 快照、备份、监控存储性能功能; 和 Cloud-Native Tools 有很好的集成:可以使用云原生工具(如 Prometheus,Grafana,Fluentd,Weavescope,Jaeger 等)来配置,监控和管理存储资源。 理解云存储 盘古 vs RADOS 对比以上三种开源/企业存储,为了更容易的理解云存储架构,我们把盘古的分层架构和 Ceph 存储的分层做一个对比。 可以把 CS(Chunk Server)类比 Ceph OSDs 服务进程,把盘古的 Master 进程类比于 Ceph MDSs 进程。 把云产品块存储类比于 Ceph RBD, 文件存储类别于 CephFS, 对象存储类比于 RADOSGW,本地块存储/高性能文件存储 CPFS 产品暂没有对应。 随着盘古架构的演进,和盘古 2.0 的全面推广、用户态 TCP 网络协议栈的推广、全面的 RDMA 存储网络、全面优化的 RPC 性能,上层产品存储也享受到了底层存储变革的巨大红利,进入了亚毫秒级别时延,和百万 IOPS 的时代,云原生存储也必然是要在产品存储层次之上,能够继承这些能力。 云原生存储在公有云和专(私)有云中的差异 通过分析了市场上云原生存储,我们可以发现这些存储都有共同的特征就是支持声明化的 API,可以实现对性能、容量、功能等方面的度量和声明,或多或少对质量/稳定/安全都有不同支持。 进一步来说,云原生负载可以直接通过数据平面无损耗的使用产品存储在容量、性能、可访问性的能力,在控制平面继续提升面向用户应用的 IO 可观测性、应用级的 QoS、多租户的隔离能力,通过控制平面接口实现 CSI/Flexvolume 等可声明的存储接口,并提供对部分存储生命周期的 Operator,容器编排把业务应用和存储粘合成为实际的负载声明,可能是更加正确使用云存储的姿势。 由于公有云的基础设施产品存储的完备,可以使用更加轻量化的数据平面(virtio, nfs-utils, cpfs-sdk, oss-sdk)来访问产品存储。 专有云环境差异较大,部分虚拟化或者无虚拟化环境,SAN 和裸盘是主要存储方式,需要通过类似构建 ceph RADOS 或者盘古实现 SDS,然后通过数据平面(librados/px/pv-controller)实现存储的访问。 针对 vSphere,OpenStack,飞天所构建的专有云,有接近于公有云的存储提供方式,但因为部署模块的差异,也存在不同的控制/数据平面支持能力的差异。 简单来说就是: 公有云
Cloud Native Storage = Declarative API + Cloud Storage 专有云
Cloud Native Storage = Declarative API + Native Storage 公有云中的云原生存储 存储分层,重用基础设施红利,不重新发明轮子。 云原生存储 提升数据平面的一致性(kernel/OS/net/client/sdk 优化参数和版本控制); 构建统一的控制平面 CSI/Flexvolume/Operator, 提供面向客户声明 API; 在调度编排层面实现拓扑感知,实现云盘的 zone awareness, 本地盘的 node awareness。 块存储 在控制平面通过与 Aliyun Linux 2 OS 结合使用 Kernel Cgroup blkio 实现进程级别的 buffer IO 控制,提升了在应用层对本地盘、云盘的 QoS 控制的粒度。通过对本地盘的 LVM 切分可以实现对单机云盘的密度提升。通过对挂载点/设备 IO 指标测采集能力,实现 IO 的可观测性。 云原生存储- 块存储的主要特征指标: 容量: 单盘 32TB 时延:0.2ms – 10ms IOPS: 5K – 1M 吞吐: 300Mbps - 4Gbps (本地 NvME ESSD: 2GBps) 可访问性: 单可用区独占 QoS:单盘隔离,进程隔离 多租户: 单盘隔离 详情见: 云盘性能 文件存储 在控制平面可以通过对 Pod Security Policy 和 SecuritContext 的控制,实现应用的强制 UID/GID 控制,实现应用对文件系统的 ACL 控制。控制平面实现对文件系统生命周期的控制,通过对挂载点 IO 指标测采集能力,实现 IO 的可观测性。 云原生存储- 文件存储的主要特征指标: 容量:单文件系统 10PB 时延:100 微妙 – 10ms IOPS: 15K – 50K 吞吐: 150Mbps - 20GBps 可访问性: 多集群多可用区共享 QoS:IO 争抢 多租户: PSP ACL (namespace) CPFS 并行文件系统 在控制平面实现对文件系统 ACL 控制,对 QoS 提供客户端限速的可配置性,文件系统提供生命周期的声明式管理能力 Operator,再进一步,在云原生环境内实现 CPFS 文件系统的声明式部署。 云原生存储- 高性能文件存储的主要特征指标: 容量:单文件系统 100PB 时延:0.5ms – 10ms IOPS: 50K – 1M 吞吐: 10Gbps - 1000GBps 可访问性: 多集群多可用区共享 QoS:支持客户端限速 多租户: PSP ACL (namespace) 总结:云原生存储 v1 – 功能性 今天的云原生存储已经实现了在控制平面/控制平面接口对阿里云产品存储的全品类支持,在数据平面也完成了大部分系统级和客户端层的优化。但随着大量的持久化企业应用和智能化应用的容器化迁移,我们依然面临着更多的问题和挑战。 在整个云原生存储 v1 的开发过程中,感谢阿里云存储团队,在文件存储、块存储和对象存储的通力合作和帮助,共同打造的云原生时代的存储。 随着云原生应用对可迁移性,扩展性和动态特性的需求,对云原生存储也带来了相应的密度,速度,混合度的要求,所以对云存储基本能力之上又提出了在效率,弹性,自治,稳定,应用低耦合,GuestOS优化,安全等方面的诉求。新的企业负载/智能工作负载容器化,迁云,存储方面遇到的性能,弹性,高可用,加密,隔离,可观测性,生命周期等方面的问题,不但是需要存储产品层次的改进,更需要在云原生的控制/数据平面的改进,推进云原生存储和云存储的演进,这是对云原生存储v2的展望和规划,我们会在后续文章进一步揭示这些新的场景,需求,方案以及发展方向。 “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 本场视频链接: EMR打造高效云原生数据分析引擎 本场ppt材料: https://www.slidestalk.com/AliSpark/2019___0926_110365 基于开源体系打造云上数据分析平台 客户选择开源方案的原因主要有以下几点: • 灵活多样的业务场景 :目前即便是一个小企业,其数据存储也可能是多种多样的,比如业务数据、日志数据和图数据等,这种情况下,需要有一个高度定制化的系统来串联不同的业务场景; • 自己有专业的运维能力 :开源系统有充足的人才储备,丰富的网上资料与开源的强大后盾,可以确保公司业务的顺利开展; • 多种业务需求vs成本压力 :每种云上产品有自己的使用场景,对于中小企业来说购买多种云产品将会造成很大的成本压力,而通过开源体系维护一套系统,在集成用户业务中所需组件的同时,可以降低用户的成本。 下图是阿里巴巴EMR系统的 产品架构图 。用户上云的方式主要有两种,一种是购买ECS资源自己搭建一套开源系统;另一种是直接选择阿里巴巴的EMR系统。第一种方式由于开源系统组件多,涉及到了Spark、Hive、Flink和TensorFlow等,从零搭建一套完整的大数据系统对于用户来讲非常复杂,尤其是成百上千的集群规模也给运维造成了很大的挑战。而使用EMR系统具有以下优点: 1) 阿里云EMR系统可以帮助用户一键化自动部署、配置相关组件,开箱即用,同时还会根据用户的机器类型进行参数的自动推荐调优。 2) 阿里云EMR系统与阿里云其他产品实现了打通,比如数据存放在OSS,EMR系统无需额外再做认证配置,便可以很方便地读取OSS上的数据; 3) 阿里云EMR系统集成了很多自研插件,这些插件在其他产品中是没有的; 4) 阿里云EMR系统的所有组件兼容开源但优于开源,如Flink集成了阿里云自研的Blink和TensorFlow(PAI),这也是阿里云为社区做的一点贡献,目的是为了让用户能用到阿里云内部的技术; 5) 阿里云EMR系统提供了全平台的作业诊断与告警组件APM来实现自动化运维,大大降低集群运维的复杂性; 6) 阿里云EMR系统还与DataWorks对接,用户可以以DataWorks为入口,傻瓜式地使用EMR系统。 EMR系统的目标主要有以下三个: • 平台化 :将EMR做成一个统一的云上数据分析平台,帮助用户打造全栈式的大数据解决方案,支持全系列VM容器化,提供企业级HAS和大数据APM; • 技术社区&深度 :持续深耕技术社区,打造大数据友好的云 Native 存储,同时将技术回馈给社区,为社区做贡献; • 生态 :EMR系统将结合阿里云其他产品构建一个生态,接入Blink、PAI,集成OSS、OTS方案。 EMR-Jindo:云原生高效数据分析引擎 下图展示了 TPC-DS的基准测试报告 ,可以发现在2019年3月份10TB的测试中,性能指标得分是182万左右,成本是0.31 USD;而2019年十月份同样的测试性能指标得分已经变成526万,成本下降到0.53 CNY,也就是说经过半年左右性能提升了2.9倍,成本缩减到原来的四分之一。同时阿里巴巴还成为了首个提交TPC-DS测试100TB测试报告的厂商。这些成绩的背后是EMR-Jindo引擎的支持。 EMR-Jindo引擎架构主要分为两部分: • Jindo-Spark :EMR内部全面优化的Spark高效计算引擎,可以处理多种计算任务; • Jindo-FS :自研的云原生存储引擎,兼容开源HDFS的接口,兼顾性能与价格。 1) Jindo-Spark Jindo-Spark高效计算引擎对Spark采取了一系列优化措施,比如Runtime Filter支持自适应的运行时数据裁剪;Enhanced Join Reorder来解决外连接重排等问题;TopK支持推理并下推 TopK 逻辑,帮助尽早地过滤数据;File Index支持文件级别过滤和min/max/bloom/倒排等;自研开发了Relational Cache,实现使用一套引擎就可以将查询从分钟级提升为亚秒级;针对特定的场景推出Spark Transaction功能,为Spark引入Full ACID支持;实现了Smart Shuffle功能,从底层来减少sort-merge 次数,提升Shuffle的效率。 • Runtime Filter : 类似于Spark中的Dynamic Partition Pruning(DPP),但是其比DPP功能更强大。除了DPP能处理的分析表之外,Runtime Filter还可以处理非分析表。其基本原理是运行时动态裁剪数据,避免不必要的计算。比如,面对一个join查询,无法通过value下推到存储层而将数据过滤,逻辑推算的时候无法预知最后的数据量级。这种情况下如果是分析表,Runtime Filter首先会估计其中一个表中参与join操作的数据量,如果数据量较小,则提前进行数据筛选,再推送到另一侧做数据过滤;而对于非分析表,会引入Filter,如BloomFilter获得Min或Max的统计信息, 根据这些统计信息,将备选数据比较少的一侧提取出来,推到另一侧进行过滤。Runtime Filter的成本很小,只需要在优化器中进行简单评估,却可以带来显著的性能提升。如下图所示,Runtime Filter实现了35%左右的整体性能提升。该特性已经在Spark提交了PR(SPARK-27227)。 • Enhanced Join Recorder : 大家都知道,算子执行顺序可能会极大地影响sql的执行效率,这种情况下优化的核心原则是改变算子的执行顺序,尽早地过滤数据。 比如下图左上角的例子中,如果最底层两个表非常大的话,则这两张表join的开销会非常大,join后的大数据再去join小表,大数据一层一层地传递下去,就会影响整个流程的执行效率。此时,优化的思想是先将大表中一些无关的数据过滤掉,减少往下游传递的数据量。针对该问题,Spark使用的是动态规划算法,但其只适用于表的数量比较少的情况,如果表的数量大于12,该算法就束手无策。面对表的数量比较多的情况,EMR提供了多表join的遗传算法,其可以将原来的动态规划算法的2n的复杂度降到线性的量级,能完成成百上千张表的join。 下图右上角可以看到,Query64有18个表参与join,动态规划算法优化时间就需要耗费1400秒,而多表join的遗传算法仅需要20秒左右就可完成。Join Recorder另外一个重要的功能是外连接重排算法,大家都知道sql中外连接不能随意交换顺序的,但这并不代表不能交换顺序,比如A left join B, 然后再left join C,事实上在某种条件下其顺序是可交换的。在Spark中,外连接的优化是直接被放弃掉,而EMR则根据现有研究找到了顺序可交换的充分必要条件,实现了外连接重排算法(如下图左下角所示),对外连接的执行效率有了质的提升(下图右下角) • Relational Cache : Spark原本的Cache存在几个局限点,其一Spark的Cache是session级别,如果发现某一个Query的片段使用比较频繁,就会对为这个session创建一个cache,但是session结束后,cache就会消失;其二Spark的Cache是存储在本机上,而不是分布式存储,因此无法做到通用。在此基础上,EMR平台实现了Relational Cache,对任意Spark表,视图或者Dataset等关系型数据抽象的数据实体都创建cache, 类似于物化视图(Materialized View),但是比物化视图功能要丰富。Relational Cache的使用场景包括a)亚秒级响应MOLAP引擎;b)交互式BI,Dashboard;c)数据同步;d)数据预组织。 Relational Cache的创建过程如下,其语法与Spark sql常见的DDL类似。首先CACHE一个表或视图,然后指定Relational Cache的更新策略(DEMAND或COMMIT)、是否用于后续优化、Cache数据的存储方式以及Cache的视图逻辑。Relational Cache支持cache任意Table、View,支持cache到内存、HDFS、OSS等任意数据源,JSON、ORC、Parquet等任意数据格式。 Relational Cache还支持对用户输入的sql的优化。原来的Spark sql Cache对于用户输入的sql优化非常僵硬死板,用户输入的sql必须精确匹配上Cache才能使用。而Relational Cache则完全不同,如果有a、b、c、d四个表join的cache,当又有a、b、e三个表join的情况下,a、b join的结果便可以从四个表join时生成的Cache数据中读取。下图中右侧展示了Cache和没有Cache的基准测试结果,可以看出Relational Cache可以保证测试的响应时间在亚秒级。 请参考 Spark Relational Cache实现亚秒级响应的交互式分析 • Spark Transaction :有些用户可能会使用Hive表,Hive表有事务支持,然而Spark在事务这一项上是不兼容Hive的。因此,为了满足用户数据订正/删除以及数据流导入的场景支持,EMR平台提供了Spark Transaction支持事务的ACID支持。 传统的数据导入是分批的,比如一天一导入,而流数据导入场景下数据是实时写入的原始数据,并未经过任何处理,因此会有delete和update的需求。Spark Transaction整体来讲是一种锁+MVCC的实现形式,MVCC与底层的存储密不可分。大数据在Hive和Spark兼容的情况下,都是文件的形式存在目录中,文件的版本通过行来控制,写入的每一行都会加上Meta Columns,如op、original_write-id、bucket id和row_id等,来标识这是全表唯一的一行。当需要更新某一行的时候,并不会原地更新该行,而是将该行取出来,重写后产生新的版本进行存储。读取的时候,多版本会进行合并后返回给用户。 ### 2) Jindo-FS EMR早期推出了一种本地盘机型,使用这种机型来部署集群类似于用本地集群在云下部署大数据发行版,价格较高;此外由于当时HDFS有元数据瓶颈,本地存储的动态化伸缩面临很大的挑战。针对这方面的问题,解决的方案是计算与存储分离,将数据存储在OSS上,但是这种分离带来的直接结果就是性能变差,因为OSS元数据操作耗时,读取数据跨网络,传输带宽也会严重影响性能。 进而的解决方案是将数据从远端拉取到计算侧进行缓存,这也是Jindo-FS做的事情。Jindo-FS是类似于HDFS的系统,其架构也类似于HDFS的Master-Slave架构,分成Name Service 和Storage Service。它支持将某些访问频率比较高的表可以放到RocksDB中进行多级缓存。Jindo-FS整体不同于HDFS的Master结点, Jindo-FS的“Master”(Name Service)是一个分布式集群,使用raft 协议,提供入口服务;提供多Name Space支持;元数据以kv形式存放于高性能kv store 中;因为其本身不存储数据,真实数据在OSS和OTS中,因此支持数据的弹性扩展和销毁重建。 Jindo-FS底层的元数据管理会将数据拆成一系列的kv,通过递增的id来逐层查询。如/home/Hadoop/file1.txt需要读三次OTS。下图右侧的测试结果说明Jindo-FS在元数据操作方面相对于OSS有较好的性能提升。 Jindo-FS使用Storage Service来进行底层存储,在写流程中Storage Service将要写的文件同时存储到本地和OSS中,然后再返回给用户写的结果,同时还会在集群结点内进行多副本传输;而读操作和HDFS类似,如果命中本地,则在本地存储中读取,否则要进行远程读取。Storage Service具备高性能、高可靠、高可用、弹性存储等特性,为了支持高性能,Jindo-FS建立了数据流高速通道,同时还有一系列的策略,如减少内存拷贝次数等。 Jindo-FS中Name Service如何实现高可靠、如何进行热点数据发现与缓存替换、块存储模式与缓存模式;以及Storage Service如何应对读写失败、数据块如何设计并存储、如何实现高速数据通道等问题,请参见大数据生态专场《 云上大数据的高效能数据库的存储方案 》的分享。 相关文章: JindoFS概述:云原生的大数据计算存储分离方案 JindoFS解析 - 云上大数据高性能数据湖存储方案 双11福利来了!先来康康#怎么买云服务器最便宜# [并不简单]参团购买指定配置云服务器仅86元/年,开团拉新享三重礼:1111红包+瓜分百万现金+31%返现,爆款必买清单,还有iPhone 11 Pro、卫衣、T恤等你来抽,马上来试试手气 https://www.aliyun.com/1111/2019/home?utm_content=g_1000083110 阅读原文 本文为云栖社区原创内容,未经允许不得转载。
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 肖长军(穹谷)阿里云智能事业群技术专家 导读 :随着云原生系统的演进,如何保障系统的稳定性受到很大的挑战,混沌工程通过反脆弱思想,对系统注入故障,提前发现系统问题,提升系统的容错能力。ChaosBlade 工具可以通过声明式配置执行混沌实验,简单高效。本文将会重点介绍 ChaosBlade 以及云原生相关的实验场景实践。 ChaosBlade 介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌实验模型的混沌实验执行工具,具有场景丰富度高、简单易用等特点,而且可以很方便的扩展实验场景,开源后不久就被加入到 CNCF Landspace 中,成为主流的一款混沌工具。 实验场景 目前支持的实验场景如下: 基础资源场景:CPU 负载、内存占用、磁盘 IO 负载、磁盘占用、网络延迟、网络丢包、网络屏蔽、域名不可访问、shell 脚本篡改、杀进程、进程 Hang、机器重启等; 应用服务场景:支持 Java 应用和 C++ 应用内的实验场景。Java 的场景组件丰富,例如支持 Dubbo、RocketMQ、HttpClient、Servlet、Druid等,而且支持编写 Java 或 Groovy 脚本实现复杂的实验场景; 容器服务场景:支持 Kubernetes 和 Docker 服务,包含 node、pod 和 container 三种资源的实验场景,例如 Pod 网络延迟、丢包等。 混沌实验模型 以上所有的实验场景都遵循混沌实验模型,此模型共分为四层,包含: Target:实验靶点。指实验发生的组件,如容器、应用框架(Dubbo、Redis)等; Scope:实验实施的范围。指具体触发实验的机器或者集群等; Matcher:实验规则匹配器。根据所配置的 Target,定义相关的实验匹配规则,可以配置多个。由于每个 Target 可能有各自特殊的匹配条件,比如 RPC 领域的 Dubbo,可以根据服务提供者提供的服务和服务消费者调用的服务进行匹配,缓存领域的 Redis,可以根据 set、get 操作进行匹配; Action:指实验模拟的具体场景,Target 不同,实施的场景也不一样,比如磁盘,可以演练磁盘满,磁盘 IO 读写高等。如果是应用,可以抽象出延迟、异常、返回指定值(错误码、大对象等)、参数篡改、重复调用等实验场景。 比如一台 IP 是 10.0.0.1 机器上的应用,调用 com.example.HelloService[@1.0.0 ]() Dubbo 服务延迟 3s,基于此模型可以描述为对 Dubbo 组件(Target)进行实验,实验实施的范围是 10.0.0.1 主机(Scope),调用 com.example.HelloService[@1.0.0 ]() (Matcher)服务延迟 3s(Action),对应的 chaosblade 命令为: blade create dubbo delay --time 3000 --service com.example.HelloService --version 1.0.0 所以此模型很简单清晰的表达出实验场景,易于理解。下文中的云原生实验场景也基于此模型定义。 面向云原生的实验场景 实现方案 将混沌实验场景按照上述的实验模型,定义为 Kubernetes 中的资源,并通过自定义控制器来管理,可以通过 Yaml 配置或者直接执行 blade 命令执行。 ChaosBlade Operator 定义了资源控制器,并且会以 daemonset 的方式,在每个节点上部署一个 chaosblade-tool pod 来执行混沌实验。不同的实验场景内部实现方式不同,比如 Node 实验场景,其上面部署的 chaosblade-tool 内部执行即可,而 Container 内的实验场景,控制器会将 chaosblade 包拷贝到目标 Container 中执行。 使用方式 安装必要组件 安装 ChaosBlade Operator,可通过 地址 下载 chaosblade-operator-0.0.1.tgz,使用以下命令安装: helm install --namespace kube-system --name chaosblade-operator chaosblade-operator-0.0.1.tgz 安装在 kube-system 命令空间下。ChaosBlade Operator 启动后会在每个节点部署 chaosblade-tool Pod 和一个 chaosblade-operator Pod。可通过以下命令查看安装结果: kubectl get pod -n kube-system -o wide | grep chaosblade 执行实验 执行方式有两种: 一种是通过配置 yaml 方式,使用 kubectl 执行; 另一种是直接使用 chaosblade 包中的 blade 命令执行。 下面以指定一台节点,做 CPU 负载 80% 实验举例。 yaml 配置方式 apiVersion: chaosblade.io/v1alpha1 kind: ChaosBlade metadata: name: cpu-load spec: experiments: - scope: node target: cpu action: fullload desc: "increase node cpu load by names" matchers: - name: names value: - "cn-hangzhou.192.168.0.205" - name: cpu-percent value: - "80" 如上所示,配置好文件后,保存为 chaosblade_cpu_load.yaml,使用以下命令执行实验场景: kubectl apply -f chaosblade_cpu_load.yaml 可通过以下命令查看每个实验的执行状态: kubectl get blade cpu-load -o json 查看 更多实验场景配置事例 。 blade 命令执行方式 下载 chaosblade 工具包 ,解压即可使用。还是上述例子,使用 blade 命令执行如下: blade create k8s node-cpu fullload --names cn-hangzhou.192.168.0.205 --cpu-percent 80 --kubeconfig ~/.kube/config 使用 blade 命令执行,会返回实验的执行结果。 修改实验 yaml 配置文件的方式支持场景动态修改,比如将上述的 cpu 负载调整为 60%,则只需将上述 value 的值从 80 改为 60 即可,例如: apiVersion: chaosblade.io/v1alpha1 kind: ChaosBlade metadata: name: cpu-load spec: experiments: - scope: node target: cpu action: load desc: "cpu load" flags: - name: cpu-percent value: "60" - name: ip value: 192.168.0.34 然后使用 kubeclt apply -f chaosblade_cpu_load.yaml 命令执行更新即可。 停止实验 可以通过以下三种方式停止实验: 根据实验资源名停止 比如上述 cpu-load 场景,可以执行以下命令停止实验: kubectl delete chaosblade cpu-load 通过 yaml 配置文件停止 指定上述创建好的 yaml 文件进行删除,命令如下: kubectl delete -f chaosblade_cpu_load.yaml 通过 blade 命令停止 此方式仅限使用 blade 创建的实验,使用以下命令停止: blade destroy 是执行 blade create 命令返回的结果,如果忘记,可使用 blade status --type create 命令查询。 卸载 chaosblade operator 执行 helm del --purge chaosblade-operator 卸载即可,将会停止全部实验,删除所有创建的资源。 总结 ChaosBlade 基于混沌实验模型,友好地将 Kubernetes 资源控制结合,部署简单而且使用简洁,实验可控。除此之外 ChaosBlade 基于实验模型实现了很多领域场景执行器,可以很方便的扩展实验场景,可详见附录中的项目列表。 社区共建 ChaosBlade 自开源以来,共有近 30 多位贡献者加入和很多企业的关注及使用,非常感谢各位。同时非常欢迎更多的人参与进来,使 ChaosBlade 变的更加强大,覆盖更多的场景,成为各个企业稳定的、通用的混沌工程工具。 贡献的形式可以是提 bug、提交代码、编写文档、补充单元测试、参与问题讨论等等。ChaosBlade 相信:开源世界中,任何帮助都是贡献。 附录 项目列表如下: ChaosBlade CLI(调用入口) ChaosBlade 实验模型定义 基础资源场景执行器 Docker 场景执行器 Kubernetes 场景执行器 Java 应用场景执行器 C++ 应用场景执行器 “ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。” 双11福利来了!先来康康#怎么买云服务器最便宜# [并不简单]参团购买指定配置云服务器仅86元/年,开团拉新享三重礼:1111红包+瓜分百万现金+31%返现,爆款必买清单,还有iPhone 11 Pro、卫衣、T恤等你来抽,马上来试试手气 https://www.aliyun.com/1111/2019/home?utm_content=g_1000083110 阅读原文 本文为云栖社区原创内容,未经允许不得转载。
「深度学习福利」大神带你进阶工程师,立即查看>>> MaxCompute –面向企业的超大规模计算 全托管,多租户,超大规模平台 MaxCompute拥有庞大的用户群体,支持阿里集团的各个关键业务和复杂场景,支持多个互联网新兴企业核心业务,以及支持关系国计民生、国家安全的关键行业。同时拥有超大规模计算存储,包括单日千万以上计算任务、多EB级别存储量、10万台以上服务器以及全球超过十个数据中心。 企业级高性能计算引擎 TPC-BigBench是更面向于大数据运算的BigBench,覆盖一些复杂类型,包括机器学习场景,更贴近于大数据场景的业务。在2017年,阿里的TPC-BigBench首个通过100TB 验证的引擎。在2018年,TPC-BigBench 首个达到18000+引擎。在2019年,进一步提升到 25000+,正式公布到TPC官网。 MaxCompute不仅仅在阿里集团内部被广泛的使用,也支撑着许多著名的互联网方面的厂商,以及关系到国计民生、国家安全方面的应用。 超大规模企业级SQL引擎– MaxCompute UniSQL 一条SQL在分布式系统中的旅程 上图所示为运行SQL任务中的大概流程。首先使用一条SQL语句,通过Compile,可以生成一个逻辑的执行计划,这个逻辑的执行计划是计算机能够理解的,再经过Optimize过程,无论逻辑计划有多复杂,都要翻译成针对目前集群和运行时刻的Runtime最优的物理执行计划,对于每一个Optimize不一定与原始的SQL相关。然后经过计算调度框架,使得合理快速的安排执行任务。由调度框架做的安排应用到每台机器之后,每台机器都会有一个SQL的运行时(Runtime Engine),它是真正能够理解物理执行计划的,并且一步一步把数据从Storage中读出来,再经过Shuffle得到结果,最后返回到Storage中。可以看出,运行时本身的性能是非常关键的,仅仅一条SQL语句有可能消耗几百T的data,这时,Storage的性能也是至关重要的。 SQL的功能 Not Only SQL – 脚本模式 上图为SQL的一个脚本,上面是配置语句,下面是创建的表,每句都是SQL的语句,但是这些SQL语句都可以串在一个脚本里,当表述一个非常复杂的逻辑时,不需要把脚本写成嵌套的形式,这种方式更灵活,能够支撑更复杂的业务场景。阿里内部有非常复杂的业务场景,过去不支持这种方式时,用户是使用嵌套的方式,使脚本变得复杂和扭曲,并且有大量的重复,以致不能解决时,就会将其拆分,再通过外部调动的方式串连起来。因为人如果承受不了维护的代价,就要引用额外性能的开销,后面的语句就要引用前面的语句。不管脚本有多复杂,经过编译器之后,还是一个单一完整的执行计划,并不会带来额外的开销。优化器看到的上下文越多,优化的机会越多,形成单一完整的执行计划之后,就可以以最高效的方式执行整个业务模式。此外,DataWorks也是支持这种模式的。通过脚本模式可以效仿C++或者Java来写SQL。 Not Only SQL– 参数化视图 例如,在写C++或者Java时,经常在公共的逻辑中抽取出来一个函数,把公共的逻辑放到某一个模块里,这个过程视为代码的重用机制。但是,标准的SQL,尤其是大数据的SQL是缺乏这种机制的。对于阿里这么复杂的场景,这种需求是很迫切的。底层的数据集提供了各个部门都需要的基础的数据,不同的业务部门可能都要消耗这部分数据,消耗的方式是不同的。这时,也想像C++或者Java那样抽取一个函数,在MaxCompute中是可以实现的。在MaxCompute里,上图中的红框除了作为普通的view,也可以封裝一些SQL复杂的逻辑和对数据的读取,可以把表的变量传入,这时就可以实现像C++或者Java中函数的功能,可以把SQL里公共的业务逻辑封装在一起,同时结合上文的脚本模式,参数化视图就可以组织非常复杂的SQL的业务逻辑用来支撑非常复杂的业务场景。 Not Only SQL – IF/ELSE 一般的大数据不支持IF/ELSE,但对于IF/ELSE是有需求的。例如,每周做一次全量的计算,但每天只做增量的计算,如果没有IF/ELSE的支持,就需要把脚本拆成两个,通过调度的框架串连起来。但是,在MaxCompute中结合脚本模式,可以直接的写入IF语句或SELECT语句,如果返回的是异常的结果,直接可以放在一个表达式里,决定执行SQL的分支。所有的SQL的功能都是针对复杂的应用场景的需要。 Not Only SQL – UDT & TRANSFROM 普通的SQL都会有基本的数据类型,有时也有复杂类型,但都是属于给定范围的数据类型。当数据类型特别复杂时,在MaxCompute里可以直接使用。右侧框架是将Java和SQL无缝的融合在一起,无需UDF封装。左侧为SELECT TRANSFORM,是直接就可以在SQL里调用shell脚本,并且完全兼容Hive。 SQL的性能 SQL Engine for Huge Data - Adaptive Join Adaptive Join包括Hash Join和Merge Join。Hash Join的性能是比较好的,但有时碰到不合适的场景时,特别是有非常多的Hash冲突时,性能就会变得很差。Merge Join的特点是能够提供一个性能的下限。可以通过动态的选择适合哪种场景,以便做智能的选取。 SQL Engine for Huge Data – Advanced Shuffle Shuffle也有针对特定大规模系统的优化,包括提升Shuffle 70%的性能,提升大规模共享集群性能,提升稳定性,降低IO压力。具体包括以下优化方式: 1、Greysort模式(Mapper不排序,Reducer排序),增加与下游流水线机会;下游转化为HashJoin时消除排序 2、Encoding & Adaptive列式压缩,降低IO与Cache Miss 3、优化内存结构,降低Working Set Size并消除Pointer Chasing 企业级分布式智能调度执行框架 打造企业级分布式调度执行系统 整个系统的发展有两个维度,一个维度是系统的规模,随着系统规模的不断成长,对于分布式调度执行系统要面对每天千万级需要解决的问题,在阿里这个大体量的数据下,单个分布式作业规模已经能达到数十万个计算节点,已经有上百亿连接和运行数万台的物理机。 另一个维度是系统的成熟度,一个系统成为企业级的分布式执行调度系统就需要达到成熟度,包括三个阶段,第一个阶段是可用性(正确性),一个作业在单机系统上执行的结果和分布式系统上执行的结果是不一样的,尤其是在系统的超大规模上,在面对系统各种各样的节点失败问题、网络层的失败问题和各种容灾问题时,怎样通过正确的方式能保证作业正确的产出是很重要的。第二阶段是够用,是指每一个计算的系统都要锻造自己的性能,能在各种各样的benchmark上标准结果,通过此方法来提升性能。第三个阶段是好用(智能化),是指在动态执行过程中拥有动态能力和自适应能力,可以根据作业的不同特点来调整作业执行的计划。 企业级分布式计算调度框架 企业级分布式计算调度框架分为三个阶段: 动态的智能执行 上图所示为阿里的一个作业在离开优化器以后,在分布式系统里执行的过程。可以理解为从逻辑图到物理图映射的过程。 上图所示为三个阶段的作业,第一个阶段是作业提交开始运行,第二个阶段是根据实际产出动态调整并发,第三个阶段是产生所需数据提前结束作业。 上图所示为智能化DAG执行的动态逻辑图,包括Sorted Merge Join和Broadcast Join两种算法。其中Sorted Merge Join的特点包括经典分布式join算法,可支持大规模作业,可用范围广(slow but reliable),代价较昂贵 (full shuffle + sort),且shuffle可能带来数据倾斜。Broadcast Join的特点是只适用特定类型作业 (一路输入可载入单计算节点内存),非适用场景上可能导致OOM,作业失败。 对动态的选择执行计划,在理想情况下都希望数据的分布是均匀的,并且可以理解数据的特性,所以优化器都可以做出“最佳”的计划,尤其是在做benchmark时,但是由于源数据统计不准确 、中间数据特性波动 ,所产生数据的特点是没有办法提前预估的,所以允许优化器来给一个非确定的执行计划(Conditional Join),这时,优化器会给出两个执行路径的计划,调度执行框架可以根据上游实际产生的数据量,动态的调整逻辑图的执行。 上图所示为并发度的例子。简单的并发调整是根据上游总数据量直接取平均作为并发,仅支持向下调整,但问题是数据可能是倾斜的,这种方法已不再适用。下面给出两种新的调度方法: 1、依据分区数据统计调整:避免并发调整加重数据倾斜,可向上向下调整。 2、分区统计基础上,自动切分大分区:双重调整,消除分区内的数据倾斜,并支持数据处理归并,以保留分区特性。 高效作业管理 对于阿里如此大规模的作业,调度的敏捷度是十分重要的,因为集群规模很大,一个作业怎样理解各个计算节点和物理机的状态,做智能的容错和预判性的容错是阿里所做的一项工作。随着作业规模越来越大,一个非常优秀的调度框架能带来的性能提升会越来越明显。 多种计算模型融合 阿里整个计算平台作为飞天的底座,不仅仅运行SQL,也有可能运行其他。最经典的SQL是batch执行。离线和一体式的执行是资源利用率和性能优化的两个极端,作为一个用户,会同时关注执行性能和资源利用率,需要思考的问题是,怎样在两个点中达到平衡。因此,阿里也支持一种称为bubble的调度,所谓bubble调度是允许一个作业的子图同时调度,下游的子图分布调度,在不同的SQL上会有不同的效果。例如。在TPCH11的情况下,相对于离线(batch)会有66%的性能提升,相对于一体式(all-in-one)会节省3倍的资源,同时获取95%的性能。 新一代列式存储引擎AliOrc 在AliOrc的里程中,起点和终点都是在存储层,数据的读和写是AliOrc执行的开始和结束,存储引擎作为AliOrc的底座,承担着一个非常重要的作用。 基于Apache Orc的深度优化 整个计算引擎是基于列结构的,技术的出发点是Apache Orc。在此基础上,阿里做了很多深度的优化,包括I/O维度、内存优化、索引和数据编码压缩。其中有一部分已经贡献到了社区。 新一代列式存储引擎 新一代列式存储引擎包括以下技术方面: 并行化编码技术 对于有一系列的大数和小数,直接存放时会产生4个字节,而对于小数,前面会产生很多的零,这些零是没有意义的。并行化编码技术的主要思想就是将冗余的信息删掉,将真正有意义的batch留下,并且pack到一起。这种编码方式的好处是能实现并行化。此外,还进行了一些扩展,包括对有序数据的优化,以及对数据的编码优化。同时重新设计了编码存储格式,更利于内存对齐,以及列存储。 从测试的结果来看,此编码技术比传统游程编码速度快4到6倍,压缩率提升大概10%左右,在反应到TPC Benchmark表扫描效率提升24%。之所以有如此快的结果,是因为使用AVX256一条指令可以处理8个64位数,或者16个32位数,同时充分利用函数模板展开,最大程度避免循环和分支预测失败。 异步并行IO 阿里是属于列存储引擎的,是指在同一个列是放在一起的,好处是在读数据时选择几个列放到存储引擎中去读,就不需要读所有的列。假设在上图中的场景中,有三个列为A、B、C。最早的IO模型是串行的,存在许多等待时间。因此,阿里做了一个改进为Prefetch模型,IO是不需要一个一个发出去的,在一开始时可以将三个读取引擎一起发出去,但是需要一个一个的等待它们回来,虽然有了一些提升,但是还仍然存在IO等待的时间。目前为止,改进的模型为Prefetch+Async Paraller IO,是将IO全部并行化,将三个一起发出去之后,并不需要按照原来A、B、C的顺序等待,可以按照回来的顺序做解压和解码。这样做可以对IO等待的时间降到最小。 如上图所示,异步并行IO与同步读取相比较,IO等待时间减少97%,端到端时间减少45%。 延迟读取、延迟解码 为了进一步的提高性能,减少数据读取量,从而减少数据解码、解压缩成为了关键。 如上图所示为延迟读取的一个例子,通过只读取DEPT列,把ADDRESS以及SALARY列延迟到过滤之后读取,可以大幅减少了不必要的数据读取。 对于字符串类型的列,有一种方法叫字典编码,是指将字符串里不一样的Key找出并且给予ID,这时,数据在存放时是不需要存放整个字符串的,只需要存放ID就可以。但是使用此方法是很耗时的。由此,做了以下改进: 使用延迟解码,跳过解码步骤,直接在字典上匹配,再以ID到数据列搜索。好处是减少了字符串匹配次数以及减少了字典解码时间。 如上图所示,对打开延迟读写和没有打开延迟读写做了比较,横坐标为filter过滤的数据,“1”表示没有过滤,纵轴是花费的时间,实现延迟读取之后,读取数据量随Selectivity的提升而减少,读取时间也相应大幅降低。 原文链接 本文为云栖社区原创内容,未经允许不得转载。
「深度学习福利」大神带你进阶工程师,立即查看>>> > 原文链接: 并发与并行的区别 现在我们都说设计可并行、高并发的程序,而且我们很多时候会在潜意识里觉得自己对并行(Parallelism)和并发(Concurrency)的区别很清楚,但如果要明确的说出二者的区别,又感觉没办法给出一个非常清晰的描述。 那么什么是并发?什么又是并行呢?并行的概念比较简单,并行总是和执行(executions)相关,很多东西同时执行就是并行;而并发则是通过一些方式组织你的程序,让它可以分成多个模块去独立的执行。并行必然是需要多核的,一个处理器是无法并行的;但并发和处理器并没有什么必然联系,在一个处理器上面,我们的程序也可以是并发的。 举个简单的例子,华罗庚泡茶,必须有烧水、洗杯子、拿茶叶等步骤。现在我们想尽快做完这件事,也就是“一共要处理很多事情”,有很多方法可以实现并发,例如请多个人同时做,这就是并行。并行是实现并发的一种方式,但不是唯一的方式。我们一个人也可以实现并发,例如先烧水、然后不用等水烧开就去洗杯子,所以通过调整程序运行方式也可以实现并发。 如果你觉得以上的讲解还是太抽象了,下面通过一个小故事来讲解,故事原型来自 Go 语言创始人之一 Rob Pike 的一篇演讲。 故事的开始有一个需求:有一群地鼠要把一堆废弃的说明书用小推车推到火炉去烧毁。 刚开始只有一只地鼠,使用一辆推车,将书装到车上,运输到火炉旁,将书卸到火炉。完成任务必然需要比较长的时间。 此时如果再增加一只地鼠,那也没什么用,因为一只地鼠在干活,另一只地鼠只能等待。(当然有人说两只地鼠轮流使用一辆推车,这样可以让地鼠得到休息,这样它们干活更快,也可以提高效率。) 再找一辆推车来,两只地鼠分别使用各自的推车,将书装到车上,运输到火炉旁,将书卸到火炉。这样会提高运输效率,但它们会在装书和卸书时进行排队,降低了效率。 这样虽然比之前快了,但还是有瓶颈的。因为书只有一堆,火炉也只有一个,所以我们还必须通过消息来协调两只地鼠的行动。好吧,那我们再把书分成两堆,再增加一个火炉。 这样就比之前的效率高差不多一倍了。现在这个模型就是并发的,因为两只地鼠可以独立完成一件事了,这样提高了运输效率,而且在装书和卸书时不会进行排队,提高了装卸的效率。但这个模型不一定是并行的,比如同一时刻可能只有一只地鼠在干活。 上面就是第一种并发模型,我们还可以设计更多的并发模型,继续看漫画。 这次找了 3 只地鼠,一只负责把书装到车上,一只负责运输,一只负责把书卸到火炉焚烧。每只地鼠做一个独立的任务,当然三只地鼠之间需要使用一些诸如消息通信之类的手段进行协调。 装书和烧书的两只地鼠都很轻松,负责运输的这只地鼠却很累,系统出现了瓶颈。那我们再找一只地鼠来,专门负责运回空推车。 我们在一个已有的设计(指三个地鼠的那个设计)中添加一个并发的步骤(第四只地鼠)增强了系统的性能。这样一来,两只地鼠去搞运输,如果协调的好,理论情况下工作效率将是一只地鼠的 4 倍。 总共有 4 个并发的步骤: 把书装到车上; 把推车运到火炉旁; 把书卸到火炉里; 运回空推车。 可以再增加一个分组,将这个并发模型并行化。 下面我们再来看另外一种并发模型。负责运输的地鼠抱怨说运输路程太长,那我们就增加一个中转站。 然后再增加一个分组,将这个并发模型并行化,两个分组并行执行。 可以把上面的并发模型再改进一下。增加中转站的同时,再增加两只地鼠,一只负责将从书堆运过来的书卸到中转站,另一只负责将书从中转站装到推车里,再让后面的地鼠运输到火炉旁。 然后再增加一个分组,将这个并发模型并行化。 漫画到这里就结束了,总共介绍了三种并发模型,每种模型都可以很容易地并行化。可以看到上面的并发模型每改进一次,其实就是将任务拆的更细了,一旦分解了问题,并发就自然而然产生了,每个人只专注于一个任务。 回到程序中,书就代表着数据,地鼠就是 CPU,而车可能就是序列化、反序列化、网络等设施,火炉就是代理、浏览器或其他的消费者。而上面的并发模型就是一个可扩展的 Web Service。 该演讲题目为 《Concurrency is not Parallelism》 ,原文链接: 演讲幻灯片: https://talks.golang.org/2012/waza.slide 演讲视频: https://www.youtube.com/watch?v=cN_DpYBzKso&t=550s 参考链接 https://my.oschina.net/3233123/blog/1047239 https://blog.csdn.net/claram/article/details/52094587 微信公众号 扫一扫下面的二维码关注微信公众号,在公众号中回复◉加群◉即可加入我们的云原生交流群,和孙宏亮、张馆长、阳明等大佬一起探讨云原生技术
「深度学习福利」大神带你进阶工程师,立即查看>>> 作者 | 李响、张磊 Kubernetes 本身并不直接产生商业价值,你不会花钱去购买 Kubernetes 。这就跟安卓一样,你不会直接掏钱去买一个安卓系统。Kubernetes 真正产生价值的地方也在于它的上层应用生态。 “未来的软件一定是生长于云上的” ,这是云原生理念的最核心假设。而所谓“云原生”,实际上就是在定义一条能够让应用最大程度利用云的能力、发挥云的价值的最佳路径。因此,云原生其实是一套指导软件架构设计的思想。按照这样的思想而设计出来的软件:首先,天然就“生在云上,长在云上”;其次,能够最大化地发挥云的能力,使得我们开发的软件和“云”能够天然地集成在一起,发挥出“云”的最大价值。 云原生的概念大家并不陌生,很多企业也已经基于云原生的架构和技术理念落地相关实践。那么,这么多企业和开发者热衷和推崇的云原生,未来的发展趋势如何?如何才能顺应云原生的主流方向去发展? 我们邀请到阿里云资深技术专家、CNCF 技术监督委员会代表,etcd 作者 李响 和阿里云高级技术专家、CNCF 应用交付领域 co-chair 张磊 分享云原生的理念、发展以及未来趋势,为大家打开新的思路和眼界。 以下内容共享给大家。 Kubernetes 项目的安卓化 云原生里有一个非常关键的项目,就是 Kubernetes。Kubernetes 的发展非常迅速,它是整个云原生体系发展的基石。今天我们来观察 Kubernetes 项目的发展特点,首先,Kubernetes 无处不在,无论是在云上,还是用户自建的数据中心里,甚至一些我们想象不到的场景里,都有 Kubernetes 的存在。 第二,所有云原生的用户使用 Kubernetes 的目的,都是为了交付和管理应用。当然这个应用是一个泛化的概念,可以是一个网站,也可以是淘宝这样非常庞大的电商主站,或者是 AI 作业、计算任务、函数、甚至虚拟机等,这些都是用户可以使用 Kubernetes 去交付和管理的应用类型。 第三,今天我们来看 Kubernetes 所处的位置,实际上是承上启下。Kubernetes 对上暴露基础设施能力的格式化数据抽象,比如 Service、Ingress、Pod、Deployment,这些都是 Kubernetes 本身原生 API 给用户暴露出来的能力。而对下,Kubernetes 提供的是基础设施能力接入的标准接口,比如说 CNI、CSI、DevicePlugin、CRD,让云能够作为一个能力提供商,以一个标准化的方式把能力接入到 Kubernetes 的体系中。 这一点其实跟安卓非常类似,安卓虽然装在你的设备里,但是它能够让你的硬件、手机、电视、汽车等都能接入到一个平台里。对上则暴露统一的一套应用管理接口,让你能够基于安卓系统来编写应用,去访问或者享受到这些基础设施能力,这也是 Kubernetes 和安卓的相似之处。 最后, Kubernetes 本身并不直接产生商业价值,你不会花钱去购买 Kubernetes。这就跟安卓一样,你不会直接掏钱去买一个安卓系统。Kubernetes 真正产生价值的地方也在于它的上层应用生态。对安卓来说,它今天已经具备了一个庞大的移动端或设备端应用的开发生态,而对于 Kubernetes 来说也是类似的,只不过现在还在于比较早的阶段。但我们已经能够看到,今天在 Kubernetes 上构建的商业层很多是垂直解决方案,是面向用户、面向应用这一侧真正能够产生商业价值的东西,而不是 Kubernetes 本身这一层。这就是为什么我说 Kubernetes 发展跟安卓很像,当然这可能也是谷歌比较擅长的一个“打法”:全力地去免费推广一个“操作系统”,真正获取商业价值的方式则是是去“收割”操作系统上层的生态价值而不是操作系统本身。 基于这些现象,我们将 Kubernetes 的发展趋势概括为以下几点: 1. 云的价值回归到应用本身 用户使用 Kubernetes 的本质目的是去交付和管理应用。从这个现象来看,如果 Kubernetes 发展下去,那么世界上所有的数据中心和基础设施上面都会有一层 Kubernetes ,自然而然用户就会开始以 Kubernetes 为基础去编写和交付以及管理其应用,就跟现在我们会以安卓这样一个操作系统为基础去编写移动应用是类似的。 这就会导致云上的大多数软件和云产品都是第三方开发的。第三方开发是指所有人都可以面向一个标准界面去开发和交付软件,这个软件本身既可以是自己的软件,也可以是一个云产品。未来,越来越多的第三方开源项目,如 MongoDB、Elasticsearch 等,都会以云原生理念去开发、部署和运维,最后直接演进成为一种云服务。 2. 云端“豌豆荚”的出现 有了 Kubernetes 这样一个标准,开发者面对的就是一个类似于操作系统的界面。由于有更多的应用是面向 Kubernetes 诞生的,或者说面向 Kubernetes 去交付的,那么就需要有一个类似于“豌豆荚”的产品,来作为云上的应用商店或者云上的应用分发系统,它的关键能力在于把应用无差别地交付给全世界任何一个 Kubernetes 上面,就跟用豌豆荚把任何一个安卓应用交付在任何一个安卓设备上的原理是一样的。 其实今天谷歌已经在做这类产品的尝试了,比如 Anthos (面向混合云的应用交付平台),虽然是一款混合云产品,但它本质上是把谷歌云的服务,比如数据库服务、大数据服务,去直接交付于任何一个基于 Kubernetes 的混合云环境里面去,其实就相当于一款云端的“豌豆荚”。 3. 基于 Kubernetes 可扩展能力的开放应用平台会取代 PaaS 成为主流 由于未来整个应用生态会面向 Kubernetes 去构建,那么基于 Kubernetes 可扩展能力的开放应用平台会逐渐取代传统 PaaS 而成为主流。基于 Kubernetes 可扩展能力去构建一个开放的应用平台,其能力是可插拔的,能够去交付和管理的应用类型是多样化的,这才更符合 Kubernetes 所构建的趋势和生态,所以一些真正高可扩展的平台层项目会大量产生。 另外,今天我们看到的 Kubernetes ,跟“理想”中的云原生应用生态之间其实还有很多路要走,这也是阿里云原生团队一直在做的事情,基于 Kubernetes 在应用层构建更丰富的应用生态,帮助用户实现多样化的需求。 应用与能力的“ Operator 化” 纵观云原生时代应用或者云的能力的发展方向,你会发现另一个趋势,就是 Operator 化。Operator 是 Kubernetes 的一个概念,是指 Kubernetes 交付的一个实体,这个实体有一个基础模型存在,这个模型分为两部分:一部分是 Kubernetes 的 API 对象(CRD),另一部分是一个控制器(Controller),如下图所示: 这里要区分两个概念,自定义和自动化。很多人会说 Operator 可以帮助我做自定义,因为很多人都会觉得 Kubernetes 内置的能力是不够用的,所以用户会利用它的可扩展能力去写一个 Controller ,从而实现跟多自定义的需求。但自定义只是 Operator 中很小的一部分价值,我们今天对应用和能力做 Operator 化的核心动力在于其实是为了实现自动化,而且只有自动化了,我们才能讲云原生。 这是因为,云原生带来的最大的红利是可以让我们最大限度、最高效地使用云的能力,二这种最高效、最大化的方式一定没办法通过人工来实现的。换句话说,只有通过自动化的方式去开发、运维应用以及与云进行交互,才能真正把云原生的价值发挥出来。 而如果要通过自动化的方式跟云进行交互,那么在云原生生态里,必须有一个类似于Controller 或者 Operator 这样的插件的存在。今天阿里巴巴在云上交付的 PolarDB、OceanBase 等,其实都有一个跟 Kubernetes 衔接的 Controller 的存在。通过 Controller 与基础设施、云进行交互,把云的能力输入到产品里面去。 在未来,会有大量的云上的应用和对应的运维能力、管理能力都会以 Kubernetes Operator 的方式交付。在这个背景下, Kubernetes 真正扮演的一个角色就是能力的接入层和标准界面。如下图所示,这是一个非常典型的用户侧 Kubernetes 集群的样子。 一个用户的 Kubernetes 只有红框里面这部分是 Kubernetes 原生提供的 API ,而大量的能力都是以插件化或者说 Operator 化的方式存在。就比如上图右边所有这些自定义的资源和能力全部来自于第三方开发,通过 Operator 这样一个标准的形态开发出来的能力来服务最终用户的。这就意味着在未来云原生的生态里面,基于 CRD Operator 的而非 Kubernetes 原生 API 的应用和能力会占到绝大多数。 随着这个趋势的不断演进,越来越多的软件和能力通过 Kubernetes Operator 去描述和定义,云产品也会开始默认以 Kubernetes 为底座,基于 Operator 进行交付。 正是因为越来越多的 Operator 的出现,这里就会逐步需要一个中心化的方式去解决 Operator 潜在的稳定性、可发现性和性能问题,也就是说在未来很可能会有一个横向的 Operator 管理平台出现,对所有基于 Kubernetes Operator 开发的应用和能力进行统一管理,从而更好、更专业地服务用户。 此外,由于未来每一个能力、每一个应用都需要去编写 Operator ,所以说对开发者友好的 Operator 编写框架也是未来一个很重要的趋势。这个编写框架可以支持不同语言,如 Go、Java、C、Rust 语言等,并且编写过程是专注于运维逻辑和应用的管理、能力的管理,而不是专注在 Kubernetes 的语义和细节上面。 最后,随着云原生生态的普及,云服务也将实现 Operator 化,并且面向多集群/混合云场景出现面向应用层的云服务标准化定义与抽象,并在云原生领域逐渐取代 IaC 项目(比如 Terraform 等)成为云服管理与消费的主流方式。 应用中间件能力进一步下沉 随着云原生以及整个生态的发展,我们看到应用中间件领域也随之发生了很多改变。从原先最开始的中心化 ESB ,到后来的胖客户端,逐步演化到今天我们经常提到的 Service Mesh 这样一种 Sidecar 化的方式。 其实今天你会发现,无论是云的能力还是基础设施的能力,都在不断丰富,很多原先只能通过中间件做的事情,现在可以很容易通过云服务来实现。应用中间件不再是能力的提供方,而是能力接入的标准界面,并且这个标准界面的构建不再基于胖客户端,而是通过非常普通的 HTTP 协议、 gRPC 协议去做,然后通过 Sidecar 方式把整个服务的接入层跟应用业务逻辑做一个解耦,这其实就是 Service Mesh 的思想。 目前 Service Mesh 只做了传统中间件里面的流量治理、路由策略、访问控制这一层的事情。而实际上, Sidecar 这个模型可以应用到所有中间件的场景里,实现中间件逻辑跟应用业务逻辑完全解耦,让应用中间件能力“下沉”,变成 Kubernetes 能力的一部分。这样应用本身会更加专一化,更多的关注业务逻辑本身。 伴随着这个趋势,在 Kubernetes 这一层还会有另外一个趋势出现,就是 Sidecar 的自动化的、规模化的运维能力会成为一个必选项。因为 Sidecar 的数量会极其庞大,应用中间件很可能会演化成 Sidecar 集群,那么这些 Sidecar 的管理和规模化的运维能力,会是集群或者云产品的一个必备选项。 下一代 DevOps 模型与体系 随着云原生生态的不断发展,云原生理念的不断普及, DevOps 的思想很可能也会发生一个本质的变化,即下一代 DevOps 模型与体系。随着 Kubernetes 的能力越来越多、越来越强大,基础设施也会变得越来越复杂,那么基于这样一个强大的基础设施去构建一个应用平台就会非常简单,并且这个应用平台最终会取代传统的PaaS平台。 我们现在之所以在用 DevOps 这一套思想,实际上是由于基础设施本身不够强大,不够标准化,不够好用,所以我们需要在业务研发侧做一套工具去黏合研发人员和基础设施。例如,基础设施提供的能力是一个虚拟机,怎么能让虚拟机变成研发侧想要的蓝绿发布或者一个渐进式的应用交付系统呢?这就需要一系列的 DevOps 的工具、 CI/CD 的流水线来完成。 但是现在的情况已经发生了变化。基于 Kubernetes 的基础设施本身的能力已经非常丰富,像蓝绿发布这些能力本身就是 Kubernetes 可以提供的能力。在这样的背景下, DevOps 的发展趋势也会发生很大的改变: 1. 关注点分离 在 Kubernetes 的背景下,“软件”不再是一个由应用 Owner 掌控的单一交付物,而是多个 Kubernetes 对象的集合,而这一堆 Kubernetes 里面的对象只有很少一部分其实才跟研发有关,所以说有很多对象会不在应用 Owner 的认知范围内,这就导致平台必须去做关注点分离,研发侧的关注点和运维侧、系统侧的关注点是完全不一样的东西。也就是研发不用再考虑运维方面的细节,比如蓝绿发布怎么做,水平扩容什么策略,只要把业务代码写完交付就好。 伴随着 Kubernetes 和基础设施越来越复杂,概念越来越多,作为平台层是不大可能让研发了解所有的概念,因此未来云原生生态一定会做抽象和分层。每一层的角色只跟属于自己的数据抽象去交互,研发侧有一套自己的声明式 API 对象,运维侧有一套自己的声明式 API 对象,每一层的关注点也是不一样的,这会是未来整个 DevOps 体系里发展的一个重要的背景。 2. Serverless 泛化 云原生本身的关注点就是应用,在这样一个背景下,Serverless 本身不再是一个独立场景,不再局限在某几个非常垂直的领域,而会变成云原生应用管理体系的一种泛化思想和天然组成部分。我从两个层面解释一下:一是在能力侧,“轻运维”“ NoOps ”以及“自助式运维能力”会成为应用运维的主流方式。云原生生态上的应用管理会体现出一种轻运维的状态,就是说应用运维不再是一个人工的、非常复杂的过程,而是一组开箱即用的、非常简单的模块化操作。无论是通过 Kubernetes 还是通过云原生能力,都是对下层基础设施的一个模块化的分装,这跟 Serverless 所提倡的 NoOps 理念非常类似。 二是在应用侧,应用描述会广泛地进行用户侧的抽象,事件驱动和 Serverless 理念被拆分和泛化,可以被应用于多样化的场景中而不仅仅是今天狭义的 Serverless 场景比如 FaaS 或者 Container Instance,未来所有的应用都可以实现 scale-to-zero 。 3. 基于 Infrastructure as Data(IaD)思想的应用层技术渐成主流 第一,基于 Infrastructure as Data(IaD)的思想会成为一个主流技术,IaD 实际就是 Kubernetes 的声明式 API ,声明式 API 的核心在于把基础设施、应用、能力以一个声明式的文件、声明式的对象去描述,那么这个文件或者对象本身就是“数据”。而 Kubernetes 或者基础设施这一层是通过数据去驱动的,这就是 Infrastructure as Data。这样的思想会延伸出很多技术和前沿的思想,比如 GitOps 、管道型 YAML 操作工具(Kustomize/kpt)等。这样的管道型应用管理会成为云原生生态里面一个非常主流的应用管理方式。 第二,声明式应用定义模型(比如 OAM),以及声明式的 CI/CD 系统和 Pipeline 会成为一个新的应用交付的模式。比如传统的 Jenkins 是一个命令式的组织方式,而随着声明式的 Pipeline 的出现,加上云原生生态、Kubernetes 的普及,基于 Infrastructure as Data 思想的流水线和下一代的 CI/CD 系统也会成为业界的主流。这跟以前的 CI/CD 和流水线有本质的区别,因为这个 CI/CD 系统里面所有的操作都是一个声明式描述。正因为是声明式描述,所有这些操作以及 CI/CD 里面的环节都可以托管到 Git 上,哪怕一个人工审核(Manual Approve)这样的动作都可以托管在 Git 里面,通过 Git 去审计和做版本管理等。 Infrastructure as Data 的出现就是告诉我们,未来云原生的系统。一切皆对象,一切皆数据。随着对象和数据越来越多,对他们的管理、审计、验证等就变得越来越复杂,那么围绕它们的策略引擎(Policy Engine)会成为一个非常重要的需求。策略引擎会成为一个非常重要的组件,未来 Kubernetes 所有的应用平台可能都需要一个策略引擎的存在,帮助用户处理不同场景下对数据的操作策略。 4. 构建于 IaD 之上的最终用户体验层 需要注意的一点是,虽然 Infrastructure as Data 会成为应用层的主流技术,但是它有一个“硬伤”,就是对最终用户并不友好。因为人的大脑比较容易去处理流程化的、规则化的事情,而不是去处理一个静态的数据,所以说在 IaD 之上会有一层面向最终用户的体验层的存在。这就意味着 Kubernetes 不会把声明式的数据直接交给最终用户,而是通过其他方式来操作这些数据,比如通过一种能够理解 Kubernetes 数据模型的动态配置语言(DSL)来完成,或者通过基于 API 对象的 CLI 或者 dashboard 来完成,也可能是通过一种以应用为中心的交互与协作流程来完成。而最终用户体验层会决定产品有没有黏性,这是云原生的这套体系有没有黏性,是不是用户友好的一个关键环节。 5. DevSecOps 随着如前所述的下一代 DevOps 体系的发展,安全会从一开始就变成应用交付的一部分。在业界大家称之为 DevSecOps ,就是从 day zero 开始就把安全策略、对安全的考量、安全配置作为应用的一部分,而不是等到应用交付出去了甚至应用已经上线了再去做事后的安全审计和管理。 底层基础设施的 Serverless 云原生化 随着云原生体系的发展,云的价值逐渐走向应用层,不断向基于声明式 API 、基于 IaD 的理念去发展,那么下层的基础设施也会发生相应的变化。第一个变化是基础设施能力声明式 API 化、自助化。今天的云是基础设施能力的集大成者,可以认为是一个无限的能力层,今天我们能想象到的基础设施上所有的能力,云都可以提供,这跟以前的基础设施完全不一样。以前云的能力很薄弱,基础设施的能力也很薄弱,所以才需要一个庞大的中间件体系和精密的 DevOps 体系来做一个“胶水层”,去弥补基础设施跟应用、研发、运维人员之间的鸿沟。 而未来,应用才是整个云原生生态的主角。应用需要使用某个能力,那么云就会提供这个能力,并且是通过一个标准化的接入层来提供,而不是直接跟基础设施打交道。云原生生态的发展会使得用户侧的视角发生很大的改变,从面向基础设施变为面向应用,从基础设施有什么用户才能用什么,变成用户要什么,基础设施就可以提供什么。以应用为中心的基础设施会是未来基础设施的一个基本形态。 这个理念跟 Serverless 理念非常类似,我们可以将它称为底层基础设施的 Serverless 原生化,这意味着基础设施会在未来也逐渐的声明式 API 化,而声明式 API 化带来的一个直接结果就是他会变成一个自助化的基础设施。 另外,由于基础设施能够实现声明式 API 化,实现自助化,那么打造更加智能化的基础设施就成为一个重要方向。因为基础设施系统的模块化能力变成了一个数据化的定义方式,那么就可以和容易的通过监控数据、历史数据来驱动基础设施的运转,也就是“自动驾驶的基础设施”。数据驱动的智能化基础设施会在未来成为可能,当然其前提是基础设施本身实现声明式 API 化和自助化。 与此同时,由于应用层本身会 Serverless 泛化,像 “scale to 0” 和 “pay as you go” 这些功能,会成为应用的一个基础的假设,导致资源层也会走向极致弹性+无限资源池的方向。作为一个智能化的基础设施,可以去做更加智能的调度与混部,从而提供极致的资源利用效能,实现成本的极低化。 与此同时,由于要实现极致的资源效能,就意味着底层一定是一个强多租架构,并且这个强多租架构是面向 Kubernetes 的,跟 Kubernetes 有一个天然的、非常融合的集成。这体现在两个方面:第一,在运行时这一层,这个基础设施会倾向走基于硬件虚拟化的容器运行时而非传统虚拟机的方向,比如 Kata Container ,并且认为神龙裸金属服务器更适合做宿主机。伴随着这套技术的发展,轻量化的 VMM(虚拟化管理技术)会成为优化容器运行时、优化整个基础设施敏捷度的一个关键技术和关键链路。 第二,强多租的控制面会针对不同租户做物理隔离,而不只是逻辑隔离,这是 Kubernetes 数据模型的要求,即租户的控制面板之间需要有强的物理隔离,这就是为什么我们讲未来的强多租架构一定会面向 Kubernetes 来构建。阿里内部也是看到了这样的趋势,在不断做一些尝试,去更好地响应未来 Serverless 原生化的基础设施的发展趋势。 另外,我们团队正在招聘2021年毕业的应届生,欢迎各位同学加入我们: 简历投递:yaowei.cyw@alibaba-inc.com 邮件标题:云原生-岗位名称 详情可点击查看: https://mp.weixin.qq.com/s/aMGMme2-p296798wlGQQfQ 。 “ 阿里巴巴云原生 关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”
「深度学习福利」大神带你进阶工程师,立即查看>>> 引语 IM ( Instant Messaging )是网络上最流行的通信方式,与日常生活息息相关。IM软件也层出不穷,例如:微信、QQ、易信等。通过多年深耕和技术沉淀,云信产出了一套成熟稳定的IM SDK架构。它提供了IM的主要功能,大大降低了第三方实现IM功能的难度。本文主要对IM接口设计实践展开论述。 1 对外接口的设计准则 SDK对外提供接口设计的基本原则是易用,易懂,易扩展,易监控。展开来可归纳为以下几个特性: API 按照业务功能分类,但所有业务具有统一的调用风格。 API 不包含方法实现,接口的实现对调用者隐藏。 API 调用可跟踪。 在功能形式上,SDK需要提供以下类型的API: 功能接口:主动调用使用其提供的功能 同步接口:在调用线程完成函数调用,并立即返回结果。 普通异步接口:在后台线程完成函数调用,可以添加回调函数。 可中断异步接口:在后台线程完成函数调用,可以添加回调函数,可以中断调用。 回调接口:监听数据和状态改变。 2 业务的分类 SDK包含多种业务,一部分是基础业务,另一部分是可选业务。比如用户认证服务、群服务等是基础业务;超大群服务、第三方推送服务等是可选业务。另外,不同的业务之间难免有相似的功能,如群服务和超大群服务中,都有添加群成员,拉取群消息等功能。因此,需要将不同的业务进行隔离,一方面方便业务功能的扩展与调整,另一方面方便函数的命名与用户的理解。 同一个业务下有多个API,按照调用的主动性,分为回调接口和功能接口,分别放在与业务一一对应的接口类Observer和Service中。例如:用户认证服务下的所有回调接口和功能接口都位于AuthServiceObserver和AuthService中。其中由用户主动调用来实现功能的功能接口在AuthService中,如登录、登出等;而用于注册回调的回调接口都在AuthServiceObserver中,如监听在线状态、监听数据同步等。 每个Service中的功能接口根据执行的性质又分为三种,同步接口、普通异步接口和可中断异步接口。其中同步接口在调用线程立即执行;异步接口在后台线程执行,在调用线程返回可设置回调的InvocationFuture类型,最终结果在主线程回调;可中断异步接口和普通异步接口相似,但是返回的是继承自InvocationFuture的AbortableFuture类型,支持中断操作,用户可以通过主动调用来中断功能接口的执行。接口调用的线程切换流程如图2.1所示,业务功能和接口的分类如图2.2所示。 图 2.1 接口调用的线程切换流程 图 2.2 业务功能和接口的分类 3 API 的实现 3.1 API 的实现方式 为了实现这些目标,并考虑到实现简单,我们选用Java的动态代理类模型。外部调用者调用API时,得到一个动态代理(Proxy)对象,通过Proxy对象,将功能接口的调用全部转接到一个实现了InvocationHandler 接口的类ProxyHandler上。再根据调用方法,执行注册/注销回调或者将调用请求分派到真正的实现类上,最后根据接口的返回类型进行返回或回调,如图3.1所示。 图 3.1 功能调用流程 和用户服务的接口类AuthService和AuthServiceObserver一样,SDK也为其他的所有业务定义了接口类。所有接口类和实现类呈一一对应关系,可以方便地找到API对应的实现。 3.2 获取 Proxy 对象的方法 SDK对外提供了静态方法NimClient.getService(Class clazz)来获取业务接口类对应的动态代理类。参数填入对应的接口类即可。例如:获取用户认证服务的接口类的方式为NimClient.getService(AuthService.class),获取用户认证服务观察者的接口类的方式为NimClient.getService(AuthServiceObserver.class)。 NimClient.getService方法同步返回一个Proxy对象。该对象的构造方式为懒加载,业务被调用的时候才构造对应实例。如图3.2所示。 图 3.2 获取业务 Proxy 对象流程 生成Proxy对象基于Proxy.newProxyInstance方法,所有生成的Proxy对象都由专门的容器类来管理。以用户认证服务为例,第一次调用NimClient.getService(AuthService.class)获取用户认证服务的Proxy对象时,容器理类创建一个对应的Proxy对象并缓存。之后再次获取用户认证服务Proxy对象时,容器类将缓存直接返回。 3.3 事务跟踪类 invoke函数中有一个重要的事务跟踪类(Transaction),它记录了方法的同步异步属性、方法体和返回值要求等。Transaction对象和他的实现方法是一一对应的。每次执行invoke方法,都会创建一个Transaction实例,并传输到真正的执行点去执行 执行完毕后, invoke 方法根据同步异步特性以及返回值,来确定功能函数的返回结果。如果是同步函数,则直接返回结果;如果是异步函数,则根据业务需求返回 InvocationFuture 或者 AbortableFuture 。 3.4 API 的执行方式 NimClient.getService返回的是动态代理类ProxyHandler ,它实现了InvocationHandler接口的 Object invoke(Object who, Method method, Object[] args)方法,用于代理所有功能接口。 API执行方式,即ProxyHandler对invoke方法的实现方式,其大体步骤是加载事务、初始化判断、执行事务和返回,如图3.3所示。 图 3.3 代理执行的简要流程 执行事务这一环节还可以细分为回调接口的执行和功能接口的执行,如果是执行回调接口,则判断是否需要回调当前状态,如果是,则立即回调。 Transaction的执行函数是TransactionExecutor. execute方法,送出Transaction后,invoke方法会根据同步异步属性,决定是在当前线程执行,还是在后台线程执行。用于异步执行Transaction的 后台线程是唯一的 ,如果有多个Transaction需要被异步执行,则会阻塞。 接口类的每个方法都被存进一个Map中,SDK以方法签名实现了同名函数重载。执行Transaction时,通过方法所在的接口类找到对应的实现类,再调用对应的invoke方法即可。对于异步方法,invoke方法的返回值不会被返回到上层,因此异步API函数的实现不用关心返回值。代理的详细执行流程如图3.4所示 图 3.4 代理的详细流程 3.5 异步方法的回调 对于异步方法,在TransactionExecutor. execute执行前,先基于Transaction生成对应的AbortableFuture的实现类TransactionFuture,然后将其缓存,用于稍后的回调。异步方法执行完毕后,将子类返回到调用层。 在调用可中断异步接口后,同步返回的是AbortableFuture实例。调用方可以直接调用abort方法中止执行。例如:调用了用于下载消息附件的downloadAttachment函数后,由于文件太大,网络状况不好等情况需要取消下载时,可以主动调用abort方法来终止。调用方式如图3.5所示。可中断异步接口对应的abort方法由SDK内部实现,调用者不需要关心其实现方式。 图 3.5 abort 函数调用示例 TransactionFuture回调的基本类型为RequestCallback,SDK在此基本类型中定义了onSuccess、onFailed和onException函数,分别用于在成功、失败和异常情况下根据执行结果的不同,回调到不同的函数。到此整个流程结束。 4. 总结 云信IM中,用户可以通过NimClient.getService方法选择业务的动态代理,然后根据业务需求在调用线程或者后台线程执行功能,最后直接返回或者回调结果。如果调用的是可中断异步接口,用户还可以中断操作。基于动态代理的实现方式,隔离了其他业务下的对外接口,并解耦了接口和实现,配合代码混淆,更进一步的提升隔离效果。 了解 网易云信IM即时通讯 >>> 了解 网易云信 ,来自网易核心架构的通信与视频云服务>> 更多技术干货,欢迎关注vx公众号 “网易智慧企业技术+” 。系列课程提前看,精品礼物免费得,还可直接对话CTO。 听网易CTO讲述前沿观察,看最有价值技术干货,学网易最新实践经验。网易智慧企业技术+,陪你从思考者成长为技术专家。
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文作者:y****n 票据反复上传,报销周期长,这样的理赔体验在保险行业十分常见。很显然,线上业务的激增与业务处理技术的不匹配,是目前保险行业面临的共同考验。 尤其是像泰康保险集团(以下简称“泰康保险”)这样的综合性大型保险公司,个人客户超6000万人,企业客户超42万家,每天需要处理大量的理赔案件。智能化成为泰康保险提升业务效率,降低运营成本,提升用户体验的最好助力。 作为业务智能化的先行者,泰康保险目前已经拥有人脸识别平台、文字识别平台、语音分析平台等6大人工智能平台,全面为公司业务场景提供智能化服务。 以财务共享中心为例,泰康保险借助百度智能云技术能力,财务共享中心效率提升110%,实现了8类票据类型的智能化识别,票务覆盖面高达99.2%,业务处理效能显著提升。 现在,泰康保险业务智能化实践又有新动作,泰康保险与百度智能云合作,将百度OCR技术应用于理赔业务,并以key-value的方式输出结构化结果,解决百万级不同模版的医疗理赔票据结构化场景,释放员工潜力,并为客户带来智能化理赔新体验。 理赔流程长 客户体验不佳 走过保险理赔流程的人都知道,保险理赔是一个严苛而复杂的过程。而且全国3万多家医院,票据各有不同,更是增加了理赔难度。 为了防止和降低骗保概率,保险公司受理被保险人的理赔申请时,一般要求提供较为详细的理赔文档材料。被保人需要提交医疗发票、结算清单、费用清单、费用收据和影像报告单等共计40多类的单据,然后保险理赔人员将资料信息录入到IT系统,最终形成电子记录文档。 但在资料提交阶段,常常由于客户对流程不熟悉,出现所提交的理赔资料残缺、资料不全等现象。等到了理赔受理阶段,理赔审核人员就需要来回审核补单,耗时耗力,最终导致理赔周期被拉长,严重影响客户体验。 此外,对于保险公司来讲,随着理赔业务量的增加,公司每年需要投入几十万元甚至上亿元的补贴到理赔业务,增加了运营成本。 想要改善理赔流程,对客户资料上传过程的实时反馈以及票据的准确识别是两大关键。 解决票据识别关键瓶颈,高效理赔 随着业务不断发展,泰康保险理赔部门面临人效成本增加的挑战。因此,泰康保险迫切期望解决理赔中票据识别的关键瓶颈问题,提高整体理赔时效,降低公司成本,进而提高用户满意度。 百度OCR技术识别速度快,总体识别准确率高,借助该技术,泰康保险实现了票据模糊、倾斜、翻转、内容重叠、信息串行等情况的优化。以褶皱、倾斜文本的矫正为例,百度OCR技术基于字段中心线的K-V对抽取和基于表格线检测的文档线抽取,轻松完成文档矫正,准确又快捷。 综合来看,医疗保险理赔智能化为泰康保险带来的价值主要体现在两方面:在降低问题件比率方面,通过上线理赔影像分类与质检能力,在客户上传的过程中提示客户影像缺失、不清晰等问题,辅助客户完成理赔资料的上传;在提升录入效率方面,通过对理赔资料的结构化解析,减少理赔人员的手工录入内容,让理赔人员由录入转为复核,极大的提升理赔效率。 以费用录入清单为例,以前人工录入一张单据40分钟才能完成,采用百度智能云智能化解决方案后,10分钟之内就能完成,采集能效提升了4倍。 通过百度OCR技术,泰康保险不仅实现了理赔票据的结构化信息提取,结合理赔业务及政策需求,还构建了泰康医疗保险知识体系,实现了智能化理赔业务的升级。 未来,智能化理赔流程全覆盖 目前泰康保险智能理赔项目已经完成一期建设,主要实现门诊发票、住院发票、费用清单、结算单、病案首页、出院小结、住院小结等7大类医疗影像,已覆盖全国31个地区,3万多家医院。 而且随着技术的升级,百度智能云智能理赔解决方案还将应用于智能控费、智能结算以及自动化结案,协助泰康保险实现理赔全流程的智能化升级,届时,几个人完成上千万的理赔将成为可能。 针对百度智能云的技术能力,泰康保险项目经理表示, “百度智能云拥有先进的产品、技术和丰富的解决方案,具备为客户提供领先的人工智能、大数据和云计算的服务能力。尤其是在保险行业,百度智能云创造了诸多经典案例,这些是我们十分看重的。” 而此次泰康基于百度OCR技术实现智能化医疗保险理赔,无疑又是一次经典案例。实际上,在OCR技术方面,除了成熟模型以外,百度还推出了OCRMind产品,百度OCRMind是基于百度机器学习基础开发平台(BML)推出的OCR训练平台,能够满足多种场景下的OCR识别与训练需求。 医疗理赔智能化的最终目的是提升理赔全流程的服务能力,让用户在方便快捷的同时,感受到更有温度的理赔服务。 未来,双方还将基于人工智能技术,在慢病管理、客户健康画像、医学知识编码等方面展开更多合作,实现保险全面智能化升级。 原文链接地址: https://developer.baidu.com/topic/show/290942
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文作者:y****n 7月12日6时38分在河北唐山市古冶区发生5.1级地震,成都高新减灾研究所与应急管理部门联合建成的大陆地震预警网成功预警该地震,给唐山市提前3秒预警,给天津市提前33秒预警。该地震是大陆地震预警网自2011年以来连续成功预警的第57次破坏性地震。 震中附近地区开通了地震预警功能的手机、电视、互联网电视和手机APP用户等提前收到地震预警信息,一些北京、天津民众提前30秒收到预警。值得关注的是,百度人工智能技术也应用到此次的快速地震预警中,百度地图的烈度速报图和人口热力图在其中发挥作用。 四川省地震预警重点实验室主任、成都高新减灾研究所所长王暾表示,我国高度重视灾害预警工作,在各级党委和政府的领导下,自汶川余震区发展的具有我国完全自主知识产权的我国地震预警成果,其系统平均响应时间、盲区半径、震级偏差等关键核心技术均优于日本,处于世界领先水平。 人工智能也在提升地震灾害预警的能力。王暾表示此次唐山5.1级地震预警得益于百度人工智能的赋能,是百度与减灾所合作推进的“人工智能+灾害预警”的合作成果。本次预警过程也应用了百度地图形成了烈度速报图+人口热力图。2020年5月20日,百度宣布与成都高新减灾研究所签署合作协议,以人工智能、云计算等技术赋能灾害预警,布局面向未来的多灾种监测预警产业,赋能应急管理,打造智慧城市。 人工智能将有效助力减灾所灾害监测和预警各环节更快、更准。 一方面,人工智能能够代替人力快速进行大量的数据分析,大大提高数据处理速度。另一方面,对于预警信息的传递,人工智能技术能够帮助产出更优的预警信息,并选择更好的渠道进行高效传递。此外,灾害的发生往往会引起灾害链,人工智能可以帮助打通不同灾害之间的灾害连锁预警,为避险争取时间。 据悉目前成都高新减灾研究所也正在和百度系产品推进合作。灾害发生时,帮助老百姓提早预警、防范风险。 备注: 地震预警不是地震预报,地震预报是对未来的地震提前发出警报,是还未解决的科技难题。地震预警的技术已成熟,它是基于电波比地震波快的原理,利用地震传感器及相关技术系统建立的地震预警网,在破坏性地震发生时,全自动地提前几秒到几十秒在目标区域对还未受波及的用户发出预警的行为,能够减少人员伤亡和次生灾害。 原文链接地址: https://developer.baidu.com/topic/show/290940
「深度学习福利」大神带你进阶工程师,立即查看>>> 本文作者:y****n 新基建浪潮下,人工智能等前沿技术正在成为提升产业发展和城市治理能力的新抓手。 7月11日,2020世界人工智能大会云端峰会签约与发布活动上,上海市浦东新区人民政府与百度签署战略合作框架协议。双方将发挥各自优势,共同探索人工智能技术在实体经济中的创新应用,推进全国首个百度飞桨人工智能产业赋能中心在浦东新区的落地,加速城市新一代智能管理,共同打造城市智能化升级新范本。 浦东新区副区长管小军,百度副总裁、智慧城市事业部总经理刘雅雯代表双方签约,上海市委副书记、代市长龚正见证签约。 管小军表示,浦东新区已经驶入人工智能发展的快车道,拥有的雄厚产业基础、丰富的应用场景和集聚的科创资源,是上海人工智能发展整体布局规划的强有力支撑。此次和百度展开合作,将借助百度在人工智能领域的技术优势,进一步推动人工智能和实体经济的融合创新,加快浦东及上海的产业升级和城市建设。 刘雅雯对此次合作充满期待。她表示,作为国内人工智能领军企业,百度拥有众多具备自主知识产权的人工智能核心技术,以及丰富的产业实践经验。当下新基建加速发展,百度愿与浦东新区一起抓住这轮机会,释放人工智能技术驱动力,协助浦东打造城市智能经济,提升城市治理智能化水平,促进城市的长久繁荣。 根据协议,浦东新区与百度的合作将从三方面展开。在创新合作层面,双方将在人工智能芯片、算法、操作系统等领域进行共同创新,促进人工智能技术和实体经济深度融合,推新一代人工智能产业创新应用。 项目落地层面,全国首个百度飞桨人工智能产业赋能中心将在浦东落地运营,基于自主知识产权的开源深度学习平台,助力浦东新区打造中国芯、蓝天梦、创新药、未来车、智能造、数据港等硬核产业,构建世界级产业集群。 在智能提升方面,双方将依托百度在数据、技术、生态方面的优势,共同推进智能化的城市治理能力和治理体系建设。 当下的新基建浪潮中,人工智能为城市建设和管理的升级转型带来新思路,城市管理者纷纷借助自主可控、场景驱动、产业融合的人工智能能力打造城市发展新动能。 浦东新区是上海人工智能先发区域,在人工智能企业集聚、技术研发、应用落地、产业生态建设等方面有较好基础,在制度创新方面也取得了积极进展。2019年5月,工业和信息化部复函上海市人民政府,支持建设上海(浦东新区)人工智能创新应用先导区,通过开展人工智能创新应用先导区的建设,将进一步加速上海人工智能技术——产业迭代,探索创新应用新模式,积累融合发展新经验,打造产业集聚发展新高地。 百度是国内最早投入、技术最强、布局最完整的人工智能领军企业,正在依托全栈、领先的人工智能技术能力打造新型AI技术基础设施,比如,技术体系完整、国内服务规模最大的百度大脑AI开放平台,拥有核心自主知识产权的“智能时代操作系统”飞桨深度学习平台, AI Cloud中国排名第一的百度智能云,自主可控的人工智能芯片、数据中心等。尤其值得关注的是,作为国内首个自主研发、开源开放、功能完备的深度学习平台飞桨,它让应用人工智能技术的门槛更低、成本更少、效率更高,对于推进自主可控的人工智能产业发展具有重要意义。 此外,在2020世界人工智能大会上,百度文心(ERNIE)知识增强语义理解技术与平台获颁大会最高奖项SAIL奖,百度人工智能技术领军实力再获认可。 基于全面、领先的人工智能布局,百度正在推进人工智能与产业深度融合,加速智慧城市、智能交通、智慧能源、智慧金融、智能客服与营销、智能办公、智慧医疗、智能汽车、工业互联网和智能制造等领域的产业智能化升级。 在智慧城市方面,百度城市大脑已经在多个城市和机构落地应用,赋能公共安全、应急管理、智能交通、城市管理、智慧教育等场景。 例如,在北京海淀区,百度智慧城市全力参与了海淀“城市大脑”建设,帮助海淀区发现和提炼城市潜在的运行规律,提供全局协同的决策依据支持管理与服务。比如在渣土车综合治理中,实现对渣土车精准识别,每天处理100万张过车数据,高峰时期发现渣土车9000多辆,识别准确率95%,行驶轨迹预测准确率超60%,全面提升渣土车管理能力,有效解决了渣土污染问题。 此外,2020年,百度与国家应急管理部门合作的自然灾害风险预警能力在四川、山西、西藏等林火救援指挥现场信息决策支持中发挥了积极作用。 此次创新产业聚集地浦东与人工智能领军企业百度强强携手,相信在不久的未来,人工智能将像水和电一样,融入浦东的城市和产业中,助力城市从智能化向智慧化发展,让城市更安全、更从容、更通畅、 更宜居,为中国城市的“AI新基建”打造一个新样本。 原文链接地址: https://developer.baidu.com/topic/show/290939
「深度学习福利」大神带你进阶工程师,立即查看>>> 快递100云平台高可用容灾框架 云平台高可用容灾框架,系统设计无论是从网络层->应用->存储,都采用高可用框架设计,给服务实现快速可靠的服务保障。 网络层,云平台使用异地容灾机制,在异地使用 XenServer 搭建私有云主机,两地机房通过专线隧道连接。通过企业防火墙进行物理硬件安全保障下层应 用,为应用层提供高可用的硬件支持。 应用层设计 云平台应用设计使用目前主流的微服务化框架设计: 前置服务:使用 LVS+Nginx 实现高可用负载均衡服务; 应用服务:使用 Jekenis +K8S+Docker ,实现微服务自动化扩容部署,利用高效开源组件实现统一配置中心,高效消息通讯。 存储层面:系统使用 Oracle 进行数据存储,使用 DG 信息数据库层容灾, 使用 Redis 集群实现应用中间缓存处理,利用 ES 集群进行数据操作采集分析等。
「深度学习福利」大神带你进阶工程师,立即查看>>> 本节,我们通过一些简单的例子来演示 Deployment 的创建、查看、更新、删除等操作,以期快速地掌握 Deployment 的用法。 创建 首先我们先将以下配置保存到名为 deployment.yaml 的文件中。 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.19.0 该份配置将创建一个名为 nginx-deployment 的 Deployment 资源对象,根据 spec.replicas 中的信息可知,它期望有3个Pod副本。 接下来使用 kubectl create 命令将该配置提交给 kube-apiserver ,如下所示: [root@ecs-d8b6 manifests]# kubectl create -f deployment.yaml deployment.apps/nginx-deployment created 根据命令行输出内容可知,名为 nginx-deployment 的 Deployment 已创建完成。 查看 当创建一个 Deployment 资源对象时, Deployment 控制器不会直接创建Pod,而是通过创建 ReplicaSet 来间接创建Pod。 查看Deployment 查看新创建的 Deployment 资源: [root@ecs-d8b6 manifests]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 90s 命令行输出中各字段含义如下: NAME: Deployment 资源名称,同配置中的 metadata.name ; READY:<已处于Reday状态的Pod数量>/<期望的Pod数量>; UP-TO-DATE:处于最新状态的Pod数量; AVAILABLE:可用的Pod数量; AGE:应用运行时间,也是资源自创建至今经过的时间。 此处 READY 和 AVAILABLE 有一些细微的区别,当 Pod 中指定的容器全部运行起来后,就可以认定该 Pod 为 READY ,所以 READY 含义更倾向于 Running ,而 AVAILABLE 要求会更严格一些,只有当 Pod 处于 READY 状态且持续一段时间后才可被认定为 AVAILABLE ,其含义更倾向于 可用 的数量。 UP-TO-DATE 表示运行最新配置的Pod数量,当修改 Deployment 配置中Pod模版时,新版的Pod会被创建且短期内会与旧版的Pod并存, UP-TO-DATE 正是表示已创建的新版Pod数量。 查看ReplicaSet 接着查看ReplicaSet: [root@ecs-d8b6 manifests]# kubectl get replicaset NAME DESIRED CURRENT READY AGE nginx-deployment-6fd78f555b 3 3 3 104s 由 Deployment 创建的 ReplicaSet 名称由 Deployment 的名称和一个随机字符串组成。 查看Pod 接着查看最终生成的Pod: [root@ecs-d8b6 manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-6fd78f555b-clf9w 1/1 Running 0 110s nginx-deployment-6fd78f555b-vlvp6 1/1 Running 0 110s nginx-deployment-6fd78f555b-wjslg 1/1 Running 0 110s 这些Pod都是由 ReplicaSet 自动创建出来的,其名称由 ReplicaSet 名称和一个随机字符串组成。 更新 由于 Deployment 控制器通过 ReplicaSet 来创建并管理Pod,当修改 Deployment 配置中的 spec.replicas 时, Deployment 控制器相应地也会修改 Replicaset 中 spec.replicas 值,最终由 Replicaset 控制器来调整Pod的副本数,该部分功能我们已经在介绍 ReplicaSet 时演示过,此处不再演示。 我们在此演示一种 Deployment 相较于 ReplicaSet 更高阶的功能,即应用版本的升降级。当前应用使用的nginx镜像版本为 1.19.0 ,我们希望把该版本降为 1.18.0 。 通过以下命令,将 spec.template.spec.containers.image 值由 nginx:1.19.0 改为 nginx:1.18.0 : [root@ecs-d8b6 manifests]# kubectl edit deployments nginx-deployment 然后再次查看 Deployment 、 ReplicaSet 和 Pod : [root@ecs-d8b6 manifests]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 33m [root@ecs-d8b6 manifests]# kubectl get replicaset NAME DESIRED CURRENT READY AGE nginx-deployment-6fd78f555b 0 0 0 33m nginx-deployment-7df9bc6ff5 3 3 3 32s [root@ecs-d8b6 manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-7df9bc6ff5-4rz8l 1/1 Running 0 40s nginx-deployment-7df9bc6ff5-tmxwl 1/1 Running 0 44s nginx-deployment-7df9bc6ff5-vmdzp 1/1 Running 0 42s 可以看到,之前的 ReplicaSet (nginx-deployment-6fd78f555b)副本数已被修改为0,新的 ReplicaSet (nginx-deployment-7df9bc6ff5)被创建了出来,进而创建了新的Pod。新的Pod中运行的容器镜像版本就是我们修改后的容器镜像版本,读者可以自行验证。 删除 当删除 Deployment 资源时,由 Deployment 控制器创建的 ReplicaSet 也会被删除,因此由 ReplicaSet 创建的Pod也会被删除。 [root@ecs-d8b6 manifests]# kubectl delete deployment nginx-deployment deployment.apps "nginx-deployment" deleted [root@ecs-d8b6 manifests]# kubectl get replicaset No resources found in default namespace. [root@ecs-d8b6 manifests]# kubectl get pods No resources found in default namespace.
「深度学习福利」大神带你进阶工程师,立即查看>>> A记录 A记录是用来创建到IP地址的记录。在命令行下可以通过nslookup -qt=a www.ezloo.com来查看A记录。 A记录设置技巧 1、如果想创建不带www的记录,即ezloo.com,在主机记录中填写@或者留空,不同的注册商可能不一样。 2、创建多个域名到同一个IP,比如给博客建了二级域名,可以使用*.blog.ezloo.com来指向一个IP,这样的话,不管是访问a.blog.ezloo.com还是b.blog.ezloo.com都能到同一个IP。 3、如果你给同一个二级域名设置了多个A记录,比如你建了两个blog的A记录,其中一个指向了111.111.111.111,另一个指向了111.111.111.112,那么在查询的时候,每次返回的数据包含了两个IP地址,但是在返回的过程中数据排列的顺序每次都不相同。由于大 部分的客户端只选择第一条记录所以通过这种方式可以实现一定程度的负载均衡。 MX记录 在命令行下可以通过 nslookup -qt=mx ezloo.com 来查看MX记录。 mx 记录的权重对 Mail 服务是很重要的,当发送邮件时,Mail 服务器先对域名进行解析,查找 mx 记录。先找权重数最小的服务器(比如说是 10),如果能连通,那么就将服务器发送过去;如果无法连通 mx 记录为 10 的服务器,那么才将邮件发送到权重为 20 的 mail 服务器上。 这里有一个重要的概念,权重 20 的服务器在配置上只是暂时缓存 mail ,当权重 20 的服务器能连通权重为 10 的服务器时,仍会将邮件发送的权重为 10 的 Mail 服务器上。当然,这个机制需要在 Mail 服务器上配置。 CNAME记录 在命令行下可以使用nslookup -qt=cname a.ezloo.com来查看CNAME记录。 CNAME记录也成别名记录,它允许你将多个记录映射到同一台计算机上。比如你建了如下几条记录: a1 CNAME a.ezloo.com a2 CNAME a.ezloo.com a3 CNAME a.ezloo.com a A 111.222.111.222 我们访问a1(a2,a3).ezloo.com的时候,域名解析服务器会返回一个CNAME记录,并且指向a.ezloo.com,然后我们的本地电脑会再发送一个请求,请求a.ezloo.com的解析,返回IP地址。 当我们要指向很多的域名到一台电脑上的时候,用CNAME比较方便,就如上面的例子,我们如果服务器更换IP了,我们只要更换a.ezloo.com的A记录即可。 XT记录 在命令行下可以使用nslookup -qt=txt a.ezloo.com来查看TXT记录。 TXT记录一般是为某条记录设置说明,比如你新建了一条a.ezloo.com的TXT记录,TXT记录内容“this is a test TXT record.”,然后你用 nslookup -qt=txt a.ezloo.com ,你就能看到“this is a test TXT record”的字样。 除外,TXT还可以用来验证域名的所有,比如你的域名使用了Google的某项服务,Google会要求你建一个TXT记录,然后Google验证你对此域名是否具备管理权限。 AAAA记录 AAAA记录是一个指向IPv6地址的记录。可以使用nslookup -qt=aaaa a.ezloo.com来查看AAAA记录。 NS记录 NS记录是域名服务器记录,用来指定域名由哪台服务器来进行解析。可以使用nslookup -qt=ns ezloo.com来查看。 TTL值 TTL=time to live,表示解析记录在DNS服务器中的缓存时间。比如当我们请求解析www.ezloo.com的时候,DNS服务器发现没有该记录,就会下个NS服务器发出请求,获得记录之后,该记录在DNS服务器上保存TTL的时间长度。当我们再次发出请求解析www.ezloo.com 的时候,DNS服务器直接返回刚才的记录,不去请求NS服务器。TTL的时间长度单位是秒,一般为3600秒。
「深度学习福利」大神带你进阶工程师,立即查看>>> 什么是传输编码? 传输编码在 HTTP 的报文头中,使用 Transfer-Encoding 首部进行标记,它就是指明当前使用的传输编码。 Transfer-Encoding 会改变报文的格式和传输的方式,使用它不但不会减少内容传输的大小,甚至还有可能会使传输变大,看似是一个不环保的做法,但是其实是为了解决一些特殊问题。 简单来说,传输编码必须配合持久连接去使用,为了在一个持久连接中,将数据分块传输,并标记传输结束而设计的,后面会详细讲解。 在早年间的设计里,和内容编码使用 Accept-Encoding 来标记客户端接收的压缩编码类型一样,传输编码还需要配合 TE 这个请求报文头来使用,用于指定支持的传输编码。但是在最新的 HTTP/1.1 协议规范中,只定义了一种传输编码:分块编码(chunked),所以并不需要再依赖 TE 这个头部。 这些细节,后面都会讲到。既然传输编码和持久连接是息息相关的,那我们就先来了解一下什么是持久连接。 持久连接(Persistent Connection) 持久连接通俗来讲,就是长连接,英文叫 Persistent Connection,其实按字面意思理解就好了。 在早期的 HTTP 协议中,传输数据的顺序大致分为发起请求、建立连接、传输数据、关闭连接等步骤,而持久连接,就是去掉关闭连接这个步骤,让客户端和服务端可以继续通过此次连接传输内容。 这其实也是为了提高传输效率,我们知道 HTTP 协议是建立在 TCP 协议之上的,自然有 TCP 一样的三次握手、慢启动等特性,这样每一次连接其实都是一次宝贵的资源。为了尽可能的提高 HTTP 的性能,使用持久连接就显得很重要了。为此在 HTTP 协议中,就引入了相关的机制。 在早期的 HTTP/1.0 协议中并没有持久连接,持久连接的概念是在后期才引入的,当时是通过 Connection:Keep-Alive 这个头部来标记实现,用于通知客户端或服务端相对的另一端,在发送完数据之后,不要断开 TCP 连接,之后还需要再次使用。 而在 HTTP/1.1 协议中,发现持久连接的重要性了,它规定所有的连接必须都是持久的,除非显式的在报文头里,通过 Connection:close 这个首部,指定在传输结束之后会关闭此连接。 实际上在 HTTP/1.1 中 Connect 这个头部已经没有 Keep-Alive 这个取值了,由于历史原因,很多客户端和服务端,依然保留了这个报文头。 长连接带来了另外一个问题,如何判定当前数据发送完成。 判断传输完成 在早期不支持持久连接的时候,其实是可以依靠连接断开来判定当前传输已经结束,大部分浏览器也是这么干的,但这并不是规范的操作。应该使用 Content-Length 这个头部,来指定当前传输的实体内容长度。 下面举个例子,在保持持久连接的情况下,依赖 Content-Length 来确定数据发送完毕。 Content-Length 在这里起到了一个响应实体已经发送结束的判断依据。这样的情况下,我们就要求 Content-Length 必须和内容实体的长度一致,如果不一致,就会出现各种问题。 如上图所示,如果 Content-Length 小于内容实体的长度,则会截断,反之则无法判定当前响应已经结束,会将请求持续挂起造成 Padding 状态。 理想情况下,我们在响应一个请求的时候,就需要知道它的内容实体的大小。但是在实际应用中,有些时候内容实体的长度并没有那么容易获得。例如内容实体来自网络文件、或者是动态生成的。这个时候如果依然想要提前获取到内容实体的长度,只能开一个足够大的 Buffer,等内容全部缓存好了再计算。 但这并不是一个好的方案,全部缓存到 Buffer 里,第一会消耗更多的内存,第二也会更耗时,让客户端等待过久。 此时就需要一个新的机制,不依赖 Content-Length 的值,来判定当前内容实体是否传输完成,此时就需要 Transfer-Encoding 这个头部来判定。 Transfer-Encoding:chunked 前面也提到, Transfer-Encoding 在最新的 HTTP/1.1 协议里,就只有 chunked 这个参数,标识当前为分块编码传输。 分块编码传输既然只有一个可选的参数,我们就只需要指定它为 Transfer-Encoding:chunked ,后续我们就可以将内容实体包装一个个块进行传输。 分块传输的规则: 1. 每个分块包含一个 16 进制的数据长度值和真实数据。 2. 数据长度值独占一行,和真实数据通过 CRLF(\r\n) 分割。 3. 数据长度值,不计算真实数据末尾的 CRLF,只计算当前传输块的数据长度。 4. 最后通过一个数据长度值为 0 的分块,来标记当前内容实体传输结束。 在这个例子中,首先在响应头部里标记了 Transfer-Encoding: chunked ,后续先传递了第一个分块 “0123456780”,长度为 b(11 的十六进制),之后分别传输了 “Hello CxmyDev” 和 “123”,最后以一个长度为 0 的分块标记当前响应结束。 chunked 的拖挂 当我们使用 chunked 进行分块编码传输的时候,传输结束之后,还有机会在分块报文的末尾,再追加一段数据,此数据称为拖挂(Trailer)。 拖挂的数据,可以是服务端在末尾需要传递的数据,客户端其实是可以忽略并丢弃拖挂的内容的,这就需要双方协商好传输的内容了。 在拖挂中可以包含附带的首部字段,除了 Transfer-Encoding、Trailer 以及 Content-Length 首部之外,其他 HTTP 首部都可以作为拖挂发送。 一般我们会使用拖挂来传递一些在响应报文开始的时候,无法确定的某些值,例如:Content-MD5 首部就是一个常见的在拖挂中追加发送的首部。和长度一样,对于需要分块编码传输的内容实体,在开始响应的时候,我们也很难算出它的 MD5 值。 注意这里在头部增加了 Trailder ,用以指定末尾还会传递一个 Content-MD5 的拖挂首部,如果有多个拖挂的数据,可以使用逗号进行分割。 内容编码和传输编码结合 内容编码和传输编码一般都是配合使用的。我们会先使用内容编码,将内容实体进行压缩,然后再通过传输编码分块发送出去。客户端接收到分块的数据,再将数据进行重新整合,还原成最初的数据。 传输编码小结 我们对传输编码应该有一定的了解了。这里简单总结一下: 1. 传输编码使用 Transfer-Encoding 首部进行标记,在最新的 HTTP/1.1 协议里,它只有 chunked 这一个取值,表示分块编码。 2. 传输编码主要是为了解决持久连接里将数据分块传输之后,判定内容实体传输结束。 3. 分块的格式:数据长度(16进制)+ 分块数据。 4. 如果还有额外的数据,可以在结束之后,使用 Trailer 进行拖挂传输额外的数据。 5. 传输编码通常会配合内容编码一起使用。 此外,传输编码应该是所有 HTTP/1.1 的标准实现,应该都有支持,如果收到无法理解的经过传输编码的报文,应该直接返回 501 Unimplemented 这个状态码来回复即可。