阿里云服务-米姆科技官方网站 http://www.51mimu.com 广州米姆信息科技有限公司,深度服务阿里云用户,为用户提供产品及技术支持:云服务器ECS、数据库RDS、网站加速CDN、阿里云邮箱、对象存储OSS、阿里云企业邮箱、WAF防火墙、高防IP、企业短信等产品服务,为用户给予阿里云优惠折扣解决方案、阿里云沙龙及阿里云峰会、 免费云主机试用、阿里云促销优惠活动、代金券优惠等活动,让用户享受米姆服务中心阿里云全栈服务。,在线咨询电话:020-22822863 Sat, 04 Jul 2020 09:33:02 +0800 zh-CN hourly 1 https://www.s-cms.cn/?v=4.7.5 公司文化 Sat, 04 Jul 2020 09:33:02 +0800

目前米姆采用人性化管理及制度综合管理相结合的方式让企业管理效率最大化,目前我公司的管理制度,涉及到安全、流程、认证等各方面,各种制度健全合理,包含部分岗位流程SOP、销售服务准则、职能认证规范及要求等十数种程序文件。从各种制度的执行情况来看,各种制度制定的有效合理,能够有效地给予生产进行指导和员工行为规范的约束


   

米姆核心目标:

米姆立志并已致力成为全球领先的企业数字化转型一站式解决方案和营销一体化的服务提供商。价值观:技术创新、诚信合作、以人为本、服务企业员工:员工相互信任、尊重、积极向上,为员工提供更多的培训机会,鼓励员工技术与管理创新、分享知识与经验,为员工提供一个公平公正的可持续发展平台,为客户提供一个搞效率服务平台。
诚信:铸诚魂 弘商誉品质:品质第一 客户至上创新:持续创新 不断超越分享:整合资源 分享世界
]]>
米姆(MEME)科技简介 Sat, 04 Jul 2020 09:33:02 +0800        



        米姆信息科技专注企业IT服务,技术创新驱动的企业服务专家,主要开展网络安全、信息化建设、公有云服务、私有云建设、中台开发、等保测评、DevOps构建&应用、K8s&容器云搭建、云MSP服务、自动化运维等业务。目前已经在全国服务了超千家企业。



]]>
短视频程序近年来为何如此的受欢迎,都有哪些吸引人的功能? Sat, 04 Jul 2020 09:33:03 +0800 一说到短视频程序,相信大家都不陌生,它已经渗入到我们的生活中,当今的大众群体,无论80后90后,还是部分70后都有了刷短视频的习惯,去消磨自己的闲暇时光,很多软件公司也纷纷涌入开发。在开发短视频小程序之前首先要了解一个问题,为什么短视小程序能够如此受欢迎呢?有人会说好玩,那么短视频程序到底为何受欢迎,以及都有哪些吸引人的功能呢。下面为大家简单整理了几点原因。
直播1_副本.jpg

一、为何受欢迎
短视频的快速发展也带动了电商的复苏,也有些人发现了其中的商机,发现了短视频与电商相结合的模式,打开了短视频带货的大门,也为疫情当下的实体店铺和电商开辟了新路径。
内容丰富多元化,用户体验度高,能够分析大数据,根据大众的喜好喜欢去推送相关的内容信息,做到“私人订制”。打开短视频程序,无不有许多种类的短视频,唱歌、搞笑等其他有意思的,一个接着一个让人过不完的瘾。“搞笑”“正能量”“新闻”“长知识”等等内容,其中搞笑类的占据多数,不少用户本着寻个开心的想法都能在短短15秒的时间内得到满足。平台内容迎合大众喜爱,因此这是短视频深受大众喜爱的最关键原因。
能够解决碎片化时间需求,每个人每天都会有充足的碎片化时间,而这些碎片化时间基本上与无聊为伴,而短视频小程序能够提供有趣的内容,为观看者解决碎片化时间的需求。
直播2_副本.jpg

社会新风向,不管是哪个行业的兴起,都离不开借助社会环境这个重要因素,而政府一向都很支持文化创意产业的发展,所以短视频的兴起也成为了大势所趋。得到了政府和人民的支持,短视频也就等于获得了社会和大众的认可。
视频虽“短”,但粘性强。“短视频”不同于长视频甚至是专业的记录视频,小视频在时间上比较的短小,有的一般都在15秒,甚至10秒。这样的时间里展现的短小的视频,一般人浏览不会产生视觉疲劳,一个视频十几秒就过了,可以快速进入下一个新的视频里去。在以快节奏阅读的时代里,这种形式是比较让人接受,受到欢迎的。视频虽“短”,但有一定粘性,人们会不自觉的滑动屏幕长时间浏览。
好的短视频也是建立在功能实用性和多样化的基础上,所以说一款短视频程序的开发也缺少不了功能的实现,那么一款短视频小程序有什么功能呢?
直播3_副本.jpg

二、短视频小程序有什么功能?
  1、在线观看:用户可以直接通过小程序进行观看短视频的相关内容,只需要打开小程序就可以直接浏览。
  2、在线评论:当用户在浏览过程中,对于自己感兴趣的内容也可以发表相应的评论。
  3、在线发布:每一位用户既然视频的浏览者也可以是创作者,为了激励他们创作,平台会进行一定的奖励。
4、在线关注:为了第一时间获取自己想要浏览的内容,用户可以直接关注相应的创作者。
声明:以上内容为云豹科技作者本人原创,未经作者本人同意,禁止转载,否则将追究相关法律责任

]]>
数据中台模型设计系列(一):维度建模初探 Sat, 04 Jul 2020 09:33:03 +0800 前言:更多关于数智化转型、数据中台内容可扫码加群一起探讨
668d7f5941782665ed1f41529db3eb677f4b9379.png
阿里云数据中台官网 https://dp.alibaba.com/index


1、与几个概念的关系

操作型业务系统
对于这个概念大家都不陌生。企业业务赖以运转的交易系统就属于操作型业务系统。因此它是为了保障业务正常运转,能够更快的处理事务。

但是因为它是针对某一特定的意图(例如满足交易业务),它不需要承诺与其他业务系统共享公共数据。因此就出现了适合于企业中交叉应用的ERP、主数据系统。当然对于有建设业务中台的企业来说,基于微服务架构的各个服务中心,能更好的提供可复用统一的公共数据。

不管是面向业务的业务系统、经过数据统一后的主数据系统或者基于微服务架构的服务中心的数据,都是作为数据中台的数据输入源头。我们通过批量同步、归档日志采集等方式,能将数据采集进数据中台,作为ODS层原始数据的一部分。

ETL
英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。在ODS层的原始数据,需要通过加工处理后,才能进入到构建好的数据模型中。

在模型设计时,需要考虑ETL加工流程,根据逻辑判断,做模型的合理设计。同样对于下游使用数据模型的ETL元数据,也是作为模型设计的输入,可基于下游应用方式做模型的横向和纵向的拆分设计,这就是“元数据驱动模型设计”的理论来源。

因此,无法理解数据开发的模型设计师是不合格的。

数据应用
数据中台提供多种数据应用的形式,包括数据报表、智能数据产品等。将统一汇总加工后的数据或者明细原子数据提供给数据应用,为业务提供数据支撑。

更加合理的数据模型设计,能够给更宽泛的应用提供数据支撑,也能够让业务方更准确无疑义的使用好数据。

2、几种企业常见的建设现状

烟囱式
也许大家都不愿意承认,但是绝大部分的企业当前是没有统一、标准、公共、全局的模型设计的,而仅仅是把数据同步上来,然后基于业务需求做烟囱式的数据开发。这种方式也许从短期来看是效率最高的,但是从长期看,不仅仅造成计算存储资源的极大浪费、没有统一可用的数据、大量的重复性的工作。企业的数据就像一团乱麻,根本无法管理。

三范式+数据集市

一些传统大型企业,由于历史原因,原子数仓中以三范式的模型设计方式构建,在各个应用的数据集市中以维度建模方式构建。通过这种方式,在原子数据设计过程中,需要投入较大的资源。

对于业务来说,三范式模型太复杂,用户难以理解和检索。并且对于业务频繁变化的企业,模型的维护成本极高。

企业级维度模型

基于企业全局的角度去构建业务总线矩阵,在此基础上完成维度模型的设计,是当前众多企业选择的方向。从众多互联网企业的数据中台实践经验来看,这也是一个绝佳的各因素平衡后的选择。

后面,我们将从各个角度来思考如何基于维度模型构建企业级数据中台。

3、维度建模初探

优势
在数据中台建设经验中,企业级维度模型设计从理解性、扩展性、高性能上都是更适应当前的技术和业务环境的。

首先由于计算和存储成本逐步下降,模型更重要的变成了易于理解,当易用性放在模型设计的重要位置时,维度模型可理解的优势就显现出来了,维度建模一直就是以业务的视角来描述数据。

另外,当新的业务出现时,新的模型不会对已有模型形成冲击,可以无影响的产出新的模型数据。

维度建模会设计部分数据的冗余,通过冗余换来数据检索的高性能。对于数据量极具膨胀的今天,高性能给用户带来了高价值。

事实表

所谓的事实表,就是企业的业务过程事件的度量信息。例如对于支付这个业务过程来说,需要度量支付的商品数、金额等度量。因此,企业的业务过程数据以事实表的形式在模型中呈现出来。

事实表每行都对应了一个度量事件,每行数据是一个特定级别的细节数据。事实表中每个度量都必须是相同的粒度级别。

事实表中的度量的可加性也至关重要,因为业务方往往需要将事实表的数据基于某些维度进行汇总,在度量上需要能够做汇总累加。

事实表还是稀疏的,它仅仅会将发生的业务过程数据放入其中。
**
维度表**

维度表是事实表不可或缺的组成成分,它描述了事实表业务过程度量的环境。用于描述“谁、什么、哪里、何时、如何、为什么”有关的事件。

维度属性是作为查询约束、分组、标识的主要来源,因此它的好坏直接决定了数据的可分析性的差异。维度属性需要是可理解的,因此需要尽量避免“0,1”之类的代码,将代码翻译成更易理解的字符避免业务的误解。

同样,会有一些数值型的可作为维度属性。例如:也许有人会问商品标价适合在事实表还是维度表中?

当用于计算度量时,它应该存在于事实表中;但是当它用于做约束、分组、标识分析时,则需要存在于维度表中。在维度表中,我们往往会把连续的数据换成离散的数值存储,例如:将标价变为价格区间段。这是要根据对业务的理解做进一步设计的。

雪花模型与星型模型

所谓的雪花模型,是当有一个或多个维表没有直接连接到事实表上,而是通过其他维表连接到事实表上时,其图解就像多个雪花连接在一起,故称雪花模型。

而星型模型则是所有维表都直接连接到事实表上,整个图解就像星星一样,故将该模型称为星型模型。

雪花模型是对星型模型的扩展。

星型模型是一种非正规化的结构,多维数据集的每一个维度都直接与事实表相连,不存在渐变维度,所以数据有一定冗余。因为有冗余,所以很多统计不需要做外部的关联查询,因此一般情况下效率比雪花模型高。

但是从可理解性上看,雪花模型是更容易让业务理解的。因为业务可以从模型上看出维度与维度之间的关系。

因此如何平衡查询效率和业务理解?我们在后面的文章中再细细道来。

**总线矩阵
**
总线矩阵,维护的是企业的各个业务过程与一致性维度的关系。是以企业的高度实现的顶层设计。它的存在对于数据中台项目至关重要。

如果数据中台的模型设计就是一本书,那么总线矩阵就是这本书的目录,能从整体上对每个模型有统一的定义。

从项目协调上看,总线矩阵在大型项目中起到举足轻重的地位,整个项目组都能基于这个目录清晰的明白自己在做什么,别人已经做了什么,极大程度上的避免了信息沟通不畅导致的重复定义。

从项目管理上看,也可以基于总线矩阵对模型设计和开发进行有效的优先级排期。

最后,总线矩阵是共同业务人员和技术人员的桥梁,通过总线矩阵在项目沟通中达成一致的语言。

结语

通过这篇文章,初浅的对数据中台模型设计发表了一些观点。
在后面的章节中,我们将继续围绕模型设计的技术细节、结合行业的模型设计案例,和数据同仁们做进一步的分享和交流 。


数据中台是企业数智化的新基建,阿里巴巴认为数据中台是集方法论、工具、组织于一体的,“快”、“准”、“全”、“统”、“通”的智能大数据体系。目前正通过阿里云数据中台解决方案对外输出,包括零售金融互联网政务等领域,其中核心产品有:

官方站点:
数据中台官网 https://dp.alibaba.com
数据中台钉钉群二维码2.jpg


]]>
小白使用阿里云建网站三种方式(自助建站+模板建站+功能定制建站) Sat, 04 Jul 2020 09:33:03 +0800


使用阿里云建网站的三种方式购买云服务器手动建站、云速成美站模板建站或者选择阿里云定制建站三种方式,站长分享利用阿里云创建网站的三种方式及优势对比:


阿里云建站方法汇总


使用阿里云建站可以有三种方式,


第一种是购买ECS云服务器,然后自行手动搭建网站,需要技术门槛;


第二种方式是购买阿里云官网云速成美站,使用模板建站,阿里云提供上千套模板,模板建站价格便宜,会打字就会建站;


第三种是使用阿里云官方定制建站,需要什么样的网站什么功能,阿里云建站专家提供一对一网站定制。参考下表:

阿里云建站方式 所需产品 优势 适用人群
自助建站 ECS云服务器 自行购买云服务器,手动搭建网站 需要些技术门槛,适用于刚接触云计算或对云服务器和建站不太了解、希望自行设计网站的个人或小企业用户。
模板建站 云·速成美站 使用阿里云提供上千套模板,可视化后台管理,会打字就会建站 适合有一定软件应用能力的个人或小企业用户,模板建站支持Web站点、移动端站点、互动表单以及会员支付多场景。
定制建站 云·企业网站定制功能定制 由阿里云专业网站设计师完成网站设计及搭建 适合对网站有品质要求或个性化需求、希望节省人力和时间成本的企业用户。

阿里云建站产品如何选择?如果您是站长类的技术人员,当然选择自助建站方式,如果非技术人员,个人或者工作室建议选择云·速成美站,如果是企业用户建站选择阿里云网站定制服务。


阿里云建站不需要用户另外购买云服务器或虚拟主机等产品,阿里云提供香港节点并且提供全球CDN加速,不用备案,拿来即用。阿里云大品牌无隐形消费,我见过太多打着免费建站的幌子,实际价格贵的离谱。举例来说,免费建站,使用的域名是对方的三级域名,域名人家说收回就收回,免费建站,云主机却要收费,而且价格很贵没有质量保障,网站说打不开就打不开。


我从新手过来的,之前使用过免费域名,用了有一段时间了,结果被收回了,使用免费虚拟主机,速度卡不说,结果网站数据丢失了,这不是免费惹的祸,是小编贪图便宜惹的祸,建议选择大品牌,值得信赖。


]]>
首次揭秘!​春晚活动下快手实时链路保障实践 Sat, 04 Jul 2020 09:33:03 +0800

摘要:本文由快手开发工程师刘建刚分享,主要介绍春晚活动下快手实时链路保障实践。内容主要包含以下四部分:

  1. 快手 Flink 简介
  2. 春晚实时保障方案
  3. 春晚实时大屏
  4. 未来规划

Tips:点击「阅读原文」链接可查看作者原版 PPT 及分享视频~

一、快手 Flink 简介

我们首先来看一下快手的实时计算架构图。主要分为4个部分,包括数据接入、数据计算、数据应用和数据展示。各层职责分明、衔接顺畅,方便用户开发。

640 1.png

快手的 Flink 集群规模大概有 3000 多台机器,日处理条目数为20万亿,峰值为38亿条。主要应用场景包含以下四类:

  • 实时 SQL 平台,这是 Flink 托管的一个产品化的 SQL 平台。
  • 短视频、直播等指标的实时计算,涵盖了公司的主要业务和产品。
  • 机器学习的数据预处理,支撑着快手广告等各种模型的训练。
  • 快手所有的日志拆分、同步等实时的数据流。

640 2.png

二、春晚实时保障方案

快手中标了2020年的央视春晚,春晚作为全球华人辞旧迎新的晚会,数据量之大前所未有。快手 Flink 作为公司的实时计算平台,支持春晚超大状态和千万并发等复杂计算。春晚项目的挑战主要体现在稳定性、实时性、准确性三个方面,我们为此制定了一系列方案为春晚保驾护航。

640 3.png

下面我会通过这4个方面来介绍一下我们为春晚做的努力。

  • 第一个是过载保护,主要介绍极端压力下的技术应对方案;
  • 第二个是全系统的稳定性,确保各个方面都万无一失;
  • 第三个是压力测试,它是春晚的提前模拟;
  • 第四个是资源的保障,涉及到资源的管理和保障。

640 4.png

1.过载保护

Flink 在流量激增或者单点性能不足的情况下,有可能会发生卡死、雪崩或者失败的情况。这个时候一旦我们的实时作业挂掉,整个作战计划就会被打乱,可能给公司带来很大的损失。

640 5.png

我们针对这种场景设计了一种健康检查、智能限速、源端控制相结合的柔性可用技术。为什么要通过源端控制?首先,如果出了问题,我们可以在下游的 task 上进行控制,但是这样的话可能带来一个问题,它会造成反压等阻塞行为,有可能会把整个作业卡死,所以我们通过控制数据源来从本质上解决问题。下面是我们技术实现:

  • TaskManager 作为从节点,将自己的健康信息定期汇报到 Master 节点。
  • Master 节点一旦检测到极端压力,立刻要求所有的 source 限速 50%。
  • 如果之后作业状态良好,就会慢慢的提高我们的输入 QPS,每次 10%。

640 6.jpg

然后看一下我们的测试效果图。流量高峰到来时 QPS 为 200K。一旦 Master 节点检测到极端压力,直接将 QPS 限速到 100K。之后检测到作业状态良好,就逐步地进行恢复。经过测试(随着逐渐恢复各项指标会有波动),我们的 CPU 使用率从最高的 100% 降到了 80%~90%,ygc 由每分钟的10秒降到了每分钟3秒以内,同时也避免了的 oom、心跳超时、卡死等各种问题。这种技术能够保障我们 Flink 在极度压力下的存活,起到了削峰保命的效果。

640 7.png

我们还设计了一种轻量级的热更新模型,在作业不停止的情况下通过 restful 接口实时的控制作业去应对各种压力,避免了繁琐的修改代码、打包、上线等耗时过程。常见功能包括关闭快照、设置采样率、source 源鲜素,如下图所示。

640 8.png

2.全系统稳定性

分布式系统涉及到方方面面,任何一个环节出了问题都可能是致命的,我们为此在故障应对和项目管理上做了很多工作。故障应对包含故障排除、故障演练、故障预案,项目管理包含作业管理、集群管理、工程管理。

640 9.png

首先进行的是 Flink 的故障排除。Flink 的交互组件包括 Yarn,HDFS,Kafka,Zookeeper,我们逐一的对每个组件进行故障排除。它们各自的风险排除步骤,如下图中的表格所示。

640 10.png

故障排除完了之后,就需要在真实的场景中进行故障演练。主要的演练方法就是在我们的集群中,随机的注入各种异常来测试并且完善 Flink 的稳定性,确保 Flink 做到以下保障:

  • 相关组件异常不影响 Flink,比如 Yarn 和 HDFS 的主节点挂掉。
  • 作业宕机,Hawk 监测系统5秒内发现并作相关处理。
  • 作业 Failover 在30秒以内。

640 11.png

为了更好地应对各种故障,我们还制定了完善的故障预案,这是一套完整的应急指导方针。针对每一种故障,我们都有快速的问题排查和解决手段。

640 12.png

除了快速应对故障,良好的管理手段也必不可少,它可以有效的减少故障。下面介绍我们管理上的一些手段。

首先是作业管理这一块,包含作业管理系统的稳定性和相关的运维工作。包括四个方面:

  • 作业管理系统支持高可用。一旦出问题可以快速的切换。
  • Checklist 规范用户开发,包括快照设置和数据源对齐等实战经验。
  • 常见工具,包含全局日志查询、高负载查询、快速迁移等。
  • 报警机制和 metric 的展示,做到问题提前发现和及时发现。

640 13.png

接下来是集群管理。集群作为我们整个系统的物理载体,一旦出现问题就是致命性的:

  • 针对高优作业搭建多套实时集群,避免离线的干扰。
  • 关键队列物理隔离。针对特定集群要求的作业,通过物理隔离来保障其稳定性。
  • 机器环境的排查。确保机器环境符合我们的预期。
  • 重要作业实现多集群的部署,出现问题秒级切换。(实时大屏会详细介绍)

640 14.png

最后一个就是工程的管理。工程管理的关键是时间线预案,主要是指导我们在什么时间点该做什么事情,贯穿整个项目开发。下面简单描述了下春晚的事前、事中、事后的主要操作:

640 15.png

3.压力测试

压力测试相当于春晚的一个模拟,它能够帮助我们发现很多问题。针对春晚,压力测试比一般的时候要更复杂一些。面临的最主要的两个问题,第一个问题就是数据模型怎么构造,比如说有哪些 topic、各 topic 的数据分布是怎么样的。第二个问题是我们如何根据这些模型生成符合条件的数据。

640 16.png

数据模型的难点在于构建的数据分布必须跟春晚保持一致。我们的解决方案是以人为参考单位,基于统计规律建立人与数据分布的映射关系。简单来说,计算出每个人在各个 Topic 的数据量,预估有多少人各个 Topic 的 QPS 就翻多少倍,当然实际情况会复杂许多。最终,我们根据公测和元旦当天用户产生的数据来进行春晚模型的建立。

640 17.png

模型构建完成之后,需要根据模型生成数据。为此,我们构建了一整套完善的数据生成服务,用户只需要进行简单的配置就可以,而流量控制、多 task 的协作、分布式生成等复杂的实现全部由平台实现。主要有三种形式的数据生成:

  • 数据翻倍,基于 bytes 的流量翻倍,性能最佳。
  • 时间压缩,在不改变数据分布的情况下压缩数据、提高 QPS。
  • 样本生成,根据用户提供样本生成符合条件(QPS、UV等)的数据。

640 18.png

4.资源保障

春晚对数据的实时性要求比较高。只有资源保障到了才可以实现我们的实时性。

640 19.png

资源保障的关键策略是分级保障。我们把作业分了三个优先级:P0、P1 和 P2:

  • P0 是高优作业,跟春晚相关的一些活动。
  • P1 是重要的作业,是指业务方的一些重要作业。
  • P2 是普通的任务,一般指非核心的作业。

为了做到分级保障,我们制定了重点保障高优先级作业的降级策略:

  • 春晚之前,我们会批量的把 P2 的任务都停止掉,把资源全部都挪给 P0 和 P1。
  • 春晚中,如果有需要,降级 P1 的资源来保障 P0 作业的资源。
  • 春晚后,我们会把之前停掉的 P2 作业再重新提起来,并且从 kafka 最新的 offset 开始消费。

通过分级保障,在资源有限的情况下,优先保障了我们的重点作业,确保了高优任务的实时消费。分级保障对今后的服务治理意义重大。比如说以后的资源调度、灰度上线、作业迁移等等,都可以参考分级保障的策略。

640 20.png

资源保障的另一个体现在于快速扩容,分为实时指标监控和资源选择两个方面。实时指标监控包括作业吞吐,作业延时,快照信息,物理信息,通过这4个重要的部分就可以衡量一个作业是否健康。如果我们检测到作业有性能问题需要扩容,需要按照一定顺序选择资源来补充——集群内冗余资源,备用集群,低优任务资源。

640 21.png

三、春晚实时大屏

下面我们以实时大屏作为经典案例来介绍。快手春晚实时大屏为作战指挥官提供最核心的活动和公司大盘实时数据,总共承接了100多个实时指标的计算,包括在线、红包、互动等各项指标。主要的挑战表现在三个方面:

  • 数据量大,QPS 在千万级别;
  • 实时性要求比较高,在秒级以内;
  • 稳定性要求高,可用性为4个9。

接下来我会从技术选型、压力测试、服务部署三个方面顺序展开。

640 22.png

1.技术选型

架构组件是以 Flink 为主,Redis 为辅。Flink 适合大规模的实时计算,Redis 作为一款高效的 KV 查询工具来辅助实时计算。

各项指标中,基于 deviceld 的 UV 计算最多、复杂度最高。一般来说,先将字符串类型的 deviceId 转成数字类型的 id,然后存储在位图结构 bitmap(存储空间小)中进行计算。这里介绍下快手的技术方案:

  • Flink+HBase。HBase 负责将 deviceId 转成 id,Flink 负责计算。
  • Flink+Redis。通过 Redis 判断 deviceId 是否首次出现,如果是就下发计算。
  • Flink 自身。Flink 自建字典为快手内部实现的精准一次方案。

前面两种方案将字典和计算解耦,适合多个作业共享一个字典。最后一种方式不再依赖外部系统,性能最佳。实时大屏根据自己需求和熟练度选择了第二种方案。

640 23.png

2.压力测试

压力测试分为单作业的压测和全链路的压测。

  • 单作业压测这一块,我们通过增量计算、批量访问、本地缓存、objectReuse 等优化技术,使单个作业的 QPS 达到百万级别。
  • 全链路压测这一块,用来评估整体性能,需要协调所有数据和作业,具体操作如下所示。

640 24.png

3.服务部署

最后一步是多链路的服务部署。实时大屏作业的稳定性要求特别高,必须多链路热备:

  • 双机房热备。一旦机房挂掉,立刻切到另一个机房。
  • 多链路热备。针对全量链路和采样链路,集群内物理隔离、多链路运行。
  • 指标故障用户无感知。最上面视图层屏蔽底层链路,底层出问题可以秒级切换。

640 25.png

四、未来规划

上面是春晚实时大屏案例的介绍,下面也跟大家分享一下我们将来的一些规划:

  • 推广 SQL,探索批流统一、Table&Stream 的广泛用途。
  • 自研 SlimBase statebackend,实现存储计算分离。
  • 提升 Flink 故障自愈能力。
  • 建立作业诊断模型,实现问题快速定位。
  • 探索数据库、K8s 等相关系统的组合应用。

文章不够看?点击「阅读原文」可直接回顾作者现场分享的讲解视频~

]]>
com.alibaba.dubbo.rpc.RpcException: No provider available from registry stable.zk.scsite.net:2181异常解决 Sat, 04 Jul 2020 09:33:03 +0800 原文链接:
https://copyfuture.com/blogs-details/20200629181409555v24mc4magq748ni

最近发现dubbo消费端一直报下面这样的error日志

06-17 15:56:50.749  ERROR default - [orSendTimer-thread-1] c.alibaba.dubbo.monitor.dubbo.DubboMonitor :  [DUBBO] Unexpected error occur at send statistic, cause: No provider available from registry *.*.*.*:端口 for service com.alibaba.dubbo.monitor.MonitorService on consumer 172.*.*.124 use dubbo version 2.8.3, please check status of providers(disabled, not registered or in blacklist)., dubbo version: 2.8.3, current host: 172.*.*.124
com.alibaba.dubbo.rpc.RpcException: No provider available from registry stable.zk.scsite.net:2181 for service com.alibaba.dubbo.monitor.MonitorService on consumer 172.*.*.124 use dubbo version 2.8.3, please check status of providers(disabled, not registered or in blacklist).
    at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:577)
    at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:74)
    at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:271)
    at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:232)
    at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:75)
    at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:77)
    at com.alibaba.dubbo.common.bytecode.proxy19.collect(proxy19.java)
    at com.alibaba.dubbo.monitor.dubbo.DubboMonitor.send(DubboMonitor.java:127)
    at com.alibaba.dubbo.monitor.dubbo.DubboMonitor$1.run(DubboMonitor.java:72)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

该个error对项目的功能没有任何影响,但反复的报错也是让人心烦,那么就解决吧。

原因

没有启动监控中心,却配了监控地址。

解决方案

  1. 把监控中心启动
  2. 把xml配置中的
  3. properties配置中的dubbo.monitor.protocol=registry去掉

dubbo:monitor

监控中心配置。对应的配置类: org.apache.dubbo.config.MonitorConfig

| 属性 | 对应URL参数| 类型| 是否必填| 缺省值| 作用 | 描述 | 兼容性 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| protocol | protocol| string| 可选| dubbo| 服务治理 |监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。| 2.0.9以上版本|
|address| | string |可选| N/A |服务治理|直连监控中心服务器地址,address="10.20.130.230:12080" | 1.0.16以上版本

]]>
数据库产品事业部月刊(2020.5) Sat, 04 Jul 2020 09:33:03 +0800 一、重大事件

1、自研云原生数仓AnalyticDB包揽权威测评TPC-DS、TPC-H全球第一!

5月4日,TPC(全球最知名非盈利的数据管理系统评测基准标准化组织)官网正式上线AnalyticDB TPC-DS成绩,AnalyticDB通过严苛的TPC-DS全流程测试,性能QphDS分数为14895566,性价比分数为0.08CNY,相比较基于Spark深度优化版的前世界纪录性能提升29%并且单位成本仅为其1/3,成为TPC-DS官方榜单上全球性能、性价比双双领先的数据仓库,这是继2019年4月26日后再次获得全球领先的成绩!

666.png

此外,AnalyticDB首次刷新TPC-H 30TB当前有效榜单纪录成为全球第一,性能、性价比全球领先!相比前世界纪录 微软SQL Server 2019,综合性能提升290%,单位成本仅为其1/4,成为中国首次荣登该榜单的产品!

000001.png


查看详情:https://developer.aliyun.com/article/759564

2、开启云原生数据库新时代,阿里云数据库启用全新品牌口号

5月18日,阿里云数据库产品事业部(ApsaraDB)宣布正式启用全新品牌口号 —— “阿里云数据库:更快、更稳、更安全(Faster, Stronger, Securer)”,未来将聚焦 “极致性能”、“稳定性”和“安全性” 三大品牌价值内核,在多个数据库细分领域,为用户提供业界领先的数据库产品和最专业的数据库技术服务。新品牌口号的提出,标志着阿里云数据库的全面升级,开启云原生数据库的新时代,同时也是更好地为客户服务的信心体现。

飞刀揭幕.JPG

查看详情:https://developer.aliyun.com/article/761835

二、重大产品更新

PolarDB下一代云原生数据库

RDS MySQL用户升级到PolarDB可保留原地址(应用程序不改连接配置)

RDS MySQL实例可直接升级为PolarDB MySQL,3分钟停机时间,业务0改动。在升级的过程中,既可以保留原来RDS主实例地址(包含公网地址/私网地址),也可以保留RDS的读写分离地址,大大降低了用户使用PolarDB的门槛,上线区域包含中国站和国际站。

国际站PolarDB上线存储包,10T及以上存储空间可节省40%成本

PolarDB在国际站现已支持包年包月购买存储包,用来抵扣PolarDB集群的存储费用,通过存储包可大幅节省用户的存储成本,尤其适合大容量用户。

PolarDB 备份功能重大升级并收费

PolarDB 面向全球所有地域的用户开放更多高级配置选项和能力,满足企业级数据备份的需求,进一步保障数据安全。支持调整备份周期;支持永久保留数据库备份;支持数据库回收站,可以从回收站恢复已释放实例,挽救误操作;备份存储分级,二级备份极大幅降低用户保存历史备份数据的成本。上线渠道包含中国站和国际站,以及金融云、新零售云聚石塔、菜鸟云等虚商。

云原生数据仓库+数据湖

云原生数据仓库弹性模式规格实例发布

ADB MySQL弹性规格上线。实现了资源层面的弹性购买,用户可按照计算资源、数据资源独立购买,存储方面无需购买按量付费。目前开放了国内区域,预计6月底开放海外部分。

云原生数据仓库基础版支持ESSD云盘

ADB MySQL基础版(单机版)规格实例的存储系统在支持高效云盘的基础上,新加ESSD云盘存储,支持高效云盘月ESSD圆盘存储之间相互切换。基于ESSD云盘存储的ADB MySQL集群读写性能有巨大提升,进一步降低用户成本。

云原生数据仓库PostgreSQL版推出资源弹性模式

分析型数据库AnalyticDB for PostgreSQL正式推出资源弹性模式。节点规格支持2C16G和4C32G两种规格,节点数可从4~256选择。同时支持ESSD云盘和高效云盘两种存储形态,空间支持50~1000GB范围选择,且支持在线扩容。通过支持资源弹性模式,AnalyticDB for PostgreSQL将为用户带来更加灵活的选择,可根据空间使用按需扩展使用,大幅降低用户前期投入。

云数据库ClickHouse支持SLS日志投递发布

云数据库ClickHouse 接入SLS 日志投递功能,支持日志数据实时投递到ClickHouse进行实时分析。为新零售,电商, 直播,游戏等行业客户构建低成本高性能的实时日志分析系统提供产品解决方案,支撑用户画像分析,用户行为分析,人群划分等数据化运营业务。

云数据库ClickHouse 接入数据管理服务DMS发布

云数据库ClickHouse 接入数据管理服务DMS,支持在线数据库表管理,在线查询和任务编排调度,避免客户下载和安装Client 的复杂开发流程, 提升了用户体验,降低了数据分析开发的成本。

RDS&NoSQL&管控工具

阿里云数据库专属集群国际站发布

阿里云数据库专属集群国际站发布,支持MySQL:杭州、北京、上海、深圳、张家口、呼和浩特、香港、新加坡、雅加达、孟买、硅谷等地域已开服。

MySQL 库表级恢复效率提升四倍

RDS MySQL 高可用版本地盘实例,包括5.6、5.7、8.0 三个版本,单库单表级恢复效率提升四倍,一般情况下可达100MB/S的恢复速度,即相当于1分钟可以恢复6GB的单表。 本次优化对于如游戏类业务场景非常友好,可以实现快速的开服回滚等业务操作。

RDS SQL Server支持SSD磁盘盘升级ESSD

RDS SQL Server 高可用系列支持SSD磁盘盘升级ESSD,客户可直接将SSD盘升级为ESSD磁盘,提升IO性能。

RDS PostgreSQL V11支持DDL回收站、防火墙、增量订阅

RDS PostgreSQL V11开放事件触发器, 支持DDL回收站、防火墙、增量订阅等功能. 增强安全、增量复制功能.

Redis 6.0 发布

Redis 6.0版本在一系列关键领域进行了改进,支持新的Redis协议:RESP3,采用网络请求多线程处理提高了性能,并修复了之前版本的多个缺陷。 此次在阿里云上线的规格是社区云盘版,后续会逐步支持本地盘版。

MongoDB 支持多安全组设置

MongoDB 支持多安全组设置,方便客户进行灵活配置

支持HBase、RDS或其它数据源数据导入HBase Serverless服务

支持从HBase、RDS、MongoDB,ElasticSearch,TableStore等数据源导入数据到HBase Serverless服务

阿里云数据库Cassandra版国际站商用发布

阿里云数据库Cassandra版国际站商用发布:青岛、北京、张家口、呼和浩特、杭州、上海、深圳、香港、新加坡、雅加达、孟买、法兰克福、弗吉尼亚、硅谷、伦敦等地域均已开服。

数据库备份DBS推出Oracle RAC备份功能

数据库备份DBS推出Oracle RAC备份功能,支持10g、11g、12c、18c、19c,提供10分钟RPO备份、任意时间点恢复能力。DBS采用Oracle原生RMAN接口,备份数据直接写到云存储,不在本地磁盘中转,数据传输和存储全程加密,数据压缩后长期归档。之前DBS备份已支持Oracle SingleInstance、DataGuard架构。

数据管理DMS国际站上线新版售卖变更

数据管理DMS新版统一产品入口,免费版升级为新版的自由操作管控模式,高级版升级为新版的稳定变更管控模式,企业版升级为新版的安全协同管控模式,同时针对安全协同管控模式最高定价降幅68%;优化多个功能模块的国际化显示与交互支持。

数据管理DMS支持云数据库ClickHouse的统一管理

数据管理DMS支持ClickHouse的数据库设计及管理,包括实例录入、权限管理、敏感字段管理、数据查询、数据变更等基础管理操作,同时数据工厂/数仓开发-任务编排也已支持ClickHouse。

数据库自治服务DAS 支持基于真实流量的数据库压测服务

数据库自治服务 DAS 发布了智能压测,该功能为客户提供轻量级、基于真实的业务流量的数据库压测服务,具备低负载获取源端真实业务流量、支持事务、支持写入流量的压测、支持自定义压测速率等优势,客户可以通过该功能实现上云搬站的容量评估、大促前的数据库压测、异构数据库的迁移评估等。

数据传输服务DTS支持了TIDB不停机迁移和和PolarDB-X为源的同步功能

数据传输服务DTS支持将TIDB的结构、全量数据、增量数据迁移到MySQL、PolarDB MySQL,实现TIDB的在线迁移。支持将PolarDB-X到PolarDB-X的全量数据、增量数据同步,支持PolarDB-X到AnalyticDB MySQL的结构、全量数据、增量数据的同步。

数据传输服务DTS集成云企业网CEN,简化线下IDC自建数据库上云迁移的网络配置

数据传输服务DTS支持通过云企业网CEN配置迁移和同步任务,DTS可以和CEN里的VPC、VBR、CCN进行互联互通,进而实现DTS和线下数据库的互联互通,大大减少了用户专线接入的网络配置,提升线下IDC数据库通过专线的上云迁移速率。

三、前沿技术

智能数据库模型训练时间缩短到最新工作的1/100

智能数据库基于混合数据模型学习数据联合分布,在几乎不损失精度的情况下,模型训练时间缩短到最新工作(Berkeley发表的VLDB20论文)的1/100,该模型可以作为数据库的基础组件用到优化器以及数据库生成等重要业务。

全加密数据库MySQL版完成重要生态工具的兼容适配

包括:TDDL支持密文数据自动加解密功能;DTS支持明文库与密文库间的全量/增量数据同步、全量数据正确性校验功能。上述工具将帮助已有业务平滑、安全地迁入加密数据库环境中。

空天数据库时空拼图大查询性能优化突破阶段性目标

采用区别于传统的影像单元化存储策略,借助SQL+NoSQL 协同数据访问以及分布式大查询并行计算优化,将覆盖中国600+遥感影像(总量600G)的时空动态拼图植被指数计算效率从分钟级优化到秒级。

数据库自治服务DAS用户突破4万

DAS作为业界第一个数据库自动驾驶云平台,发布以来,用户数已经超过4w,商业化两个月时间付费实例数超过1000,当前日GAAP超过1.7w,月增长率67%。DAS已经为3000+用户,超过1w的实例提供辅助自治服务,用友、米连科技、宝宝树、单创等GC7/6大客户利用DAS的智能压测功能,在上云搬站、大促容量评估、数据库引擎选型切换上面都提供重要的帮助。从数据库冲击Gartner Leader象限调研可以看到,增加了对数据库Autonomous能力的评估,DAS提供的能力可以帮助团队在自治能力上拿到分数。

四、客户案例

1、大型药企朗致集团抛弃传统商业数据库迁移上云,数据库运维成本下降50%

日前,阿里云携手用友帮助国内大型医药控股型集团公司朗致集团将核心ERP系统和核心数据库迁移上云,数据库直接成本下降20%,运维成本下降50%,同时提升了内外部协同效率,促进业务进一步的发展。

2020 年 1月,朗致集团正式启动上云进程。在用友与阿里云的共同推进下,历时3个月,成功将业务系统及数据库搬迁上云。

由于采用了阿里云服务,朗致集团大幅降低了机房管理和运维成本;通过业务系统上云,实现企业内外部高效协同,快速响应市场需求;此外,通过实现业务系统的在线化,为公司未来的数字化、智能化战略落地奠定了坚实基础。

朗致集团IT负责人表示:借助阿里云强大的云数据库运管能力,公司除了大幅度降低运维负担,更重要的是确保了数据安全——RDS秒级历史数据恢复能力,让企业免去了数据丢失的隐忧。

朗朗.png

查看详情:https://developer.aliyun.com/article/762664

2、银泰百货抛弃传统数据库转投阿里云PolarDB,投入产出比增长2倍以上

5月15日,银泰百货数据库团队举办数据库上云一周年庆祝活动。银泰数据库负责人李亚博透露,公司核心业务系统中的数据库搬迁至阿里云PolarDB之后,在相同成本的情况下可以支撑三倍以上的业务量。

新零售四年,银泰百货通过数字化转型,成为一家全面架构在云上的互联网百货公司。在此过程中,银泰百货数据库上云对业务飞跃式发展进行了很好地支撑。

“对于银泰这样的新零售企业,每年有较多的大促节点,大促时数据库资源消耗非常大,对稳定性要求也非常高。” 李亚博表示,数据库上云之后,银泰大促时可以非常灵活地使用PolarDB云数据库的弹性扩容与缩容能力。今天银泰的交易峰值增长20倍以上,但IT成本并没有上涨。

银泰~~.png

查看详情:https://developer.aliyun.com/article/760663?spm=a2c6h.13148508.0.0.1f984f0epNgUPJ

]]>
Greenplum json类型的使用 Sat, 04 Jul 2020 09:33:03 +0800 1.建json类型字段的表

CREATE TABLE orders (
    ID serial NOT NULL PRIMARY KEY,   
    info json NOT NULL
);

2.插入json类型的数据

INSERT INTO orders (info) VALUES  
( '{ "customer": "John Doe", "items": {"product": "Beer","qty": 6}}' );

INSERT INTO orders (info) VALUES   
( '{ "customer": "Lily Bush", "items": {"product": "Diaper","qty": 24}}' ), 
( '{ "customer": "Josh William", "items": {"product": "Toy Car","qty": 1}}' ), 
( '{ "customer": "Mary Clark", "items": {"product": "Toy Train","qty": 2}}' );

3.查看json类型数据

select info from orders;

显示如下:

111.jpeg

select info-> 'customer' AS customer from orders;

显示如下:

222.jpeg

select info->> 'customer' AS customer from orders;

显示如下:

333.jpeg

- The operator -> returns JSON object field by key.
- The operator ->> returns JSON object field by text.
- The operator -> returns a JSON object, you can chain it with the operator ->> to retrieve a specific node. For example, the following statement returns all products sold:
SELECT   info -> 'items' ->> 'product' as productFROM   ordersORDER BY product;

显示如下:

444.jpeg
First info -> 'items' returns items as JSON objects. And then info->'items'->>'product' returns all products as text.

4.在where条件里面使用json


SELECT info ->> 'customer' AS customer,  info -> 'items' ->> 'product' AS product
  FROM orders
 WHERE CAST ( info -> 'items' ->> 'qty' AS INTEGER ) = 2;

显示如下:

555.jpeg

5.在函数里面使用json

SELECT MIN ( CAST ( info -> 'items' ->> 'qty' AS INTEGER ) ),
       MAX ( CAST ( info -> 'items' ->> 'qty' AS INTEGER ) ),
       SUM ( CAST ( info -> 'items' ->> 'qty' AS INTEGER ) ),
       AVG ( CAST ( info -> 'items' ->> 'qty' AS INTEGER ) ) 
  FROM orders;

显示如下:

666.jpeg

6.json类型的一些函数

json_each function
The json_each() function allows us to expand the outermost JSON object into a set of key-value pairs. See the following statement:

SELECT   json_each (info)FROM   orders;

显示如下:

777.jpeg

json_object_keys function
To get a set of keys in the outermost JSON object, you use the json_object_keys() function. The following query returns all keys of the nested items object in the info column

SELECT json_object_keys (info->'items') FROM orders;

显示如下:

888.jpeg

json_typeof function
The json_typeof() function returns type of the outermost JSON value as a string. It can be number, boolean, null, object, array, and string.
The following query return the data type of the items:

SELECT json_typeof (info->'items') FROM orders;

显示如下:

999.jpeg

The following query returns the data type of the qty field of the nested items JSON object.

SELECT json_typeof ( info->'items'->'qty') FROM orders;

显示如下:

111.jpeg

]]>
阿里达摩院:1 秒替换直播背景,像素级视频分割如何实现? Sat, 04 Jul 2020 09:33:03 +0800

--------点击屏幕右侧或者屏幕底部“+订阅”,关注我,随时分享机器智能最新行业动态及技术干货----------

1.gif

与图像识别不同,AI 分析理解视频的技术门槛较高。长期以来,业界在视频 AI 技术的研究上鲜有重大突破。以 CVPR 会议难度最高的比赛之一 DAVIS( Densely Annotated Video Segmentation)为例,该比赛需要参赛团队精准处理复杂视频中物体快速运动、外观变化、遮挡等信息,过去几年,全球顶级科技在该比赛中的成绩从未突破 80 分,而达摩院的模型最终在 test-challenge 上取得了 84.1 的成绩。

DAVIS 的数据集经过精心挑选和标注,视频分割中比较难的点都有体现,比如:快速运动、遮挡、消失与重现、形变等。DAVIS 的数据分为 train(60 个视频序列), val(30 个视频序列),test-dev(30 个视频序列),test-challenge(30 个视频序列)。 其中 train 和 val 是可以下载的,且提供了每一帧的标注信息。对于半监督任务, test-dev 和 test-challenge,每一帧的 RGB 图片可以下载,且第一帧的标注信息也提供了。算法需要根据第一帧的标注 mask,来对后续帧进行分割。分割本身是 instance 级别的。

阿里达摩院:像素级视频分割

阿里达摩院提供了一种全新的空间约束方法,打破了传统 STM 方法缺乏时序性的瓶颈,可以让系统基于视频前一帧的画面预测目标物体下一帧的位置;此外,阿里还引入了语义分割中的精细化分割微调模块,大幅提高了分割的精细程度。最终,精准识别动态目标的轮廓边界,并且与背景进行分离,实现像素级目标分割。

基本框架

达摩院的算法基于去年 CVPR 的 STM 做了进一步改进。STM 的主要思想在于,对于历史帧,每一帧都编码为 key-value 形式的 feature。预测当前帧的时候,以当前帧的 key 去和历史帧的 key 做匹配。匹配的方式是 non-local 的。这种 non-local 的匹配,可以看做将当前 key,每个坐标上的 C 维特征,和历史每一帧在这个坐标上的 C 维特征做匹配。 匹配得到的结果,作为一个 soft 的 index,去读取历史 value 的信息。读取的特征和当前帧的 value 拼接起来,用于后续的预测。

image.png

image.png

三大技术创新

image.png

1. 空间约束

STM 的特征匹配方式,提供了一种空间上的长依赖, 类似于 Transformer 中,通过 self-attention 来做序列关联。这种机制,能够很好地处理物体运动、外观变化、遮挡等。但也有一个问题,就是缺乏时序性,缺少短时依赖。当某一帧突然出现和目标相似的物体时,容易产生误召回。在视频场景中,很多情况下,当前帧临近的几帧,对当前帧的影响要大于更早的帧。基于这一点,达摩院提出依靠前一帧结果,计算 attention 来约束当前帧目标预测的位置,相当于对短期依赖的建模。

具体的方法如下图所示:

  1. 当前帧的特征和前一帧的预测 mask 在 channel 维度上做 concat,得到 HxWx(c+1) 的特征;
  2. 通过卷积将特征压缩为 HxW;
  3. 用 sigmoid 函数将 HxW 的特征,压缩范围,作为空间 attention;
  4. 把 attention 乘到原特征上,作为空间约束。

image.png

下图为空间 attention 的可视化结果,可以看到大致对应了前景的位置。

image.png

2. 增强 decoder

达摩院引入了语义分割中的感受野增强技术 ASPP 和精细化分割的微调(refinement)模块。ASPP 作用于 memory 读取后的特征,用于融合不同感受野的信息,提升对不同尺度物体的处理能力。

image.png

3. 训练策略

达摩院提出了一个简单但是有效的训练策略,减少了训练阶段和测试阶段存在的差异,提升了最终效果。

原始 STM 训练时,会随机从视频中采样 3 帧。这三帧之间的跳帧间隔,随着训练逐渐增大,目的是增强模型鲁棒性。但达摩院发现,这样会导致训练时和测试时不一致,因为测试时,是逐帧处理的。为此,在训练的最后阶段,达摩院将跳帧间隔重新减小,以保证和测试时一致。

其他

backbone: 达摩院使用了 ResNeST 这个比较新的 backbone,它可以无痛替换掉原 STM 的 resnet。在结果上有比较明显提升。

测试策略: 达摩院使用了多尺度测试和 model ensemble。不同尺度和不同 model 的结果,在最终预测的 map 上,做了简单的等权重平均。

显存优化: 达摩院做了一些显存优化方面的工作,使得 STM 在多目标模式下,可以支持大尺度的训练、测试,以及支持较大的 memory 容量。

数据: 训练数据上,达摩院使用了 DAVIS、Youtube-VOS,以及 STM 原文用到的静态图像数据库。没有其他数据。

结果

达摩院的模型,最终在 test-challenge 上取得了 84.1 的成绩。

image.png

在 test-dev 上的消融实验。达摩院复现的 STM 达到了和原文一致的结果。在各种 trick 的加持下, 得到了 11 个点的提升。

image.png

随着互联网技术、5G 技术等的发展,短视频、视频会议、直播的场景越来越多,视频分割技术也将成为不可或缺的一环。比如,在视频会议中,视频分割可以精确区分前背景,从而对背景进行虚化或替换;在直播中,用户只需要站在绿幕前,算法就实时替换背景,实现一秒钟换新直播间; 在视频编辑领域,可以辅助进行后期制作。

image.png

文章来源:https://www.infoq.cn/article/QyZjDa0A1ePkrog2p1jO

]]>
预警|Apache Dubbo漏洞补丁绕过,阿里云上可默认拦截,请尽快修复 Sat, 04 Jul 2020 09:33:03 +0800 2020年6月29日,阿里云应急响应中心监测到 CVE-2020-1948 Apache Dubbo反序列化漏洞补丁存在缺陷,可以绕过原有补丁并执行任意指令。

针对这一情况,阿里云默认防御已启动紧急响应,为阿里云上受影响客户免费提供一个月的虚拟补丁帮助缓解该漏洞的影响,建议利用这个期间尽快完成漏洞修复,避免该漏洞被利用造成数据、资产的损失。

时间线

  • 2020.06.23 监测到 CVE-2020-1948 Apache Dubbo反序列化漏洞
  • 2020.06.29 监测到 CVE-2020-1948 Apache Dubbo反序列化漏洞 补丁绕过

漏洞描述

Apache Dubbo是一种基于Java的高性能RPC框架。Apache Dubbo官方披露在Dubbo Provider中存在一个反序列化远程代码执行漏洞(CVE-2020-1948),攻击者可以构造并发送带有恶意参数负载的RPC请求,当恶意参数被反序列化时将导致远程代码执行。

目前,2.7.7版本的官方补丁中存在缺陷,攻击者可以绕过并执行任意指令,危害极大。

漏洞影响范围

  • Apache Dubbo 2.7.0~2.7.7
  • Apache Dubbo 2.6.0~2.6.7
  • Apache Dubbo 2.5.x系列所有版本(官方不再提供支持)

安全建议

目前官方还未发布针对此漏洞绕过手法的补丁,在阿里云提供一个月的默认防御期限内,建议客户参考以下方法进行缓解,并关注官方补丁动态,及时进行更新:

  1. 升级至2.7.7版本,并根据https://github.com/apache/dubbo/pull/6374/commits/8fcdca112744d2cb98b349225a4aab365af563de的方法进行参数校验
  2. 禁止将Dubbo服务端端口开放给公网,或仅仅只对能够连接至Dubbo服务端的可信消费端IP开放
  3. Dubbo协议默认采用Hessian作为序列化反序列化方式,该反序列化方式存在反序列化漏洞。在不影响业务的情况下,建议更换协议以及反序列化方式。具体更换方法可参考:http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-protocol.html

安全产品建议

建议使用阿里云安全的下一代云防火墙产品,即使在官方没有发布针对此漏洞绕过手法的补丁情况下,其阻断恶意外联、配置智能策略的功能,也能够从根本上阻止防御入侵。

]]>
【0629 - 0703 直播导视 | PPT 下载】阿里云Offer 5000人! 快来和阿里妹做同事吧预热来啦! Sat, 04 Jul 2020 09:33:03 +0800 *本预告时间仅供参考,最终直播时间以直播间信息为准。
*本文提供直播PPT下载,请在对应直播介绍处查看。

本周直播重磅推荐:

6月30日:

研发效能提升的挑战、方法和解决方案

直播时间:06-30 16:00
直播亮点:
我们将引来全新《研发效能36计》的开篇。本次课程将带你一起,分析研发效能提升的挑战,了解其中的关键实践,并设计效能提升的完整解决方案。通过本次课程中,你将了解到:
云原生和中台化时代研发效能提升的挑战和机会
如何凝聚组织对研发效能提升的共识
如何分析和找到导致研发效能问题的根因
如何综合应用协作、工程、技术三个方面实践,设计研发效能提升的解决方案
分享嘉宾
何勉,阿里云云研发部门资深技术专家

*PPT下载待更新

【Dev Talks第十期】10分钟快速构建云原生数据仓库

直播时间:06-30 14:00
直播亮点:
企业经常会受到数据孤岛未打通,数据无法实现快速共享的困扰,而构建数据仓库也往往非常复杂,所以在面对数字业务化时缺少基本的系统支持,数字化转型困难重重。通过本课程,无需掌握复杂的大数据技术栈,就能够快速的构建起基于云原生的数据仓库,完成数据接入,数据开发,数据服务发布以及数据可视化工作, 来支持大规模高并发实时在线分析服务,让数据价值在线化,从而使敏捷高效的数字化运营变的可能而且简单。
分享嘉宾
南仙,阿里云高级技术专家

*PPT下载待更新

6月30日:

【Dev Talks第十一期】基于OAM和Kubernetes快速构建开放Serverless

直播时间:07-02 14:00
直播亮点:
OAM(Open Application Model)是 2019 年阿里和微软联合在社区推出的开放应用模型,一经推出便被众多 Kubernetes 社区的用户采用,解决了许多诸如“YAML 复杂”、“CRD Operator 难以协作”等应用管理难题。而拥有自动弹性伸缩、无限资源池等先进理念的 Serverless 同样也备受关注。事实上 OAM 也是构建 Serverless 平台的最佳实践,通过 OAM Traits的概念,可以让 Serverless 所需要的各项能力包括 BaaS 资源通过统一的方式管理,同时对用户暴露“以应用为中心”的接口,降低用户使用门槛。
次演讲将为你解开基于 OAM 和 Kubernetes 快速构建开放 Serverless 平台背后的核心技术原理,真正解决云原生应用的管理难题。
分享嘉宾
孙建波(天元),阿里云技术专家

*PPT下载待更新

Hadoop 小文件/冷文件分析

直播时间:07-02 19:00
直播亮点:
庞大的小文件和冷文件数量会对HDFS的性能产生不利影响,严重时甚至影响业务稳定性,这个主题将介绍对大容量HDFS进行小文件和冷文件分析的方法,并基于分析结果可以采取哪些处理措施。
分享嘉宾
郭聪,花名析源,阿里云计算平台事业部技术专家

*PPT下载待更新

阿里云Offer 5000人! 快来和阿里妹做同事吧。

直播时间:07-09 19:00
直播亮点:
阿里云开发者社区“Offer 5000”活动正式开启,7月9日 19:00 - 21:30 15位技术大咖在线招人,更有独家资料《阿里云技术面数红宝书》助你斩获Offer,一键投递进阿里。
分享嘉宾
15个团队的技术大咖在线直播招人

]]>
大数据的下一站是什么?服务/分析一体化(HSAP) Sat, 04 Jul 2020 09:33:03 +0800 作者:蒋晓伟(量仔) 阿里巴巴研究员
因为侧重点的不同,传统的数据库可以分为交易型的 OLTP 系统和分析型的 OLAP 系统。随着互联网的发展,数据量出现了指数型的增长,单机的数据库已经不能满足业务的需求。特别是在分析领域,一个查询就可能需要处理很大一部分甚至全量数据,海量数据带来的压力变得尤为迫切。这促成了过去十多年来以 Hadoop 技术开始的大数据革命,解决了海量数据分析的需求。与此同时,数据库领域也出现了一批分布式数据库产品来应对 OLTP 场景数据量的增长。
01.jpg
为了对 OLTP 系统里的数据进行分析,标准的做法是把里面的数据定期(比如说每天)同步到一个 OLAP 系统中。这种架构通过两套系统保证了分析型查询不会影响线上的交易。但是定期同步导致了分析的结果并不是基于最新数据,这种延迟让我们失去了做出更及时的商业决策的机会。为了解决这个问题,近几年出现了 HTAP 的架构,这种架构允许我们对 OLTP 数据库里的数据直接进行分析,从而保证了分析的时效性。分析不再是传统的 OLAP 系统或者大数据系统特有的能力,一个很自然的问题是:既然 HTAP 有了分析的能力,它是不是将取代大数据系统呢?大数据的下一站是什么?

背景

为了回答这个问题,我们以推荐系统为例分析一下大数据系统的典型场景。
当你看到购物应用给你展示正好想要买的商品,短视频应用播放你喜欢的音乐时,推荐系统正在发挥它神奇的作用。一个先进的推荐系统,核心目标是根据用户的实时行为做出个性化的推荐,用户和系统的每一次交互都将即时优化下一步的体验。为了支持这样一个系统,后端的大数据技术栈已经演变为一个非常复杂和多元化的系统。
下图展示了一个支持实时推荐系统的大数据技术栈。
02.jpg
为了提供优质的实时个性化推荐,推荐系统重度依赖实时特征和模型的连续更新。

实时特征可以分为两类:

  1. 系统会收集大量的用户行为事件(比如说浏览、点击等),以及交易记录(比如说从 OLTP 数据库同步过来的付款记录等)。这些数据量非常巨大(可能高达每秒种数千万甚至上亿条),并且其中的绝大部分不是来自交易系统。为了方便以后使用,这些数据会导入到系统里(图中的 a),同时它们会和各种维表数据做关联推导出一系列重要的特征(图中的 1),这些特征会实时更新到推荐系统以优化用户体验。这里的实时维表关联需要低延迟高吞吐的点查支持才能跟得上新产生的数据。
  2. 系统也会使用滑动窗口等方式去计算出各种不同维度和时间粒度的特征(比如说一个商品过去 5 分钟的点击数、过去 7 天的浏览量和过去 30 天的销售等)。根据滑动窗口的粒度,这些聚合可能通过流计算或者批处理的方式完成。

这些数据也被用来产生实时和离线机器学习的样本,训练出来的模型经过验证后会持续地更新到推荐系统中。

上述所解释的是一个先进的推荐系统的核心部分,但这只是整个系统的冰山一角。除此之外还需要实时模型监控、验证、分析和调优等一整套体系,这包含:使用实时大屏去查看 A/B 测试的结果(3),使用交互式分析(4)去做 BI 分析,对模型进行细化和调优。除此之外,运营还会使用各种复杂的查询去洞察业务的进展,并且通过圈人圈品等方式进行针对性的营销。

这个例子展示了一个非常复杂但典型的大数据场景,从数据的实时导入(a),到预聚合(b),从数据服务(1),持续聚合(3),到交互式查询(4),一直到批处理(2)。这类复杂场景对大数据系统有着非常多样化的需求,在构建这些系统的实践中我们看到了两个新的趋势。

  • 实时化:业务需要快速地从刚刚收集到的数据中获得商业洞察。写入的数据需要在秒级甚至亚秒级就可见。冗长的离线 ETL 过程正在变得不可容忍。同时,收集到的数据比从 OLTP 系统同步过来的数据要大得多,用户浏览点击等日志类数据甚至要比它大几个数量级。我们的系统需要有能力在大量实时数据写入的同时提供低延迟的查询能力。
  • 服务 / 分析的融合:传统的 OLAP 系统在业务中往往扮演着比较静态的角色。我们通过分析海量的数据得到业务的洞察(比如说预计算好的视图、模型等),这些获得的知识通过另外一个系统提供在线数据服务。这里的服务和分析是个割裂的过程。与此不同的是,理想的业务决策过程往往是一个持续优化的在线过程。服务的过程会产生大量的新数据,我们需要对这些新数据进行复杂的分析。分析产生的洞察实时反馈到服务创造更大的商业价值。服务和分析正在形成一个闭环。

现有的解决方案通过一系列产品的组合来解决实时的服务 / 分析融合的需求。比如说,通过 Apache Flink 做数据的实时预聚合,聚合后的数据会存储在类似 Apache Druid 这种提供多维分析的产品中,并且通过 Apache HBase 这类产品来提供数据服务。这种烟囱式开发的模式会不可避免地产生数据孤岛,从而引起不必要的数据重复,各个产品间复杂的数据同步也使数据的一致性和安全性成为挑战。这种复杂度使得应用开发很难快速响应新需求,影响了业务的迭代速度,也给开发和运维都带来了较大的额外开销。
03.jpgimage.gif
我们认为实时的服务 / 分析的融合应该通过一个统一的 Hybrid Serving/Analytical Processing(HSAP)系统来实现。
通过这样一个系统,应用开发不再需要和多个不同的产品打交道,不再需要去学习和接受每个产品的问题和局限,这能够大大简化业务的架构,提升开发和运维效率。这样一个统一的系统能够避免不必要的数据重复从而节约成本。同时这种架构还能够为系统带来秒级甚至亚秒级的实时性,让业务的决策更实时,从而让数据发挥出更大的商业价值。

分布式 HTAP 系统虽然具有了实时分析的能力,但是并不能解决大数据的问题。

首先,交易系统同步过来的数据只是实时推荐系统需要处理的一小部分数据,其他绝大部分数据来自日志等非交易系统(用户每次购买前往往有数十个甚至数百个浏览行为),大部分分析是在这些非交易数据上进行的。但 HTAP 系统并没有这部分数据,所以在这些非交易数据上做分析就无从谈起。
那么是不是可以将这些非交易数据写入 HTAP 系统来进行分析呢?我们来分析一下 HTAP 系统和 HSAP 系统在数据写入模式上的不同。HTAP 系统的基石和优势是支持细粒度的分布式事务,交易型数据往往以很多分布式小事务的方式写入 HTAP 系统。然而来自日志等系统的数据并没有细粒度分布式事务的语意,如果要把这些非交易型数据导入 HTAP 系统势必会带来不必要的开销。
相比之下, HSAP 系统并没有这种高频率分布式小事务的需求。数据写入 HSAP 系统一般有两种模式:1)海量的单条数据实时写入;2)相对低频的分布式批量数据写入。这就允许 HSAP 系统在设计上做出一系列优化,从而提升性价比,避免把非交易型数据导入 HTAP 系统带来的不必要开销。
就算我们不在乎这些开销,假设能不计成本把数据都写入 HTAP 系统,是不是就解决问题了呢?答案仍然是否定的。
支持好 OLTP 的场景是 HTAP 系统的前提条件,为了做到这点,HTAP 系统往往采用了行存的数据格式,而分析型的查询在行存的效率相比于列存有很大的(数量级的)劣势。具备分析的能力和能够高效地分析并不是一回事。为了提供高效分析的能力,HTAP 系统必须把海量的非交易数据复制到列存,但这势必带来不小的成本,不如把少量的交易数据复制到 HSAP 系统成本更低,同时还能更好地避免对线上交易系统产生影响。
所以,我们认为 HTAP 和 HSAP 会相辅相成,分别引领数据库和大数据领域的方向。

HSAP 的挑战

作为一种全新的架构,HSAP 面临着和已有的大数据以及传统的 OLAP 系统相比很不一样的挑战。

高并发的混合工作负载:HSAP 系统需要处理远远超出传统的 OLAP 系统的并发查询。在实践中,数据服务的并发远远超出了 OLAP 查询。比如说,我们在实践中见到数据服务需要处理高达每秒钟数千万个查询,这比 OLAP 查询的并发高出了 5 个数量级。同时,和 OLAP 查询相比,数据服务型查询对延迟有着更加苛刻的要求。除此之外,更大的挑战是系统在提供数据服务查询的同时需要处理非常复杂的分析型查询。这些混合查询负载在延迟和吞吐间有着非常不同的取舍。如何高效地利用系统资源处理好这些非常不一样的查询,并且保证每个查询的 SLO 是一个巨大的挑战。

高吞吐实时数据导入:在处理高并发的查询负载的同时,HSAP 系统还需要支持海量数据的实时写入。这些实时写入的数据量远远超出了传统的 OLAP 系统的需求。比如说,上面的实时推荐场景会持续写入每秒钟数千万甚至上亿条事件。和传统的 OLAP 系统的另外一个区别是 HSAP 系统对数据的实时性有着很高的要求,写入的数据需要在秒级甚至亚秒级可见,这样才能保证我们服务和分析结果的时效性。

弹性和可扩展性:数据写入和查询负载可能会有突发的高峰,这对系统提出了很高的弹性和可扩展性的要求。在实践中,我们注意到数据写入峰值能达到平均的 2.5 倍,查询的峰值能达到平均的 3 倍。而且数据写入和查询的峰值不一定同时出现,这也需要系统有根据不同的峰值做迅速调整的能力。

HSAP 的系统设计

为了应对这些挑战,我们认为一个典型的 HSAP 系统可以采用类似于上图的一个架构。
image.gif04.jpg
存储计算分离:所有的数据存储在一个分布式文件系统中,我们以数据分片的方式来扩展系统,Storage Manager 会管理这些数据分片(Shard),Resource Manager 管理系统的计算资源,保证系统能够处理高吞吐的数据写入和查询的需求。这种架构能够快速应对工作负载的变化,当查询负载变大需要更多的计算资源的时候可以扩展计算资源,当数据量快速增长的时候可以快速扩展存储资源。存储计算分离的架构保证了不需要等待移动 / 拷贝数据就能快速完成这些操作。这种架构较大地简化了运维,为系统的稳定性提供了保障。

统一的实时存储:为了能够支持各种查询模式,统一的实时存储层至关重要。查询大体可以分为两类,一类是简单的点查询(数据服务类的大多是这类),另一类是扫描大量数据的复杂查询(分析类的大多是这类),当然这是一个连续变化的过程,很多查询介于两者之间。这两种查询模式对数据存储也提出了不同的要求。行存储能够比较高效地支持点查询,而列存储在支持大量扫描的查询上有明显的优势。我们可以通过类似 PAX 的方式在行存和列存之间做一个折衷,付出的代价是可能在点查和扫描数据的场景都不能获得最佳的性能。我们希望在两种场景都做到最优,所以在系统里同时支持了行存和列存,用户可以根据场景选择每个表的存储方式。对同时有两种需求的表我们通过索引的抽象允许用户同时选择两种存储,系统通过索引维护的机制保证两者间的一致性。在实践中我们发现这种设计带来的效率和灵活性能够更好地支持业务。

工作负载的隔离:系统在混合工作负载下的 SLO 是通过调度来保证的。在理想情况下,一个大查询就应该能把所有的资源都利用起来。而当有多个查询同时运行的时候,这些查询需要公平地共享资源。由于服务型的查询通常比较简单从而需要的资源比较少,这种公平调度的机制能够保证服务型查询的延迟即使在有复杂的分析型查询的情况下仍然能够得到保障。作为一个分布式的系统,调度可以分为分布式和进程内两部分。Coordinator 会把一个查询分解为多个任务,这些任务被分发到不同的进程,Coordinator 需要采取一定的策略保证公平性。同样重要的是,在一个进程内我们也需要让不同任务公平地分享资源。由于操作系统并不理解任务间的关系,所以我们在每个进程里实现了一个用户态的 Scheduler 去更灵活地支持工作负载的隔离。

系统的开放性:很多业务已经使用了其他存储平台或者计算引擎,新的系统必须考虑和已有系统的融合。对时效性要求高的查询,计算和存储的一体化能够带来明显的优势。但是对时效性不高的离线计算,存储层可以提供统一的接口开放数据,这种开放性允许其他引擎把数据拉出去处理能够赋予业务更大的灵活度。开放性的另外一面是对存储在其他系统中数据进行处理的能力,这个可以通过联邦查询的方式去实现。

HSAP 的应用

这里我们分享一下阿里巴巴搜索推荐精细化运营业务,下图显示了在采用 HSAP 前这样一个系统架构的示例。
05.jpgimage.gif
我们通过一系列存储和计算引擎(HBase、Druid、Hive、Drill、Redis 等)的复杂配合才能满足业务的需求,并且多个存储之间需要通过数据同步任务来保持大致的同步。这种业务架构极其复杂,整个业务的开发耗费了大量的时间。
06.jpg
我们在 2019 年的双十一使用 HSAP 系统升级了这个业务,新架构得到了极大的简化。用户、商品、商家属性数据和海量的用户行为数据经过实时和离线的数据清洗统一进入 HSAP 系统,由 HSAP 系统向上承接了实时大屏、实时报表、效果跟踪、实时数据应用等查询和分析服务。实时大屏、实时销售预测、实时库存监控、实时 BI 报表实时监测业务进展,洞悉运营增长,跟踪算法效果,从而助力高效决策。实时标签、实时画像、竞对分析、圈人圈品、权益投放等数据产品助力精细化运营和决策。实时数据接口服务支持算法调控、库存监控预警等服务。一套 HSAP 系统实现了全渠道全链路的数据共享和复用,解决了运营、产品、算法、开发、分析师到决策层不同业务视角的数据分析和查询需求。

总结

HSAP 架构通过统一的实时存储,数据无需复制就能一站式提供简单查询、OLAP 分析、在线数据服务等多样化的数据查询和应用服务,满足数据应用方的访问和接入需求。这种新架构大大地降低了业务的复杂度,让我们能够快速应对新的业务需求。它提供的秒级甚至亚秒级实时性让决策更及时高效,从而让数据创造出更大的商业价值。
最后,欢迎加入交互式分析Hologres交流群
image.png

]]>
错误码如何设计才合理?-阿里云开发者社区 Sat, 04 Jul 2020 09:33:03 +0800 image.png

一 前言

在工作中,接触过不少外部接口,其中包括:支付宝,微信支付,微博开发平台,阿里云等等。每家公司错误码风格都不尽相同,有使用纯数字的,有使用纯英文的,也有使用字母和数字组合的。也接触过很多内部系统,错误码设计也不尽相同。

错误码的输出路径

面向日志输出

  • 服务内传递,最终是输出到日志。
  • 域内服务间,比如同时大麦电商之间的系统,最终目的是输出到日志。

面向外部传递

  • 域内向域外
  • 服务端传递到前端
  • OpenAPI 错误码
  • 内部不同域之间

错误码使用场景

  • 通过错误码配置监控大盘。
  • 通过日志进行问题排查,快速定位问题。
  • 后端服务之间错误码传递。
  • 前端展示的错误提示/OpenAPI。

本文希望从错误码使用的不同场景讨论得到一个合理的错误码规约,得到一个面向日志错误码标准和一个面向外部传递的错误码标准。

PS:本文引用全部引自阿里巴巴《Java 开发手册》,下称《手册》。

二 什么是错误码

错误码要回答的最根本的问题是,谁的错?错在哪?

那么一个错误能表示出谁的错和错在哪里就是一个好的错误码吗?答案显然是否定的,这个标准太基础了。

  • 好的错误码必须能够快速知晓错误来源。
  • 好的错误码必须易于记忆和对比。
  • 好的错误码必须能够脱离文档和系统平台达到线下轻量沟通的目的(这个要求比较高)。

引自《手册》- 异常日志-错误码

错误码的制定原则:快速溯源、简单易记、沟通标准化。

说明:错误码想得过于完美和复杂,就像康熙字典中的生僻字一样,用词似乎精准,但是字典不容易随身携带并且简单易懂。
正例:错误码回答的问题是谁的错?错在哪?
1)错误码必须能够快速知晓错误来源,可快速判断是谁的问题。
2)错误码易于记忆和比对(代码中容易 equals)。
3)错误码能够脱离文档和系统平台达到线下轻量化地自由沟通的目的。

这个原则写在异常日志-错误码这个章节,我认为同样适用在面向用户的错误码。

image.png

三 错误码规范

错误码定义要有字母也要有数字

纯数字错误码

错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。

说明:数字是一个整体,每位数字的地位和含义是相同的。
反例:一个五位数字 12345,第1位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

《手册》说明了纯数字错误码存在的问题。

纯字母错误码

那么纯字母错误码不香吗?有两个问题:

  • 对于使用汉语的我们用英语去准确描述一个错误有时是比较困难的。
  • 纯英文字母的错误码不利于排序。

错误码尽量有利于不同文化背景的开发者进行交流与代码协作。

说明:英文单词形式的错误码不利于非英语母语国家(如阿拉伯语、希伯来语、俄罗斯语等)之间的开发者互相协作。

快速溯源 | 简单易记 | 沟通标准化

什么是快速溯源?就是一眼看上去就知道哪里出了什么问题。

李雷负责 A 服务,韩梅梅负责 B 服务。韩梅梅发现服务 B 出现了一个错误码,韩梅梅能够快速定位这是服务 A 的内部业务异常造成的问题,这个时候韩梅梅就可以拿着错误码找到李雷说,"hi,Li Lei,How old are you。(李雷,怎么老是你)"。李雷拿过来错误码一看,内心万马奔腾,一下就能知道这是上游 Polly 负责的应用阿尔法出了错。

怎么能达到这个效果呢?

  • 首先要有一套标准并且在域内各个业务都在用同样的标准。
  • 其次要求错误码有自我解释的能力是有信息含量的有意义。
  • 最后在域内要传递错误码。

错误码标准的意义

开宗明义借用了《手册》对于错误码定义的原则作为错误码规范能够给我们带来的收益。我想再次强调并且试着从反面阐述没有错误码标准会带来的成本。

错误码是用来做沟通的:系统与系统间的沟通,人与人间的沟通,人与系统间的沟通。

试想下面这个场景:

韩梅梅看到一个异常日志其中一个纯数字的错误码。

韩梅梅需要理解这串数字代表的是什么,它到底是不是一个错误码,经过几秒钟确定下来这是一个错误码,但她不能确定这是不是本系统中错误码,因为在她负责的系统是由韩梅梅、Lucy 和 Lily 三个人共同维护的,每个人都按照自己的理解定义了一套错误码。

韩梅梅去系统源码中查找这个错误码,但是发现这个错误码并不是本系统的错误码。

然后再前翻两页后翻两页从日志上下文中确定这是李雷负责系统的错误码,“Li Lie,how old are you?”。

韩梅梅把错误码甩到李雷脸上,李雷一脸懵逼,这是我的系统的错误码吗?

李雷也不确定,因为李雷负责的系统是由李雷、林涛和 Jim 维护的,也是三人共同维护的。

李雷只好打开源码,还真是!

上边的场景经过了发现-初判断-判断来源-确定来源-沟通-二次判断-二次确认七个步骤。

希望上边的场景描述能够说明没有统一标准的错误所带来的成本。

四 面向日志的错误码

输出到日志的错误码有两个用途:

  • 用来快速溯源找到问题。
  • 用来形成监控大盘。

错误码设计

《手册》对于错误码的建议有非常多的可取参考的地方:

错误码不体现版本号和错误等级信息。

说明:错误码以不断追加的方式进行兼容。错误等级由日志和错误码本身的释义来决定。

错误码为字符串类型,共 5 位,分成两个部分:错误产生来源+四位数字编号。

错误码不能直接输出给用户作为提示信息使用。

说明:堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip)是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。

在获取第三方服务错误码时,向上抛出允许本系统转义,由 C 转为 B,并且在错误信息上带上原有的第三方错误码。

结合错误码设计原则、错误码用途、规约建议,面向服务端日志的错误码应该是如下形式。

错误码分为一级宏观错误码、二级宏观错误码、三级宏观错误码。

错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。
说明:数字是一个整体,每位数字的地位和含义是相同的。

反例:一个五位数字 12345,第 1 位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

按照《手册》的建议设计出的面向日志的错误码定义共十三位(十位有意义,三位连接符),并且应该具有如下分类:

  • 应用标识,表示错误属于哪个应用,三位数字。
  • 功能域标识,表示错误属于应用中的哪个功能模块,三位数字。
  • 错误类型,表示错误属于那种类型,一位字母。
  • 错误编码,错误类型下的具体错误,三位数字。

image.png

《手册》还有一条是规定错误码应该如何定义:

错误码为字符串类型,共 5 位,分成两个部分:错误产生来源+四位数字编号。

说明:错误产生来源分为 A/B/C,A 表示错误来源于用户,比如参数错误,用户安装版本过低,用户支付超时等问题;B 表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;C 表示错误来源于第三方服务,比如 CDN 服务出错,消息投递超时等问题;四位数字编号从 0001 到 9999,大类之间的步长间距预留 100。

五位错误码的好处是易记,但是对于面向日志的错误码场景利用错误码制作需要分类的业务监控大盘将变得比较困难,比如统计应用 A 的功能 B 的错误出现次数。

同样在系统间传递这个类型的错误码非常有可能发生错误码冲突。

当然对于分为四段的错误码同样尤其不好的一面,应用标识和功能域标识需要有专人去管理或者开发一个错误码管理工具,否则时间一长很容易产生定义的混乱形成破窗。

《手册》对于错误码定义我认为非常适合面向外部传递的错误码。简单、易记、是大家熟悉的错误码样式,并且透出的错误码数量是非常有限的。

不用枚举定义错误码

国际化支持是一个不使用枚举定义错误码很重要的理由。

我们通过 i18n 的支持可以做到错误码、错误状态、错误描述的管理。

五 面向外部传递的错误码

面向外部传递的错误码是为了把域内的错误信息传递出去。

可以让域外系统通过错误码进行错误码进行后续的动作或是中断操作或是记录日志继续执行。

可以让前端通过错误码给出用户准确的错误提示或者忽略错误进行重试。

错误码设计

根据《手册》给出的错误码定义建议设计出的面向外部传递的错误码共五位,并且有如下分类:

  • 错误类型,表示错误来源,一位字母。
  • 错误编码,表示具体错误,四位数字。

image.png

错误码的后三位编号与 HTTP 状态码没有任何关系。

错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。

说明:数字是一个整体,每位数字的地位和含义是相同的。
反例:一个五位数字 12345,第1位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

下图是《手册》给出的错误码示例:

image.png

他山之石

他山之石不一定能攻玉。

谷歌 API 错误码定义

谷歌 API 的错误码定义与 HTTP 状态码有着非常强的联系,并且是一个全数字错误码定义。

没有明显的错误分类,快速识别和自解释能力比较弱。

image.png

腾讯 OpenAPI(文智)错误码定义

这也是一个全数字的错误码,没有明确的分类字段,纯数字的某一位已看不出明显的分类。

不利于进行感性记忆。
image.png

微博 API 错误码定义

同样是全数字的错误码定义:

image.png

其他建议

《手册》中有一条建议:

全部正常,但不得不填充错误码时返回五个零:00000。

这也是在其他家 API 错误码中能够看到的定义。

参考

《阿里巴巴java开发手册》
《Google API Design Guide 》(https://www.bookstack.cn/books/API-design-guide
《阿里云-文件存储-错误码》(https://help.aliyun.com/document_detail/62603.html
《微博开放平台-API-错误码》(https://open.weibo.com/wiki/Help/error
《腾讯开放平台-错误码》(https://wiki.open.qq.com/wiki/%E9%94%99%E8%AF%AF%E7%A0%81

]]>
在Kubernetes中用Alluxio加速Spark数据访问(一)-阿里云开发者社区 Sat, 04 Jul 2020 09:33:03 +0800 1.背景信息

1.1 alluxio

Alluxio是一个开源的基于内存的分布式存储系统,适合作为云上大数据和AI / ML的数据编排方案。Alluxio可以同时管理多个底层文件系统,将不同的文件系统统一在同一个名称空间下,让上层客户端可以自由访问统一名称空间内的不同路径,不同存储系统的数据。

alluxio的short-circuit功能可以使alluxio客户端直接访问alluxio worker所在主机的工作存储,而不需要通过网络栈与alluxio worker完成通信,可以提高性能。

1.2 spark operator

Spark-operator用于管理k8s集群中spark job。通过spark-operator可以在k8s集群中创建、查看和删除spark job。

2.前提条件

本文档的操作依赖如下的一些条件:

  • kubernetes集群:版本大于1.8,本次实验的集群通过阿里云容器服务创建,集群名称为"ack-create-by-openapi-1"。

image.png

  • 安装有linux或者mac操作系统的计算机作为我们的实验环境(本次实验中,假设该计算机名称为alluxio-test)。该计算机需要准备如下环境:

    • docker >= 17.06
    • kubectl >= 1.8,能够连接kubernets集群ack-create-by-openapi-1

3.实验步骤

实验步骤主要包括如下几步:

  • 部署alluxio
  • 部署spark-operator
  • 制作spark docker镜像
  • 上传文件到alluxio
  • 提交spark job

下面将对每个步骤进行说明:

3.1 部署alluxio

进入容器服务应用目录,在右上角的搜索框中搜索"alluxio",然后进入alluxio主界面,如图:
image.png

选择“参数”,修改配置中properties部分的"alluxio.user.short.circuit.enabled"值为"false",然后选择将alluxio安装到目标集群上(本次实验的集群为"ack-create-by-openapi-1"),最后点击创建,如图
image.png

点击创建后,使用kubectl给待安装的alluxio组件的节点打上标签"alluxio=true",首先查看该集群有哪些节点:

$ kubectl get nodes -o wide
NAME                      STATUS   ROLES    AGE   VERSION            INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                               KERNEL-VERSION            CONTAINER-RUNTIME
cn-beijing.192.168.8.12   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.12   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.13   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.13   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.14   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.14   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.15   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.15   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.16   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.16   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.17   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.17   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5

可以看到有三个worker节点,分别为:

  • cn-beijing.192.168.8.15
  • cn-beijing.192.168.8.16
  • cn-beijing.192.168.8.17

我们给是三个节点都打上标签"alluxio=true":

$ kubectl label nodes cn-beijing.192.168.8.15 
  cn-beijing.192.168.8.16 
  cn-beijing.192.168.8.17 
  alluxio=true

使用kubectl查看各个pod是否都处于running状态:

$ kubectl get po -n alluxio
NAME                   READY   STATUS    RESTARTS   AGE
alluxio-master-0       2/2     Running   0          4h1m
alluxio-worker-5zg26   2/2     Running   0          4h1m
alluxio-worker-ckmr9   2/2     Running   0          4h1m
alluxio-worker-dvgvd   2/2     Running   0          4h1m

验证alluxio是否处于ready:

$ kubectl exec -ti alluxio-master-0 -n alluxio bash

//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fsadmin report capacity

Capacity information for all workers:
    Total Capacity: 3072.00MB
        Tier: MEM  Size: 3072.00MB
    Used Capacity: 0B
        Tier: MEM  Size: 0B
    Used Percentage: 0%
    Free Percentage: 100%

Worker Name      Last Heartbeat   Storage       MEM
192.168.8.15    0                capacity      1024.00MB
                                  used          0B (0%)
192.168.8.16    0                capacity      1024.00MB
                                  used          0B (0%)
192.168.8.17    0                capacity      1024.00MB
                                  used          0B (0%)

3.2 部署spark-operator

进入容器服务应用目录,在右上角的搜索框中搜索"ack-spark-operator",然后进入ack-spark-operator主界面,如图:
image.png
选择将ack-spark-operator安装到目标集群上(本次实验的集群为"ack-create-by-openapi-1"),然后点击创建,如图:
image.png

本次实验将会使用sparkctl向k8s集群提交一个spark job,需要将sparkctl安装到我们在"2.前提条件"中所提到的实验环境"alluxio-test"中:

$ wget http://spark-on-k8s.oss-cn-beijing.aliyuncs.com/sparkctl/sparkctl-linux-amd64 -O /usr/local/bin/sparkctl
$ chmod +x /usr/local/bin/sparkctl

3.3 制作spark docker镜像

spark下载页面下载所需的spark版本,本次实验选择的saprk版本为2.4.6。运行如下命令下载spark:

$ cd /root
$ wget https://mirror.bit.edu.cn/apache/spark/spark-2.4.6/spark-2.4.6-bin-hadoop2.7.tgz
#

下载完成后,执行解压操作:

$ tar -xf spark-2.4.6-bin-hadoop2.7.tgz
$ export SPARK_HOME=/root/spark-2.4.6-bin-hadoop2.7

spark docker镜像是我们提交spark任务时使用到的镜像,这个镜像中需要包含alluxio client jar包。使用如下的命令获取alluxio client jar包:

$ id=$(docker create alluxio/alluxio-enterprise:2.2.1-1.4)
$ docker cp $id:/opt/alluxio/client/alluxio-enterprise-2.2.1-1.4-client.jar 
    $SPARK_HOME/jars/alluxio-enterprise-2.2.1-1.4-client.jar
$ docker rm -v $id 1>/dev/null

alluxio client jar包准备好以后,开始构建镜像:

$ docker build -t spark-alluxio:2.4.6 -f kubernetes/dockerfiles/spark/Dockerfile $SPARK_HOME

请记住镜像名称“spark-alluxio:2.4.6”,在向k8s提交spark job中会用到这个信息。

镜像构建完成以后,对镜像的处理有两种方式:

  • 如果有私有镜像仓库,将该镜像推送到私有镜像仓库中,同时保证k8s集群节点能够pull该镜像
  • 如果没有私有镜像仓库,那么需要使用docker save命令将该镜像导出,然后scp到k8s集群的各个节点,在每个节点上使用docker load命令将镜像导入,这样就能保证每个节点上都存在该镜像。

3.4 上传文件到alluxio

文章开头提到过:本次实验是提交一个spark job到k8s中,该spark job的目标是对某一个文件统计每一个单词出现的次数。现在需要把这个文件传到alluxio存储上,这里为了方便,直接把alluxio master中/opt/alluxio-2.3.0-SNAPSHOT/LICENSE(文件路径可能因alluxio版本有点差异)这个文件传到alluxio上。

使用"kubectl exec"进入alluxio master pod,并拷贝当前目录下的LICENSE文件到alluxio的根目录中:

$ kubectl exec -ti alluxio-master-0  -n alluxio bash
//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fs copyFromLocal LICENSE /

接着查看一下LICENSE这个文件分成的block被alluxio放到哪些worker上了。

$ kubectl exec -ti alluxio-master-0 -n alluxio bash
//下面步骤alluxio-master-0 pod中执行

bash-4.4# alluxio fs stat /LICENSE
/LICENSE is a file path.
FileInfo{fileId=33554431, fileIdentifier=null, name=LICENSE, path=/LICENSE, ufsPath=/opt/alluxio-2.3.0-SNAPSHOT/underFSStorage/LICENSE, length=27040, blockSizeBytes=67108864, creationTimeMs=1592381889733, completed=true, folder=false, pinned=false, pinnedlocation=[], cacheable=true, persisted=false, blockIds=[16777216], inMemoryPercentage=100, lastModificationTimesMs=1592381890390, ttl=-1, lastAccessTimesMs=1592381890390, ttlAction=DELETE, owner=root, group=root, mode=420, persistenceState=TO_BE_PERSISTED, mountPoint=false, replicationMax=-1, replicationMin=0, fileBlockInfos=[FileBlockInfo{blockInfo=BlockInfo{id=16777216, length=27040, locations=[BlockLocation{workerId=8217561227881498090, address=WorkerNetAddress{host=192.168.8.17, containerHost=, rpcPort=29999, dataPort=29999, webPort=30000, domainSocketPath=, tieredIdentity=TieredIdentity(node=192.168.8.17, rack=null)}, tierAlias=MEM, mediumType=MEM}]}, offset=0, ufsLocations=[]}], mountId=1, inAlluxioPercentage=100, ufsFingerprint=, acl=user::rw-,group::r--,other::r--, defaultAcl=}
Containing the following blocks:
BlockInfo{id=16777216, length=27040, locations=[BlockLocation{workerId=8217561227881498090, address=WorkerNetAddress{host=192.168.8.17, containerHost=, rpcPort=29999, dataPort=29999, webPort=30000, domainSocketPath=, tieredIdentity=TieredIdentity(node=192.168.8.17, rack=null)}, tierAlias=MEM, mediumType=MEM}]}

可以看到LICENSE这个文件只有一个block(id为16777216),被放在了ip为192.168.8.17的k8s节点上。我们使用kubectl查看该节点名称为cn-beijing.192.168.8.17

$ kubectl get nodes -o wide
NAME                      STATUS   ROLES    AGE   VERSION            INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                               KERNEL-VERSION            CONTAINER-RUNTIME
cn-beijing.192.168.8.12   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.12   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.13   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.13   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.14   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.14   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.15   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.15   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.16   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.16   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.17   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.17   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5

3.5 提交spark job

下面的步骤将提交一个spark job到k8s集群中,该job主要是计算alluxio中/LICENSE文件的每个单词出现的次数。

在步骤3.4中我们获取到LICENSE这个文件所包含的block都在节点cn-beijing.192.168.8.17上,此次实验中,我们通过指定node selector让spark driver和spark executor都运行在节点cn-beijing.192.168.8.17,验证在关闭alluxio的short-circuit功能的情况下,spark executor和alluxio worker之间的通信是否通过网络栈完成。

  • 说明:如果在开启alluxio的short-circuit功能的情况下,并且spark executor与其所要访问的文件(本次实验为/LICENSE这个文件)的block在同一个k8s节点上,那么spark executor中的alluxio client与该k8s节点上的alluxio worker之间的通信通过domain socket方式完成。

首先生成提交spark job的yaml文件:

$ export SPARK_ALLUXIO_IMAGE=<步骤3.3中制作的image,即spark-alluxio:2.4.6>
$ export ALLUXIO_MASTER="alluxio-master-0"
$ export TARGET_NODE=<步骤3.4获取到的LICENSE文件的block存储的节点,即cn-beijing.192.168.8.17>
$ cat > /tmp/spark-example.yaml <<- EOF
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: spark-count-words
  namespace: default
spec:
  type: Scala
  mode: cluster
  image: "$SPARK_ALLUXIO_IMAGE"
  imagePullPolicy: Always
  mainClass: org.apache.spark.examples.JavaWordCount
  mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.6.jar"
  arguments:
    - alluxio://${ALLUXIO_MASTER}.alluxio:19998/LICENSE
  sparkVersion: "2.4.5"
  restartPolicy:
    type: Never
  volumes:
    - name: "test-volume"
      hostPath:
        path: "/tmp"
        type: Directory
  driver:
    cores: 1
    coreLimit: "1200m"
    memory: "512m"
    labels:
      version: 2.4.5
    serviceAccount: spark
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
    nodeSelector:
      kubernetes.io/hostname: "$TARGET_NODE"
  executor:
    cores: 1
    instances: 1
    memory: "512m"
    labels:
      version: 2.4.5
    nodeSelector:
      kubernetes.io/hostname: "$TARGET_NODE"
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
EOF

然后,使用sparkctl提交spark job:

$ sparkctl create /tmp/spark-example.yaml

4.实验结果

当提交任务后,使用kubectl查看spark driver的日志:

$ kubectl get po -l spark-role=driver
NAME                                 READY   STATUS      RESTARTS   AGE
spark-alluxio-1592296972094-driver   0/1     Completed   0          4h33m

$ kubectl logs spark-alluxio-1592296972094-driver --tail 20

USE,: 3
Patents: 2
d): 1
comment: 1
executed: 1
replaced: 1
mechanical: 1
20/06/16 13:14:28 INFO SparkUI: Stopped Spark web UI at http://spark-alluxio-1592313250782-driver-svc.default.svc:4040
20/06/16 13:14:28 INFO KubernetesClusterSchedulerBackend: Shutting down all executors
20/06/16 13:14:28 INFO KubernetesClusterSchedulerBackend$KubernetesDriverEndpoint: Asking each executor to shut down
20/06/16 13:14:28 WARN ExecutorPodsWatchSnapshotSource: Kubernetes client has been closed (this is expected if the application is shutting down.)
20/06/16 13:14:28 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!
20/06/16 13:14:28 INFO MemoryStore: MemoryStore cleared
20/06/16 13:14:28 INFO BlockManager: BlockManager stopped
20/06/16 13:14:28 INFO BlockManagerMaster: BlockManagerMaster stopped
20/06/16 13:14:28 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
20/06/16 13:14:28 INFO SparkContext: Successfully stopped SparkContext
20/06/16 13:14:28 INFO ShutdownHookManager: Shutdown hook called
20/06/16 13:14:28 INFO ShutdownHookManager: Deleting directory /var/data/spark-2f619243-59b2-4258-ba5e-69b8491123a6/spark-3d70294a-291a-423a-b034-8fc779244f40
20/06/16 13:14:28 INFO ShutdownHookManager: Deleting directory /tmp/spark-054883b4-15d3-43ee-94c3-5810a8a6cdc7

最后我们登陆到alluxio master上,查看相关指标统计到的值:

$ kubectl exec -ti alluxio-master-0 -n alluxio bash
//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fsadmin report metrics
Cluster.BytesReadAlluxio  (Type: COUNTER, Value: 290.47KB)
Cluster.BytesReadAlluxioThroughput  (Type: GAUGE, Value: 22.34KB/MIN)
Cluster.BytesReadDomain  (Type: COUNTER, Value: 0B)
Cluster.BytesReadDomainThroughput  (Type: GAUGE, Value: 0B/MIN)

BytesReadAlluxio和BytesReadAlluxioThroughput代表数据从网络栈传输;BytesReadDomain和BytesReadDomainThroughput代表数据从domain socket传输。可以看到所有数据都是从网络栈传输的(即使spark executor和LICENSE文件的block在同一k8s节点上)。

5.参考文档

]]>
【精品问答】110+数据挖掘面试题集合 | 技术日报(17期)-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 每日干货推荐

年中福利!阿里技术电子书 80 本+上半年大会资料 PDF 免费下载! >>>

阿里云开发者社区超大技术福利!80+阿里系电子书开放下载,覆盖 Java、物联网、云原生、前端、大数据、开源、AI 等技术领域,深度分享阿里工程师实践精华,顶级技术内容一手掌握。

更多精彩文章

编程萌新看过来,一文带你入门Python | 伸手党福利篇>>>

这是一篇介绍Python入门的文章,对于没有任何编程经验甚至不懂电脑的新手都是非常实用的。本文会从计算机的使用开始讲解,中间搭配一些经典的针对知识点的练习,最终大家都可以用Python开发出一个小游戏,快来跟我一起往下看!

【【精品问答】110+数据挖掘面试题集合>>>

数据挖掘工程师面试宝典双手呈上,快来收藏吧!

精品公开课

阿里云千万级架构的构建——架构的成长演变之路>>>

在阿里云我们如何构建千万级架构?本次分享内容摘选《「阿里云」运维架构实践秘籍》,主要介绍了在云端如何从单机演变到如今普及的分布式+大数据架构,并且又如何演变到微服务+Fast Data千万级架构。

]]>
阿里云省钱方法5条-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 以最省钱的方式购买阿里云服务器等云产品,要学会合理用户资格、代金券优惠和促销活动,才是最省钱的方法,利用好下面这5种方法,可以有效的节约我们购买阿里云产品的成本。

阿里云省钱方法第1条:阿里云代金券一定要领取

阿里云代金券是阿里云官方的一种长期行活动,旨在让用户利用代金券减少购买阿里云服务器等产品的成本,代金券有云服务器专用代金券、云数据库产品专用代金券、云产品通用代金券,其中云服务器专用代金券和云产品通用代金券是我们在购买阿里云服务器的时候可以使用的,使用方法的是最后支付购买订单的时候,系统会自动根据订单金额匹配可使用的代金券面额。
阿里云代金券地址:阿里云官方云小站
代金券抵扣最新版.png

阿里云省钱方法第2条:尽量使用新用户账号购买

阿里云针对新用户的优惠力度是最大的,无论是注册域名还是购买阿里云虚拟主机、ecs云服务器等热门产品,新用户的优惠力度都是最大的,例如1核1GB基础版的阿里云独享云虚拟主机,新用户购买只要206元,而老用户购买就需要500元了,足足高了294元。
新用户还有一个好处就是参与阿里云的各种促销活动更加便利,因为阿里云的促销活动大多都只限新用户购买,例如当下最热门的活动价格只要91.80元的共享型s6实例1核2G1M带宽云服务器,就只能新用户购买。
新用户优惠.png

阿里云省钱方法第3条:尽量通过阿里云促销活动购买

阿里云的各种促销活动不仅包含阿里云服务器产品,其他阿里云热门产品,例如云数据库、CDN、防火墙、云安全类产品都是可以通过促销活动购买到的,利用活动购买可以便宜很多,例如用户购买最多的计算型c5实例2核4G配置的阿里云服务器,通过阿里云活动购买价格只要699.84元,比原价购买节省了1892.16元。
699.png

阿里云省钱方法第4条:合理利用学生身份

阿里云针对学生用户是有单独优惠的,如果你的实名认证身份证没有超过24岁,那么你可以直接获得学生身份,有了学生身份可以以9.5元一个月、114元一年的优惠价格购买到一款1核2G配置的ecs云服务器或者轻量应用服务器。
阿里云学生机申请地址:云翼计划
学生套餐.png

阿里云省钱方法第5条:老用户也要学会利用好阿里云各种优惠福利

虽然阿里云针对老用户的专属活动不多,但是我们应该多关注阿里云各种活动的具体规则,有些优惠政策老用户也是可以参与的,例如618年中大促活动中的云服务器专场,就有如下优惠政策是老用户也可以参与的:

  • 续费权益规则:活动期间,领取到续费权益的用户,可享受单实例续费,包1年7折优惠。
  • 购物车满减权益规则:活动期间,领取到购物车满减权益的用户,可在页面选择产品加入购物车后享受。
    618权益.png

以上就是5条当下比较有效的阿里云省钱方法,相信利用好这些方法,可以帮助我们以最低的价格购买到自己所需的阿里云产品。

]]>
浅谈动图文件格式 - GIF-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

简介

GIF的全称是Graphics Interchange Format,可译为图形交换格式,用于以超文本标志语言(Hypertext Markup Language)方式显示索引彩色图像,在因特网和其他在线服务系统上得到广泛应用。GIF虽然是一个古老的文件格式,但是随着移动互联网的发展,在手机社交应用中因表情包和动图的火爆而重新大范围的进入公众视野, 重新流行起来。

版本

GIF具有GIF87a和GIF89a两个版本。
GIF87a版本是1987年推出的,一个文件存储一个图像,严格不支持透明像素;GIF87a采用LZW压缩算法,它能够在保持图像质量的前提下将图像尺寸压缩百分之二十到二十五。
GIF89a版本是1989年推出的很有特色的版本,该版本允许一个文件存储多个图像,可实现动画功能,允许某些像素透明。在这个版本中,为GIF文档扩充了图形控制区块、备注、说明、应用程序编程接口4个区块,并提供了对透明色和多帧动画的支持。

文件格式详解

一个典型的GIF文件,由以下内容构成:

  • Q:这是什么文件?A:GIF (Header)
  • Q:显示它需要多大的区域?A:宽xxx,高xxx(LSD)
  • Q:显示它需要准备哪些色彩?A:色表(LSD、GCT、ID、LCT)
  • Q:某一帧的内容是什么样的?A:LZW压缩后的像素列表
  • Q:如何绘制?A:位置、尺寸、透明色、隔行扫描(GCE、ID)
  • Q:绘制完一帧后还要做什么?A:Disposal Method(GCE)
  • Q:开始绘制下一帧前等待多久?A:0.01秒的倍数(GCE)
  • Q:循环播放几次?A:无限,或者1~65535次(NETSCAPE2.0)

image.png

Header

前三个字节叫做“文件签名”,固定为'G' 'I' 'F'
后三个字节标记GIF规范的版本,有"89a"和"87a"两种

image.png

Logical Screen Descriptor(LSD)

包含以下信息:

  • 整个文件的尺寸
  • 是否有全局色表
  • 全局色表的颜色分辨率
  • 色表是否经过了排序
  • 全局色表中颜色的数量
  • 哪种颜色被视为背景色
  • 像素的长宽比
    image.png

色表

很多古老的显示设备并不能直接展示RGB数据, 由于硬件的限制,设备会预先将一些颜色加载到内部寄存器中, 每种颜色对应一个编号,传输图像时,不必传输每一个像素的颜色,而只需要传输每一个像素的颜色编号。

假定色表中最多含有256项
我们需要利用一些算法,提取出最能代表一张图片的256种颜色,配合抖动算法,让色表绘制出的图片尽量接近原图

image.png
原图色彩信息太丰富,会导致难以还原,这就是为什么我们很多时候看到的GIF图片,看起来像是信息缺失或失真的原因。
image.png

色表信息 - 颜色分辨率

颜色分辨率表示原图中一个色彩通道的位数,例如,对于RGB444格式的原图,颜色分辨率为4,RGB888格式的原图,颜色分辨率为8。
LSD中,颜色分辨率用3位​表示,将这个值+1可以得到实际的颜色分辨率数值, 例如,011代表颜色分辨率为4,111代表颜色分辨率为8
image.png

色表信息 - 色表大小

色表大小表示色表中含有的项目数量,用3位表示,记为n,则实际的项目数量为2(n+1),例如,010代表8,100代表32, 111代表色表大小的上限,即256
image.png

色表的格式

每一项含有RGB三个通道的值, 按照编号顺序排列
image.png

全局色表与本地色表

除了GCT之外,每一帧还可以有自己的色表, 本地色表存在时,忽略全局色表
image.png

Image Descriptor

描述如何绘制一帧图片, 一帧不需要占满整张图片, 图片可能是隔行扫描的
image.png

Graphics Control Extension(GCE)

Graphics Control Extension(GCE)是在GIF89a中加入的,属于可选内容,它含有一些动画相关的属性(包括透明色)
image.png

LZW(Lempel–Ziv–Welch)编码

LZW(Lempel–Ziv–Welch)编码由Abraham Lempel、Jacob Ziv和Terry Welch发明, 用于信息的无损压缩,它于1984年被提出,用固定长度的码,表示不同长度的字符串。

GIF中的压缩算法采用的是该LZW的一个变体。

LZW中,字典是不固定的,开始编解码前,会有一个初始字典,编解码时,随着数据的增多,字典也在不断扩充,读入的每一个此前未见过的新字符串,都会被加入到字典中

如编码过程:

  • 字符串:aabcaac
  • 初始字典:#1->a,#2->b,#3->c
  • 见到aa,是我们没见过的字符串,在字典中增加#4->aa,输出1
  • 见到ab,在字典中增加#5->ab,输出1
  • 见到bc,增加#6->bc,输出2
  • 见到ca,增加#7->ca,输出3;见到aac,增加#8->aac,输出4
  • 最后见到c,输出3
  • 得到112343
  • 它对应的解码过程如下:
  • LZW串:112343
  • 初始字典:#1->a,#2->b,#3->c
  • 见到11,输出aa,并在字典中增加#4->aa
  • 见到23,输出bc,增加#5->ab和#6->bc
  • 见到43,输出aac,增加#7->ca和#8->aac
  • 得到aabcaac

在GIF中,图像数据的内容是每个像素的颜色编号串,初始字典就是颜色编号对应同值的字典编号,另外加入两个码:Clear Code和End Of Information Code
以4色图片为例,初始字典为:#1->1,#2->2,#3->3,#4->4,#5->Clear Code(遇到此Code时,清空字典重新开始
),#6->EOI code(图片结束)

图像数据如下图所示,开头是初始字典(除去特殊Code)的位数,接着是数据块的字节数,接着是LZW数据块,以00结尾:

image.png

Disposal method

绘制完一帧之后,如何处理
0:未定义(可以清空)
1:不处理
2:在本帧绘制的区域填上背景色
3:将本帧绘制的区域还原到绘制之前的状态

GIF文件格式的优劣

GIF是一个古老但流行的文件格式,这就概况了GIF这个文件格式的优劣,其优势在于推出时间早,广泛流行,几乎所有的操作系统和浏览器都有对GIF的很好的支持,基于浏览器对于该文件格式的解释,GIF具备加载即播放,同屏多播放等特性,这些都是与同类动态画面的文件(如短视频)所不一致的。而其缺陷在于它的信息承载比很低,同等文件尺寸下分辨率低,画面质量差,还原度差。
现在有很多互联网公司都在推出新的动图格式如GIFV等,但一个新的格式需要将编解码工作都完成,这就需要既提供文件格式,又需要提供解码环境,虽然已经有一些公司在自己的SDK里面封装了新的动图格式,但这离成为行业标准还有一定距离。

本文作者:
李霄,陈敏

]]>
无人车部署方式对比测试报告-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 1引言
1.1 文档目的
本文档是咪网停车系统实施过程中的文档,此文档作为测试的指导性方案,用以明确与描述在客户选用阿里云服务时,服务器负载情况,以确保当客户选用阿里云服务可以适用。
预期参考人员包括:产品用户、测试人员、开发人员、项目管理人员、以及质量管理人员和需要阅读本报告的高层经理。
1.2 参考文档
无人车监控客户端_概要设计.xlsx
无人车监控客户端产品需求文档 .docx
2 功能测试概要
2.1 测试用例设计
场景编号001:
对“登录注册”模块中的“注册”及“登录”进行测试,要求注册正常,登录登出正常。
场景编号002
对“停车数据”模块中的“停车数据”进行测试,要求1平均车位周转率;2近30天停车收费数据总览;3停车方式占比;4停车时间占比功能正常。
场景编号004
对“车位管理”模块中的“车位地图”及“车位列表”进行测试,要求1展示车位地图;2全部、违停、空闲、计费数据;3搜索支持;4可创建搜索条件:路段,巡检员,查询是否正确;5车位列表展示;6可分页显示功能正常。
场景编号005
对“违停监控”模块中的“取证记录”进行测试,要求1搜索条件检查:2停车路段、巡检员、车辆信息、审核状态、提交时间;3取证记录审核,取消;4数据列表展示功能正常。
环境编号001
对阿里云环境及本地环境进行对比测试,主要关注同任务场景下负载情况。
2.2 测试环境与配置
数据库:MySql,Sqlserver
Tomcat:Tomcat7.0
服务器:阿里云
2.3 测试方法
场景法
边界值
等价类划分
因果图等,混合使用
3性能测试摘要
3.1压力机器配置
(IP)地址 操作系统 内存 CPU 硬盘
10.0.0.55 Linux 16G 8C 100
3.2被测机器配置
主机型号 数量 操作系统 处理器 内存 硬盘 网络环境
阿里云 8 Linux 4C 4GB 100GB 10M共享
3650M5 1 ESXI/LINUX 32C 64GB 1TB*9 100MB独享不含BGP
3.3基础数据准备
咪表200个
用户50个
订单20000笔
3.4性能测试目标要求

  1. 相关测试查询场景要求能支持50并发数
  2. CPU小于等于70%,内存小于等于70%
  3. 单一事务的成功率大于等于99.9%

3.5 系统监控记录
序号 测试场景
(阿里云) cpu(%) RAM DB-CPU DB-RAM
1 登录 78% 38% 30% 88%
2 取证记录审核 78% 40% 29% 88%
3 待付款订单查询 78% 41% 59% 88%
4 已付款查询 78% 42% 48% 88%
5 咪表健康 78% 43% 25% 88%

序号 测试场景
(本地) cpu(%) RAM DB-CPU DB-RAM
1 登录 15% 42% 22% 45%
2 取证记录审核 43% 35% 29% 75%
3 待付款订单查询 23% 15% 67% 69%
4 已付款查询 20% 15% 75% 33%
5 咪表健康 32% 26% 25% 65%

4 测试结果分析
4.1 测试结果说明
若客户仅选用单节点来支撑整体业务的情况,考虑年服务费与设备费用,建议选用阿里云服务器予以支撑。
仅当客户并发量级超过500,且必须本地存储数据时,考虑采用本地部署方式。
5.对软件功能的结论
测试全部通过。

]]>
乘风破浪的阿里云MVP--第13期全球发布-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 阿里云智能总裁张建峰在6月9日阿里云线上峰会上对外展示了阿里云再生长的三大方向:“做深基础”,从飞天云系统操作向下延伸定义硬件;“做厚中台”,将钉钉这样的新型操作系统与阿里云进行深度融合,实现云钉一体;“做强生态”基于云和新型操作系统,构建一个繁荣的应用服务生态。这些方向的引领,离不开阿里云的合作伙伴、离不开我们的生态建设,而阿里云MVP的招募和认证是我们生态建设中不可或缺的一环,这些专家精英在自己熟悉的领域里帮助阿里云积极影响着各行各业的开发者们。

多人海报.png

阿里云最有价值专家,简称阿里云 MVP(Most Valuable Professional)
是积极向上,专注于帮助他人充分了解和使用阿里云技术产品的实践领袖。疫情过后,新基建加速,MVPs与阿里云精准反应,共同协作,不断精进。今天发布13期的全球名单,阿里云充分认可全球的阿里云MVP并对这个温暖的大家庭表示感谢,期待与MVPs一起思考,带领开发者走在世界科技前沿,探索更多的技术真相。

打破视觉局限,掌握主流技术趋势,此时此刻,我们正在经历的,是一个日益加速的“新秩序时代”因为浪潮不属于逐流者,浪潮只属于对未来保持敏锐、对明天报以观点的人。

第13期阿里云MVP,共有来自15个国家和地区的31位成功入选,其中缅甸、西班牙、德国、塞尔维亚及哥斯达黎加均为该国首位MVP。内化于心,外化于行,MVPs与阿里云携手共建科技新生态。本期入选MVP平均拥有超过10年的工作经验,覆盖DevOps、AI、大数据、数据库、服务器、云迁移、金融科技等技术与行业领域,厚积科技之力,薄发创新未来,这就是阿里云MVP的风采。

多人海报.png

查看更多的阿里云MVP
MVPs与阿里云一起,在技术建设的道路上不遗余力,不断颠覆。

阿里云MVP精通多领域技术,愿意主动分享,面向全 世界的开发者和企业,帮助开发者站在巨人肩膀上,帮助企业成为新形态技术顶端的新企业,互联互通,把技术的创造者和使用者链接到一起,构建全球技术新时代

阿里云和MVPs对全球科技的影响正在继续,更加深刻、快速和广泛,新基建、云计算、IoT、大数据、AI…新技能,新模型,新服务,新应用,新领域,新内容…科技正在创造更多奇迹,继续改变世界。阿里云,阿里云MVP,依然值得期待。
申请加入阿里云 MVP

]]>
MySQL数据库优化技巧大全-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 MySQL优化三大方向
① 优化MySQL所在服务器内核(此优化一般由运维人员完成)。
② 对MySQL配置参数进行优化(my.cnf)此优化需要进行压力测试来进行参数调整。
③ 对SQL语句以及表优化。
MySQL参数优化
1:MySQL 默认的最大连接数为 100,可以在 mysql 客户端使用以下命令查看
mysql> show variables like 'max_connections';
2:查看当前访问Mysql的线程
mysql> show processlist;
3:设置最大连接数
mysql>set globle max_connections = 5000;
最大可设置16384,超过没用
4:查看当前被使用的connections
mysql>show globle status like 'max_user_connections'

申请阿里云服务时,可以使用2000元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui (长期有效)

对MySQL语句性能优化的16条经验
① 为查询缓存优化查询
② EXPLAIN 我们的SELECT查询(可以查看执行的行数)
③ 当只要一行数据时使用LIMIT 1
④ 为搜索字段建立索引
⑤ 在Join表的时候使用相当类型的列,并将其索引
⑥ 千万不要 ORDER BY RAND ()
⑦ 避免SELECT *
⑧ 永远为每张表设置一个ID
⑨ 可以使用ENUM 而不要VARCHAR
⑩ 尽可能的使用NOT NULL
⑪ 固定长度的表会更快
⑫ 垂直分割
⑬ 拆分打的DELETE或INSERT语句
⑭ 越小的列会越快
⑮ 选择正确的存储引擎
⑯ 小心 "永久链接"

阿里云服务器1核2G低至89元/年,阿里云官活动网址:https://dashi.aliyun.com/site/yun/aliyun

具体描述如下:
(一) 使用查询缓存优化查询
大多数的MySQL服务器都开启了查询缓存。这是提高性能最有效的方法之一,而且这是被MySQL引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放入一个缓存中,这样后续的相同查询就不用操作而直接访问缓存结果了。
这里最主要的问题是,对于我们程序员来说,这个事情是很容易被忽略的。因为我们某些查询语句会让MySQL不使用缓存,示例如下:
1:SELECT username FROM user WHERE signup_date >= CURDATE()
2:SELECT username FROM user WHERE signup_date >= '2014-06-24‘
上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。
(二) 使用EXPLAIN关键字检测查询
使用EXPLAIN关键字可以使我们知道MySQL是如何处理SQL语句的,这样可以帮助我们分析我们的查询语句或是表结构的性能瓶颈;EXPLAIN的查询结果还会告诉我们索引主键是如何被利用的,数据表是如何被被搜索或排序的....等等。语法格式是:EXPLAIN +SELECT语句;
SELECT语句.png

我们可以看到,前一个结果显示搜索了 7883 行,而后一个只是搜索了两个表的 9 和 16 行。查看rows列可以让我们找到潜在的性能问题。
(三)当只要一行数据时使用LIMIT 1
加上LIMIT 1可以增加性能。MySQL数据库引擎会在查找到一条数据后停止搜索,而不是继续往后查询下一条符合条件的数据记录。
(四)为搜索字段建立索引
索引不一定就是给主键或者是唯一的字段,如果在表中,有某个字段经常用来做搜索,需要将其建立索引。
索引的有关操作如下:
1.创建索引
在执行CREATE TABLE语句时可以创建索引,也可以单独用CREATE INDEX或ALTER TABLE来为表增加索引。
1.1> ALTER TABLE
ALTER TABLE 用来创建普通索引、唯一索引、主键索引和全文索引
ALTER TABLE table_name ADD INDEX index_name (column_list);
ALTER TABLE table_name ADD UNIQUE (column_list);
ALTER TABLE table_name ADD PRIMARY KEY (column_list);
ALTER TABLE table_name ADD FULLTEXT (column_list);
其中table_name是要增加索引名的表名,column_list指出对哪些列列进行索引,多列时各列之间使用半角逗号隔开。索引名index_name是可选的,如果不指定索引名称,MySQL将根据第一个索引列自动指定索引名称,另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。
1.2> CREATE INDEX
CREATE INDEX可对表增加普通索引或UNIQUE索引以及全文索引,但是不可以对表增加主键索引
CREATE INDEX index_name ON table_name (column_list);
CREATE UNIQUE index_name ON table_name (column_list);
CREATE FULLTEXT index_name ON table_name (column_list);
table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名必须指定。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。
2.索引类型
普通索引INDEX:适用于name、email等一般属性
唯一索引UNIQUE:与普通索引类似,不同的是唯一索引要求索引字段值在表中是唯一的,这一点和主键索引类似,但是不同的是,唯一索引允许有空值。唯一索引一般适用于身份证号码、用户账号等不允许有重复的属性字段上。
主键索引:其实就是主键,一般在建表时就指定了,不需要额外添加。
全文检索:只适用于VARCHAR和Text类型的字段。
注意:全文索引和普通索引是有很大区别的,如果建立的是普通索引,一般会使用like进行模糊查询,只会对查询内容前一部分有效,即只对前面不使用通配符的查询有效,如果前后都有通配符,普通索引将不会起作用。对于全文索引而言在查询时有自己独特的匹配方式,例如我们在对一篇文章的标题和内容进行全文索引时:
ALTER TABLE article ADD FULLTEXT ('title', 'content'); 在进行检索时就需要使用如下的语法进行检索:
SELECT * FROM article WHERE MATCH('title', 'content') AGAINST ('查询字符串');
在使用全文检索时的注意事项:
MySql自带的全文索引只能用于数据库引擎为MYISAM的数据表,如果是其他数据引擎,则全文索引不会生效。此外,MySql自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。如果需要对包含中文在内的文本数据进行全文检索,我们需要采用Sphinx(斯芬克斯)/Coreseek技术来处理中文。另外使用MySql自带的全文索引时,如果查询字符串的长度过短将无法得到期望的搜索结果。MySql全文索引所能找到的词默认最小长度为4个字符。另外,如果查询的字符串包含停止词,那么该停止词将会被忽略。
3.组合索引
组合索引又称多列索引,就是建立索引时指定多个字段属性。有点类似于字典目录,比如查询 'guo' 这个拼音的字时,首先查找g字母,然后在g的检索范围内查询第二个字母为u的列表,最后在u的范围内查找最后一个字母为o的字。比如组合索引(a,b,c),abc都是排好序的,在任意一段a的下面b都是排好序的,任何一段b下面c都是排好序的
组合索引的生效原则是 从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用;
造成断点的原因:
前边的任意一个索引没有参与查询,后边的全部不生效。
前边的任意一个索引字段参与的是范围查询,后面的不会生效。
断点跟索引字字段在SQL语句中的位置前后无关,只与是否存在有关。在网上找到了很好的示例:
比如:
where a=3 and b=45 and c=5 .... #这种三个索引顺序使用中间没有断点,全部发挥作用;
where a=3 and c=5... #这种情况下b就是断点,a发挥了效果,c没有效果
where b=3 and c=4... #这种情况下a就是断点,在a后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;
where b=45 and a=3 and c=5 .... #这个跟第一个一样,全部发挥作用,abc只要用上了就行,跟写的顺序无关
(a,b,c) 三个列上加了联合索引(是联合索引 不是在每个列上单独加索引)而是建立了a,(a,b),(a,b,c)三个索引,另外(a,b,c)多列索引和 (a,c,b)是不一样的。
具体实例可以说明:
(0) select * from mytable where a=3 and b=5 and c=4;

abc三个索引都在where条件里面用到了,而且都发挥了作用
(1) select * from mytable where c=4 and b=6 and a=3;

这条语句为了说明 组合索引与在SQL中的位置先后无关,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
(2) select * from mytable where a=3 and c=7;

a用到索引,b没有用,所以c是没有用到索引效果的
(3) select * from mytable where a=3 and b>7 and c=3;

a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
(4) select * from mytable where b=3 and c=4;

因为a索引没有使用,所以这里 bc都没有用上索引效果
(5) select * from mytable where a>4 and b=7 and c=9;

a用到了 b没有使用,c没有使用
(6) select * from mytable where a=3 order by b;

a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的
(7) select * from mytable where a=3 order by c;

a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
(8) select * from mytable where b=3 order by a;

b没有用到索引,排序中a也没有发挥索引效果
注意:在查询时,MYSQL只能使用一个索引,如果建立的是多个单列的普通索引,在查询时会根据查询的索引字段,从中选择一个限制最严格的单例索引进行查询。别的索引都不会生效。
4.查看索引
mysql> show index from tblname;
mysql> show keys from tblname;
5.删除索引
删除索引的mysql格式 :DORP INDEX IndexName ON tab_name;
注意:不能使用索引的情况
对于普通索引而言 在使用like进行通配符模糊查询时,如果首尾之间都使用了通配符,索引时无效的。
假设查询内容的关键词为'abc'
SELECT * FROM tab_name WHERE index_column LIKE 'abc%'; #索引是有效的
SELECT * FROM tab_name WHERE index_column LIKE '%abc'; #索引是无效的
SELECT * FROM tab_name WHERE index_column LIKE '%cba'; #索引是有效的
SELECT * FROM tab_name WHERE index_column LIKE '%abc%'; #索引是无效的
当检索的字段内容比较大而且检索内容前后部分都不确定的情况下,可以改为全文索引,并使用特定的检索方式。
(五)在join表的时候使用相当类型的列,并将其索引
如果在程序中有很多JOIN查询,应该保证两个表中join的字段时被建立过索引的。这样MySQL颞部会启动优化JOIN的SQL语句的机制。注意:这些被用来JOIN的字段,应该是相同类型的。例如:如果要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)
例如:
SELECT company_name FROM users LEFT JOIN companies ON (users.state = companies.state) WHERE users.id = “user_id”
两个 state 字段应该是被建过索引的,而且应该是相当的类型,相同的字符集。
(六)切记不要使用ORDER BY RAND()
如果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得不去执行RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit 1也无济于事(因为要排序)
(七)避免使用SELECT *
从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果我们的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。 所以,我们应该养成一个需要什么就取什么的好的习惯。
Hibernate性能方面就会差,它不用*,但它将整个表的所有字段全查出来
优点:开发速度快
(八)永远为每张表设置一个ID主键
我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的 AUTO_INCREMENT标志。 就算是我们 users 表有一个主键叫 “email”的字段,我们也别让它成为主键。使用 VARCHAR 类型来当主键会使用得性能下降。另外,在我们的程序中,我们应该使用表的ID来构造我们的数据结构。 而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区…… 在这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”其共同组成主键。
(九)使用ENUM而不是VARCHAR
ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。 如果我们有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,我们知道这些字段的取值是有限而且固定的,那么,我们应该使用 ENUM 而不是 VARCHAR。
(十)尽可能的不要赋值为NULL
如果不是特殊情况,尽可能的不要使用NULL。在MYSQL中对于INT类型而言,EMPTY是0,而NULL是空值。而在Oracle中 NULL和EMPTY的字符串是一样的。NULL也需要占用存储空间,并且会使我们的程序判断时更加复杂。现实情况是很复杂的,依然会有些情况下,我们需要使用NULL值。 下面摘自MySQL自己的文档: “NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”
(十一) 固定长度的表会更快
如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要我们包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。 固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。 并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论我们用不用,他都是要分配那么多的空间。另外在取出值的时候要使用trim去除空格
(十二)垂直分割
“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。
(十三)拆分大的DELETE或INSERT
如果我们需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,我们需要非常小心,要避免我们的操作让我们的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。Apache 会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。如果我们把我们的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让我们的WEB服务Crash,还可能会让我们的整台服务器马上掛了。所以在使用时使用LIMIT 控制数量操作记录的数量。
(十四)越小的列会越快
对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把我们的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。 参看 MySQL 的文档 Storage Requirements 查看所有的数据类型。 如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果我们不需要记录时间,使用 DATE 要比 DATETIME 好得多。
(十五)选择正确的存储引擎
在MYSQL中有两个存储引擎MyISAM和InnoDB,每个引擎都有利有弊。
MyISAM适合于一些需要大量查询的应用,但是对于大量写操作的支持不是很好。甚至一个update语句就会进行锁表操作,这时读取这张表的所有进程都无法进行操作直至写操作完成。另外MyISAM对于SELECT COUNT(*)这类的计算是超快无比的。InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。
MyISAM是MYSQL5.5版本以前默认的存储引擎,基于传统的ISAM类型,支持B-Tree,全文检索,但是不是事务安全的,而且不支持外键。不具有原子性。支持锁表。
InnoDB是事务型引擎,支持ACID事务(实现4种事务隔离机制)、回滚、崩溃恢复能力、行锁。以及提供与Oracle一致的不加锁的读取方式。InnoDB存储它的表和索引在一个表空间中,表空间可以包含多个文件。
MyISAM和InnoDB比较,如下图所示:
下图所示.png

在5.5之后默认的存储引擎是INNODB
可以单独进行修改也可以在创建表时修改:
ALTER TABLE tab_name ENGINE INNODB;
(十六)小心永久链接
“永久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了。而且,自从我们的Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的 MySQL 链接。
而且,Apache 运行在极端并行的环境中,会创建很多很多的了进程。这就是为什么这种“永久链接”的机制工作地不好的原因。在我们决定要使用“永久链接”之前,我们需要好好地考虑一下我们的整个系统的架构。

]]>
序列化和反序列化-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。

序列化和反序列化

通过⽂件操作,我们可以将字符串写⼊到⼀个本地⽂件。但是,如果是⼀个对象(例如列表、字典、元组等),就⽆法直接写⼊到⼀个⽂件⾥,需要对这个对象进⾏序列化,然后才能写⼊到⽂件⾥。

设计⼀套协议,按照某种规则,把内存中的数据转换为字节序列,保存到⽂件,这就是序列化,反之,从⽂件的字节序列恢复到内存中,就是反序列化。

Python中提供了JSON和pickle两个模块⽤来实现数据的序列化和反序列化。

JSON模块

JSON(JavaScriptObjectNotation, JS对象简谱)是⼀种轻量级的数据交换格式,它基于 ECMAScript 的⼀个⼦集,采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。JSON的本质是字符串!JSON里要使用双引号表示字符串。

使⽤JSON实现序列化

JSON提供了dump和dumps⽅法,将⼀个对象进⾏序列化。
dumps⽅法的作⽤是把对象转换成为字符串,它本身不具备将数据写⼊到⽂件的功能。

import json

file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# file.write(names) 出错,不能直接将列表写⼊到⽂件⾥

# 可以调⽤ json的dumps⽅法,传⼊⼀个对象参数
result = json.dumps(names)

# dumps ⽅法得到的结果是⼀个字符串
print(type(result)) # <class 'str'>

# 可以将字符串写⼊到⽂件⾥
file.write(result)

file.close()

dump⽅法可以在将对象转换成为字符串的同时,指定⼀个⽂件对象,把转换后的字符串写⼊到这个⽂件⾥。

import json

file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']

# dump⽅法可以接收⼀个⽂件参数,在将对象转换成为字符串的同时写⼊到⽂件⾥
json.dump(names, file)
file.close()

注意:如果是⼀个空对象,调⽤dumps⽅法转换成为⼀个JSON对象,得到的结果是null(JS⾥的空对象)

json.dumps(None) # null

使⽤JSON实现反序列化

使⽤loads和load⽅法,可以将⼀个JSON字符串反序列化成为⼀个Python对象。

loads⽅法需要⼀个字符串参数,⽤来将⼀个字符串加载成为Python对象。

import json

# 调⽤loads⽅法,传⼊⼀个字符串,可以将这个字符串加载成为Python对象
result = json.loads('["zhangsan", "lisi", "wangwu", "jerry", "henry", "merry", "chris"]')
print(type(result)) # <class 'list'>

load⽅法可以传⼊⼀个⽂件对象,⽤来将⼀个⽂件对象⾥的数据加载成为Python对象。

import json

# 以可读⽅式打开⼀个⽂件
file = open('names.txt', 'r')

# 调⽤load⽅法,将⽂件⾥的内容加载成为⼀个Python对象
result = json.load(file)

print(result)
file.close()

pickle模块

和json模块类似,pickle模块也有dump和dumps⽅法可以对数据进⾏序列化,同时也有load和loads⽅法进⾏反序列化。区别在于,json模块是将对象转换成为字符串,⽽pickle模块是将对象转换成为⼆进制。

pickle模块⾥⽅法的使⽤和json⾥⽅法的使⽤⼤致相同,需要注意的是,pickle是将对象转换成为⼆进制,所以,如果想要把内容写⼊到⽂件⾥,这个⽂件必须要以⼆进制的形式打开。
序列化
dumps:将Python数据转化为二进制
dump:将Python数据转化为二进制,同时保存到指定文件

反序列化
loads:将二进制加载成为python数据
load:读取文件,并将文件的二进制内容加载成为python数据

import pickle

names = ['张三', '李四', '杰克', '亨利']
b_names = pickle.dumps(names)

file  = open('names.txt', 'wb')
file.write(b_names)   # 写入的是二进制
file.close()

file1 = open('names.txt', 'rb')
x = file1.read()
y = pickle.loads(x)
print(y)
file1.close()


file2 = open('names.txt', 'wb')
pickle.dump(names, file2)
file2.close()


file3 = open('names.txt', 'rb')
pickle.load(file3)
class Dog(object):
    def __init__(self, name, color):
        self.name = name
        self.color = color

     def eat(self):
        print(self.name + '正在吃东西')

d = Dog('大黄', '白色')

# 保存到文件里
pickle.dump(d, open('dog.txt', 'wb'))

# 从文件里加载出来
dd = pickle.load(d, open('dog.txt', 'rb'))
dd.eat()  

print(dd.name, dd.color)   # 大黄 白色

区别

思考: json和pickle两个模块都可以将对象进⾏序列化和反序列化,那它们有哪些区别,在使⽤场景上⼜该如何选择?

json模块:

  • 将对象转换成为字符串,不管是在哪种操作系统,哪种编程语⾔⾥,字符串都是可识别的。
  • json就是⽤来在不同平台间传递数据的。
  • 并不是所有的对象都可以直接转换成为⼀个字符串,下标列出了Python对象与json字符串的对应关系。

image.png

  • 如果是⼀个⾃定义对象,默认⽆法装换成为json字符串,需要⼿动指定JSONEncoder。
  • 如果是将⼀个json串重新转换成为对象,这个对象⾥的⽅法就⽆法使⽤了。
import json

class MyEncode(json.JSONEncoder):
    def default(self, o):
        # return {"name":o.name,"age":o.age}
        return o.__dict__

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(self.name+'正在吃东⻄')

p1 = Person('zhangsan', 18)

# ⾃定义对象想要转换成为json字符串,需要给这个⾃定义对象指定JSONEncoder
result = json.dumps(p1, cls=MyEncode)
print(result) # {"name": "zhangsan", "age": 18}

# 调⽤loads⽅法将对象加载成为⼀个对象以后,得到的结果是⼀个字典
p = json.loads(result)
print(type(p))

pickle模块:

  • pickle序列化是将对象按照⼀定的规则转换成为⼆进制保存,它不能跨平台传递数据。
  • pickle的序列化会将对象的所有数据都保存。

配套视频

]]>
阿里云服务器如何修改远程端口?-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 本文介绍如何修改 Windows 和 Linux 服务器的默认远程端口。

修改 Windows 服务器默认远程端口
本节以 Windows Server 2008 为例介绍如何修改 Windows 服务器默认远程端口。

远程连接并登录到 Windows 实例。
运行regedit.exe打开注册表编辑器。
找到如下注册表子项:HKEY_LOCAL_MACHINESystemCurrentControlSetControlTerminal ServerWinStationsRDP-TcpPortNumber
找到如下.png

申请阿里云服务时,可以使用2020元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui (长期有效)

在弹出的对话框中,选择十进制,在数值数据中输入新的远程端口号,在本例中即 3399。单击确定。
在弹出的对.png

(可选)如果您开启了防火墙,需要将新的端口号添加到防火墙并设置允许连接。
具体方法参见设置 ECS 实例远程连接防火墙。

阿里云服务器1核2G低至89元/年,阿里云官活动网址:https://dashi.aliyun.com/site/yun/aliyun

登录 ECS管理控制台,找到该实例,选择更多 > 重启。
登录 ECS管理.png

实例重新启动后,在实例的右侧单击管理,进入实例详情页面。选择本实例安全组。
实例重新启.png

在安全组列表页面,找到相应的安全组,单击配置规则。
在安全组规则页面,单击添加安全组规则。根据实际的使用场景来定义安全规则,允许新配置的远程端口进行连接。关于如何设置安全组参见添加安全组规则。
在安全组规.png

以上步骤完成后,远程访问服务器,在远程地址后面添加新远程端口号即可连接实例。例如:192.168.1.2:3399。
以上步骤完.png

说明 调整 3389 端口后,使用 Mac 的远程桌面连接客户仅支持默认的 3389 端口。

修改 Linux 服务器默认远程端口
本节以 CentOS 6.8 为例介绍如何修改 Linux 服务器默认远程端口。

说明 不要直接修改 22 端口,先添加需要的默认远程端口。之所以先设置成两个端口,测试成功后再关闭一个端口,是为了防止在修改配置文件及网络调试过程中,万一出现新端口无法连接的情况下,还能通过 22 端口进行登录调试。

远程连接并登录到 Linux 实例。
运行 vim /etc/ssh/sshd_config 命令。
在键盘上按“I”键,进入编辑状态。添加新的远程服务端口,本节以 1022 端口为例。在Port 22下输入Port 1022。
在键盘上按“Esc”,输入:wq退出编辑状态。
执行以下命令重启实例,之后您可以通过 22 端口和 1022 端口 SSH 登录到 Linux 实例。
/etc/init.d/sshd restart

(可选)配置防火墙。使用 CentOS 7 以前的版本并开启默认防火墙 iptables 时,应注意 iptables 默认不拦截访问,如果您配置了 iptables 规则,需要执行iptables -A INPUT -p tcp --dport 1022 -j ACCEPT配置防火墙。然后执行service iptables restart 重启防火墙。
说明 CentOS 7 以后版本默认安装 Firewalld。如果您已经启用 firewalld.service,需要放行 TCP 1022 端口:运行命令 firewall-cmd --add-port=1022/tcp --permanent。返回结果为 success 即表示已经放行 TCP 1022 端口。

登录 ECS管理控制台,找到该实例,选择管理。
进入实例详情页面。选择本实例安全组。
进入实例详.png

在安全组列表页面,找到相应的安全组,单击配置规则。
在安全组规则页面,单击添加安全组规则。根据实际的使用场景来定义安全规则,允许新配置的远程端口进行连接。关于如何设置安全组参见添加安全组规则。
使用 SSH 工具连接新端口,来测试是否成功。登录时在 Port 一栏输入新修改的端口号,在本例中即 1022。
使用 SSH.png

使用 1022 端口连接成功后,再次运行vim /etc/ssh/sshd_config命令,将 Port 22 删除。
运行 /etc/init.d/sshd restart 命令重启实例,服务器默认远程端口修改完成。再次登录时使用新端口号登录即可。

]]>
牛客融合阿里云,助您找到心仪好工作-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

“您好,可以听到吗?“
“……. 您…好,我…这里画面卡顿….了!”
“…..不好意….思,能重复一下您刚才的描述吗吗吗,没听太清….楚…………..”
“哎,感觉这次又糊了,这已经是我的第99次了]]> 阿里“去 IOE”十二年,弹性计算如何二次去 I 和 E?-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 王坚院士曾讲过一句话让人印象深刻,他说「云计算的本质是服务,如果不能将计算资源规模化、大范围地进行共享,如果不能真正以服务的方式提供,就根本算不上云计算。」众所周知,阿里云是完全经历了从 0 到 1,再到 100 的过程,将计算发挥到极致背后有一个关键的服务,那就是弹性计算。

阿里云弹性计算是阿里云提供的 IaaS 级别云计算服务,它免去了客户采购 IT 硬件的前期准备,让客户像使用水、电、天然气等公共资源一样便捷、高效地使用计算资源,实现计算资源的即开即用和弹性伸缩。在「CSDN 在线峰会 —— 阿里云核心技术竞争力」上,阿里云研究员蒋林泉(花名:雁杨)深入分享了在众多大规模实践下百炼成钢的弹性计算。

image.png
演讲者 | 蒋林泉(雁杨),阿里云研究员

前言:弹性计算 More than just 虚拟机

一般而言,大家理解的弹性计算,可能首先会想到是虚拟机、云服务器。

但弹性计算除了是众所周知的 IaaS 的核心——云服务器 ECS 之外,还是一个完整的产品家族,而不只是虚拟机。

弹性计算不仅是阿里云的大底座,更是阿里巴巴集团的大底座,能够用强大的性能、稳定性、弹性、效率能力来支撑云上客户和阿里云的云产品。目前,中国 80% 的创新企业都在使用我们的弹性计算产品,更有 99% 的阿里云其他产品是在弹性计算产品之上为客户提供服务。

image.png

对于弹性计算而言,我们所承担的角色可从三个切面去看待,即制造商、零售(运营)商和服务商:

1、制造商负责设计虚拟机/云服务器,以满足客户不同的场景需求;
2、零售(运营)商负责将这些实例售卖出去,提供按量付费、包年包月、RI 以及抢占式实例等多种付费方式,使得售卖形态更加灵活;

3、服务商则提供大规模集群部署、运维、迁移和弹性伸缩套件产品,实现客户从 Capex 走向 Opex,让客户能够轻松在时间域和空间域上实现扩容,高效交付、部署和运维大规模云服务器。

零售商(运营商):资源池化&弹性

我们先从零售商的角度来理解弹性计算。

对于零售商而言,需要考虑如何将弹性资源卖出去,如何让客户使用这种池化后的弹性资源。

零售商主要是让用户的服务器从购买变成租赁形态,可以按照年或者月进行付费,这样更符合客户的使用习惯,阿里云也提供按使用量,甚至是通过竞价闲置资源的方式来进行付费,使得客户可以享受到在线下无法实现的付费方式来节约成本。

在弹性计算的底层提升供应链效率,进行服务器硬件资源虚拟化以及调度,并且保证非常高的 SLA,来给客户提供弹性能力。

image.png

▐ 狭义弹性:时域维度的弹性

我们先来讲讲狭义的弹性。所谓狭义弹性就是时域维度的弹性。

如下图中白色条线,这表示的就是时域的弹性,企业上线新特性、年中促销或者日常促销,甚至是业务发展变化很快,后台的计算能力却往往不能很快跟上。

image.png

一般传统企业的解决方式其实是提前备货,提前一年甚至三年做预算,进行 IT 资源的储备。其目标是为了保证在未来一到两年内,业务都不会因为容量不够而受损,这也是导致大量线下传统企业的日常 CPU 利用率无法达到 5% 的原因。

最糟糕的情况是,当有新业务上线需要大规模容量的时候,IT 资源无法支撑,这样的矛盾就会使得上图中间的虚线部分越来越大。因此,传统方式要么就会造成浪费计算资源和资金,要么就无法很好地支撑业务的快速增长。

▐ ECS 狭义弹性能力:天下武功,唯快不破

对于狭义弹性而言,更多需要考虑如何让其跑得更快,当需要资源的时候以最快的速度给到客户。

目前,阿里云云服务器 ECS 从开启服务器到 SSH 可以登录只需要 22 秒的时间,同时,单位时间内能够交付的计算力面积,可以做到单客户、单 Region 5 分钟 16 万核 vCPU 的交付能力。

image.png

▐ 弹性容量自动伸缩最佳实践

我们来看看一个弹性容量的最佳实践案例。

首先,企业客户需要守住自己的一个底座,也就是自己日常流量所需的计算资源,也就是下图中绿色的线,这部分比较适合使用包年包月或者 RI 的模式,因为价格比较便宜。

而在底座之上的弹性部分则可以使用按量计费或者抢占式的计算资源帮助消除峰值流量,再加上 ESS 的自动化,就能够实现在不同流量峰谷的时候可以自动包裹业务曲线。

image.png

▐ 容量弹性:ESS 弹性自动化 4 种模式

ESS 弹性自动化提供了 4 种模式,即定时模式、动态模式、手动+动态模式和 AI 预测模式:

1、定时模式适用于业务波动的时间和范围均可准确预测的场景;

2、动态模式适合业务波动的时间和范围完全不可预测的场景,根据 CPU 和内存负载情况,进行自动扩容;

3、手动+动态模式是两者叠加使用,适合业务波动范围较小,但时间不可预测的场景;

4、AI 预测模式则根据历史资源使用量的峰谷和时域特征拟合,通过智能分析预测来做提前扩容,保证在可能的峰值来临之前,就可以完成资源的准备。

image.png

通过多种伸缩模式的灵活组合,能够帮助企业快速响应计划内外的业务变化,实现按需取用,降低成本,自动智能运维,甚至是零运维。

▐ 广义弹性:基础设施规模全预铺-空间域的弹性

第二个维度与大家分享广义弹性。云,特别是像阿里云这么大规模的云,很大的一个特征就是基础设施规模化的全铺设,也就是说具有了空间域的弹性。

任何一个物理设备,都有扩容上限。当扩张到上限的时候,就会遇到扩容墙的问题,此时就需要设备全部迁移到另外一个地域并重新启动,无法做到跨地域调度。

云计算则能够实现跨机房、跨可用区,甚至是跨 Region 的扩容。阿里云拥有日不落的数据中心,业务部署到海外也是非常容易的,这就是广义的弹性——空间域的弹性。

image.png

▐ 广义弹性:空间域上覆盖全球的大规模基础设施

大家经常会听到阿里云部署了多少个 Region 以及多少个 AZ(Availability Zone,可用区),而 AZ 之间是互联的,延时也有严格的保障,因此用户可以突破 IDC 的边界,扩容自己的应用。

image.png

▐ 广义弹性:在 ECS 之上,使用丰富云服务拓展应用的系统支撑能力的弹性

ECS 会映射到线下的 IDC 服务器,因此无论是数据库还是应用,都是购买软件之后进行交付、运维和使用。对多数云上系统各种 Workload,都可以基于 ECS 用软件自己搭建。

同时,阿里云还提供了大规模的服务化的云产品,一定会有一款满足你。比如数据库、容器、函数、中间件等都已经实现了服务化,客户不需要去安装、运维和管理这些软件,而能够利用这些软件的弹性实现开箱即用,且按时付费。而且这些软件的数量和质量还不断的进化,因此选择上云还能够为将来拓展应用能力的弹性奠定基础。

制造商:性能优异,稳如磐石

客户的应用都在这个云服务器上面,因此性能很重要。云厂商生产了各种不同规格的云服务器,通过 IDC、物理机、网络资源之上的这些操作系统将其切成资源池给到客户。

这样就像是工业 4.0,客户选择了配置,如内核、CPU、内存、磁盘、操作系统等,阿里云会将这些资源调度到一台机器上,实时生产出来交给用户。

阿里云提供了封装形态、规格族、规格大小粒度这样广谱覆盖的实例矩阵来覆盖用户在不同场景下对于计算力的需求。

image.png

▐ 制造商成功的本分:稳定性&性能

中国是个制造业大国,而制造商成功的本分其实就是稳定性和性能。阿里云具有计算、网络、存储性能的稳定性,AZ 内、AZ 间、Region 间以及网络性能的稳定性。

此外,加上飞天操作系统在计算、存储、网络 3 个底层技术上的不断投入,以及大规模调度系统,结合底层硬件不断进行研发迭代,实现高性能和成本红利。

image.png

▐ 云的稳定性

云的稳定性主要挑战在两个方面:宕机迁移业务恢复,磁盘损坏不丢数据;硬件批量维修、过保,保证客户对过保无感。

阿里云将运维和虚拟化解耦,可以做到用户无感的物理硬件替换,对客户业务的连续性打扰降低到非常小的程度,这正是云上核心的稳定性逻辑。

image.png

弹性计算的“二次去 I”:用 x86 硬件,挑战小机型稳定性

下图中数据来自于各厂商官网,阿里云 ECS 单实例可用性 SLA 可以达到 99.975%,跨可用区多实例可用性 SLA 可达到 99.995%。

image.png

标题中的“二次去 I”指的是阿里云在服务客户的过程中发现客户单实例对稳定性要求也非常高。

在“第一次去 IOE”的时候,用的是应用层的分布式技术来解决 x86 的稳定性问题。而在弹性计算领域,则是用基础层的能力去解决 x86 的稳定性问题,目标是用 x86 的硬件做到和小型机一样的稳定性,这就是“二次去 I”。客户的技术能力各不相同,有很大一部分客户对单机的稳定性有非常高的依赖,无法做应用层的容灾,这样严苛的需求就推动阿里云的服务要达到小型机的稳定性,阿里云的基础沉淀了多年,才得以实现这样的业界领先的 SLA。

弹性计算的云盘快存储“二次去 E”:业界主流厂商云盘可靠性 SLO 一览

阿里云云盘的可靠性能够做到“9 个 9”,也是目前业界领先的,需要非常严谨和先进的技术架构来保障。通过分布式的基于 x86 的软件定义存储,替代掉原来商业非常昂贵的存储,并达到了存储的高可靠性。

80% 的宕机,都来自 IDC 电力、IDC 网络和服务器系统三类原因

阿里云是如何做到上述能力的呢?其实对于服务器而言,80%的宕机,都来自 IDC 电力、IDC 网络和服务器系统三类原因。接下来针对于这三个原因谈谈阿里云所做的事情。

强健的电力,强健的网络带来强健的 IDC 基础设施

IDC 掉电的新闻中经常出现,属于高频事件。阿里云在 IDC 的管理上非常严格,拥有高可用电力架构、网络架构以及 3+N 多线 BGP 接入,这也源于多年来的经验和教训,才形成背后成熟的管理体系和技术体系。阿里云帮助客户消除掉了 IDC 机房的大部分电力、网络的可用性威胁。

image.png

**
冗余架构**

举一个例子,阿里云在服务器和接入交换机的架构上,存储、网络和云盘等都是通过网卡虚拟化出来的。服务器上的电力、网络,都是双线接入的。通过自研技术,在服务器、飞天操作系统中实现物理网络的路由切换。如果这个地方是个单点,没有双路就经常会出现各种各样的问题。阿里云选择在软件侧实现冗余的网络线路路由调度。

image.png

批量运维变更故障规避技术平台

既然是大规模的云,技术迭代和产品更新背后就会有大量的系统发布和变更。如何让其变得更稳定?阿里云背后依赖于非常高精尖的热迁移技术,95% 以上的热迁移,对所有用户都是无感的。

image.png

**玄机大脑的异常预测&调度
**
飞天操作系统中的玄机大脑能够对于异常进行预测,做提前的热迁移,实现对客户服务的稳定性。

image.png

**核心部件的故障预测:准确率和召回率高达 99%
**
阿里云核心部件的故障预测的准确率和召回率高达 99%,这背后来自于阿里巴巴这么多年的技术积累。阿里巴巴是一家数据公司,拥有 10 年百万级的服务器打标的高质量数据,再结合达摩院科学家的合作,通过算法训练让这些数据产生价值,提前预测硬件的健康程度,再结合热迁移的能力,实现服务的稳定性。

成果:70% 的用户可感知故障被消除&规避

目前,阿里云由于硬件产生的问题中的 70% 都是客户无感的。很多用户使用云服务器已经大约 2 到 3 年的时间了,底层的硬件可能已经更换了 2 至 3 次,但是自己却毫无感知,也没有重启过。这就是使用 x86 的硬件实现了小型机的稳定性。

image.png

为何弹性计算如此看重稳定性:进化的力量

阿里云之所以这么看重稳定性并做了大量的投入,主要是因为技术进化的力量。双 11 一直在考验阿里巴巴集团的系统,不断发现小问题并快速逐一修复。

此外,还有一个原因就是客户群体的差异,中美的云计算成熟度存在一些差异,在北美或者欧洲,IT 客户群体的能力相对成熟,可以在应用上做容灾,对服务稳定性的依赖相对较小,而国内的 IT 客户群体还不够成熟,很多客户强依赖单机的稳定性,这就让阿里云必须重视稳定性的提升。

阿里云带着一个梦想,就是能够通过努力,降低中国企业创业的门槛,减小企业数字化转型的阻力,这些都是驱动弹性计算不断进化的驱动力。

▐ 云的优异性能

讲完稳定性,我们来讲讲性能。

业界领先的 E2E 性能

虚拟化使得 IT 业务的灵活度、交互效率大大提升,而带来的问题其实就是虚拟化的损耗,这就需要从技术上不断进步。阿里云弹性计算具有业界领先的 E2E 性能,ECS 第六代相比第五代在性能方面在 MySQL、nginx、Redis 等场景下都有了大幅度提升,并且综合性能超越市场同类主售产品。

image.png

ECS 性能更强,成本更低的秘密——全链路自研底层技术

无论是神龙、盘古、洛神,还是阿里自研的 IDC 网络和服务器,这些全链路的融合以及软硬结合,会持续地进行迭代,将技术红利提供给客户和市场。

image.png

高性能背后的自研技术:神龙计算平台

阿里自研的神龙计算平台在 2017 年发布第一代产品,并且每年都在迭代,现在给客户提供服务的是第二代神龙计算平台。第三代马上就会开放给客户,目前处于邀测过程中。

image.png

高性能背后的自研技术:神龙、盘古 2.0,物理网络的完美结合

阿里云是第一个能够把 RDMA 真正用在云上的云厂商,这是因为要解决 RDMA 的规模化问题,存在着大量的挑战。为了享受 RDMA 的技术红利,则必须要在软硬件以及架构上进行大量适配,才能够保证它能够大规模环境下稳定运行。

image.png

高性能背后的自研技术:玄机大脑的性能调度

在高性能的背后,也需要有强大的调度系统,通过玄机大脑和达摩院进行数据化分析,进行大规模调度,让购买小规格实例的客户也能享受到稳定的服务,甚至超出基线的性能。

image.png

全球最极端场景对性能、稳定性的打磨

举一个极端场景的例子,去年双 11 中阿里巴巴的全部业务都已经上云了,峰值会到达无法想象的量级。在平时演练中,会毫无预兆的人为制造各种问题,例如断电、交换机故障、系统故障等场景,弹性计算团队需要在最短的时间内解决出现的问题,这样的考验对于稳定性的打磨是世界独一无二的。

服务商:云上安全感到效率幸福感

除了上述谈到的能力之外,用户上云之后还需要交付、部署、配置、运维的服务。就像是开车一样,出了性能好,更需要这种自动驾驶、定速巡航、精准操控等能力辅助。

image.png

服务商:集群复杂度和规模变化,对交付、部署、配置、运维效率要求产生质的变化

上云企业的大小规模不一样,企业规模小的时候,使用的资源数量非常少,自动化要求、管理复杂度、运用复杂度都会很低。在规模变大之后,企业会划分多个部门,具有多个服务和应用,甚至横跨多个地域。海量的集群复杂度、交付复杂度、服务器管理配置的复杂度都会提升,需求就会有质的变化。

服务商:部署&运维自动化编排,上云用云自动化驾驶

在云上,为了应对以上挑战,提供了两套配套方案,部署集+ROS 资源编排,和云助手+OOS 运维编排,分别解决规模化、自动化部署配置的能力,还有自动化运维的能力,结合稳定的计算实例、时域和空间域的弹性,以及原子 API 和透明监控事件,进而实现了云上完整弹性。

image.png

ROS:用部署编排自动化,轻松交付单元化集群

举个例子,2020 年 2 月疫情期间,钉钉使用 ROS 进行大规模多集群扩容。保障扩容的顺利完成,首先要有资源扩容,其次要有空间进行扩容,并且还走向海外,需要在海外为其扩容。集群扩容规模非常大,需要大量的时间,所以阿里云通过 ROS 帮助钉钉进行集群扩容,效率提升了 100 倍。而应对如此快速增长的 DAU,背后的弹性能力、快速部署能力、自动化能力都缺一不可。

OOS:运维编排自动化,云上轻松实现大规模集群高效发布和运维

这里的例子是一个 1.5 亿客户的大型 App 后端大规模集群发布运维编排,通过 OOS 编排模板去自动刷新资源,帮助其将单次完整线上发布时间从 150 分钟缩短到 10 分钟,并且不需要人工干预和 0 误操作。使得发布频率从每周一次提升到了每天一次,真正地做到了基础设施级别的深度持续发布,使得业务创新效率大幅度提升。

规模&进化:宝剑锋从磨砺出

如下图所示的曲线表明规模很重要,规模变大之后,单台服务器的稳定性、弹性、性能大大提升,研发成本也会急剧下降,而阿里云背后强大的技术团队,才让 ECS 有了极致的体验。

image.png

弹性计算和阿里云同一年诞生,如今在规模方面已经成为中国乃至亚太的第一,世界第三。弹性计算团队从创建开始,与客户一起成长了 11 年的时间。

小结:规模化实践驱动的云计算的优势会不断扩大

大规模实践锻造而成的弹性计算,驱动着云计算市场不断地发展壮大,同时规模化实践驱动的云计算由于其优势,规模也在不断扩大。

而所有这些竞争力都是构建不同行业的国内外大客户、严苛的云产品内部客户、庞大的集团内部客户的大规模需求驱动之上;构建在阿里云与集团数据和技术积累的肩膀之上;构建在弹性计算这十年中训练出来的强大技术团队,以及在这十年间不断涌现的技术创新之上。

演讲者简介:蒋林泉是阿里巴巴集团研究员,阿里云弹性计算负责人。过去几年他带领团队,在大规模客户场景的驱动下,对平台技术进行架构升级,让 ECS 的整体产品弹性、性能、稳定性以及功能体验都突飞猛进,弹性计算产品体系在业界具备了很强的竞争力。在负责弹性计算之前,他还曾经担任过阿里云平台架构师,阿里云专有云总架构师,是云计算领域最优秀的架构师之一。

【END】

]]>
浅谈制造协同的基础设施 - 阿里云数字工厂-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 简介

制造企业数字化转型,是近年来越来越流行起来的概念,尤其在《工业4.0》和《中国制造2025》概念的引领下,越来越多的企业服务提供商开始涉足该领域,为广大制造业赋能。阿里云作为一个云上基础设施提供商,也不例外的整合了自己在制造企业数字化转型方面已有的信息化改造能力,以及阿里生态在电商销售平台、供应链平台、金融平台、物流平台等多方面的能力,为制造业数字转型的企业、服务商、行业运营商以及区域运营商提供了一个工业互联网领域全面的支撑平台:阿里云数字工厂

制造业的数字化转型

制造业的数字化转型,是制造协同及智能制造的基础,制造业从传统的作坊式生产方式步入制造协同及智能制造,一般都需要经过以下步骤:

数字化

数字化是基础,简言之就是将纸上的数据,用数字的方式描述出来,将生产经营过程中的所有要素,都用数字及数字间的关系的方式进行表述,这些要素包括:
人 - 生产经营过程中涉及的人员,如下图的客户,人员,供应商等
物 - 生产经营过程中涉及的物品,如生产设备,物料等
事件 - 由人与物的互联,产生的事件,如某某操作员新增了一个物料,某某生产设备的生产活动完成等

数字化的核心就是建模与描述,对以上要素进行建模,阿里云数字工厂产品里的数据管理功能包括主数据管理工厂建模等,都是围绕这个合理建模的目标展开的。

数字工厂运营中心
总的来说,一个典型的工厂的基础数据建模包括:
企业的组织结构:一个企业包括一个或者多个工厂,工厂又细化分割为不同的部门组织,组织则被定义为拥有不同工作职能的业务实体。
人员及角色:人员是生产制程过程中重要的基础性单元,根据员工的角色规划不同的系统权限,根据参数设定区分员工的角色和能力,可根据信息制定完善的人员分配和调度计划。
工作流、操作规范:根据业务实际对产品生产的流程进行定义,即用来定义制造产品的步骤顺序,作为一个标准化的指导。并根据工作流中的每一个工作中心或者工作站的工序标准和要求制定统一化的操作流程,形成唯一的规范。
物料、物料谱系:定义工厂内部的物料属性:材料、组装件、配件、成品等。并归集同系列的物料成物料分组,形成不同的物料谱系信息。
制造 BOM、工艺路线:根据产品搭建产品 BOM 架构,并根据产品设计配合工作流 定义和物理模型的设备定义,合理设计产品的工艺路线。规划定义的范围包括:数据记录、变更、工艺监控等。
在制品状态:定义范围包含在制品数量、产线位置、生产时间、状态等。

信息化

在数字化的基础上,人与人之间,物与物之间以及人与物之间,在一定的规则和流程下,产生关联事件,则产生出来了信息,基于这些信息则可以构建上层应用。
阿里云数字工厂目前有两个官方应用,一个是订单管理,订单管理提供手动、API创建订单、订单查询、订单操作等; 支持面向工厂用户完成生产环节与工序映射, 支持面向生产报工映射;支持导入生产计划单及关联。另一个是产品管理,提供产品创建、编辑,发布产品到主数据、对不再使用的产品进行归档,实现对自己研发、在产及停产的产品进行管理。
目前看来这两个信息化的应用还是主要集中在销售侧的信息化,而在生产侧还不够完善,对于接到订单之后如何联动后端的生产制造协同处理过程的支持度还不够,举个简单的例子,一个相对更完善的工艺路线管理应该包含对产品制造的工艺过程采用流程图等直观的方式进行定义,支持开始,过程,结束工序的定义,能描述返工或异常处理工序流程,能支持工艺路线的嵌套使用,支持多版本定义。
虽然如此,目前阿里云数字工厂接口式的开放能力的设计,可以支持第三方开发者去实现更多行业相关的制造协同细节,这个也比较符合toB的平台产品原则: 颗粒度粗,适用范围就广,与行业的结合就浅;颗粒度细,适用范围就窄,与行业的结合就深,阿里云作为平台,走前者的路线也是合理的。

智能化

智能化就是系统在具备一定的感知与计算能力之后,能够反向输出预警、决策支持等能力,在阿里云数字工厂里,与之相关的模块有集成组态以及经营驾驶舱

集成组态页面为车间操作人员提供了可视化的界面,结合云端能力可以远程,多设备的实时查看设备运行状态,风险预警等
集成组态

经营驾驶舱则在信息化的基础上,按照企业既定的生产经营指标进行统计与计算,为企业经营者的综合决策提供数据支持
经营驾驶舱

总结

从目前阿里云数字工厂的实现程度来说,已经具备了比较完整完善的云上制造协同基础设施的能力,但对于一般小型工厂来说太过于庞大,而对于生产经营过程复杂和特殊的大型工厂来说,需要有配套的实施甚至定制开发支持才能提供结合度更高更完善的支持,这就需要发挥生态优势,多引入优质的第三方深度应用及第三方实施服务商。

引用

阿里云文档 - 工业互联网平台

]]>
如何选择阿里云服务器操作系统?阿里云操作系统说明指南-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800


随着网站服务器技术的发展,越来越多的站长建站首先选择云服务器。时下阿里云云服务器ECS脱颖而出,成为多数站长网站服务器的首选。那么对于刚刚接触云服务器的站长来说,如何选择适合网站的阿里云云服务器ECS操作系统,阿里云云服务器ECS的操作系统有什么区别,阿里云linux服务器和windows服务器有何不同呢。


前提:若后期有需求购买阿里云任何产品的朋友,可以提前领取优惠劵。后期可为大家减少成本:点击领取阿里云优惠劵


阿里云个人购买+阿里云企业购买



首先,我们要清楚的便是每个系统之间的差别,以及在阿里云上的差别:


1.Windows


1.1)系统内含正版激活。


1.2)适合于运行Windows下开发的程序,如.net等。


1.3)支持SQLServer等数据库(需自行安装)。


1.4)可以使用远程桌面方式登录进行管理。


注:512内存不支持选择Windows系统,1G以上内存才能很好支持该系统。


2.Linux


2.1.1)最流行的服务器端操作系统,强大的安全性和稳定性。


2.1.2)免费且开源,轻松建立和编译源代码。


2.1.3)通过SSH方式远程访问您的云服务器。


2.1.4)一般用于高性能web等服务器应用,支持常见的PHP/Python等编程语言,支持MySQL等数据库(需自行安装)。


2.2CentOS(推荐)请使用yum方式在线安装软件。


2.3Ubuntu请使用aptitude方式在线安装软件。


2.4Debian请使用apt-get方式在线安装软件。


2.5AliyunLinux(兼容RedHat)请使用yum方式在线安装软件,yum源需要自行购买redhat的商业支持。


操作系统更换规则:


1.更换操作系统


更换系统之前请先停止云服务器,云服务器更换操作系统会直接重置系统盘【IP不变】,系统盘数据将会丢失!


请您注意:


1.1.更换操作系统会使云服务器的系统盘更换为新的镜像,原有系统盘的数据都会丢失。


1.2.云服务器数据盘的数据不会受到影响。


1.3.建议您将系统盘的个人数据备份到数据盘中,或采用其他方式进行备份。


1.4.因您没有备份系统盘相关个人数据而造成的数据丢失,阿里云不承担责任。


1.5.内存为512M云服务器不支持更换Windows操作系统。


2.CPU/内存与操作系统的选择


2.1)如需选择/变更4G以上内存请您选择64位操作系统(32位操作系统存在寻址限制)。


2.2)如您选择32位操作系统,4G以上内存页面暂不展示,只有云服务器更换为64位操作系统才可展示。


2.3)Windows32位操作系统支持最高CPU为4核。


2.4)配置:[CPU:1核;内存:512M]的云服务器不支持选择/更换Windows操作系统。


Windows篇


阿里云提供了6种window系统,涵盖了Server2003sp2以及Server2008R2这两大类操作系统。


其中又分为了32位和64位


(1)如何选择32位还是64位


32位系统相比64位系统,最主要的限制体现在内存的大小上。因为32位本身的限制,其最大只可支持到4GB内存,如果您的网站要使用高于4GB的内存或者以后有扩充内存寻到4GB以上的打算,请使用64位操作系统。


(2)选择2003还是选择2008


对于windows来说,我个人建议是选择版本越高的越好。相对来说新版本漏洞相对来说更少,而且IIS7.5相对于IIS6提供了更多的功能以及更方便的控制台。但是考虑到大家的机器配置不同,在此给出一下几种选择:


A:配置低于双核2GB内存:选择server2003不装数据库配置双核4GB:server2003mssql或者server2008R2不带数据库


B:配置高于双核8GB:serever2008R2mssql建议如果大家要在云服务器上跑数据库,尽量选择大内存配置,或者降低配置去选用RDS


(3)中英文、安全加固版如何选择


这个就依据大家各自的喜好来了,在此不多说了至于Windows服务器配置教程,因为网上教程很多而且相对于Linux来说Windows配置难度更低,所以Windows的配置教程会比较晚的放出。


Linux篇


(1)这些linux大类有什么区别


Debian:用的deb包,使用APT包管理系统。


同时Debian提供了大多数软件比较新的版本,并且提供了更多的软件包(相对于原版RedHat)。Debian的优点在于更新迅速,软件包完善(Ubuntu尤其),操作便利。缺点是部分时候稳定性欠佳,跟进最新软件有可能存在Bug。


Centos:用rpm包,使用yum包管理系统。


相对于Debian来说,Centost的一大特点就是慢。大部分软件停留在稳定版本,而且相距最新版版本也差较多。而且某些新版软件的一些新特性支持也比较慢,比如php-fpm。


因为Centos是面向企业用户提供的操作系统,所以在稳定性上十分突出,一般在新功能或稳定性的选择上更倾向于后者。只有当某个功能完全确定稳定了,才会加入到系统里。优点是系统稳定,技术文档完善,如果付费的话能得到企业级别的技术支持。缺点是软件包比较老旧,而且一些较新功能会欠缺。


总结一下:如果你喜欢尝鲜,喜欢用最新的功能或喜欢折腾系统,那么Debian是个更好的选择。
上手难度Ubunt


(2)Debian与Ubuntu的选择


Ubuntu是基于Debian所开发,可以简单地认为Ubuntu是Debian的功能加强版。


与Debian相比,Ubuntu提供了更人性化系统配置,更强大的系统操作以及比Debian更激进的软件更新。


Ubuntu与Debian比较,可以认为Debian更趋向于保守一些,Ubuntu对新手友好度更高,上手更容易。


用过Ubuntu的都会体会到它的易用,反之如果用过Ubuntu再换到别的系统,都会觉得不适应,Ubuntu真的很方便。


个人建议,如果你打算选择Debian类的,建议选择Ubuntu。


Ubuntu提供了更好的操作,更激进的软件更新,更方便管理软件以及相差无几的稳定性。


如果你不想放弃稳定'那么请选择Debian。


关于Ubuntu版本选择:


在此解释下Ubuntu的版本支持时间。Ubuntu普通版本只提供18个月的技术支持,过期则不管。


服务器版本提供长达五年的技术支持。所以建议大家选择12.04版,提供长达5年的技术支持,可以确保在静候相当长的一段时间内你的服务器可以继续收到系统升级补丁以及可用的软件源。


(3)Centos的选择


对于阿里云Centos的选择,建议选择Centos6.5版本,带来了更多的新特性以及更多的新功能。


除非你的软件需要php5.1的环境,那么就选择Centos6.5。如果网站需要支持php5.1,只能选用Centos5.8。


至于具体版本选择,建议php5.1用户选择Centos5.8,其他的用户则为Centos6.5。
最后的最后提醒大家一定要领取价值2000优惠劵


]]>
异常的概念-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。

异常的概念

程序在运⾏过程中,由于我们的编码不规范,或者其他原因⼀些客观原因,导致我们的程序⽆法继续运⾏,此时,程序就会出现异常。如果我们不对异常进⾏处理,程序可能会由于异常直接中断掉。为了保证程序的健壮性,我们在程序设计⾥提出了异常处理这个概念。
读取文件异常
在读取⼀个文件时,如果这个文件不存在,则会报出 FileNotFoundError 错误。
image.png
除数为零异常
出现ZeroDivisionError异常
image.png
程序在运⾏过程中会经常遇到类似的异常,如果我们不进⾏处理,此时程序就会中断并退出。为了提⾼程序的健壮性,我们可以使⽤异常处理机制来解决程序运⾏过程中可能出现的问题。

try...except语句

try...except语句可以对代码运⾏过程中可能出现的异常进⾏处理。 语法结构:

try:
    可能会出现异常的代码块
except 异常的类型:
    出现异常以后的处理语句

示例:

try:
    f = open('test.txt', 'r')
    print(f.read())
except FileNotFoundError:
    print('⽂件没有找到,请检查⽂件名称是否正确')

try...else语句

咱们应该对else并不陌⽣,在if中,它的作⽤是当条件不满⾜时执⾏的实⾏;同样在try...except...中也是如此,即如果没有捕获到异常,那么就执⾏else中的事情

def div(a, b):
    return a / b

try:
    x = div(5 / 0)
except Exception as e:
    print('程序出错了!!!!')
else:
    print('计算的结果是', x)

try..finally语句

try...finally...语句⽤来表达这样的情况:

在程序中,如果⼀个段代码必须要执⾏,即⽆论异常是否产⽣都要执⾏,那么此时就需要使⽤finally。⽐如⽂件关闭,释放锁,把数据库连接返还给连接池等。

try:
    f = open('test.txt')
    try:
        while True:
            content = f.readline()
            if len(content) == 0:
                break
                print(content)
    except:
        #如果在读取⽂件的过程中,产⽣了异常,那么就会捕获到
        #⽐如 按下了 ctrl+c
        pass
    finally:
        f.close()
        print('关闭⽂件')
except:
    print("没有这个⽂件")

说明:

我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执⾏,把⽂件关闭。

异常使用场景

解决输入不是数字以及输入年龄非整数的问题。

age  = input('请输入您的年龄:')

try:
    age = float(age)
except ValueError as e:
    print('输入的不是数字')
else:
    if age > 18:
        print('欢迎来到我的网站')
    else:
        print('未满18岁,请自动离开')

配套视频

]]>
计算机视觉如何改善我们的日常生活-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

--------点击屏幕右侧或者屏幕底部“+订阅”,关注我,随时分享机器智能最新行业动态及技术干货----------

人工智能,利用机器学习的力量来处理各种日常任务的技术,已经在改变我们工作、购物、银行和驾驶的方式。

它给我们带来了一些技术,可以为工人处理平凡、重复的工作,检测欺诈性的金融交易,并允许自动驾驶汽车做出决定。但是人工智能如何改变我们在自己家里管理日常生活的方式呢?

通过采用Alexa和许多其他物联网设备,我们已经开始向智能技术移交一些责任。

image.png

如果我们忘记锁车,我们可以很快纠正错误并远程锁车。如果我们忘记锁上房门或设置DVR来录制喜爱的节目,我们也可以远程处理。

人工智能技术的下一步将增强它们的实用性。就像它们接管工作场所耗时、无需大脑的日常任务一样,它们将开始从我们家里接手一些苦差事。

前面仅是一些场景,探索家庭中智能技术的惊人可能性,这些场景可以看到我们需要的东西,并以各种方式帮助我们解决问题。

轻松购物

你的智能冰箱在不久的将来有一个摄像头,可以看到牛奶的存量正在减少,或者盒子已经永久地从冰箱中取出,并了解这对你意味着什么。

冰箱和食品储藏室(也有一个智能摄像头)可交换有关牛奶供应状况的信息。这两个食品存储系统意识到您将要用尽这一必需品,因此向您发送一条文本信息,询问您是否要将其添加到购物清单中。这就是物体识别的魔力。

为了让您的购物清单保持最新,您的冰箱将信息与洗衣房、浴室、车库和其他任何需要持续存放物品的地方的货架和存储单元进行协调。当需要进行实际的购物时,您所要做的就是检查列表,添加您认为缺失的任何东西并下订单。

每天的家务活都有很多电器的帮助

以下是一些日常情况的例子,每天都会出现在某个人身上。他们并不太重要或导致过大压力,但在漫长的工作日、家庭和其他责任之外,又增添了太多的这些小烦恼,使他们开始感到有点沉重。

1. 洗衣

你有没有过不小心洗了有污点的东西却没有注意到的经历?那个污点会毁了你的白衬衫。想象一下,如果有一台洗衣机,由于异常检测,它能在你最喜欢的一件衣服上漏了一块污渍时告诉你,例如“灰色运动衫上有芥末渍。 您想预处理吗?”

再也不会忘记,您将鸡翅掉在您最喜欢的那条紧身牛仔裤上,然后漫不经心地将它们洗了一遍,使污点永生。

当然,如果污渍没有消失,您的裤子抽屉将告诉您,您需要购买更多的裤子。

2. 晚餐没主意

如果你冰箱和食品存储室里的东西不多了。不用担心,两者可以结合起来,提出使用你手头已有物品的食谱建议。这样你就可以专注于下午的会议,而不是纠结于晚餐做什么。

3. 睡个好觉

宝宝房间的空调可以将房间保持在一定温度,但这仍然不能告诉您她是太暖还是太冷。智能温度控制可以“看到”孩子额头上的汗水,或者注意到她已经踢开了毯子,或者正在翻来覆去,然后决定为房间降温直到她感到舒适为止。

相反,如果她太冷,人工智能动作检测可以捕捉到视觉信息,比如把毯子拉在一起。然后它可以检查房间的温度,确定它是有点冷,并决定让房间暖和起来。

同样的智能温度控制,不仅对于不能自己调节空调的宝宝来说特别方便,同样也适用于爸爸妈妈,他们在房间变得不舒服之前也无法唤醒任何人,他们也需要智能调节温度。

智能家电给了人类时间的礼物

智能家电和存储系统可以让工作繁忙的父母们在早上和晚上花更多的时间与他们的孩子和彼此亲密接触,而不用花那么多时间去打理家务。

智能家居技术有许多节省时间和精力的应用。在这个职业不断发展的时代,时间是我们最需要的东西,人工智能驱动的设备可以减轻我们的负担,还给我们一些宝贵的、失去的时间,是一些最能提高生活质量的技术创新。

image.png

文章来源:https://ai.51cto.com/art/202006/619638.htm
文章转自51cto,本文一切观点和《机器智能技术》圈子无关

]]>
图文详解 DFS 和 BFS-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

原文链接

一、前言

深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在 leetcode,高频面试题中。
本文将会从以下几个方面来讲述深度优先遍历,广度优先遍历,相信大家看了肯定会有收获。

  • 深度优先遍历,广度优先遍历简介
  • 习题演练
  • DFS,BFS 在搜索引擎中的应用

二、深度优先遍历,广度优先遍历简介

深度优先遍历

深度优先遍历主要思路是从图中一个未访问的顶点 V 开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底...,不断递归重复此过程,直到所有的顶点都遍历完成,它的特点是不撞南墙不回头,先走完一条路,再换一条路继续走。
树是图的一种特例(连通无环的图就是树),接下来我们来看看树用深度优先遍历该怎么遍历。
image.png
1、我们从根节点 1 开始遍历,它相邻的节点有 2,3,4,先遍历节点 2,再遍历 2 的子节点 5,然后再遍历 5 的子节点 9。
image.png
2、上图中一条路已经走到底了(9是叶子节点,再无可遍历的节点),此时就从 9 回退到上一个节点 5,看下节点 5 是否还有除 9 以外的节点,没有继续回退到 2,2 也没有除 5 以外的节点,回退到 1,1 有除 2 以外的节点 3,所以从节点 3 开始进行深度优先遍历,如下
image.png
3、同理从 10 开始往上回溯到 6, 6 没有除 10 以外的子节点,再往上回溯,发现 3 有除 6 以外的子点 7,所以此时会遍历 7
image.png
3、从 7 往上回溯到 3, 1,发现 1 还有节点 4 未遍历,所以此时沿着 4, 8 进行遍历,这样就遍历完成了
完整的节点的遍历顺序如下(节点上的的蓝色数字代表)
image.png
相信大家看到以上的遍历不难发现这就是树的前序遍历,实际上不管是前序遍历,还是中序遍历,亦或是后序遍历,都属于深度优先遍历。
那么深度优先遍历该怎么实现呢,有递归和非递归两种表现形式,接下来我们以二叉树为例来看下如何分别用递归和非递归来实现深度优先遍历。
1、递归实现
递归实现比较简单,由于是前序遍历,所以我们依次遍历当前节点,左节点,右节点即可,对于左右节点来说,依次遍历它们的左右节点即可,依此不断递归下去,直到叶节点(递归终止条件),代码如下

public class Solution {
    private static class Node {
        /**
         * 节点值
         */
        public int value;
        /**
         * 左节点
         */
        public Node left;
        /**
         * 右节点
         */
        public Node right;
        public Node(int value, Node left, Node right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }
    public static void dfs(Node treeNode) {
        if (treeNode == null) {
            return;
        }
        // 遍历节点
        process(treeNode)
        // 遍历左节点
        dfs(treeNode.left);
        // 遍历右节点
        dfs(treeNode.right);
    }
}

递归的表达性很好,也很容易理解,不过如果层级过深,很容易导致栈溢出。所以我们重点看下非递归实现
2、非递归实现
仔细观察深度优先遍历的特点,对二叉树来说,由于是先序遍历(先遍历当前节点,再遍历左节点,再遍历右节点),所以我们有如下思路

  1. 对于每个节点来说,先遍历当前节点,然后把右节点压栈,再压左节点(这样弹栈的时候会先拿到左节点遍历,符合深度优先遍历要求)
  2. 弹栈,拿到栈顶的节点,如果节点不为空,重复步骤 1, 如果为空,结束遍历。

我们以以下二叉树为例来看下如何用栈来实现 DFS。
image.png
整体动图如下
2.gif
整体思路还是比较清晰的,使用栈来将要遍历的节点压栈,然后出栈后检查此节点是否还有未遍历的节点,有的话压栈,没有的话不断回溯(出栈),有了思路,不难写出如下用栈实现的二叉树的深度优先遍历代码:

/**
 * 使用栈来实现 dfs
 * @param root
 */
public static void dfsWithStack(Node root) {
    if (root == null) {
        return;
    }
    Stack<Node> stack = new Stack<>();
    // 先把根节点压栈
    stack.push(root);
    while (!stack.isEmpty()) {
        Node treeNode = stack.pop();
        // 遍历节点
        process(treeNode)
        // 先压右节点
        if (treeNode.right != null) {
            stack.push(treeNode.right);
        }
        // 再压左节点
        if (treeNode.left != null) {
            stack.push(treeNode.left);
        }
    }
}

可以看到用栈实现深度优先遍历其实代码也不复杂,而且也不用担心递归那样层级过深导致的栈溢出问题。

广度优先遍历

广度优先遍历,指的是从图的一个未遍历的节点出发,先遍历这个节点的相邻节点,再依次遍历每个相邻节点的相邻节点。
上文所述树的广度优先遍历动图如下,每个节点的值即为它们的遍历顺序。所以广度优先遍历也叫层序遍历,先遍历第一层(节点 1),再遍历第二层(节点 2,3,4),第三层(5,6,7,8),第四层(9,10)。3.gif
深度优先遍历用的是栈,而广度优先遍历要用队列来实现,我们以下图二叉树为例来看看如何用队列来实现广度优先遍历
image.png
动图如下
4.gif
相信看了以上动图,不难写出如下代码

/**
 * 使用队列实现 bfs
 * @param root
 */
private static void bfs(Node root) {
    if (root == null) {
        return;
    }
    Queue<Node> stack = new LinkedList<>();
    stack.add(root);
    while (!stack.isEmpty()) {
        Node node = stack.poll();
        System.out.println("value = " + node.value);
        Node left = node.left;
        if (left != null) {
            stack.add(left);
        }
        Node right = node.right;
        if (right != null) {
            stack.add(right);
        }
    }
}

三、习题演练

接下来我们来看看在 leetcode 中出现的一些使用 DFS,BFS 来解题的题目:

leetcode 104,111: 给定一个二叉树,找出其最大/最小深度。

例如:给定二叉树 [3,9,20,null,null,15,7],

3
   / 
  9  20
    /  
   15   7

则它的最小深度  2,最大深度 3
解题思路:这题比较简单,只不过是深度优先遍历的一种变形,只要递归求出左右子树的最大/最小深度即可,深度怎么求,每递归调用一次函数,深度加一。不难写出如下代码

/**
 * leetcode 104: 求树的最大深度
 * @param node
 * @return
 */
public static int getMaxDepth(Node node) {
    if (node == null) {
        return 0;
    }
    int leftDepth = getMaxDepth(node.left) + 1;
    int rightDepth = getMaxDepth(node.right) + 1;
    return Math.max(leftDepth, rightDepth);
}
/**
 * leetcode 111: 求树的最小深度
 * @param node
 * @return
 */
public static int getMinDepth(Node node) {
    if (node == null) {
        return 0;
    }
    int leftDepth = getMinDepth(node.left) + 1;
    int rightDepth = getMinDepth(node.right) + 1;
    return Math.min(leftDepth, rightDepth);
}

leetcode 102: 给你一个二叉树,请你返回其按层序遍历得到的节点值。(即逐层地,从左到右访问所有节点)。示例,给定二叉树:[3,9,20,null,null,15,7]

3
   / 
  9  20
    /  
   15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

解题思路:显然这道题是广度优先遍历的变种,只需要在广度优先遍历的过程中,把每一层的节点都添加到同一个数组中即可,问题的关键在于遍历同一层节点前,必须事先算出同一层的节点个数有多少(即队列已有元素个数),因为 BFS 用的是队列来实现的,遍历过程中会不断把左右子节点入队,这一点切记!动图如下
5.gif
根据以上动图思路不难得出代码如下:
Java 代码

/**
 * leetcdoe 102: 二叉树的层序遍历, 使用 bfs
 * @param root
 */
private static List<List<Integer>> bfsWithBinaryTreeLevelOrderTraversal(Node root) {
    if (root == null) {
        // 根节点为空,说明二叉树不存在,直接返回空数组
        return Arrays.asList();
    }
    // 最终的层序遍历结果
    List<List<Integer>> result = new ArrayList<>();
    Queue<Node> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        // 记录每一层
        List<Integer> level = new ArrayList<>();
        int levelNum = queue.size();
        // 遍历当前层的节点
        for (int i = 0; i < levelNum; i++) {
            Node node = queue.poll();
            // 队首节点的左右子节点入队,由于 levelNum 是在入队前算的,所以入队的左右节点并不会在当前层被遍历到
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
            level.add(node.value);
        }
        result.add(level);
    }
    return result;
}

Python 代码:

class Solution:
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []  #嵌套列表,保存最终结果
        if root is None:
            return res
        
        from collections import deque
        que = deque([root])  #队列,保存待处理的节点
        while len(que)!=0:
            lev = []  #列表,保存该层的节点的值
            thislevel = len(que)  #该层节点个数
            while thislevel!=0:
                head = que.popleft()  #弹出队首节点
                #队首节点的左右孩子入队
                if head.left is not None:
                    que.append(head.left)
                if head.right is not None:
                    que.append(head.right)
                lev.append(head.val)  #队首节点的值压入本层
                thislevel-=1
            res.append(lev)
        return res

这题用 BFS 是显而易见的,但其实也可以用 DFS, 如果在面试中能用 DFS 来处理,会是一个比较大的亮点。
用 DFS 怎么处理呢,我们知道, DFS 可以用递归来实现,其实只要在递归函数上加上一个「层」的变量即可,只要节点属于这一层,则把这个节点放入相当层的数组里,代码如下:

private static final List<List<Integer>> TRAVERSAL_LIST  = new ArrayList<>();
/**
 * leetcdoe 102: 二叉树的层序遍历, 使用 dfs
 * @param root
 * @return
 */
private static void dfs(Node root, int level) {
    if (root == null) {
        return;
    }
    if (TRAVERSAL_LIST.size() < level + 1) {
        TRAVERSAL_LIST.add(new ArrayList<>());
    }
    List<Integer> levelList = TRAVERSAL_LIST.get(level);
    levelList.add(root.value);
    // 遍历左结点
    dfs(root.left, level + 1);
    // 遍历右结点
    dfs(root.right, level + 1);
}

四、DFS,BFS 在搜索引擎中的应用

我们几乎每天都在 Google, Baidu 这些搜索引擎,那大家知道这些搜索引擎是怎么工作的吗,简单来说有三步
1、网页抓取
搜索引擎通过爬虫将网页爬取,获得页面 HTML 代码存入数据库中
2、预处理
索引程序对抓取来的页面数据进行文字提取,中文分词,(倒排)索引等处理,以备排名程序使用
3、排名
用户输入关键词后,排名程序调用索引数据库数据,计算相关性,然后按一定格式生成搜索结果页面。
我们重点看下第一步,网页抓取。
这一步的大致操作如下:给爬虫分配一组起始的网页,我们知道网页里其实也包含了很多超链接,爬虫爬取一个网页后,解析提取出这个网页里的所有超链接,再依次爬取出这些超链接,再提取网页超链接。。。,如此不断重复就能不断根据超链接提取网页。如下图示
image.png
如上所示,最终构成了一张图,于是问题就转化为了如何遍历这张图,显然可以用深度优先或广度优先的方式来遍历。
如果是广度优先遍历,先依次爬取第一层的起始网页,再依次爬取每个网页里的超链接,如果是深度优先遍历,先爬取起始网页 1,再爬取此网页里的链接...,爬取完之后,再爬取起始网页 2...
实际上爬虫是深度优先与广度优先两种策略一起用的,比如在起始网页里,有些网页比较重要(权重较高),那就先对这个网页做深度优先遍历,遍历完之后再对其他(权重一样的)起始网页做广度优先遍历。

五、总结

DFS 和 BFS 是非常重要的两种算法,大家一定要掌握,本文为了方便讲解,只对树做了 DFS,BFS,大家可以试试如果用图的话该怎么写代码,原理其实也是一样,只不过图和树两者的表示形式不同而已,DFS 一般是解决连通性问题,而 BFS 一般是解决最短路径问题,之后有机会我们会一起来学习下并查集,Dijkstra, Prism 算法等,敬请期待!

来源 | 码海
作者 | 码海

]]>
阿里高级技术专家:如何结构化地思考、做事、成长?-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 图片无法显
点击图片或戳我查看详情和投简历
1.png

作者 | 承风 阿里巴巴高级前端技术专家

导读:建立结构化的思维,以结构化的模式驱动工作,以结构化的体系构建自身的能力,小到写 PPT、大到为业务提供更大价值,都是非常值得我们使用的模式。阿里巴巴数字供应链事业部高级前端技术专家 - 承风,将会在本文中和大家分享他在建立和践行结构化思维过程中的方法论。

引言

在每年自评、汇报、工作中总会感受到一些结构化带来的问题:

  • 老板问我当前做的事情怎么样了,我讲了合作中的难点、视觉风格问题、业务情况、代码质量······工作的进展,说了半小时,老板还是 get 不到我做的事情的情况和价值,是老板不在意这件事、还是我语言表达能力不行?
  • 我这一年做了很多事情,都有一定产出,但是跳出细节来看,发现对业务、对团队价值都不大,是我做得不好、还是运气不好做的事情不好?
  • 最近流行 codeless,我打算研究下可视化搭建;团队业务涉及到流程编排,我打算研究下 TMF······一年下来折腾了不少成果出来,似乎老板也没有很认可,是我不讨老板喜欢还是做的事情没价值?

这些问题,根据我自己工作经验的总结,认为大都是对结构化认知不足和践行不佳导致的。

  • 第一个问题:对事情的认知和表述结构化方面存在问题 - 结构化的思维相关问题;
  • 第二个问题:做事儿多而杂不成体系 - 结构化的工作模式问题;
  • 第三个问题:学习和成长缺乏重点 - 结构化的能力建设的问题。

关于结构化

Structured:建立中心(问题、目标)。以中心的核心要素对中心进行分解,形成分类子结构。以一定的范式、流程顺序进行分类子结构的合理分类、减少非关键分类结构;对关键分类子结构进行分析,寻找对策,制订行动计划。

同理,逆向的顺序,对多种杂乱的内容,进行分类、剪枝、归纳汇总成一个中心。我认为也是结构化。

有很多相关的书籍:

领导者之剑:成功人士的 5 大突破思维技巧、金字塔原理、极简思考:来自世界顶尖咨询公司的高效工作法······

也可以参看很多结构化的应用方式:结构化面试、结构化金融产品设计、结构化系统开发方法······从多行业多领域的使用可以反思和加深自己的认知。

在工作中认知和践行结构化

结构化的理论是简单清晰的(道的层面总是比较简洁),但实际应用中如何进行结构化、最有效的使用结构化却有很多经验(术的层面总是多变的)。在此结合我个人的经验给出一些建议:

1. 建立中心

当我们接手一个业务需求、面对一项挑战的时候,应当先思考这个需求的核心目标是干嘛的。

1)结构化的建立中心

思考的过程也是结构化的,我通常会分解为两个子结构进行:

  • 这个业务需求当前的目标是什么(事的维度):1. 目标是快速完成上线试一试业务效果:目标事的维度为高效稳定上线;2. 目标是建立后续业务铺开的基础方案:目标事的维度是强架构设计下的核心与功能拆分方案;
  • 为什么需要我来做(人的维度):1. 是因为我工作量还有 buffer 所有承担这部分:目标人的维度是完成职能范畴内的工作;2. 是因为我在这方面技术比较擅长:目标人的维度是利用事情强化自身能力和使用能力把事儿做好。

2)沿中心上行

对单个业务需求而言,从事、人两个维度建立起的中心即其核心,是最主要部分,建立一颗结构树的基础。但我们不应当停止于此,还应当向上推导:这个需求在整个业务的范畴内,是在哪一层次,哪一分类的。即应当更高层面、或整体业务和行业发展,对这方面业务是怎样的期许。(价值的维度)

  • 一个团队接手某项业务或需求,其背后都会有思考:我们是期望借着这个业务打造一个平台,提升整体行业的表现;还是突击这个业务方向,占领局部的商业蓝海······
  • 接到一个需求时一定要思考更大层面这事的价值,才能更好的判断优先级、做事模式。

例如:我们做采购系统,当前需求是,提供采购单列表,按总价范畴搜索单据的能力。按结构化的中心建立,它是:高效稳定上线(事)、我职能范围内的工作(人)。

  • 如果止步于单个需求建立的中心,我们后续的分解应当是如何快速搞定、如何更稳定······
  • 如果我们继续向上构建树,我们可以和产品、使用者深度沟通下为什么要做价格搜索:1. 管理员期望能看到高价订单的情况。那么这个需求的上一个中心节点应当是:管理提效;2. 继续向上,是基于什么原因需要做管理提效?因为防止贪腐、提高工作效率。那么上一个中心节点应当是:降低成本;3. 依次向上,直到抵达整个业务的目标。比如总结觉得,我们的业务是构建一个集成高效的集团采购系统;
  • 再以此反思:1. 降低成本是不是当前工作的重点?团队是否有足够的架构设计和人员组织来支撑?2. 下一步到到管理提效层面,订单的搜索是否真的是当前最佳的提效工具,因为用户如何定义高价格?他执行这种搜索式查阅工作是否真的是有效不遗漏的?查阅到了订单有问题他能做什么?······我们会发现这个需求背后更多的问题。我们也可以沿着更大的中心树,去思考是否构建更好的方案可以更根本的解决这个问题;
     
  • 再回过头来看当前的任务,是否真的是高效稳定上线(事)、我职能范围内的工作(人)。或者当前最紧急的部分(用户直接需求嘛)是高效稳定上线(事)、我职能范围内的工作(人),但后续更要做更多的其他的根本性解决方案。

2.png

沿当前的中心向上建立更大的结构化的认知体系:

  • 会让我们对当前事情的判断(中心)更加清晰,也有更好的认知基础,极有利于与合作方的沟通碰撞和内容创新;
  • 建立更大结构化认知体系的过程,也是深入业务、扩展认知力的过程。一定要多和老板、业务方交流,从各自认知的差异性上提升自身的认知能力。

此外,构建更大认知体系,对个人和团队发展也是有价值的。

  • 很多时候我们忙于业务实现,都没有花时间去思考业务的价值。一部分是因为忙,一部分是因为懒,一部分是因为不懂,一部分是因为我们是来做事拿工资的,而不是带着愿景想把事做好的。这都不是真正能把事情做好的方式;
  • 作为团队的一员,我们不应当只做“花时间、生鸡蛋”的极低人效、技术外包的母鸡模式,而应当积极的尝试做“建机器、铺厂房、出产品”的工厂模式。这对业务和个人的发展才是积极的作用。

2. 中心的分解

建立完成中心后,有多种对中心进行分解的方式。其目标在于将中心拆解为多个内聚的子部分。整体思想是 MECE(Mutually Exclusive Collectively Exhaustive)原则,即相互独立,完全穷尽不重叠、不遗漏的分类。够借此有效把握问题的核心,并成为有效解决问题的方法。

下文是一些分解方案的简介。

1)SWOT

SWOT 分析方法又称态势分析法:即 Strengths(优势)、Weaknesses(劣势)、Opportunities(机会)、Threats(威胁)四类。最早用于进行企业竞争态势分析,对个人而言用于分析自身的竞争态势也是极佳的。

3.png

(对团队数据可视化能力建设的 SWOT 分析示例)

SWOT 分析法四个象限可以分别分类四大独立的方面,而其中 SW 部分 - 优势劣势一般用于分析内部条件;OT 部分 - 机会威胁一般用于分析外部情况。又形成了两个独立而全覆盖的大类分隔。非常有助于看清楚当前的情况。

此外,SWOT 形成的象限又可以结合跨大类进行组合分析:

  • SO 的关联部分,是我们做事的重点,重要紧急的。比如 Node + 可视化能力 =》我们可以构建基础平台;
  • WO 相关的部分,是我们必须解决的,很多情况下是我们需要进行专享突破式学习的内容。比如图形学 + 基础框架 =》如果我们要做基础框架这个机会,那么必须补全图形学相关知识;
  • WT 部分是威胁到这件事或者成长的部分,必须重视、避免、纠正。比如图形学 + 多公司发力基础框架 =》如果我们没有基础框架基础沉淀,又缺乏图形学相关学习目标或者相关引导,那么我们就应当放弃做基础框架;
  • ST 部分是我们直面竞争的部分,如何发挥自身优势去面对威胁,需要有相关的抓手。比如 Node + 成体系的 ISV =》ISV 肯定会在系统化建设上发力,我们必须使用 node 的基础能力提供更加灵活高效的解决方案。

2)AHP

AHP 分析方法又称层次分析法:Analytic Hierarchy Process,将与决策总是有关的元素分解成目标、准则、方案等层次,在此基础之上进行定性和定量分析的决策方法。它是一种定性 & 定量结合,系统化 & 层次化的分析方法。

4.png

第一层是目标,第二层是分解的准则,第三层是实施方案。构建 A1...A5 与目标相关权重,形成构造判断(成对比较)矩阵。对矩阵进行层次单排序及其一致性检验,再计算 B1....B3 层总排序权值和一致性检验,按照权重结果进行方案优先级的判断。更多详细计算内容可参考 MBALib。

我们在实际使用中有两种方式:

  • 以层次建模的模式,对核心目标进行有效分解,即如果某一类分解,无法被赋予权重,则不是一个有效的分解;
  • 根据层次分析建模,对当前事情优先级进行决策,在实际应用中我们即便不去精确计算权重,至少按此结构看各个工作目标与分解的相关性,亦是一种指导。

3)进行分解的顺序逻辑

中心的分解应当使用流程化思维。指的是找出事情发生的内在逻辑,思考的时候可以逻辑顺序作为参考。

  • 时间顺序:中心执行的步骤、流程等;
  • 结构顺序:中心的空间、地理位置、内部外部条件等;
  • 程度顺序:中心的轻重缓急、重要性等;
  • ······

以 XMind 为例:

5.png

(规划的时间顺序分解)

6.png

(按相关性进行结构顺序分解)
7.png

(按照重要性即与鱼头的距离进行程度结构分解)

按照哪种顺序进行分解因个人爱好和事情的不同而不一致,没有优劣之分只有合适不合适。多加应用多做尝试不同模式,会不断提升自身思维和行为的逻辑性以更加结构化。

3. 清理

事业是无限的,人力总是有穷、认知高度总是不够的。我们不能把分析出的所有点都做好,也不是分解出的所有层次都真正有价值的。那么针对分解的产出物,应当以数据挖掘的物料准备类似的逻辑进行前期处理,来提高效率、去除噪声。常用的分别为:

  • 泛化:过度细碎的层次应当抽象总结到更高层次,以进行更有效分类;
  • 补漏:针对中心,某些关键决策子层级缺失,应当补充完全;
  • 剪枝:针对中心,与中心紧密度关联较低或无可操作性的部分应当去除,以降低整体分析复杂度。

1)泛化

例如我们要提高部门的研发效率,日常工作收集了一些反馈:开发环境不稳定天天抢日常部署,jar 包冲突屡禁不止,经常有人 push origin -f,前后端联调确定字段巨麻烦,对当前业务 webx 用起来不够顺手迅速······

这些问题都可以归纳到“研发效率提升要解决的点”这个分支下,但细碎的陈列让对问题的解决显得没有重点,后续遇到其他问题也没办法进行有效的区分。

泛化一般是这样的模式:我们有一些用户年龄,分布为 10、14、35、42、55、72 岁。可以抽象成年龄分层 - 青少年(10、14)、中年(35、42)、老年(55、72),降低数据量提高内聚性。

针对上面的研发效率问题,我们可以按照研发工作的主要方面,泛化相关的问题:对当前业务 webx 用起来不够顺手迅速(研发架构);抢日常部署、前后端联调(研发环境)、jar 包冲突、强制提交(研发态度)。

在结构化中,不是越深、越细的结构是越好的,很多时候越内聚抽象的结构反而更有利于进行后续实操改进工作的开展。

2)补漏

例如我们要提升前端研发效能。通过调研、学习和思考,认为需要进行几方面的结构化建设:

  • 高效的研发环境:极佳的研发工具、稳定的研发环境、可测试和追述的代码表现、可测试和追述的代码表现······
  • 平台技术驱动研发:核心能力不断沉淀、非核心能力能无侵入的快速定制······
  • 合理的团队人员结构······

进行结构化的梳理可以更清晰的看出针对目标,哪些部分是我们缺失的。因而针对缺失部分的重要性和紧迫程度,可以更合理的安排工作,而非一味的在较强的部分进行优化、或者各种事情东打一枪西放一炮。

同理,对个人技术成长而言,整理针对当前行业发展下当前技术环境下个人能力的要求点,进行结构化分层和缺失标注,也是指明自身学习方向的好手段。

3)剪枝

在我们进行中心的层层分解时,我们即便做到了归类,也总会生产一些特别发散的点。针对这些点,我们应当进行非关键分类结构的减少,即剪枝过程。

8.png

通常需要进行剪枝的部分:

  • 是和其余结构关联不大的部分
  • 针对当前核心问题是非主要相关的部分
  • 兼顾该部分的成本比产出的效果更大

例如我们要通关只狼,一个牛逼的手柄花费的代价,和其对核心目标的提升是不对等的。如果要兼顾该子结构,可能对自己身体和心理造成更大的负影响,放弃是明智的选择。

我们在安排自身的学习成长也是类似的,是否需要报个昂贵的视频课程,是否需要深入研究 TMF 源代码,都应当看对当前自身的学习目标的结合度、性价比来做决策,是去是留。

结构化中,要果断剪枝,保持专注、保持可行性。

小结

结构化是一个非常简洁的理论:

建立中心;
以中心的核心要素对中心进行分解,形成分类子结构;
以一定的范式、流程顺序进行分类子结构的合理分类、减少非关键分类结构;
对关键分类子结构进行分析,寻找对策,制订行动计划。

我们在思考、做事、成长时应当随时使用,对于梳理复杂问题、进行决策支撑都有很大好处。

最后回答下最开始的问题:

  • 老板问我当前做的事情怎么样了,我讲了合作中的难点、视觉风格问题、业务情况、代码质量······工作的进展,说了半小时,老板还是 get 不到我做的事情的情况和价值:按照事情核心目标的达成情况,各子部分重点问题和解进行结构化的讲述,两分钟说清楚;
  • 我这一年做了很多事情,都有一定产出,但是跳出细节来看,发现对业务、对团队价值都不大:先建立团队当前业务的核心目标,分解目标达成所需的各个部分,自身努力在某个部分上做深,或者补全当前缺少的部分,或者强力推进将团队目标向上拔高一层更大的目标。
  • 最近流行 codeless,我打算研究下可视化搭建;团队业务涉及到流程编排,我打算研究下 TMF······一年下来折腾了不少成果出来,老板却不提名我晋升:先确定自身技术能力提升的目标,分解到需要提升的各个部分,针对不同部分向老板强求从事相关工作、在当前工作内尝试和深耕,从深入一个部分到横切一个面的能力提升,晋升自然水到渠成。

课程推荐

为了更多开发者能够享受到 Serverless 带来的红利,这一次,我们集结了 10+ 位阿里巴巴 Serverless 领域技术专家,打造出最适合开发者入门的 Serverless 公开课,让你即学即用,轻松拥抱云计算的新范式——Serverless。

点击即可免费观看课程:https://developer.aliyun.com/learning/roadmap/serverless

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

]]>
DataWorks数据处理全流程技术站点地图-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 一图读懂

基于阿里DataWorks产品实现数据中台数据处理的技术要点梳理。
基于阿里DataWorks数据处理技术站点地图.png

主线流程

1.数据集成

数据源的多种类型以及数据源管理。

2.数据交换

数据交换管理管理和调度管理。

3.数据开发

需要实现的核心功能,包含数据处理规则和处理时机。
在进行数据处理过程中,需要使用的Dataworks产品功能包含数据地图,数据质量,数据保护伞,数据分析等功能。

4.数据应用

数据处理结果对外进行数据交换,生成数据API服务以及使用阿里的数据展现工具quickBI和datav进行数据展示。

]]>
应用中心最佳实践之 -- Git数据源发布实战 Sat, 04 Jul 2020 09:33:04 +0800 应用中心最佳实践之 -- Git数据源发布实战

适用场景

  • 希望使用应用中心
  • 有自己git仓库(包括github,bitbucket,自己搭建的gitlab)
  • 部署模板托管在git

前置资源准备

应用中心手动部署托管在Git上的Kubernetes 模板

这里我们使用此模板作为样例,本模板包含一个Ingress+Service+Deployment,对外通过Ingress提供服务。部署模板的全量链接在此https://github.com/xianlubird/argocd-example-apps/blob/master/ingress-demo/deploy.yaml

创建应用

创建应用的所有参数如下所示,这里的部署策略选择手动。
Git仓库地址需要输入https或者git协议的地址,结尾需要以.git结尾,与git clone 命令需要的地址相同。这里的Git版本就是指branch或者tag,路径指的是存放部署模板的文件夹名称,这里要求部署模板必须存放在文件夹内。
目标集群默认的In-Cluster 指的就是部署应用中心控制器的本集群,选择后显示的https://kubernetes.default.svc指的为本集群的ApiServer 地址,因为是本集群内部连接,所以使用的是内部Service 名称。命名空间就是希望这个应用安装到哪个命名空间,这里要求必须指定一个存在的命名空间内。
image.png


image.png


部署应用

创建应用完毕后,我们就可以看到应用的全量拓扑结构,如下图所示:
image.png

这里的黄色的小标识OutOfSync代表的意思是,当前模板描述的资源和Kubernetes集群内的实际情况不一致,也就是说,目前的应用模板并没有部署到集群中,下面我们点击右上角的部署按钮,将应用部署到集群中。


稍等片刻应用就会部署完毕,整个部署过程会实时的展现在用户面前,最终的部署样式如图所示。这里最下方的状态显示为Healthy 和Synced,表示当前模板已经部署到Kubernetes 集群中,且已经符合部署模板的期望状态。
image.png

除了查看整个应用的部署拓扑外,我们还可以查看应用的流量结构,点击右上角的图标就可以观察这个应用的流量拓扑情况。
image.png

更新应用

下面我们来演示一下如何更新应用,首先我们在github上更新一下应用模板,将镜像的tag由blue改为green,如这个commit 为例 https://github.com/xianlubird/argocd-example-apps/commit/dbc1296d20b2a92f0fc4826af2448b452d4a40ca。更新完毕后,我们回到应用中心页面,点击刷新按钮,可以看到如下的图片:
image.png

这里的OutOfSync就是表明,部署模板已经发生了变化,但是Kubernetes集群内的资源和git上托管的模板不一致,如果想查看具体的版本差异,可以点击版本差异按钮,查看具体的不同点。
image.png

这里就有详细的对比,展示当前git上的变更与Kubernetes集群内实际应用资源之间的关系。下面我们就可以部署这个更新。
image.png

可以看到部署模板里面,应用中心识别了只有Deployment 发生了变化,我们点击部署就可以完成应用的更新。更新完毕后,可以看到镜像已经变成了我们指定的green
image.png

回滚应用

首先我们查看一下当前发布版本的历史记录,通过点击历史版本就可以看到。
image.png

这里会根据git commit和git 提交信息来描述每个版本的具体情况,我们可以选取任何一个版本进行回滚,比如这里我们选取第一个版本进行回滚。


image.png



回滚过程中,可以刷新查看具体的情况,回滚完毕后,可以看到镜像已经回到了blue,但是整个应用的状态是OutOfSync,这个是因为和git里面存放的部署模板不一致导致的。


image.png


应用中心自动部署托管在Git上的Kubernetes模板

前面我们介绍了手动的部署应用,每次更新完毕git后,手动的触发应用的更新。下面我们来介绍另一种方式,可以自动化的更新应用。

创建自动更新的应用

创建应用与前面的手动更新的应用区别不大,主要就是更新方式的选择,只需要部署策略选择为自动就可以了,其他参数和前面的手动更新应用是一致的。
这里的修整资源和自我修复我们可以不选择,具体的介绍如下。
image.png

创建完毕和上面的应用是相同的,下面我们来看一下更新的操作。

自动更新应用

首先我们还是需要去git上更新一下应用,这里我们将green更新为blue,如这个commit 一致 https://github.com/xianlubird/argocd-example-apps/commit/bfaa85784835281e7e30e4d0e88ab7cd9ff5c4b2。更新完毕后,稍等一会,大约1min,刷新一下应用就会发现,应用已经被自动更新,新的镜像为blue,同时发布记录也已经生成,一切都是自动的,不需要用户手动介入任何事情,只要把模板提交上去,就可以完成自动化的发布,同时发布记录也会记录在册。


image.png


image.png

]]>
应用中心最佳实践之 -- 多集群多参数发布实战 Sat, 04 Jul 2020 09:33:04 +0800 应用中心最佳实践之 -- 多集群多参数发布实战

如果一个用户账号下有多个集群的情况,希望将一个应用同时发布到多个集群里面,并且不同集群环境有不同的参数,这里就可以使用应用中心的多集群发布功能。

添加多个集群

首先需要在应用中心 -> 配置 -> 集群页面里面,将需要发布的集群添加到应用中心内。这里添加的集群需要kubeconfig,系统会自动读取Kubernetes的配置。我们这里一共添加了三个集群,第一个是本集群,另外的一个是呼和浩特区域的集群,还有一个是上海区域的集群。


image.png

为每个集群创建对应的应用

由于每个应用只能对应一个集群,所以我们需要给每个集群创建对应的集群,这里我们后期会提供一键创建多个集群的功能。


image.png



下面可以试用右上角的部署所有应用功能,一键部署此应用到多个环境中。
image.png





可以看到,如下图所示,两个应用都已经部署完毕。后面如果在git上更新应用,这两个应用都会
image.png

]]>
应用中心最佳实践之—— Helm编排应用的多集群部署实战 Sat, 04 Jul 2020 09:33:04 +0800 如果一个用户账号下有多个集群的情况,希望将一个应用同时发布到多个集群里面,并且不同集群环境有不同的参数,这里就可以使用应用中心的多集群发布功能。

添加多个目标集群

应用中心 -> 配置 -> 集群,将需要发布的集群添加到应用中心内。这里添加的集群需要kubeconfig,系统会自动读取Kubernetes的配置。我们这里一共添加了三个集群,第一个是本集群,另外的一个是北京区域的集群,还有一个是香港区域的集群。
1592817023181-7bf39d68-f556-4464-9ef1-829cd2439212.png

添加示例git repo

示例git repo地址: https://github.com/haoshuwei/appcenter-samples.git
编排模板路径:examples/demo-helm
1.png
1.png

应用中心 -> 配置 -> 仓库 -> 连接Repo

创建应用demo-helm-pre和demo-helm-pro
demo-helm-pre应用部署至目标集群ack-pre-beijing并指定使用values.yaml文件进行参数渲染
1.png

demo-helm-pro应用部署至目标集群ack-pre-hk并指定使用values-pro.yaml文件进行参数渲染
1.png

以下为2个应用创建参数配置对比

通用-应用名称 demo-helm-pre demo-helm-pro
通用-部署策略 手动 手动
源-类型 Git Git
源-版本 https://github.com/haoshuwei/appcenter-samples.git https://github.com/haoshuwei/appcenter-samples.git
源-路径 master master
目标集群-集群 examples/demo-helm examples/demo-helm
目标集群-命名空间 ack-pre-beijing ack-pro-hk
源-仓库地址 demo-helm demo-helm
Helm-VALUES values.yaml values-pro.yaml

一键部署应用到多个集群

应用中心 -> 应用 -> 部署所有应用
1.png

勾选需要部署的demo-helm-pre和demo-helm-pro 2个应用并点击部署
1.png

应用部署成功
1.png

]]>
应用中心最佳实践之 —— Template数据源发布实战 Sat, 04 Jul 2020 09:33:04 +0800 适用场景

• 希望使用应用中心
• 由于安全合规等问题无法将应用部署模板托管在git仓库中

前置资源准备

已经开通应用中心服务,参考链接 https://help.aliyun.com/document_detail/169923.html

创建Template数据源

容器服务控制台 -> 市场 -> 编排模板
1.png

创建模板appcenter-template-demo,包含deployment、service和ingress 3个资源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  labels:
    app: demo
spec:
  minReadySeconds: 5
  revisionHistoryLimit: 5
  progressDeadlineSeconds: 60
  strategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9797"
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        image: registry.cn-hangzhou.aliyuncs.com/acs/rollouts-demo:blue
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        readinessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 5
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 2000m
            memory: 512Mi
          requests:
            cpu: 100m
            memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
  name: demo-svc
spec:
  selector:
    app: demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: demo
  labels:
    app: demo
spec:
  rules:
    - host: app.demo.example.com
      http:
        paths:
          - backend:
              serviceName: demo-svc
              servicePort: 80

创建完毕
1.png

创建应用

应用中心 -> 应用 -> 创建应用
1.png

通用

应用名称: appcenter-template-demo
部署策略: 手动
1.png

类型:自定义模板
模板:appcenter-template-demo
1.png

目标集群

集群:in-cluster(https://kubernetes.default.svc)
命名空间:demo-template
1.png

点击 创建
1.png

部署应用

点击应用可以查看应用详情, 下图是示例应用的Kubernetes资源全量拓扑结构
1.png

点击右上角的部署, 默认勾选的要部署资源有deployment、service和ingress资源
1.png
这里的黄色的小标识OutOfSync代表的意思是,当前模板描述的资源和Kubernetes集群内的实际情况不一致,也就是说,目前的应用模板并没有部署到集群中,下面我们点击右上角的部署按钮,将应用部署到集群中。
点击部署完成应用部署

稍等片刻应用就会部署完毕,整个部署过程会实时的展现在用户面前,最终的部署样式如图所示。这里最下方的状态显示为Healthy 和Synced,表示当前模板已经部署到Kubernetes 集群中,且已经符合部署模板的期望状态。
1.png

除了查看整个应用的部署拓扑外,我们还可以查看应用的流量结构,点击右上角的图标就可以观察这个应用的流量拓扑情况。
1.png

更新应用

下面我们来演示一下如何更新应用, 首先需要在编排模板中更新appcenter-template-demo, 本示例中我们把Deployment资源中的image tag从blue改为red,此时您会发现appcenter-template-demo模板有了新的历史版本记录
1.png
此时回到应用中心页面,手动点击 刷新 -> 强制刷新(若部署策略为自动,则应用中心每3分钟自动检查数据源更新)
可以看到应用状态为OutOfSync, 意为当前环境中应用状态与数据源中所声明的状态不一致
1.png

点击 版本差异 可以查看本次变更的详细内容
1.png

再次点击部署,更新集群环境中的应用到最新版本
1.png

可以看到应用已经更新为image tag为red的新版本
1.png

应用回滚

历史版本/回滚 -> 选择需要回滚的历史版本 -> 回滚
1.png

回滚过程中,可以刷新查看具体的情况,回滚完毕后,可以看到镜像已经回到了blue,但是整个应用的状态是OutOfSync,这个是因为和git里面存放的部署模板不一致导致的。
1.png

]]>
基于ASM的GRPC服务部署实践 Sat, 04 Jul 2020 09:33:04 +0800 继MicroServices之后,ServiceMesh是又一个推动软件工业的革命性技术。其服务治理的方法论,不仅改变了技术实现的方式和社会分工。

运行于数据平面的用户服务与治理服务的各种规则彻底解耦。运行于控制平面的规则定义组件,将流量控制的具体规则推送给运行于数据平面的proxy,proxy通过对用户服务的ingress和egress的实际控制,最终实现服务治理。

原本需要服务开发者编程实现的服务发现、容错、灰度、流量复制等能力,被ServiceMesh非侵入的方式实现。此外,ServiceMesh还提供了访问控制、认证授权等功能,进一步减轻了用户服务的开发成本。

阿里云提供的服务网格(ASM)是基于容器服务(ACK)之上的托管版ServiceMesh,在提供完整的ServiceMesh能力的同时(ASM还在底层横向拉通了阿里云云原生的各种能力,不在本篇讲述范围),免去了用户搭建和运维ServiceMesh平台istio的繁琐工作。本篇将分享如何将我们自己的GRPC服务,托管到阿里云的服务网格中。

1. grpc服务

grpc协议相比http而言,既具备http跨操作系统和编程语言的好处,又提供了基于流的通信优势。而且,grpc逐渐成为工业界的标准,一旦我们的grpc服务可以mesh化,那么更多的非标准协议就可以通过转为grpc协议的方式,低成本地接入服务网格,实现跨技术栈的服务通信。

grpc服务的示例部分使用最普遍的编程语言Java及最高效的编程框架SpringBoot。示例的拓扑示意如下:

1.grpc.png

1.1 springboot

common——proto2java

示例工程包含三个模块,分别是commonproviderconsumer。其中,common负责将定义grpc服务的protobuf转换为java的rpc模板代码;后两者对其依赖,分别实现grpc的服务端和客户端。

示例工程的protobuf定义如下,实现了两个方法SayHelloSayByeSayHello的入参是一个字符串,返回一个字符串;SayBye只有一个字符串类型的出参。

syntax = "proto3";
import "google/protobuf/empty.proto";
package org.feuyeux.grpc;

option java_multiple_files = true;
option java_package = "org.feuyeux.grpc.proto";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc SayBye (google.protobuf.Empty) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string reply = 1;
}

common构建过程使用protobuf-maven-plugin自动生成rpc模板代码。

provider——grpc-spring-boot-starter

provider依赖grpc-spring-boot-starter包以最小化编码,实现grpc服务端逻辑。示例实现了两套grpc方法,以在后文演示不同流量的返回结果不同。

第一套方法示意如下:

@GRpcService
public class GreeterImpl extends GreeterImplBase {

    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
        String message = "Hello " + request.getName() + "!";
        HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();
        responseObserver.onNext(helloReply);
        responseObserver.onCompleted();
    }

    @Override
    public void sayBye(com.google.protobuf.Empty request, StreamObserver<HelloReply> responseObserver) {
        String message = "Bye bye!";
        HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();
        responseObserver.onNext(helloReply);
        responseObserver.onCompleted();
    }
}

第二套方法示意如下:

@GRpcService
public class GreeterImpl2 extends GreeterImplBase {

    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
        String message = "Bonjour " + request.getName() + "!";
        HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();
        responseObserver.onNext(helloReply);
        responseObserver.onCompleted();
    }

    @Override
    public void sayBye(com.google.protobuf.Empty request, StreamObserver<HelloReply> responseObserver) {
        String message = "au revoir!";
        HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();
        responseObserver.onNext(helloReply);
        responseObserver.onCompleted();
    }
}

consumer——RESTful

consumer的作用有两个,一个是对外暴露RESTful服务,一个是作为grpc的客户端调用grpc服务端provider。示意代码如下:

@RestController
public class GreeterController {
    private static String GRPC_PROVIDER_HOST;

    static {
        GRPC_PROVIDER_HOST = System.getenv("GRPC_PROVIDER_HOST");
        if (GRPC_PROVIDER_HOST == null || GRPC_PROVIDER_HOST.isEmpty()) {
            GRPC_PROVIDER_HOST = "provider";
        }
        LOGGER.info("GRPC_PROVIDER_HOST={}", GRPC_PROVIDER_HOST);
    }

    @GetMapping(path = "/hello/{msg}")
    public String sayHello(@PathVariable String msg) {
        final ManagedChannel channel = ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)
                .usePlaintext()
                .build();
        final GreeterGrpc.GreeterFutureStub stub = GreeterGrpc.newFutureStub(channel);
        ListenableFuture<HelloReply> future = stub.sayHello(HelloRequest.newBuilder().setName(msg).build());
        try {
            return future.get().getReply();
        } catch (InterruptedException | ExecutionException e) {
            LOGGER.error("", e);
            return "ERROR";
        }
    }

    @GetMapping("bye")
    public String sayBye() {
        final ManagedChannel channel = ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)
                .usePlaintext()
                .build();
        final GreeterGrpc.GreeterFutureStub stub = GreeterGrpc.newFutureStub(channel);
        ListenableFuture<HelloReply> future = stub.sayBye(Empty.newBuilder().build());
        try {
            return future.get().getReply();
        } catch (InterruptedException | ExecutionException e) {
            LOGGER.error("", e);
            return "ERROR";
        }
    }
}

这里需要注意的是GRPC_PROVIDER_HOST变量,我们在ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)中使用到这个变量,以获得provider服务的地址。相信你已经发现,服务开发过程中,我们没有进行任何服务发现能力的开发,而是从系统环境变量里获取这个值。而且,在该值为空时,我们使用了一个hardcode值provider。没错,这个值将是后文配置在isito中的provider服务的约定值。

1.2 curl&grpcurl

本节将讲述示例工程的本地启动和验证。首先我们通过如下脚本构建和启动provider和consumer服务:

# terminal 1
mvn clean install -DskipTests -U
java -jar provider/target/provider-1.0.0.jar

# terminal 2
export GRPC_PROVIDER_HOST=localhost
java -jar consumer/target/consumer-1.0.0.jar

我们使用curl以http的方式请求consumer:

# terminal 3
$ curl localhost:9001/hello/feuyeux

Hello feuyeux!

$ curl localhost:9001/bye

Bye bye!

最后我们使用grpcurl直接测试provider:

$ grpcurl -plaintext -d @ localhost:6565 org.feuyeux.grpc.Greeter/SayHello <<EOM   
{
  "name":"feuyeux"
}
EOM

{
  "reply": "Hello feuyeux!"
}

$ grpcurl -plaintext localhost:6565 org.feuyeux.grpc.Greeter/SayBye                                                                                                 
{
  "reply": "Bye bye!"
}

1.2 docker

服务验证通过后,我们制作三个docker镜像,以作为deployment部署到kubernetes上。这里以provider的dockerfile为例:

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=provider-1.0.0.jar
COPY ${JAR_FILE} provider.jar
COPY grpcurl /usr/bin/grpcurl
ENTRYPOINT ["java","-jar","/provider.jar"]

构建镜像和推送到远端仓库的脚本示意如下:

docker build -f grpc.provider.dockerfile -t feuyeux/grpc_provider_v1:1.0.0 .
docker build -f grpc.provider.dockerfile -t feuyeux/grpc_provider_v2:1.0.0 .
docker build -f grpc.consumer.dockerfile -t feuyeux/grpc_consumer:1.0.0 .

docker push feuyeux/grpc_provider_v1:1.0.0
docker push feuyeux/grpc_provider_v2:1.0.0
docker push feuyeux/grpc_consumer:1.0.0

本地启动服务验证,示意如下:

# terminal 1
docker run --name provider2 -p 6565:6565 feuyeux/grpc_provider_v2:1.0.0

# terminal 2
docker exec -it provider2 sh
grpcurl -v -plaintext localhost:6565 org.feuyeux.grpc.Greeter/SayBye
exit
# terminal 3
export LOCAL=$(ipconfig getifaddr en0)
docker run --name consumer -e GRPC_PROVIDER_HOST=${LOCAL} -p 9001:9001 feuyeux/grpc_consumer
# terminal 4
curl -i localhost:9001/bye

1.3 istio

验证完镜像后,我们进入重点。本节将完整讲述如下拓扑的服务治理配置:
2.mesh-arch.png

Deployment

consumer的deployment声明示意如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: consumer
    version: v1
...
      containers:
        - name: consumer
          image: feuyeux/grpc_consumer:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9001

provider1的deployment声明示意如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: provider-v1
  labels:
    app: provider
    version: v1
...
      containers:
        - name: provider
          image: feuyeux/grpc_provider_v1:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6565

provider2的deployment声明示意如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: provider-v2
  labels:
    app: provider
    version: v2
...
      containers:
        - name: provider
          image: feuyeux/grpc_provider_v2:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6565

Deployment中使用到了前文构建的三个镜像。在容器服务中不存在时(IfNotPresent)即会拉取。

这里需要注意的是,provider1和provider2定义的labels.app都是provider,这个标签是provider的唯一标识,只有相同才能被Service的Selector找到并认为是一个服务的两个版本。

服务发现

provider的Service声明示意如下:

apiVersion: v1
kind: Service
metadata:
  name: provider
  labels:
    app: provider
    service: provider
spec:
  ports:
    - port: 6565
      name: grpc
      protocol: TCP
  selector:
    app: provider

前文已经讲到,服务开发者并不实现服务注册和服务发现的功能,也就是说示例工程不需要诸如zookeeper/etcd/Consul等组件的客户端调用实现。Service的域名将作为服务注册的名称,服务发现时通过这个名称就能找到相应的实例。因此,前文我们直接使用了hardcode的provider

grpc路由

服务治理的经典场景是对http协议的服务,通过匹配方法路径前缀来路由不同的RESTful方法。grpc的路由方式与此类似,它是通过http2实现的。grpc的service接口及方法名与 http2的对应形式是`Path : /Service-Name/{method name}。因此,我们可以为Gateway的VirtualService定义如下的匹配规则:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grpc-gw-vs
spec:
  hosts:
    - "*"
  gateways:
    - grpc-gateway
  http:
...
    - match:
        - uri:
            prefix: /org.feuyeux.grpc.Greeter/SayBye
        - uri:
            prefix: /org.feuyeux.grpc.Greeter/SayHello

AB流量

掌握了grpc通过路径的方式路由,定义AB流量便水到渠成:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: provider
spec:
  gateways:
    - grpc-gateway
  hosts:
    - provider
  http:
    - match:
        - uri:
            prefix: /org.feuyeux.grpc.Greeter/SayHello
      name: hello-routes
      route:
        - destination:
            host: provider
            subset: v1
          weight: 50
        - destination:
            host: provider
            subset: v2
          weight: 50
    - match:
        - uri:
            prefix: /org.feuyeux.grpc.Greeter/SayBye
      name: bye-route
...

到此,示例工程的核心能力简单扼要地讲述完毕。详细代码请clone本示例工程。接下来,我将介绍如何将我们的grpc服务实例部署到阿里云服务网格。

2. 服务网格实践

2.1 托管集群

首先使用阿里云账号登录,进入容器服务控制台(https://cs.console.aliyun.com),创建Kubernetes集群-标准托管集群。详情见帮助文档:快速创建Kubernetes托管版集群

2.2 服务网格

进入服务网格控制台(https://servicemesh.console.aliyun.com>),创建服务网格实例。详情见帮助文档:[服务网格 ASM > 快速入门 使用流程](https://help.aliyun.com/document_detail/149552.html)

服务网格实例创建成功后,确保数据平面已经添加容器服务集群。然后开始数据平面的配置。

2.3 数据平面

kubeconfig

在执行数据平面的部署前,我们先确认下即将用到的两个kubeconfig。

  • 进入容器实例界面,获取kubconfig,并保存到本地~/shop/bj_config
  • 进入服务网格实例界面,点击连接配置,获取kubconfig,并保存到本地~/shop/bj_asm_config

请注意,在数据平面部署过程中,我们使用~/shop/bj_config这个kubeconfig;在控制平面的部署中,我们使用~/shop/bj_asm_config这个kubeconfig。

设置自动注入

kubectl 
--kubeconfig ~/shop/bj_config 
label namespace default istio-injection=enabled

可以通过访问容器服务的命名空间界面进行验证。

部署deployment和service

export DEMO_HOME=

kubectl 
--kubeconfig ~/shop/bj_config 
apply -f $DEMO_HOME/istio/kube/consumer.yaml

kubectl 
--kubeconfig ~/shop/bj_config 
apply -f $DEMO_HOME/istio/kube/provider1.yaml

kubectl 
--kubeconfig ~/shop/bj_config 
apply -f $DEMO_HOME/istio/kube/provider2.yaml

可以通过访问容器服务的如下界面进行验证:

通过如下命令,确认pod的状态是否符合预期:

$ kubectl 
--kubeconfig ~/shop/bj_config 
get pod

NAME                           READY   STATUS    RESTARTS   AGE
consumer-v1-5c565d57f-vb8qb    2/2     Running   0          7h24m
provider-v1-54dbbb65d8-lzfnj   2/2     Running   0          7h24m
provider-v2-9fdf7bd6b-58d4v    2/2     Running   0          7h24m

入口网关服务

最后,我们通过ASM管控台配置入口网关服务,以对外公开http协议的9001端口和grpc协议的6565端口。

image.png

创建完成后,我们就有了公网的IP。余文测试验证环节将使用到这里配置的入口网关IP 39.102.37.176

image.png

2.4 控制平面

部署Gateway

kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/gateway.yaml

部署完毕后,在ASM控制台的控制平面-服务网关界面下,可以看到这个Gateway实例。也可以直接使用该界面创建和删除服务网格的Gateway实例。
image.png

部署VirtualService

kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/gateway-virtual-service.yaml

kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/provider-virtual-service.yaml


kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/consumer-virtual-service.yaml

部署完毕后,在ASM控制台的控制平面-虚拟服务界面下,可以看到VirtualService实例列表。也可以直接使用界面创建和删除服务网格的VirtualService实例。
image.png

部署DestinationRule

kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/provider-destination-rule.yaml

kubectl 
--kubeconfig ~/shop/bj_asm_config 
apply -f $DEMO_HOME/istio/networking/consumer-destination-rule.yaml

部署完毕后,在ASM控制台的控制平面-目标规则界面下,可以看到DestinationRule实例列表。也可以直接使用界面创建和删除服务网格的DestinationRule实例。

image.png

2.5 流量验证

完成grpc服务在ASM的部署后,我们首先验证如下链路的流量:
image.png

HOST=39.102.37.176
for ((i=1;i<=10;i++)) ;  
do   
curl ${HOST}:9001/hello/feuyeux
echo
done

最后再来验证我如下链路的流量:
image.png

# terminal 1
export GRPC_PROVIDER_HOST=39.102.37.176
java -jar consumer/target/consumer-1.0.0.jar

# terminal 2
for ((i=1;i<=10;i++)) ;  
do   
curl localhost:9001/bye
echo
done

到此,GPRC服务成功部署到ASM。篇幅所限,更多服务网格的能力有待开发者结合自己的业务场景去探索。欢迎技术交流。

]]>
进击的Kubernetes调度系统(一):Scheduling Framework Sat, 04 Jul 2020 09:33:04 +0800 作者:王庆璨 张凯

前言

Kubernetes已经成为目前事实标准上的容器集群管理平台。它为容器化应用提供了自动化部署、运维、资源调度等全生命周期管理功能。经过3年多的快速发展,Kubernetes在稳定性、扩展性和规模化方面都有了长足进步。 尤其是Kubernetes控制平面的核心组件日臻成熟。而作为决定容器能否在集群中运行的调度器Kube-scheduler,更是由于长久以来表现稳定,且已能满足大部分Pod调度场景,逐渐不被开发人员特别关注。

伴随着Kubernetes在公有云以及企业内部IT系统中广泛应用,越来越多的开发人员尝试使用Kubernetes运行和管理Web应用和微服务以外的工作负载。典型场景包括机器学习和深度学习训练任务,高性能计算作业,基因计算工作流,甚至是传统的大数据处理任务。此外,Kubernetes集群所管理的资源类型也愈加丰富,不仅有GPU,TPU和FPGA,RDMA高性能网络,还有针对领域任务的各种定制加速器,比如各种AI芯片,NPU,视频编解码器等。开发人员希望在Kubernetes集群中能像使用CPU和内存那样简单地声明式使用各种异构设备。

总的来说,围绕Kubernetes构建一个容器服务平台,统一管理各种新算力资源,弹性运行多种类型应用,最终把服务按需交付到各种运行环境(包括公共云、数据中心、边缘节点,甚至是终端设备),已然成为云原生技术的发展趋势。

阿里云容器服务团队结合多年Kubernetes产品化与客户支持经验,对Kube-scheduler进行了大量扩展和改进,逐步使其在多种场景下依然能稳定、高效地调度复杂工作负载类型。

《进击的Kubernetes调度系统》系列文章将把我们的经验、技术思考和实现细节全面地展现给Kubernetes用户和开发者,期望帮助大家更好地了解Kubernetes调度系统的强大能力和未来发展方向。

早期方案

首先,让我们来了解一下Kubernetes社区都有过哪些提升调度器扩展能力的方案。

要统一管理和调度异构资源与更多复杂工作负载类型,首先面对挑战的就是Kube-scheduler。在Kubernetes社区里关于提升调度器扩展能力的讨论一直不断。sig-scheduling给出的判断是,越多功能加入,使得调度器代码量庞大,逻辑复杂,导致维护的难度越来越大,很多bug难以发现、处理。而对于使用了自定义调度的用户来说,跟上每一次调度器功能更新,都充满挑战。

在阿里云,我们的用户遇到了同样的挑战。Kubernetes原生调度器循环处理单个Pod容器的固定逻辑,无法及时、简单地支持用户在不同场景的需求。所以针对特定的场景,我们会基于原生Kube-scheduler扩展自己的调度策略。

最初对于Kube-scheduler进行扩展的方式主要有两种,一种是调度器扩展(Scheduler Extender), 另外一种是多调度器(Multiple schedulers)。接下来我们对这两种方式分别进行介绍和对比。

Scheduler Extender

社区最初提供的方案是通过Extender的形式来扩展scheduler。Extender是外部服务,支持Filter、Preempt、Prioritize和Bind的扩展,scheduler运行到相应阶段时,通过调用Extender注册的webhook来运行扩展的逻辑,影响调度流程中各阶段的决策结果。


以Filter阶段举例,执行过程会经过2个阶段:

  1. scheduler会先执行内置的Filter策略,如果执行失败的话,会直接标识Pod调度失败。
  2. 如何内置的Filter策略执行成功的话,scheduler通过Http调用Extender注册的webhook, 将调度所需要的Pod和Node的信息发送到到Extender,根据返回filter结果,作为最终结果。

scheduler-extender.svg

我们可以发现Extender存在以下问题:

  1. 调用Extender的接口是HTTP请求,受到网络环境的影响,性能远低于本地的函数调用。同时每次调用都需要将Pod和Node的信息进行marshaling和unmarshalling的操作,会进一步降低性能。
  2. 用户可以扩展的点比较有限,位置比较固定,无法支持灵活的扩展,例如只能在执行完默认的Filter策略后才能调用。

基于以上介绍,Extender的方式在集群规模较小,调度效率要求不高的情况下,是一个灵活可用的扩展方案,但是在正常生产环境的大型集群中,Extender无法支持高吞吐量,性能较差。

Multiple schedulers

Scheduler在Kubernetes集群中其实类似于一个特殊的Controller,通过监听Pod和Node的信息,给Pod挑选最佳的节点,更新Pod的spec.NodeName的信息来将调度结果同步到节点。所以对于部分有特殊的调度需求的用户,有些开发者通过自研Custom Scheduler来完成以上的流程,然后通过和default scheduler同时部署的方式,来支持自己特殊的调度需求。


1588144283202-b3734bbe-b06d-4c65-81b2-d17bf44b521e.svg
]]> 进击的Kubernetes调度系统(二):支持批任务的Coscheduling/Gang scheduling Sat, 04 Jul 2020 09:33:04 +0800 作者:王庆璨 张凯

进击的Kubernetes调度系统(一):Scheduling Framework
进击的Kubernetes调度系统(二):支持批任务的Coscheduling/Gang scheduling

前言

首先我们来了解一下什么是Coscheduling和Gang scheduling。Wikipedia对 Coscheduling的定义是“在并发系统中将多个相关联的进程调度到不同处理器上同时运行的策略”。在Coscheduling的场景中,最主要的原则是保证所有相关联的进程能够同时启动。防止部分进程的异常,导致整个关联进程组的阻塞。这种导致阻塞的部分异常进程,称之为“碎片(fragement)”。
在Coscheduling的具体实现过程中,根据是否允许“碎片”存在,可以细分为Explicit Coscheduling,Local Coscheduling和Implicit Coscheduling。 其中Explicit Coscheduling就是大家常听到的Gang Scheduling。Gang Scheduling要求完全不允许有“碎片”存在, 也就是“All or Nothing”。

我们将上述定义的概念对应到Kubernetes中,就可以理解Kubernetes调度系统支持批任务Coscheduling的含义了。 一个批任务(关联进程组)包括了N个Pod(进程),Kubernetes调度器负责将这N个Pod调度到M个节点(处理器)上同时运行。如果这个批任务需要部分Pod同时启动即可运行,我们称需启动Pod的最小数量为min-available。特别地,当min-available=N时,批任务要求满足Gang Scheduling。

为什么Kubernetes调度系统需要Coscheduling?

Kubernetes目前已经广泛的应用于在线服务编排,为了提升集群的的利用率和运行效率,我们希望将Kubernetes作为一个统一的管理平台来管理在线服务和离线作业。默认的调度器是以Pod为调度单元进行依次调度,不会考虑Pod之间的相互关系。但是很多数据计算类的离线作业具有组合调度的特点,即要求所有的子任务都能够成功创建后,整个作业才能正常运行。如果只有部分子任务启动的话,启动的子任务将持续等待剩余的子任务被调度。这正是Gang Scheduling的场景。

如下图所示,JobA需要4个Pod同时启动,才能正常运行。Kube-scheduler依次调度3个Pod并创建成功。到第4个Pod时,集群资源不足,则JobA的3个Pod处于空等的状态。但是它们已经占用了部分资源,如果第4个Pod不能及时启动的话,整个JobA无法成功运行,更糟糕的是导致集群资源浪费。


1585658750819-8fe7f3da-ffc1-49a4-a5a0-9d8f7b624b59.png
]]> 在Kubernetes中用Alluxio加速Spark数据访问(一) Sat, 04 Jul 2020 09:33:04 +0800 1.背景信息

1.1 alluxio

Alluxio是一个开源的基于内存的分布式存储系统,适合作为云上大数据和AI / ML的数据编排方案。Alluxio可以同时管理多个底层文件系统,将不同的文件系统统一在同一个名称空间下,让上层客户端可以自由访问统一名称空间内的不同路径,不同存储系统的数据。

alluxio的short-circuit功能可以使alluxio客户端直接访问alluxio worker所在主机的工作存储,而不需要通过网络栈与alluxio worker完成通信,可以提高性能。

1.2 spark operator

Spark-operator用于管理k8s集群中spark job。通过spark-operator可以在k8s集群中创建、查看和删除spark job。

2.前提条件

本文档的操作依赖如下的一些条件:

  • kubernetes集群:版本大于1.8,本次实验的集群通过阿里云容器服务创建,集群名称为"ack-create-by-openapi-1"。

image.png

  • 安装有linux或者mac操作系统的计算机作为我们的实验环境(本次实验中,假设该计算机名称为alluxio-test)。该计算机需要准备如下环境:

    • docker >= 17.06
    • kubectl >= 1.8,能够连接kubernets集群ack-create-by-openapi-1

3.实验步骤

实验步骤主要包括如下几步:

  • 部署alluxio
  • 部署spark-operator
  • 制作spark docker镜像
  • 上传文件到alluxio
  • 提交spark job

下面将对每个步骤进行说明:

3.1 部署alluxio

进入容器服务应用目录,在右上角的搜索框中搜索"alluxio",然后进入alluxio主界面,如图:
image.png

选择“参数”,修改配置中properties部分的"alluxio.user.short.circuit.enabled"值为"false",然后选择将alluxio安装到目标集群上(本次实验的集群为"ack-create-by-openapi-1"),最后点击创建,如图
image.png

点击创建后,使用kubectl给待安装的alluxio组件的节点打上标签"alluxio=true",首先查看该集群有哪些节点:

$ kubectl get nodes -o wide
NAME                      STATUS   ROLES    AGE   VERSION            INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                               KERNEL-VERSION            CONTAINER-RUNTIME
cn-beijing.192.168.8.12   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.12   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.13   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.13   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.14   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.14   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.15   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.15   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.16   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.16   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.17   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.17   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5

可以看到有三个worker节点,分别为:

  • cn-beijing.192.168.8.15
  • cn-beijing.192.168.8.16
  • cn-beijing.192.168.8.17

我们给是三个节点都打上标签"alluxio=true":

$ kubectl label nodes cn-beijing.192.168.8.15 
  cn-beijing.192.168.8.16 
  cn-beijing.192.168.8.17 
  alluxio=true

使用kubectl查看各个pod是否都处于running状态:

$ kubectl get po -n alluxio
NAME                   READY   STATUS    RESTARTS   AGE
alluxio-master-0       2/2     Running   0          4h1m
alluxio-worker-5zg26   2/2     Running   0          4h1m
alluxio-worker-ckmr9   2/2     Running   0          4h1m
alluxio-worker-dvgvd   2/2     Running   0          4h1m

验证alluxio是否处于ready:

$ kubectl exec -ti alluxio-master-0 -n alluxio bash

//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fsadmin report capacity

Capacity information for all workers:
    Total Capacity: 3072.00MB
        Tier: MEM  Size: 3072.00MB
    Used Capacity: 0B
        Tier: MEM  Size: 0B
    Used Percentage: 0%
    Free Percentage: 100%

Worker Name      Last Heartbeat   Storage       MEM
192.168.8.15    0                capacity      1024.00MB
                                  used          0B (0%)
192.168.8.16    0                capacity      1024.00MB
                                  used          0B (0%)
192.168.8.17    0                capacity      1024.00MB
                                  used          0B (0%)

3.2 部署spark-operator

进入容器服务应用目录,在右上角的搜索框中搜索"ack-spark-operator",然后进入ack-spark-operator主界面,如图:
image.png
选择将ack-spark-operator安装到目标集群上(本次实验的集群为"ack-create-by-openapi-1"),然后点击创建,如图:
image.png

本次实验将会使用sparkctl向k8s集群提交一个spark job,需要将sparkctl安装到我们在"2.前提条件"中所提到的实验环境"alluxio-test"中:

$ wget http://spark-on-k8s.oss-cn-beijing.aliyuncs.com/sparkctl/sparkctl-linux-amd64 -O /usr/local/bin/sparkctl
$ chmod +x /usr/local/bin/sparkctl

3.3 制作spark docker镜像

spark下载页面下载所需的spark版本,本次实验选择的saprk版本为2.4.6。运行如下命令下载spark:

$ cd /root
$ wget https://mirror.bit.edu.cn/apache/spark/spark-2.4.6/spark-2.4.6-bin-hadoop2.7.tgz
#

下载完成后,执行解压操作:

$ tar -xf spark-2.4.6-bin-hadoop2.7.tgz
$ export SPARK_HOME=/root/spark-2.4.6-bin-hadoop2.7

spark docker镜像是我们提交spark任务时使用到的镜像,这个镜像中需要包含alluxio client jar包。使用如下的命令获取alluxio client jar包:

$ id=$(docker create alluxio/alluxio-enterprise:2.2.1-1.4)
$ docker cp $id:/opt/alluxio/client/alluxio-enterprise-2.2.1-1.4-client.jar 
    $SPARK_HOME/jars/alluxio-enterprise-2.2.1-1.4-client.jar
$ docker rm -v $id 1>/dev/null

alluxio client jar包准备好以后,开始构建镜像:

$ docker build -t spark-alluxio:2.4.6 -f kubernetes/dockerfiles/spark/Dockerfile $SPARK_HOME

请记住镜像名称“spark-alluxio:2.4.6”,在向k8s提交spark job中会用到这个信息。

镜像构建完成以后,对镜像的处理有两种方式:

  • 如果有私有镜像仓库,将该镜像推送到私有镜像仓库中,同时保证k8s集群节点能够pull该镜像
  • 如果没有私有镜像仓库,那么需要使用docker save命令将该镜像导出,然后scp到k8s集群的各个节点,在每个节点上使用docker load命令将镜像导入,这样就能保证每个节点上都存在该镜像。

3.4 上传文件到alluxio

文章开头提到过:本次实验是提交一个spark job到k8s中,该spark job的目标是对某一个文件统计每一个单词出现的次数。现在需要把这个文件传到alluxio存储上,这里为了方便,直接把alluxio master中/opt/alluxio-2.3.0-SNAPSHOT/LICENSE(文件路径可能因alluxio版本有点差异)这个文件传到alluxio上。

使用"kubectl exec"进入alluxio master pod,并拷贝当前目录下的LICENSE文件到alluxio的根目录中:

$ kubectl exec -ti alluxio-master-0  -n alluxio bash
//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fs copyFromLocal LICENSE /

接着查看一下LICENSE这个文件分成的block被alluxio放到哪些worker上了。

$ kubectl exec -ti alluxio-master-0 -n alluxio bash
//下面步骤alluxio-master-0 pod中执行

bash-4.4# alluxio fs stat /LICENSE
/LICENSE is a file path.
FileInfo{fileId=33554431, fileIdentifier=null, name=LICENSE, path=/LICENSE, ufsPath=/opt/alluxio-2.3.0-SNAPSHOT/underFSStorage/LICENSE, length=27040, blockSizeBytes=67108864, creationTimeMs=1592381889733, completed=true, folder=false, pinned=false, pinnedlocation=[], cacheable=true, persisted=false, blockIds=[16777216], inMemoryPercentage=100, lastModificationTimesMs=1592381890390, ttl=-1, lastAccessTimesMs=1592381890390, ttlAction=DELETE, owner=root, group=root, mode=420, persistenceState=TO_BE_PERSISTED, mountPoint=false, replicationMax=-1, replicationMin=0, fileBlockInfos=[FileBlockInfo{blockInfo=BlockInfo{id=16777216, length=27040, locations=[BlockLocation{workerId=8217561227881498090, address=WorkerNetAddress{host=192.168.8.17, containerHost=, rpcPort=29999, dataPort=29999, webPort=30000, domainSocketPath=, tieredIdentity=TieredIdentity(node=192.168.8.17, rack=null)}, tierAlias=MEM, mediumType=MEM}]}, offset=0, ufsLocations=[]}], mountId=1, inAlluxioPercentage=100, ufsFingerprint=, acl=user::rw-,group::r--,other::r--, defaultAcl=}
Containing the following blocks:
BlockInfo{id=16777216, length=27040, locations=[BlockLocation{workerId=8217561227881498090, address=WorkerNetAddress{host=192.168.8.17, containerHost=, rpcPort=29999, dataPort=29999, webPort=30000, domainSocketPath=, tieredIdentity=TieredIdentity(node=192.168.8.17, rack=null)}, tierAlias=MEM, mediumType=MEM}]}

可以看到LICENSE这个文件只有一个block(id为16777216),被放在了ip为192.168.8.17的k8s节点上。我们使用kubectl查看该节点名称为cn-beijing.192.168.8.17

$ kubectl get nodes -o wide
NAME                      STATUS   ROLES    AGE   VERSION            INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                               KERNEL-VERSION            CONTAINER-RUNTIME
cn-beijing.192.168.8.12   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.12   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.13   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.13   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.14   Ready    master   21d   v1.16.6-aliyun.1   192.168.8.14   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.15   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.15   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.16   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.16   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5
cn-beijing.192.168.8.17   Ready    <none>   21d   v1.16.6-aliyun.1   192.168.8.17   <none>        Aliyun Linux 2.1903 (Hunting Beagle)   4.19.57-15.1.al7.x86_64   docker://19.3.5

3.5 提交spark job

下面的步骤将提交一个spark job到k8s集群中,该job主要是计算alluxio中/LICENSE文件的每个单词出现的次数。

在步骤3.4中我们获取到LICENSE这个文件所包含的block都在节点cn-beijing.192.168.8.17上,此次实验中,我们通过指定node selector让spark driver和spark executor都运行在节点cn-beijing.192.168.8.17,验证在关闭alluxio的short-circuit功能的情况下,spark executor和alluxio worker之间的通信是否通过网络栈完成。

  • 说明:如果在开启alluxio的short-circuit功能的情况下,并且spark executor与其所要访问的文件(本次实验为/LICENSE这个文件)的block在同一个k8s节点上,那么spark executor中的alluxio client与该k8s节点上的alluxio worker之间的通信通过domain socket方式完成。

首先生成提交spark job的yaml文件:

$ export SPARK_ALLUXIO_IMAGE=<步骤3.3中制作的image,即spark-alluxio:2.4.6>
$ export ALLUXIO_MASTER="alluxio-master-0"
$ export TARGET_NODE=<步骤3.4获取到的LICENSE文件的block存储的节点,即cn-beijing.192.168.8.17>
$ cat > /tmp/spark-example.yaml <<- EOF
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: spark-count-words
  namespace: default
spec:
  type: Scala
  mode: cluster
  image: "$SPARK_ALLUXIO_IMAGE"
  imagePullPolicy: Always
  mainClass: org.apache.spark.examples.JavaWordCount
  mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.6.jar"
  arguments:
    - alluxio://${ALLUXIO_MASTER}.alluxio:19998/LICENSE
  sparkVersion: "2.4.5"
  restartPolicy:
    type: Never
  volumes:
    - name: "test-volume"
      hostPath:
        path: "/tmp"
        type: Directory
  driver:
    cores: 1
    coreLimit: "1200m"
    memory: "512m"
    labels:
      version: 2.4.5
    serviceAccount: spark
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
    nodeSelector:
      kubernetes.io/hostname: "$TARGET_NODE"
  executor:
    cores: 1
    instances: 1
    memory: "512m"
    labels:
      version: 2.4.5
    nodeSelector:
      kubernetes.io/hostname: "$TARGET_NODE"
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
EOF

然后,使用sparkctl提交spark job:

$ sparkctl create /tmp/spark-example.yaml

4.实验结果

当提交任务后,使用kubectl查看spark driver的日志:

$ kubectl get po -l spark-role=driver
NAME                                 READY   STATUS      RESTARTS   AGE
spark-alluxio-1592296972094-driver   0/1     Completed   0          4h33m

$ kubectl logs spark-alluxio-1592296972094-driver --tail 20

USE,: 3
Patents: 2
d): 1
comment: 1
executed: 1
replaced: 1
mechanical: 1
20/06/16 13:14:28 INFO SparkUI: Stopped Spark web UI at http://spark-alluxio-1592313250782-driver-svc.default.svc:4040
20/06/16 13:14:28 INFO KubernetesClusterSchedulerBackend: Shutting down all executors
20/06/16 13:14:28 INFO KubernetesClusterSchedulerBackend$KubernetesDriverEndpoint: Asking each executor to shut down
20/06/16 13:14:28 WARN ExecutorPodsWatchSnapshotSource: Kubernetes client has been closed (this is expected if the application is shutting down.)
20/06/16 13:14:28 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!
20/06/16 13:14:28 INFO MemoryStore: MemoryStore cleared
20/06/16 13:14:28 INFO BlockManager: BlockManager stopped
20/06/16 13:14:28 INFO BlockManagerMaster: BlockManagerMaster stopped
20/06/16 13:14:28 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
20/06/16 13:14:28 INFO SparkContext: Successfully stopped SparkContext
20/06/16 13:14:28 INFO ShutdownHookManager: Shutdown hook called
20/06/16 13:14:28 INFO ShutdownHookManager: Deleting directory /var/data/spark-2f619243-59b2-4258-ba5e-69b8491123a6/spark-3d70294a-291a-423a-b034-8fc779244f40
20/06/16 13:14:28 INFO ShutdownHookManager: Deleting directory /tmp/spark-054883b4-15d3-43ee-94c3-5810a8a6cdc7

最后我们登陆到alluxio master上,查看相关指标统计到的值:

$ kubectl exec -ti alluxio-master-0 -n alluxio bash
//下面步骤alluxio-master-0 pod中执行
bash-4.4# alluxio fsadmin report metrics
Cluster.BytesReadAlluxio  (Type: COUNTER, Value: 290.47KB)
Cluster.BytesReadAlluxioThroughput  (Type: GAUGE, Value: 22.34KB/MIN)
Cluster.BytesReadDomain  (Type: COUNTER, Value: 0B)
Cluster.BytesReadDomainThroughput  (Type: GAUGE, Value: 0B/MIN)

BytesReadAlluxio和BytesReadAlluxioThroughput代表数据从网络栈传输;BytesReadDomain和BytesReadDomainThroughput代表数据从domain socket传输。可以看到所有数据都是从网络栈传输的(即使spark executor和LICENSE文件的block在同一k8s节点上)。

5.参考文档

]]>
【漏洞预警】Apache Spark 远程代码执行漏洞(CVE-2020-9480) Sat, 04 Jul 2020 09:33:04 +0800

2020年6月24日,阿里云应急响应中心监测到 CVE-2020-9480 Apache Spark 远程代码执行漏洞。


漏洞描述

Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。由于Apache Spark的认证机制存在缺陷,导致共享密钥认证失效。攻击者利用该漏洞,可在未授权的情况下,远程发送精心构造的过程调用指令,启动Spark集群上的应用程序资源,获得目标服务器的权限,实现远程代码执行。阿里云应急响应中心提醒Apache Spark 用户尽快采取安全措施阻止漏洞攻击。


影响版本

Apache Spark< = 2.4.5


安全版本

Apache Spark 2.4.6 或 3.0以上版本


安全建议

建议将Apache Spark升级至安全版本。下载地址参考:https://spark.apache.org/downloads.html


相关链接

https://spark.apache.org/security.html#CVE-2020-9480



我们会关注后续进展,请随时关注官方公告。

如有任何问题,可随时通过工单或服务电话95187联系反馈。

阿里云应急响应中心

2020.06.24

]]>
【漏洞预警】Apache Dubbo反序列化漏洞CVE-2020-1948补丁被绕过 Sat, 04 Jul 2020 09:33:04 +0800

2020年6月29日,阿里云应急响应中心监测到Apache Dubbo GitHub官方发布Pull requests修复了CVE-2020-1948漏洞补丁被绕过现象,Dubbo <=2.7.7版本仍存在反序列化漏洞。目前官方还未发布新版本,漏洞属0day级,风险极大。


时间线

2020年6月23日,阿里云发布【漏洞预警】Apache Dubbo反序列化漏洞(CVE-2020-1948)

2020年6月29日,阿里云监测到CVE-2020-1948漏洞补丁被绕过,风险依旧存在。


漏洞描述

Apache Dubbo是一款应用广泛的Java RPC分布式服务框架。Apache Dubbo于2020年6月23日披露在Dubbo Provider中存在一个反序列化远程代码执行漏洞(CVE-2020-1948),官方发布2.7.7版本修复漏洞,但近日该漏洞补丁被绕过,经阿里云工程师测试绕过有效,且目前官方还未发布新版本,漏洞属0day级,风险极大。阿里云应急响应中心提醒Apache Dubbo用户尽快采取安全措施阻止漏洞攻击。


影响版本

Apache Dubbo <=2.7.7


安全版本

暂无安全版本


安全建议

1. 禁止将Dubbo服务端端口开放给公网,或仅仅只对能够连接至Dubbo服务端的可信消费端IP开放。

2. Dubbo协议默认采用Hessian作为序列化反序列化方式,该反序列化方式存在反序列化漏洞。在不影响业务的情况下,建议更换协议以及反序列化方式。具体更换方法可参考:http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-protocol.html


相关链接

https://github.com/apache/dubbo/pull/6374


阿里云云安全中心应急漏洞模块已支持对该漏洞一键检测


我们会关注后续进展,请随时关注官方公告。

如有任何问题,可随时通过工单或服务电话95187联系反馈。


阿里云应急响应中心

2020.06.29

]]>
【其他】关于CDN产品新增突发带宽保障服务的通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【CDN突发峰值保障服务】【发布通知】

  • 为了给您提供更稳定、可靠的CDN服务,阿里云推出“突发峰值保障服务”,并更新【CDN产品服务协议】,具体如下:

  • 如果您对CDN服务有突发性的带宽使用需求(通常指带宽计费客户的全国使用增量超过500Gbps或流量计费客户的总量超过10Gbps,或者以上客户的突发增长的部分是平时平均使用量的30%),您需提前至少3个工作日(重大节日的突发,包括但不限于春晚,双十一等,需要提前至少1个月)联系阿里云申请突发增长的带宽用量,并确认能否/是否购买“突发峰值保障服务”,若购买成功的,可确保您的服务不受影响;若未购买“突发峰值保障服务”的,总量超过200Gbps(带宽计费)或10Gbps(流量计费)的,阿里云有权采取限流等措施来保障全网用户的稳定性(以上数值另有约定的,从其约定)。

  • 具体影响:

  1. 流量客户(峰值>10Gbps,或>合同约定值)

  2. 带宽客户(峰值>200Gbps,或>合同约定值)

  • 在触发带宽上限后会产生告警,阿里云可能会采取限流保护措施。

  • 温馨提示:

  1. 针对流量计费的客户,若有更大带宽的需求,可以转为带宽计费,或通过工单申请合理的带宽上限,由阿里云评估通过后给予上限调整;

  2. 所有客户可以通过申请“突发峰值保障服务”来确保突发带宽的服务质量


  • 阿里云计算有限公司

]]>
【升级】6月22日阿里云商标服务升级维护通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【阿里云商标服务】【升级维护通知】

升级窗口:北京时间2020年6月22日 00:00 - 08:00

升级内容:因业务系统升级,阿里云商标服务将于上述时间停服维护

升级影响:升级期间,登录及查看阿里云商标控制台、购买阿里云阿里云商标服务(含商标注册申请、驳回复审申请、续展申请及商标优选业务)、支付费用及补齐申请材料将停止服务,请您在维护结束后再进行操作。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【升级】6月22日阿里云公司注册升级维护通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【公司注册】【升级维护通知】

升级窗口:北京时间2020年6月22日 00:00 - 08:00

升级内容:阿里云云上公司注册和公司注册服务将于上述时间进行系统升级维护。

升级影响:升级期间,gs.aliyun.com的云上公司注册和公司注册服务将无法下单, 工商注册的控制台也将无法使用。如果您需要购买或管理以上业务操作,建议您避开该时间段,以免给您的业务造成影响。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【升级】6月22日阿里云图片与设计服务升级维护通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【图片与设计服务】【升级维护通知】

升级窗口:北京时间2020年6月22日 00:00 - 08:00

升级内容:因业务系统升级,阿里云图片与设计服务将于上述时间停服维护。

升级影响:升级期间,登录及查看阿里云的图片与设计控制台,购买阿里云图片与设计服务(含图片单张、图片VIP、Logo设计)、支付费用将暂停服务,请您在维护结束后再进行操作。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【升级】6月22日阿里云资质管家/ICP/EDI咨询代理服务升级维护通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【资质管家/ICP/EDI咨询代理服务】【升级维护通知】

升级窗口:北京时间2020年6月22日 00:00 - 08:00

升级内容:因业务系统升级,阿里云资质管家 / 阿里云ICP证 / 阿里云EDI证咨询代理服务将于上述时间停服维护。

升级影响:系统升级维护期间,登陆查询阿里云资质管家/工商财税控制台,提交购买阿里云资质相关服务,提交咨询单、需求单,补齐材料等操作将停止服务,请您在维护结束后再进行相关操作。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【升级】6月22日阿里云云市场代理记账服务应用系统升级维护通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【云市场代理记账服务】【升级维护通知】

升级窗口:北京时间2020年6月22日 00:00 - 08:00

升级内容:因业务系统升级,云市场代理记账服务的应用系统将于上述时间停服维护。

升级影响:升级期间,云市场代理记账服务的应用系统,包括登录及查看、补充代账企业信息、服务进度及报表查询将停止服务。请您在维护结束后再进行操作。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【升级】6月29日Datahub升级通知 Sat, 04 Jul 2020 09:33:04 +0800

【阿里云】【Datahub】【升级通知】

升级窗口:北京时间2020年6月29日 10:00 - 19:00

升级区域:华北,华南,华东,新加坡,吉隆坡,孟买,法国

升级内容:

1、支持MaxComputer2.0数据类型同步

2、支持订阅延迟云监控

升级影响:升级期间,会出现短暂的请求失败重试,属于正常现象,请确保您在业务上做好重连重试机制,以增强业务的容错能力。

给您带来的不便敬请谅解,有任何问题,可点击联系我们进行咨询反馈。

]]>
【漏洞预警】Apache Dubbo反序列化漏洞(CVE-2020-1948) Sat, 04 Jul 2020 09:33:04 +0800

2020年6月23日,阿里云应急响应中心监测到 CVE-2020-1948 Apache Dubbo反序列化漏洞。


漏洞描述

Apache Dubbo是一款应用广泛的Java RPC分布式服务框架。Apache Dubbo于2020年6月23日披露在Dubbo Provider中存在一个反序列化远程代码执行漏洞(CVE-2020-1948),攻击者可以构造并发送带有恶意参数负载的RPC请求,当恶意参数被反序列化时将导致远程代码执行。阿里云应急响应中心提醒Apache Dubbo用户尽快采取安全措施阻止漏洞攻击。


影响版本

Apache Dubbo 2.7.0 ~ 2.7.6

Apache Dubbo 2.6.0 ~ 2.6.7

Apache Dubbo 2.5.x 所有版本 (官方不再提供支持)。


安全版本

Apache Dubbo >= 2.7.7


安全建议

升级至安全版本或禁止Dubbo Provider对外开放


相关链接

https://www.mail-archive.com/dev@dubbo.apache.org/msg06544.html

https://github.com/apache/dubbo/releases/tag/dubbo-2.7.7


阿里云云安全中心应急漏洞模块已支持对该漏洞一键检测


我们会关注后续进展,请随时关注官方公告。

如有任何问题,可随时通过工单或服务电话95187联系反馈。


阿里云应急响应中心

2020.06.23

]]>
windows激活报错0x80070020或0x80041010-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

作者:棋玉

问题现象

激活报错,slmgr /ato后报错代码类似如下:
image.png

排查步骤

1.运行命令行 slmgr /dlv 同样报错,说明是slmgr 本身命令有问题,不像是网络层面的问题

2.查看msinfo32, 发现报错,提示 winmgmt 服务有问题
image.png

3.重启winmgmt 服务,可以正常重启,说明winmgmt 服务本身正常,需要rebuild wmi 数据库。
image.png

4.按照以下步骤rebuild wmi 数据库(注:此操作可能会对环境产生影响,建议先进行快照)
windows Server 2008R2
右击cmd,选择以管理员身份运行,运行以下命令行:

sc config winmgmt start= disabled
net stop winmgmt /y
cd %windir%system32wbem
rename repository repository.old
for /f %s in ('dir /b *.dll') do regsvr32 /s %s
wmiprvse /regserver 
sc config winmgmt start= auto
net start winmgmt
for /f %s in ('dir /b *.mof *.mfl') do mofcomp %s

Windows Server 2012及以后版本
右击cmd,选择以管理员身份运行,运行以下命令行:

sc config winmgmt start= disabled
net stop winmgmt /y
%systemdrive%
cd %windir%system32wbem
ren repository repository-backup
for /f %s in ('dir /b *.dll') do regsvr32 /s %s
sc config winmgmt start= Auto
net start winmgmt
dir /b *.mof *.mfl | findstr /v /i uninstall > moflist.txt & for /F %s in (moflist.txt) do mofcomp %s

5.之后成功激活。

]]>
Docker容器启动时初始化Mysql数据库-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 77.jpg
镜像下载、域名解析、时间同步请点击 阿里巴巴开源镜像站

1. 前言
Docker在开发中使用的越来越多了,最近搞了一个Spring Boot应用,为了方便部署将Mysql也放在Docker中运行。那么怎么初始化 SQL脚本以及数据呢?
我这里有两个传统方案。 第一种方案是在容器启动后手动导入,太low了不行。第二种在Spring Boot客户端连接Mysql容器时初始化数据库,你可以参考使用flyway进行数据库版本控制一文,但是这依赖客户端的能力。能不能做到Mysql容器启动时就自己初始化数据库呢?当然可以!今天就来演示一下。全部代码见文末。
2.原理
当Mysql容器首次启动时,会在 /docker-entrypoint-initdb.d目录下扫描 .sh,.sql,.sql.gz类型的文件。如果这些类型的文件存在,将执行它们来初始化一个数据库。这些文件会按照字母的顺序执行。默认情况下它们会初始化在启动容器时声明的 MYSQL_DATABASE变量定义的数据库中,例如下面的命令会初始化一个REGION_DB 数据库:
image.png
如果你的启动命令没有指定数据库那么就必须在数据库DDL脚本中声明并指定使用该数据库。否则就会实现下面的异常:
image.png
那么接下来我们将利用这一机制来实现Docker容器启动时初始化数据库。
3.自定义Dockerfile
我们编写自己的Dockerfile来实现我们的需求,这里以 Mysql:5.7 为例。不同的版本可能有一定的出入,需要详细去阅读官方文档。脚本如下:
image.png

  • 第一步,引入官方 Mysql:5.7 Docker镜像。
  • 第二步,无实际意义,主要是作者、组织信息。
  • 第三步,很重要!本来我没有配置第三行,结果运行容器后发现初始化数据的中文全部乱码了。所以需要在初始化数据库前修改Mysql的编码等配置,这里我顺便把时区也改为了+8:00。
  • 第四步,复制包含数据库脚本的 ./sql文件夹到镜像的/tmp/sql下。
  • 第五步,使用 mv 命令把第四步拷贝的文件夹下的所有.sql文件复制到 /docker-entrypoint-initdb.d下,这样才能利用2.章节的机制进行初始化数据库。
  • 第六步,删除使用过的临时目录。

然后你可以通过构建镜像命令构建自定义的Mysql镜像:
image.png
通过mysql:5.7c镜像启动一个名称为mysql-service的容器,root密码为123456,并持久化数据到宿主机 D:/mysql/data下:

docker run --name mysql-service -v d:/mysql/data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7c

小贴士:你可以通过 SHOW VARIABLES LIKE 'character%' 查看字符集是否更改为utf8mb4,也可以通过SHOW VARIABLES LIKE '%time_zone%' 查看时区是否是东八区。
4. 总结
今天我们自定义一个可以执行初始化数据库的Mysql镜像,方便我们进行部署。你也可以参考这个思路来定制其它一些自己需要的Docker镜像。

本文作者 | 码农小胖哥
本文来自 | 掘金

阿里巴巴开源镜像站 提供全面,高效和稳定的镜像下载服务。钉钉搜索 ' 21746399 ‘ 加入镜像站官方用户交流群。”

]]>
2020年便宜购买阿里云服务器攻略(阿里云小站篇)-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 本文主要讲通过阿里云小站便宜购买阿里云服务器的攻略,力争将可获取的优惠完整清晰的列出来,以供阿里云新老用户参考。云小站所提供的优惠包括代金券优惠、今日限时秒杀、新用户专享1折起、企业新用户特惠、心选建站以及其他热门活动推荐。

地址:阿里云小站

一:代金券优惠
首先,有一张金额为20元的云服务器ECS代金券,虽然金额比较小,但是如果你是购买1核1G 1核2G这种配置比较低的阿里云服务器还是很有用的,这张20元的代金券是只要订单金额满100元即可使用,云小站上有一款1核2G5M带宽的云服务器,优惠价格是197.47元,使用这张代金券就可以抵扣20元,实际购买只要177.47元。
要注意的是:20元的代金券只能是新用户才能领取,而且有效期是7天,因此,领取了之后请尽快使用哦。

如果你需要购买的阿里云服务器配置比较高,那么这张20元的代金券作用就不是很大了,订单金额比较高的,就需要用到其他几张代金券了,另外几张可用于购买阿里云服务器使用的代金券金额分别是:100元云服务器专用代金券、300元云产品通用代金券、800元云产品通用代金券,小编已经领取过了,根据小编了解的政策,这几张代金券的使用订单限制是:100元的订单满1000元可使用,300元的订单满3000元可使用,800元的订单满8000元可使用。
需要注意的是:这几张代金券的有效期是30天,我们可以领取了以后使用,但是这几张代金券仅限产品新购才能用,如果我们是老用户,想用这个代金券去续费阿里云服务器使用,是用不了的。
代金券.png

二、今日限时秒杀
限时秒杀所推出的这几款阿里云服务器,小编觉得是最经济实惠的,具体配置和秒杀价额如下下图所示:
限时秒杀.png
如果你是个人用户,放的网站流量不是很高,也没有在线视频这些吃带宽比较高的内容,推荐购买秒杀价格只要320.20元的这款共享型s6实例2核4G1M带宽的秒杀云服务器。如果您是企业用户,对云服务器性能要求高一点,推荐购买秒杀价格为636.72元一年的这款配置为共享型s6实例4核8G5M带宽的云服务器,这个配置可以满足绝大部分企业用户的上云需求了。

三、新用户专享1折起
新用户1折起专区所展示的优惠云产品,主要汇集了当下阿里云其他优惠活动中所推出的一些爆款云产品及配置,也就是用户购买最多的一些阿里云服务器配置和其他云产品,目前已经上架了27款云产品,除了阿里云服务器之外,还有云数据库MySQL高可用版、国内通用短信套餐包、云数据库SQL Server、SSL证书等云产品。

小编比较推荐的是活动价格为1166.40元起,实例规格为计算型c5的这款2核4G1M带宽的阿里云服务器,放一些主流的网站是没问题的,比如企业官网之类的。
具体云服务器产品及价格如下表:

实例规格 配置 带宽 云小站报价
共享型 s6 2核8G 2M 460.80元/1年 1209.60元/3年
共享型 s6 4核8G 5M 1910.16元/3年
通用型 g5 2核8G 1-5M可选 1576.80元/1年起
通用型 g6 2核8G 1-5M可选 1495.80元/1年起
通用型 g6 4核16G 1-5M可选 2791.80元/1年起
计算型 c6 2核4G 1-5M可选 1209.60元/1年起
计算型 c6 4核8G 1-5M可选 2219.40元/1年起
计算型 c5 2核4G 1M 1166.40元/1年
计算型 c5 4核8G 5M 2954.88元/1年

四、企业新用户特惠
企业新用户特惠是阿里云最近才在云小站上推出的全新板块,折扣低至2.6折,只要是企业认证且初次购买ECS的新用户均可以购买此版块的云服务器。这个专区所推出的云服务器主要以计算型c5 计算型c6和通用型g5 通用型g6为主,配置包含了2核4G、4核8G、2核8G、4核16G等,这些配置都是企业用户最常购买的一些配置。
另外,企业新用户特惠专区所推出的云服务器带宽均为1-10M带宽可选,这就给了企业用户在选择带宽上很大的灵活空间,因为企业用户的网站一般来说流量都比较高,最高10M足可以应付网站的流量高峰了。
具体云服务器产品及价格如下表:

实例规格 配置 带宽 云小站报价
共享型 s6 2核4G 1-10M可选 301.44元/1年起
共享型 s6 2核8G 1-10M可选 572.88元/1年起
共享型 s6 4核8G 1-10M可选 731.28元/1年起
计算型 c5 2核4G 1-10M可选 699.84元/1年起 2021.76元/3年起
计算型 c5 4核8G 1-10M可选 1279.80元/1年起 3697.20元/3年起
共享型 s6 2核4G 1-10M可选 904.32元/3年起
共享型 s6 2核8G 1-10M可选 1484.28元/3年起
共享型 s6 4核8G 1-10M可选 2094.12元/3年起
通用型 g5 2核8G 1M 946.08元/1年
计算型 c5 2核4G 1-10M可选 1166.40元/1年起 2954.88元/3年起
计算型 c5 4核8G 1-10M可选 2133.00元/1年起 5403.60元/3年起
计算型 c5 8核16G 1-10M可选 4066.20元/1年起
计算型 c6 2核4G 1-10M可选 1209.60元/1年起
计算型 c6 4核8G 1-10M可选 2219.40元/1年起
计算型 c6 8核16G 1-10M可选 4239.00元/1年起
通用型 g6 2核8G 1-10M可选 1495.80元/1年起 3789.36元/3年起
通用型 g6 4核16G 1-10M可选 2791.80元/1年起
通用型 g6 8核32G 1-10M可选 5383.80元/1年起
通用型 g5 2核8G 1-10M可选 1576.80元/1年起
通用型 g5 4核16G 1-10M可选 2953.80元/1年起
通用型 g5 8核32G 1-10M可选 5707.80元/1年起

五、爆款云产品5折起
这个专区是阿里云专为老用户开设的优惠购买通道,虽然总体价格还是没有新用户那么便宜,但是提供优惠的产品还是比较丰富的,包括云服务器ECS、云数据库Mysql、CDN流量包、Web应用防火墙、短信套餐包,这些应该都是老用户经常用到的产品,另外还提供了商标注册、企业工商注册等服务。
具体云服务器产品及价格如下表:

实例规格 配置 带宽 云小站报价
计算网络增强型sn1ne 2核4G 1M 2386.80元/1年
计算网络增强型sn1ne 4核8G 1M 4396.20元/1年
计算网络增强型sn1ne 8核16G 1M 8415.00元/1年
内存网络增强型se1ne 2核16G 1M 3671.40元/1年
内存网络增强型se1ne 4核32G 1M 6965.40元/1年
内存网络增强型se1ne 8核64G 1M 13553.40元/1年
通用网络增强型sn2ne 2核8G 1M 2951.40元/1年
通用网络增强型sn2ne 4核16G 1M 5525.40元/1年
通用网络增强型sn2ne 8核32G 1M 10673.40元/1年

六、心选建站
心选建站是阿里云最近上架的建站产品专区,产品包括模板站基础版、模板站标准版、模板站企业版、定制站标准版、定制站高级版、定制站尊贵版。目前主要的优惠为云·企业官网类建站产品可以享受买一年送半年,下单抽iphone11奖品的优惠。

七、热门活动推荐
这里汇总了阿里云全站所有热门的优惠活动,如果云小站上所展示的云产品或者配置不是自己想要的,你可以通过该板块了解阿里云当下正在进行哪些热门活动,通过其他热门活动去选购自己想要的阿里云服务器或者其他云产品。

]]>
内存占用高-AWE-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

作者:棋玉

问题现象:

内存占用高,任务管理器看不到问题,使用RAMMAP, 看到AWE 占用了大部分内存
https://docs.microsoft.com/en-us/sysinternals/downloads/rammap
image.png

解决方案:

AWE 占用内存高的问题一般发生在SQL 服务器上,一般建议客户调整“ maximum server memory”
https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/server-memory-server-configuration-options?view=sql-server-ver15

如果服务器上只安装了SQL 应用,建议给系统留2-4G 内存,其他内存留给SQL。
image.png

可以参考如下指标:
image.png

]]>
二叉树前序、中序、后序遍历的非递归写法-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 前序和中序遍历的非递归写法都比较好实现,后序遍历稍微复杂一些.

数据结构定义:

struct Node{

char c;
pNode lchild, rchild;
Node(char c, pNode lchild = nullptr, pNode rchild = nullptr) :

c(c), lchild(lchild), rchild(rchild) {}

};

申请阿里云服务时,可以使用2000元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui

二叉树形态:

A
/
B C
/ /
D E F G

/
H I

前序遍历:

先根遍历,拿到一个节点的指针,先判断是否为空,不为空就先访问该结点,然后直接进栈,接着遍历左子树;为空则要从栈中弹出一个节点来,这个时候弹出的结点就是其父亲,然后访问其父亲的右子树,直到当前节点为空且栈为空时,算法结束.

阿里云服务器1核2G低至82元/年,阿里云官活动网址:https://dashi.aliyun.com/site/yun/aliyun 可以用20代金券,即102-20=82。

void preVisitStack(pNode root)
{

stack st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    visit(p);
    st.push(p);
    p = p->lchild;
} else {
    p = st.top();
    st.pop();
    p = p->rchild;
}

}
cout << endl;
}

中序遍历:

和前序遍历一样,只不过在访问节点的时候顺序不一样,访问节点的时机是从栈中弹出元素时访问,如果从栈中弹出元素,就意味着当前节点父亲的左子树已经遍历完成,这时候访问父亲,就是中序遍历.

void midVisitStack(pNode root)
{

stack st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    st.push(p);
    p = p->lchild;
} else {
    p = st.top();
    visit(p);
    st.pop();
    p = p->rchild;
}

}
cout << endl;
}

后序遍历:

后续遍历就不一样了,首先肯定是先访问左子树,把父亲节点保存于栈中,问题是当元素从栈中弹出的时候,我们无法判断这个时候是该访问其右子树还是访问父亲节点,于是我们就需要一个标记,当访问左子树时我们把父亲节点的标记设为1,表示下一步如果弹出该节点,就访问其右子树;弹出一个节点时,我们要判断该节点的标记,如果是1,则访问其右子树,并把该节点的标记设置成2,表示下一步就访问该节点,然后把该节点继续入栈,如果是2,那么表示访问该节点,访问并且丢弃该节点.

为了不继续添加新的数据结构,我是用了STL中的pair来封装节点与标记.

void backVisitStack(pNode root)
{

stack > st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    st.push(make_pair(p, 1));
    p = p->lchild;
} else {
    auto now = st.top();
    st.pop();
    if (now.second == 1) {
        st.push(make_pair(now.first, 2));
        p = now.first->rchild;
    } else
        visit(now.first);
}

}
cout << endl;
}

完整测试代码:

include
using namespace std;

typedef struct Node *pNode;

struct Node{

char c;
pNode lchild, rchild;
Node(char c, pNode lchild = nullptr, pNode rchild = nullptr) :

c(c), lchild(lchild), rchild(rchild) {}

};

pNode build()
{

/*

     A
   /  
 B     C
/    / 

D E F G

    / 
   H   I

*/
pNode root = new Node('A');
root->lchild = new Node('B');
root->rchild = new Node('C');
root->lchild->lchild = new Node('D');
root->lchild->rchild = new Node('E');
root->rchild->lchild = new Node('F');
root->rchild->rchild = new Node('G');
root->rchild->lchild->lchild = new Node('H');
root->rchild->lchild->rchild = new Node('I');
return root;
}

void visit(pNode x)
{

cout << x->c << " ";
}

void preVisitStack(pNode root)
{

stack st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    visit(p);
    st.push(p);
    p = p->lchild;
} else {
    p = st.top();
    st.pop();
    p = p->rchild;
}

}
cout << endl;
}

void midVisitStack(pNode root)
{

stack st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    st.push(p);
    p = p->lchild;
} else {
    p = st.top();
    visit(p);
    st.pop();
    p = p->rchild;
}

}
cout << endl;
}

void backVisitStack(pNode root)
{

stack > st;
pNode p = root;
while (p || !st.empty()) {

if (p) {
    st.push(make_pair(p, 1));
    p = p->lchild;
} else {
    auto now = st.top();
    st.pop();
    if (now.second == 1) {
        st.push(make_pair(now.first, 2));
        p = now.first->rchild;
    } else
        visit(now.first);
}

}
cout << endl;
}

int main()
{

pNode root = build();
preVisitStack(root);
midVisitStack(root);
backVisitStack(root);
}

测试结果:

依次为前序、中序、后序遍历的结果.

A B D E C F H I G
D B E A H F I C G
D E B H I F G C A

]]>
如何安装discuz论坛-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 安装discuz论坛的方法:

首先,您需要去 http://www.discuz.net/ 下载一个合适的版本,并申请一个虚拟主机或服务器。建议你用阿里云服务器1核2G低至82元/年,阿里云官活动网址:https://dashi.aliyun.com/site/yun/aliyun 可以用20代金券,即102-20=82。
然后通过FTP上传所需要的程序,
运行安装程序,
设置论坛

安装详细流程

第 1 步:FTP上传 (如果FTP软件也不会用,那就比较麻烦了。可以上百度搜索FTP教材)

使用 FTP 软件登录您的服务器,建立一个单独的目录,或选择合适的位置,确保存放在此位置的文件能够被 web 请求所访问到,并且该目录中具有执行 PHP 代码的权限。将 Discuz! 文件包的 ./upload 目录中的全部文件和目录结构上传到服务器(注意是上传 upload 目录中的文件和目录,而不是上传包含 upload 目录本身的目录和结构)。

如果您仍然不了解应该上传哪些内容,请参考《文件及目录结构》中的说明。

申请阿里云服务时,可以使用2000元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui

Discuz! 要求使用 FTP 软件上传 php 文件时,使用二进制(BINARY)方式进行,否则将无法正常使用。有关二进制上传的具体细节,请参考《安装常见问题》中的说明。

第 2 步:设置目录属性

如果您的服务器使用 Windows 操作系统,可跳过这一步。

您在正式安装以前,需要设置相关的目录属性,以便数据文件可以被 Discuz! 正确的读写。使用 FTP 软件登录您的服务器,将服务器上以下的目录属性设置为 777。

./templates
./templates/default
./templates/default/.
./attachments
./customavatar
./forumdata
./forumdata/cache
./forumdata/templates
./forumdata/threadcaches
./forumdata/logs
如果您仍不了解那些目录或文件需要设置属性,请参考《文件及目录结构》中的说明。

如果您不了解应该如何设置属性,请参考《安装常见问题》中的说明。

第 3 步:配置数据库信息

使用编辑器打开您本地机器上的默认配置文件(config.inc.php),看到以下的内容:

$dbhost = 'localhost'; // database server

            // 数据库服务器

$dbuser = 'dbuser'; // database username

            // 数据库用户名

$dbpw = 'dbpw'; // database password

            // 数据库密码

$dbname = 'discuz'; // database name

            // 数据库名

$adminemail = 'admin@your.com'; // admin email

            // 论坛系统 Email

$dbreport = 0; // send db error report? 1=yes

            // 是否发送数据库错误报告? 0=否, 1=是

请依据以上的注释配置空间服务商提供的数据库服务器、用户名、密码及数据库名。如果您使用自己安装的服务器环境,我们建议您在可能的情况下,尽量不要使用 root 账号,而依据 Discuz! 及服务器上其他软件的需要,单独为每个程序分配账号和数据库,以减少安全问题发生的可能。

请您了解:数据库参数我们也无法告诉您如何设置,需要根据服务器账号的实际情况而定。如果您不了解,请咨询您的空间服务商,他们会完整的告诉您具体的设置方法。

配置好参数设置后,请保存该文件(config.inc.php),并不要忘记将其上传到服务器上的论坛目录中,覆盖原有的默认配置文件。

第 4 步:执行安装脚本

请在浏览器中运行 install.php,即访问 http://您的域名/论坛目录/install.php。

安装脚本会检查您的服务器系统环境、剩余空间、数据库环境,并具备一定的纠错功能。如果您在之前某一步骤操作有问题,通常安装脚本会发现并作以提示,请您根据提示再对安装过程进行检查。如果没有提示出问题,请您按照其中的说明,完成最后的安装。使用中的问题,请参考《使用指南》。

第 5 步:运行快速设置向导

现在进行到最后一步,如果您了解整个论坛的设置则不必运行此向导。

请在浏览器运行admincp.php,即访问 http://您的域名/论坛目录/admincp.php,进行设置,此向导将根据您论坛的类型批量设置相关参数,您可以在运行完后,再进入详细设置进行微调。

安装成功后,请通过 FTP 删除安装脚本(install.php),以避免被再次安装。

]]>
数据库周刊29│2020数据库研究报告;Oracle取消今年技术大会;腾讯云DBbridge发布支持一键迁库;饿了么迁至阿里云;PG数组查询;Oracle被比特币勒索;DM8 安全管理…-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 数据库周刊29.jpg

热门资讯

1、快讯:2020年Oracle OOW大会因疫情取消 系近20年首度
【摘要】Oracle 近日宣布,2020年 Oracle OpenWorld 技术大会因新冠疫情而取消,取而代之的将是在线的免费网络分享活动,活动将在不久后宣布,敬请关注。Oracle OpenWorld原定今年秋天在拉斯维加斯举行,这是近20年内Oracle首次取消这一活动。

2、腾讯云DBbridge正式发布:传统数据库迁移上云一键搞定
【摘要】6月18日,腾讯云正式发布企业级数据库迁移产品DBbridge。这款产品通过提供一站式数据迁移平台以及专家服务,帮助企业实现异构数据库之间数据的迁移和同步。目前,DBbridge已经支持Oracle、TDSQL、TBase、MySQL、PostgreSQL等多种数据库类型的迁移。

3、甲骨文第四财季收入同比下降6%,Cloud和License收入下降了22%
【摘要】甲骨文今天发布了2020财年第四财季及全年财报。报告显示,甲骨文第四财季总营收为104.40亿美元,同比下降6%,Cloud和License收入下降了22%。Oracle首席执行官Safra Catz表示:因为疫情影响,业务交易量有所减少,随着各国重新开放经济,许多业务已经恢复,我们相信,大部分客户将继续购买使用我们的产品和服务。

4、饿了么100%迁至阿里云:高峰时可支持1亿人同时点单
【摘要】6月17日,饿了么宣布已完成100%上云,旗下所有业务系统、数据库设施等均已迁移至阿里云。高峰期饿了么可在阿里云上快速扩容,可以支持1亿人同时在线点单,低峰期则可以释放算力,每年节省上千万元,同时动态规划最优线路,让外卖更快送达。

精选文章

1、Postgresql array数组查询及操作array_remove、array_append
【摘要】array_remove 从数组中移除某个值,array_append 向数组中批量插入值。移除数组中重复值:先将数组unnest,取distinct并再次转换成数组,如果得到的数组和name[1:cardinality(name)-1])相等,那么说明这些name数组中存在重复值,通过set name=name[1:cardinality(name)-1]达到去重目的。

2、用Benchmark压测PostgreSQL测试
【摘要】在我们学习数据库或者开发数据库监控软件的时候,经常需要给数据库加压。经过简单的配置,目前我们使用benchmark为Oracle、达梦、金仓、华为高斯、Postgres等数据库加压。本文分享使用Benchmark工具对PG库进行加压的实验案例。

3、深入理解:Oracle Move 和Shrink释放高水位空间HWM的区别
【摘要】在Oracle数据库中,进行了大量的数据增删改之后,就可能出现空间的碎片,通过 move 和shrink 可以对空间进行回收。本文介绍少了move 和shrink的功能介绍和注意事项。

4、Oracle物化视图日志表收缩
【摘要】某些物化视图日志由于客户端物化视图刷新地不是很及时,导致物化视图日志表膨胀地非常厉害,但实际日志表里的数据又不是很多。对于这种膨胀比较厉害的物化视图日志,需要进行收缩。本文分别介绍了线下和线下操作物化视图日志表收缩的方法。

干货文档

1、《2020数据库研究报告:国产数据库的宽赛道、高壁垒、新机遇》.doc
【摘要】本文档为兴业证券发布的2020年国产数据库行业研究与投资机会报告。报告显示,数据库上云进入快车道,国产数据库有望实现弯道超车。当前国产数据库已经形成三大核心竞争阵营,包括:以阿里、腾讯和华为科技巨头为代表的云数据厂商……

2、《数据安全:Oracle多场景下比特币勒索的解密与恢复实战》.ppt
【摘要】近年来很多用户遭遇数据库的安全问题,比特币勒索也层出不穷。本文档带你了解Oracle数据库遭比特币勒索的场景与恢复手段,以及如何避免此类安全问题。

3、《基于Oracle自治数据库快速开发智能分析应用》甲骨文-李青.doc
【摘要】本文档分享Oracle自治数据仓库入门、ADW自动化管理、ADW自动化调优、ADW帮助DBA工作减负,自治数据仓库云的关键应用场景和案例分享等。

4、《达梦数据库 DM8 安全管理》官方文档.doc
【摘要】本文档主要介绍达梦数据库DM8的安全体系结构,各安全管理模块的功能、原理及相关的数据库管理员和用户如何利用这些安全管理功能对数据库或数据进行安全保护。


详情及往期周刊请访问墨天轮数据库周刊专栏。
https://www.modb.pro/topic/12711?06

]]>
C盘空间占满排查方案-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

作者:棋玉

C盘空间占满的问题,首先要明确一下,空间被占满就是说明有文件把空间给占用了,右键所有文件属性看到差距很大的原因,总结有如下两个:
1,隐藏文件(包括pagefile.sys)
2, 系统管理员没有权限访问的文件比如System volume information 这个文件夹

排查方案如下:

=========

1.将隐藏文件设为可见。

Computer>Local Disk(C)>View>Options>Change folder and search options, 显示隐藏文件。
image.png

2.默认情况下,System volumeinformation 这个文件夹系统管理员没有权限访问,所以大小为0.

运行以下命令行赋予管理员完全控制权限这样才知道这个文件夹的实际大小。用管理员权限运行以下命令行:

takeown /f "C:system volumeinformation" /r /a
icacls "c:system volumeinformation" /grant builtinadministrators:F

3.使用工具 windirstat 或者treesize工具,这两个工具都可以非常直观的显示每个目录及文件夹占用大小
https://windirstat.net/
image.png

4.如果以上两个工具也未能定位到问题,说明还是存在管理员没有权限查看的文件,比如:
IIS服务器: 主要是log 文件,默认是如下路径: C:inetpublogsLogFiles
SQL server: 查看如下路径C:Program FilesMicrosoft SQLServerMSSQL10_50.MSSQLSERVERMSSQL

PS:第三步中使用工具如果看到占用最多的是winsxs 或者任何系统目录的话,不要轻易去清除这个文件夹,而是应该查看除了这个文件夹以外哪些文件占用了磁盘空间。

Winsxs 相当于系统的备份数据库,不可以完全删除或者移除,一般来讲清理的空间非常有限,如果坚持要清理,请参考如下链接:
2008R2:
https://support.microsoft.com/zh-cn/help/2852386/disk-cleanup-wizard-addon-lets-users-delete-outdated-windows-updates-o
2012&2012R2:
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-8.1-and-8/dn251565(v=win.10)?redirectedfrom=MSDN

]]>
多点生活在 Service Mesh 上的实践 | 线上直播整理-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

Service Mesh Webinar 是由 ServiceMesher 社区和 CNCF 联合发起的线上直播活动,活动将不定期举行,为大家带来 Service Mesh 领域的知识和实践分享。

本文根据5月28日晚 Service Mesh Webinar#1 多点生活平台架构组研发工程师陈鹏,线上主题分享《多点生活在 Service Mesh 上的实践 -- Istio + Mosn 在 Dubbo 场景下的探索之路》整理,文末包含本次分享的视频回顾链接以及 PPT 下载地址。

前言

随着多点生活的业务发展,传统微服务架构的面临升级困难的问题。在云原生的环境下,Service Mesh 能给我们带来什么好处。如何使用社区解决方案兼容现有业务场景,落地成符合自己的 Service Mesh 成为一个难点。

今天主要给大家分享一下 Service Mesh 的一些技术点以及多点生活在 Service Mesh 落地过程中适配 Dubbo 的一些探索。

首先我们从三个方面入手:

  • 为什么需要 Service Mesh 改造;
  • 探索 Istio 技术点;
  • Dubbo 场景下的改造;

为什么需要 Service Mesh 改造

说到为什么需要改造,应该先说一下 Service Mesh 和传统微服务架构的一些特点。

微服务

微服务一般有这些模块:

  • 安全;
  • 配置中心;
  • 调用链监控;
  • 网关;
  • 监控告警;
  • 注册和发现;
  • 容错和限流;

这些模块在传统的微服务架构中有的是和 SDK 结合在一起,有的是一个独立的中间件。

特点:

  • 独立部署;
  • 模块的边界;
  • 技术多样性;

正是由于技术多样性,我的微服务系统可以使用不同的语言进行开发,比如我一个商城系统,订单系统使用 Java 开发,库存系统使用 Go 开发,支付系统使用 Python 开发,微服务之间通过轻量级通信机制协作,比如:HTTP/GRPC 等。比如目前多点使用的 Dubbo(服务治理框架),随着多点生活的业务发展,目前遇到最棘手的问题就是中间件在升级过程中,推进很慢,需要业务方进行配合,接下来我们看看 Service Mesh。

Service Mesh

优点:

  • 统一的服务治理;
  • 服务治理和业务逻辑解藕;

缺点:

  • 增加运维复杂度;
  • 引入延时;
  • 需要更多技术栈;

看了 Service Mesh 的优缺点,如果我们 Mesh 化了之后就可以解决我们目前的痛点,升级中间件只需要重新发布一下 Sidecar 就好了,不同语言开发的微服务系统可以采用同样的服务治理逻辑,业务方就可以尝试更多的技术。

探索 Istio 技术点

在谈 Dubbo 场景下的改造之前我们先介绍一下 Istio 相关的技术点,然后结合 Dubbo 场景应该如何进行适配

MCP

MCP(Mesh Configuration Protocol)提供了一套用于订阅(Watch)、推送(Push)的 API,分为 Source 和 Sink 两个角色。

  • Source 是资源提供方(server),资源变化了之后推送给订阅者(Pilot),Istio 1.5 之前这个角色就是 Galley 或者自定义 MCP Server;
  • Sink 是资源的订阅者(client),在 Istio 1.5 之前这个角色就是 Pilot 和 Mixer,都是订阅 Galley 或者自定义 MCP Server 的资源

MCP 的订阅、推送流程图:

mcp

为了和实际情况结合,我们就以 MCPServer 作为 Source,Pilot 作为 Sink 来介绍订阅、推送流程,其中 MCP 通信过程中所传输的「资源」就是 Istio 定义的 CRD 资源,如:VirtualService、DestinationRules 等。

订阅

  • Pilot 启动后会读取 Configmap 的内容,里面有一个 configSources 的一个数组配置(Istio 1.5 之后没有这个配置,需要自己添加)、存放的是 MCP Server 的地址;
  • Pilot 连接 MCPServer 之后发送所关注的资源请求;
  • MCPServer 收到资源请求,检查请求的版本信息(可能为空),判断版本信息和当前最新维护的版本信息是否一致,不一致则触发 Push 操作,一致则不处理;
  • Pilot 收到 Push 数据,处理返回的数据(数据列表可能为空,为空也标示处理成功),根据处理结果返回 ACK(成功)/ NACK(失败),返回的应答中包含返回数据的版本信息,如果返回的是 NACK,Pilot 会继续请求当前资源;
  • MCPServer 收到 ACK(和资源请求一致)之后对比版本号,如果一致则不推送,否则继续推送最新数据;

推送

  • MCPServer 自身数据发生变化,主动推送变化的资源给 Pilot;
  • Pilot 收到之后处理这些数据,并根据处理结果返回 ACK / NACK;
  • MCPServer 收到 ACK(和资源请求一致) 之后对比版本号,如果一致则不推送,否则继续推送最新数据;

这样的订阅、推送流程就保证了 MCPServer 和 Pilot 资源的一致。MCPServer 只能通过 MCP 协议告诉 Pilot 资源发生变化了么?当然不是,MCPServer 可以使用创建 CR 的方式,Pilot 通过 Kubernetes 的 Informer 机制也能感知到资源发生变化了,只是通过 MCP 传输的资源在 Kubernetes 里面看不到,只是存在于 Pilot 的内存里面,当然也可以通过 Pilot 提供的 HTTP debug 接口(istiod_ip:8080/debug/configz)来查。

https://github.com/champly/mcpserver  提供了一个 MCPServer 的一个 demo,如果需要更加细致的了解 MCP 原理可以看一看。

更多 debug 接口可以查看: https://github.com/istio/istio/blob/5b926ddd5f0411aa50fa25c0a6f54178b758cec5/pilot/pkg/proxy/envoy/v2/debug.go#L103

Pilot

Pilot 负责网格中的流量管理以及控制面和数据面之前的配置下发,在 Istio 1.5 之后合并了 Galley、Citadel、Sidecar-Inject 和 Pilot 成为 Istiod。我们这里说的是之前 Pilot 的功能,源码里面 pilot-discovery 的内容。

功能

  • 根据不同平台(Kubernetes、Console)获取一些资源,Kubernetes 中使用 Informer 机制获取 Node、Endpoint、Service、Pod 变化;
  • 根据用户的配置(CR、MCP 推送、文件)触发推送流程;
  • 启动 gRPC server 用于接受 Sidecar 的连接;

推送流程

  • 记录变化的资源类型;
  • 根据变化的资源类型(数组)整理本地数据;
  • 根据变化的资源类型判断需要下发的 xDS 资源;
  • 构建 xDS 资源,通过 gRPC 下发到连接到当前 Pilot 的 Sidecar;

xDS

Sidecar 通过动态获取服务信息、对服务的发现 API 被称为 xDS。

  • 协议部分(ADS、控制资源下发的顺序及返回确认的数据);
  • 数据部分(CDS、EDS、LDS、RDS、SDS);

Pilot 资源类型发生变化需要下发的 xDS 资源对照:

资源名称 CDS EDS LDS RDS
Virtualservices
Gateways
Serviceentries
Destinationrules
Envoyfilters
Sidecars
ConfigClientQuotaspecs
ConfigClientQuotaspecbindings
Authorizationpolicies
Requestauthentications
Peerauthentications
Other

以上内容是根据 源码 整理的

MOSN

MOSN 是一款使用 Go 语言开发的网络代理软件,作为云原生的网络数据平面,旨在为服务提供多协议、模块化、智能化、安全的代理能力。MOSN 是 Modular Open Smart Network 的简称。MOSN 可以与任何支持 xDS API 的 Service Mesh 集成,亦可以作为独立的四、七层负载均衡,API Gateway,云原生 Ingress 等使用。

MOSN:https://github.com/mosn/mosn

配置文件:

  • mosn_config:MOSN 的配置信息;
  • listener:LDS;
  • routers:RDS;
  • cluster:CDS 和 EDS;

listener

listener

其中 address 就是 MOSN 监听的地址。

filter chains

filter_chains 在 MOSN 里面的 network chains,实现的还有:

  • fault_inject;
  • proxy;
  • tcp_proxy;

network chains 同级的还有 listener chainsstream chains, 其中
listener chains 目前只有 original_dst 实现。stream chains 可以对请求中的

  • StreamSender;
  • StreamReceiver;
  • StreamAccessLog;

进行 BeforeRoute AfterRoute 这些关键步骤进行修改请求信息。

所有的 filter 都只有两种返回结果:

  • Continue:如果后面还有 filter 那就执行后续 filter
  • Stop:执行完当前 filter 就不再继续执行了;
conv

看图中的配置信息 config 的内容, downstream_protocolupstream_protocol 这里如果配置不一致,就需要协议转换。比如 HTTP1 转换为 HTTP2,MOSN 就会先把 HTTP1 转换为 common 的中间协议,然后再把 common转换为 HTTP2,这样就实现了协议之间的转换。如果需要自己实现其他协议转换,那么只需要编写转换 common 的内容和 common 转换为当前协议的内容即可实现协议之间的互转。

proxy

我们再来看 filters 里面的 proxy,这个就是一个会经过路由的代理,配置信息里面配置了router_config_name,就是要路由的router名字。

routers

routers

根据 listener 里面的 proxy 的配置信息里面的 router_config_name 会找到一个 router,如上图所示。然后就会根据请求里面的 domains 去匹配 virtual_hosts, 这里的 domains 里面在 HTTP 里面就会是 host,当在 Dubbo 协议里面我们可以把 service(有些地方叫做 interface、target,我们这里统一叫 service) 放到 x-mosn-host 这个 MOSN 的 Header 里面,MOSN 就可以根据这个去匹配 domains

然后匹配到一个 virtual_hosts 之后,就会得到对应的 routers,这里又会根据 match 里面的匹配规则进行匹配,HTTP 协议里面可以根据 pathqueryparamheader 等信息进行匹配,具体匹配规则通过 VirtualService 下发,如果是 Dubbo 协议,那么可以套用 HTTPRoute 规则,然后把 Dubbo 的 attachment 解析出来当作 header去用,目前 MOSN 没有解析 attachment,我们自己实现了一个。

匹配到了之后会得到一个 route,图中所示只有一个 cluster_name,如果是有多个 subset(DestinationRule 定义),那么就会有 weighted_cluster ,里面会有 cluster_nameweight 构成的对象的数组,例如:

"route":{
    "weighted_clusters":[
        {
            "cluster":{
                "name":"outbound|20882|green|mosn.io.dubbo.DemoService.workload",
                "weight":20
            }
        },
        {
            "cluster":{
                "name":"outbound|20882|blue|mosn.io.dubbo.DemoService.workload",
                "weight":80
            }
        }
    ],
    "timeout":"0s",
    "retry_policy":{
        "retry_on":true,
        "retry_timeout":"3s",
        "num_retries":2
    }
}

其中 weight 之和必须为 100(Istio 定义的),必须是非负数的整数。

下面有一些 timeoutretry_policy 服务策略。

匹配上了之后会得到一个cluster_name,然后我们再看 cluster

cluster

routers 里面匹配出来的 cluster_name 作为 keycluster 里面会找到这么一个对象。

cluster

其中 lb_type 就是节点的负载均衡策略,目前 MOSN 支持:

  • ROUNDROBIN;
  • RANDOM;
  • WEIGHTED_ROUNDROBIN;
  • EAST_REQUEST;

hosts 里面的 address 里面也可以配置权重,这个权重必须是大于 0 或小于 129 的整数。可以通过 Istio 1.6 里面的 WorkloadEntry 来配置权重。然后根据负载均衡策略拿到 host 之后直接请求到对应的节点。

这就完成了流量的转发。接下来我们看看 Dubbo 场景下应该如何改造。

Dubbo 场景下的改造

所有的改造方案里面都是要把 SDK 轻量化,关于服务治理的逻辑下沉到 Sidecar,我们在探索的过程中有三种方案。

Istio + Envoy

这个方案是 Istio+Envoy 的方案,是参考的华为云的方案: https://support.huaweicloud.com/bestpractice-istio/istio_bestpractice_3005.html

  • 通过创建 EnvoyFilter 资源来给 xDS 资源打 patch;
  • Envoy 解析 Dubbo 协议中的 Service 和 Method;
  • 根据路由策略配置把流量转发到对应的 Provider;

这种方案如果需要解析更多的 Dubbo 内容,可以通过 WASM 扩展。

MOSN + Dubbo-go

  • MOSN 提供 Subscribe、Unsubscribe、Publish、Unpublish 的 HTTP 服务;
  • SDK 发送请求到 MOSN 提供的这些服务,让 MOSN 代为与真正的注册中心交互;
  • MOSN 通过 Dubbo-狗直接和注册中心连接;

这种方案的话就不需要 Istio。

Istio + MOSN

这种方案就是我们现在采用的方案,包括:

  • 数据面改造;
  • 控制面适配;

我们有一个理念就是如果能通过标准的 CRD 最好,如果描述不了的话我们就通过 EnvoyFilter 进行修改。这里特别说一下,我们一开始也有一个误区就是 EnvoyFilter 是作用于 Envoy,其实不是的,是对生成好的 xDS 资源进行 ADD, MERGE 等操作,目前只可以修改 LDS、RDS、CDS,这个修改也是有一定局限性的。如果 EnvoyFilter 修改不了某些特定的场景(比如 Istio 1.6 之前的 ServiceEntry 里面的 Endpoint 不能单独为每个实例指定不同的端口),那么我们只能修改 pilot-discovery 的代码,xDS 是不会作任何修改的。按照这个理念,我们开始探索如何改造。

数据面改造

mosn

首先有三个端口需要说明一下:

  • 20880 : provider 监听端口;
  • 20881 : consumer 请求 mosn 的这个端口,mosn 做转发到 provider;
  • 20882 : 接受来自下游(mosn/consumer)的请求,直接转到 127.0.0.1:20880;

步骤:

  • provider 启动之后请求本地 mosn 的注册接口,把服务信息注册到注册中心(zk/nacos),注册请求到达 mosn 之后,mosn 会把注册端口号改为 20882;
  • consumer 启动之后不需要连接注册中心,直接把请求发送到 127.0.0.1:20881;
  • consumer 端的 mosn 收到请求之后,根据配置信息 listener->routers->cluster->host,找到合适的 host(可以是 provider 的 mosn 或者 直接是 provider) 发送请求,这里的匹配过程可以修改 MOSN 让 Dubbo 的 service 作为 domains,attachment 作为 header;
  • provider 端 mosn 收到请求后(20882),直接转发请求到本地 127.0.0.1:20880;

这个只是通过静态配置实现的,如果 provider 这些信息如何通过 Pilot 下发呢?

控制面适配

MOSN 本身支持 xDS API,配置信息可以通过 xDS 下发,而不是静态配置。我们有一个对接配置中心,注册中心的程序我们叫 Adapter,这个主要获取注册中心的服务信息,然后根据配置中心的服务治理策略(比如流程比例,还有一些我们内部的一些单元的信息)构建出 Istio 支持的 CR,然后创建 CR,Pilot 自己感知 CR 变化 或者 通过 MCP 把这些信息直接发送给 Pilot,触发 Pilot 的资源变化,然后 Pilot 根据资源的变化去下发一些 xDS 资源,Sidecar 收到资源变化后,就可以动态调整路由策略,从而达到服务治理的目的。

最终架构图如图所示:

architecture

注册(灰色部分):

  1. provider 发送注册信息给 MOSN;
  2. MOSN 修改注册信息(端口号等),然后注册到真正到注册中心(ZK / Nacos 等);

配置下发(蓝色部分):

  1. Adapter 连接注册中心和配置中心并感知其变化;
  2. Adapter 感知到变化之后通过 MCP 把变化的信息传递给 Pilot(或者创建 CR 让 Pilot 自己感知);
  3. Pilot 感知到资源变化触发配置下发流程,根据变化到资源类型下发对应到 xDS 资源到 连接到它的 Sidecar;

服务请求(黄色部分):

  1. consumer 请求本地 127.0.0.1:20881(MOSN 监听的端口);
  2. MOSN 根据 listener->router->cluster 找到一个 host,然后把请求转发到这个 host 上;

以上就完成了服务注册、发现、治理的所有逻辑。

Istio 1.6 之后可以通过 WorkloadEntry + ServiceEntry 这两种 CRD 资源来描述集群外的服务,当实例上线或者下线的时候就会直接触发 EDS 增量下发

Demo 演示

首先要说明一下:

  • 由于没有真正的注册,所以使用手动添加 ServiceEntry 的方式代替 Adapter 功能;
  • Listener 和 Routers 配置信息目前是固定的;
  • Provider 只注册到本地 ZK;
  • Sidecar 注入到方式使用的是多个 Container;

具体操作可以按照 mosn-tutorial,里面的istio-mosn-adapt-dubbo。即使你没有 Kubernetes 环境也可以尝试的,后期这个会移植到 MOSN 官网,敬请期待。

mosn-tutorial:https://github.com/mosn/mosn-tutorial

以上就是本期分享的全部内容,感谢大家的收看。

本期嘉宾介绍

陈鹏,多点生活平台架构组研发工程师,开源项目与云原生爱好者。有多年的网上商城、支付系统相关开发经验,2019年至今从事云原生和 Service Mesh 相关开发工作。

回顾资料

PPT 下载:https://github.com/servicemesher/meetup-slides/tree/master/2020/05/webinar
视频回顾:https://www.bilibili.com/video/BV15k4y1r7n8

]]>
通过阿里云云小站申请阿里云服务器低至89元/年-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 在阿里云云小站上购买阿里云服务器可以领取哪些优惠呢?申请阿里云服务时,可以使用2020元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui

云服务器ECS 20元代金卷, 云服务器ECS 100元代金券,阿里云通用代金券800元,云产品通用代金卷300元, 数据库代金券 500元, 数据库代金券 300元
云服务器.png

如上图 所示

云服务器ECS 20元优惠券 用于阿里云新用户(从没买过阿里云任何产品的用户 域名不算)有效期7天。
云服务器ECS 100元代金卷用于产品首购(没买过阿里云ecs的用户)有效期30天
阿里云通用代金券800元和300元 产品首购(顾名思义涵盖所有阿里云产品首次购买可以使用)有效期30天
阿里云数据库代金券500元(没有买过数据库的用户 可领取使用)有效期7天
阿里云数据库代金券300元,产品复购(已经买过数据库的用户 可接着领取使用)
我们领取代金券以后就可以挑选自己想要购买的云服务器机型如下图所示基本涵盖了各种基础应用场景。阿里云代金券阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui
QQ图片20200623134944.png

更多阿里云云服务器优惠折扣可以去阿里云官网的:阿里云云小站 查看(https://dashi.aliyun.com/site/yun/youhui 看这个网址就知道属于阿里云官网,不是某个第三方网站 ),如果您有更多对活动不理解以及阿里云服务器技术上的问题可以联系我们,为您解答。

]]>
Windows 数据恢复-动态盘显示无效-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800

作者:棋玉

背景:

很多客户在使用磁盘时选择了动态盘,又对这块动态盘创建了快照,之后在数据恢复或其他场景下用快照创建了新的磁盘,将新磁盘挂载到相同实例时,发现新磁盘显示无效。
image.png

问题原因:

动态盘通过LDM进行管理,对于mbr分区,LDM保存在磁盘的最后1MB(如下图所示),这1MB空间保存了磁盘信息,分区信息以及磁盘id,group id等,由于源磁盘和新磁盘最后1MB空间是一样的,两块盘的ldm数据库完全相同,对应的磁盘id,group id也是完全相同,导致系统只能识别一块磁盘。
image.png

可以通过微软的LDMDump工具查看LDM database的具体信息:
https://docs.microsoft.com/en-us/sysinternals/downloads/ldmdump
image.png

解决方案:

将新磁盘在无损数据的前提下从动态盘转换到基本盘:重新配置分区表并将system id从dynamic 改为ntfs。需要借助diskprobe工具 (包含在Windows XP Service Pack 2 Support Tools)https://www.microsoft.com/en-us/download/details.aspx?id=18546
Drives找到对应的磁盘,选择Set Active(以drive2 为例)
image.png

首先读取sector0的信息,view 以partition table展示,其中relative 表示起始扇区,total sectors 表示总扇区数。从截图看到起始扇区是63,总扇区数是41940929,总扇区数=结束扇区-开始扇区+1,因此结束扇区是41940991。
image.png

image.png

之后判断起始扇区和结束扇区是否正确,查看sector 63和 sector 41940991 都是空,说明起始和结束扇区不正确,需要在偏移位3的位置用ntfs 标志查找起始和结束扇区,分别是2048和41938943
image.png

image.png

转到sector 2048,View 以NTFS BootSector 展示, Hidden sector 设置为起始扇区2048,Total sectors 设置为结束扇区-起始扇区=41936895
image.png

最后查看sector0, View 以Partition table 展示,relatvie 设置为起始扇区2048,Total Sectors 为结束扇区-起始扇区+1=41936896.
image.png

sector 0以Bytes显示,将42改为07(42表示的是动态分区,07表示是NTFS 分区 ),write sector 进行保存。
image.png
image.png

重新扫描磁盘后,可以看到磁盘显示为一个基本盘,可以进行数据读取写入操作。
image.png

]]>
蚂蚁金服智能监控云原生可观测大盘设计概览-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 背景

蚂蚁金服业务自定义监控是蚂蚁金服监控产品中的一个重要功能,主要是通过自定义日志数据源并配置大盘的方式来解决蚂蚁金服业务实时监控的需求。在产品功能上,用户可以通过对一系列日志数据源的创建、组织、管理及表单配置化的方式,简单、快速组织出一个多维监控大盘。这项能力在当时是一个具有创新性的能力,从功能到产品体验上很好解决了当时蚂蚁金服复杂业务监控的痛点。

但是,随着蚂蚁金服监控产品的不断迭代更新,以及云原生可观测性对于监控大盘的高要求,大家对自定义监控的体验诉求也越来越多,包括更便捷的交互方式、更丰富的图表、更丰富的数据源、更多扩展点等,因此对监控大盘的升级也势在必行。

本文将介绍蚂蚁金服监控产品在监控大盘方面的创新设计与尝试,新版自定义监控大盘 Barad-Dur 目标成为业界体验最优秀的自定义监控大盘,在交互、体验与设计理念上有诸多创新点,同时将以模块的形式发布,支持二次开发,可以同时为蚂蚁金服内外监控系统服务。

产品体验

WYSIWYG

当前优秀的监控大盘产品都标配一个“所见即所得(WYSIWYG)”编辑器,这方面能力是蚂蚁金服监控产品一直缺失的。在蚂蚁金服监控产品中配置大盘还是通过传统的表单方式,对用户非常不友好、学习曲线陡峭、配置效率不高。导致用户经常将配置大盘作为一项需求提给监控团队,由监控团队的“大盘配置专家”来进行配置,不仅存在较高的沟通成本,也给监控团队增加了很大的负担。

在新版监控大盘 Barad-Dur 中,对 WYSIWYG 编辑器的交互体验进行了大量工作,力求做到市面上最优秀的编辑体验。

体验1:缩放

Barad-Dur 的缩放是可以在四周以及四角上进行的,而市面上常见的大盘产品只支持右下角的缩放。由于坐标系统一般采用的是 (left, top, width, height) 来定义一个矩形,最容易实现的就是右下角缩放,只需要变动 width 和 height 两个参数即可。最难实现的是左上角的缩放,四个参数需要同时变动,且关系比较复杂。特别是在引入网格布局后,缩放时要自动“吸附”临近的网格点,难上加难。

1_scale.gif

体验2:拖动

Barad-Dur 的图表拖动可以实现图表位置的一步交换,而市面上常见的大盘产品需要进行多次拖动才能实现两个图表的交换。且在拖动过程中,图表的整体布局会被打乱,而 Barad-Dur 不会存在这样的问题。

2_swap.gif

体验3:自动重布局

Barad-Dur 的自动重布局功能非常强大,可以支持实时布局预览(当然市面上常见的大盘产品也支持),同时大盘的布局调整会根据具体操作(缩放、拖动)的方向进行。而市面上常见的大盘产品只能在垂直方向上进行布局调整,因为所用的算法非常简单,只是粗暴地把所有图表向页面上“推”。

3_layout.gif

体验4:任意位置

Barad-Dur 的布局支持图表在任意位置摆放,而市面上常见的大盘产品由于上述的简陋算法,不支持此功能,所有的图表必须堆叠在页面的顶部。

4_free.gif

体验5:布局复位

Barad-Dur 的自动重布局能够在对单个图表进行调整时将其他图表“推开”,然后更强大的是可以再将被推开的图表复位。这里找到了市面上常见的大盘产品直接拿来用的开源布局框架进行对比。该框架其实提供了上述的任意位置功能,然而由于没有布局复位的功能,导致该功能一旦启用,会令整个大盘在编辑过程中布局被扰乱,对用户起不到任何帮助,所以市面上常见的大盘产品没有启用这个功能。

5_reset.gif

体验6:文字编辑

Barad-Dur 支持在大盘中添加静态文字以及对于文字的编辑。静态文字可用于公告、标题、说明等一些常见的大盘场景。

6_text.gif

功能对比

Barad-Dur 市面上常见的大盘产品
任意拖动 ✔︎ ✔︎
任意缩放 ✔︎
多样图表 ✔︎ ✔︎
图表实时编辑 ✔︎ ✔︎
图表导入导出 ✔︎ ✔︎
任意布局 ✔︎
添加文字 ✔︎

综上对比,可以看出 Barad-Dur 的 WYSIWYG 编辑器在各项功能上已经领先于市面上常见的大盘产品。

控制器

大盘,即 Dashboard (in an automobile or similar vehicle) a panel beneath the front window having various gauges and accessories for the use of the driver; instrument panel。其本意是指汽车上的仪表板,这里的仪表板包括了两类组成部分:监视器、控制器。在仪表板上不仅能看到汽车的当前状态,也能对汽车进行各种控制。这是大盘的本意,但是就目前看来,市面上所有的监控大盘产品都缺失了控制器这个重要的组成部分,导致监控大盘其实只是监视大盘。如果只是用来监视的,那大盘独立存在就没有意义,就像汽车的仪表板上只有转速表、时速表、里程表,却没有油门、刹车、换挡杆。

我们再来看几个工业产品的大盘:

image.png

面向普通消费者的量产产品

image.png

面向专业消费者的量产产品

chernobyl.jpeg

面向专家的定制产品

控制器是不可或缺的组成部分,甚至比监视器更加重要。Barad-Dur 提供了在大盘中设置控制按钮的功能,可以实现一些简单的控制,比如关闭/启动报警、打开钉钉聊天窗口、启动控制预案等。日后会不断加入更加强大的控制功能,让蚂蚁金服监控大盘变成一个完整的监控系统。

技术实现

自定义数据源

上文提到 Barad-Dur 支持二次开发,支持自定义数据源,仅需一点点工作即可接入自己的数据源:

  1. 继承 AbstractDatasource,并实现 doRequestData 接口;
  2. 调用 registerDatasource 将数据源注册至 Barad-Dur(如果使用 Barad-Dur 的数据源编辑器,可在注册时指定自定义的数据源的编辑器);

Barad-Dur 会对所有的数据源进行包装,提供缓存、增量加载、请求合并等功能。

统一时序数据源

为了实现自定义数据源能够在任意图表中正确展现,Barad-Dur 定义了一种 universal 的时序数据格式,支持多 key 以及多 value。所有的时序数据源(以后可能会支持非时序数据源)都会将查询结果转换为这种格式,所有的图表也都会使用这种数据格式进行展现。

使用统一数据格式的优势在于,图表和数据源都是按照同样的数据接口(约定)来实现的,所以图表和数据源是可以独立变化的。即图表可以任意切换而不需要改动数据源配置,数据源也可以任意切换而不需要调整图表配置。这是市面上常见的大盘产品做不到的。

另一大优势在于计算。Barad-Dur 支持数据源的简单前端计算(如计算比率的场景需要将数据 A 与数据 B 相除),在使用了统一的数据格式之后,将计算也视为一个时序数据源,它的输入是一组时序数据源,也就是说一个计算数据源可以引用另一个计算数据源。这也是市面上常见的大盘产品做不到的。

Scene Graph

Scene Graph 的概念常用于游戏引擎对于场景的渲染。由于场景中各个节点有父子关系且子节点的空间关系常常用相对于父节点的量来表示,所以需要一种数据结构来将这些 local 空间的量(translation、rotation)转变为 global 空间的量,才能最终转换成屏幕空间的量用于渲染。这种父子关系恰好对应了大盘中的各个图表以及整个大盘的关系。就拿一个最常见的需求来举例说明:大盘上有全局回放的功能(这是一个非常重要的功能,没有这个功能大盘就对排查问题毫无意义),而每个图表又有自己的设置:

  • 时间跨度:分钟级的图表与秒级的图表不会展现同样范围的数据;
  • 时间偏移:图表数据产生存在不同的延时;

我们可以使用类似 Scene Graph 的数据结构来保存每个图表自己的时间轴配置以及全局大盘的时间轴配置,最后计算出查询数据所需的时间参数。

同时,未来还会引入技术栈的概念,即一个预定义的图表组,可以直接放入到自定义的大盘中,只需要做少量配置。例如,用户可以一步创建一台物理机的 CPU、Memory、Disk 监控图表,只需要修改这个图表组的 ip 参数。

所以在 Barad-Dur 中借鉴了 Scene Graph 的设计理念,并融入了大盘的设计需求。

image.png

总体是一个树形结构,但是每个节点都会有一个 MVC 结构,将数据源、视图以及控制数据分离,控制流与数据流分离。同时数据源部分可以相互依赖,使 Barad-Dur 可以优化数据查询,做到缓存、增量查询、合并查询等。

未来展望

目前 Barad-Dur 已经内置支持 OpenTSDB、CeresDB(蚂蚁自研的高性能、分布式、高可靠时序数据库,支持  PromQL)以及部分蚂蚁金服内部数据源,计划将兼容更多数据源,如 PromQL、InfluxDB、MySQL 等常用监控数据源。本文提到的可以预定义一组图表以及一组变量,创建大盘时可以快速添加相应的图表组件,同时也支持导入从其他大盘产品直接导出的大盘,使用户可以快速平滑迁移。

希望本文的介绍可以为大家在云原生监控领域的设计带来一些思考与启发,也欢迎关注该领域的优秀的你,跟我们交流更多想法~

关于我们

欢迎来到「蚂蚁智能运维」的世界。本公众号由蚂蚁智能监控团队出品,面向关注智能运维技术的同学,将不定期与大家分享云原生时代下蚂蚁金服在智能监控的架构设计与创新方面的思考与实践。

蚂蚁智能监控团队,负责蚂蚁金服的基础设施和业务应用的监控需求,正在努力建设一个支撑百万级机器集群、亿万规模服务调用场景下的,覆盖指标、日志、性能和链路等监控数据,囊括采集、清洗、计算、存储乃至大盘展现、离线分析、告警覆盖和根因定位等功能,同时具备智能化 AIOps 能力的一站式、一体化的监控产品,并服务蚂蚁金服众多业务和场景。

关于「智能运维」有任何想要交流、讨论的话题,欢迎留言告诉我们。

PS:蚂蚁智能监控正在招聘 AIOps 专家,欢迎加入我们,有兴趣联系 boyan@antfin.com

]]>
记Elasticsearch安装与数据同步-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800
  • 公司开展电商业务,之前有开发过类似项目,并没有涉及首页搜索功能,这次鉴于首页所搜需求变动,不仅仅是搜索商品,还要搜索店铺,直播及主播,现有实现方式是直接搜索数据库,为了增加用户体验,减小数据库的压力,so改用Elasticsearch实现首页搜索功能。
  • Elasticsearch安装

    1. 准备elasticsearch安装包,版本选择7.6.0;官网地址
    2. 使用root用户创建es用户
    useradd es

    然后为es用户设置密码

    passwd es
    
    1. 修改/etc/security/limits.conf文件 在文件末尾添加
    *       hard    nofile           65536
    *       soft     nofile           65536
    
    1. 修改/etc/security/limits.d/20-nproc.conf文件
    *            soft            nproc     4096
    
    *            hard          nproc     4096
    
    root       soft            nproc     unlimited
    

    在/etc/sysctl.conf文件末尾添加

    vm.max_map_count = 2621441

    root用户执行命令

    sudo sysctl -p /etc/sysctl.conf

    切换用户

    su es

    上传elasticsearch-7.6.0-linux-x86_64.tar.gz文件至es用户目录下

    解压到当前目录

    tar -zxvf elasticsearch-7.6.0-linux-x86_64.tar.gz

    修改/home/es/elasticsearch-7.6.0/config/elasticsearch.yml配置文件

    #这里写本机ip,
    network.host: 192.168.110.191
    #
    # Set a custom port for HTTP:
    #
    #http.port: 9200
    
    #跨域配置 网页直连使用需要该配置,否则不需要
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    安装elasticsearch-analysis-ik中文分词器;在/home/es/elasticsearch-7.6.0/config/目录下创建analysis-ik目录

    cd /home/es/elasticsearch-7.6.0/config/
    mkdir analysis-ik

    将下载下来的中文分词器文件解压,并将config目录下的所有文件拷贝到/home/es/elasticsearch-7.6.0/config/analysis-ik目录下

    在/home/es/elasticsearch-7.6.0/plugins目录下创建analysis-ik目录

    cd /home/es/elasticsearch-7.6.0/plugins
    mkdir analysis-ik
    

    将分词器中除config之外的文件拷贝到/home/es/elasticsearch-7.6.0/plugins/analysis-ik目录下

    启动elasticsearch服务

    cd /home/es/elasticsearch-7.6.0/bin
    ./elasticsearch -d
    

    浏览器访问http://192.168.110.191:9200/出现如下页面则服务启动成功

    {
      "name" : "eshost",
      "cluster_name" : "elasticsearch",
      "cluster_uuid" : "muEaR2aHT6uT_F1lop84Lg",
      "version" : {
        "number" : "7.6.0",
        "build_flavor" : "default",
        "build_type" : "tar",
        "build_hash" : "7f634e9f44834fbc12724506cc1da681b0c3b1e3",
        "build_date" : "2020-02-06T00:09:00.449973Z",
        "build_snapshot" : false,
        "lucene_version" : "8.4.0",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }

    数据同步工具Logstash;注意:一定要保证版本一致

    cd /home/es/
    wget https://artifacts.elastic.co/downloads/logstash/logstash-7.6.0.zip
    unzip logstash-7.6.0.zip
    cd logstash-7.6.0
    mkdir myconfig
    cd myconfig

    在此目录下需要创建mysql.conf文件以及要执行的sql文件,以及数据库驱动jar包,示例(此示例为多表同步):

    -rw-rw-r--. 1 es es      23 Jun 22 14:08 commodity.sql
    -rw-rw-r--. 1 es es      24 Jun 23 10:35 instructor.sql
    -rw-rw-r--. 1 es es      18 Jun 23 10:36 live.sql
    -rw-rw-r--. 1 es es    4658 Jun 23 10:50 mysql.conf
    -rw-rw-r--. 1 es es 2018353 May 28 11:25 mysql-connector-java-8.0.9-rc.jar
    -rw-rw-r--. 1 es es      24 Jun 23 10:36 user_store.sql
    

    sql文件中的内容为

    select * from commodity

    mysql.conf文件中的内容为

    input {
        stdin {
        }
        jdbc {
          # mysql数据库连接
          jdbc_connection_string => "jdbc:mysql://192.168.110.191:3306/platform?allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false"
          # mysqly用户名和密码
          jdbc_user => "xxx"
          jdbc_password => "xxxx"
          # 驱动配置
          jdbc_driver_library => "/home/es/logstash-7.6.0/myconfig/mysql-connector-java-8.0.9-rc.jar"
          # 驱动类名
          jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
          jdbc_paging_enabled => "true"
          jdbc_page_size => "50000"
          # 执行指定的sql文件
          statement_filepath => "/home/es/logstash-7.6.0/myconfig/commodity.sql"
          # 设置监听 各字段含义 分 时 天 月  年 ,默认全部为*代表含义:每分钟都更新
          schedule => "* * * * *"
          # 索引类型
          type => "commodity"
        }
            jdbc {
          # mysql数据库连接
          jdbc_connection_string => "jdbc:mysql://192.168.110.191:3306/platform?allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false"
          # mysqly用户名和密码
          jdbc_user => "xxxx"
          jdbc_password => "xxxx"
          # 驱动配置
          jdbc_driver_library => "/home/es/logstash-7.6.0/myconfig/mysql-connector-java-8.0.9-rc.jar"
          # 驱动类名
          jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
          jdbc_paging_enabled => "true"
          jdbc_page_size => "50000"
          # 执行指定的sql文件
          statement_filepath => "/home/es/logstash-7.6.0/myconfig/instructor.sql"
          # 设置监听 各字段含义 分 时 天 月  年 ,默认全部为*代表含义:每分钟都更新
          schedule => "* * * * *"
          # 索引类型
          type => "instructor"
        }
            jdbc {
          # mysql数据库连接
          jdbc_connection_string => "jdbc:mysql://192.168.110.191:3306/platform?allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false"
          # mysqly用户名和密码
          jdbc_user => "xxxx"
          jdbc_password => "xxxx"
          # 驱动配置
          jdbc_driver_library => "/home/es/logstash-7.6.0/myconfig/mysql-connector-java-8.0.9-rc.jar"
          # 驱动类名
          jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
          jdbc_paging_enabled => "true"
          jdbc_page_size => "50000"
          # 执行指定的sql文件
          statement_filepath => "/home/es/logstash-7.6.0/myconfig/live.sql"
          # 设置监听 各字段含义 分 时 天 月  年 ,默认全部为*代表含义:每分钟都更新
          schedule => "* * * * *"
          # 索引类型
          type => "live"
        }
            jdbc {
          # mysql数据库连接
          jdbc_connection_string => "jdbc:mysql://192.168.110.191:3306/platform?allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false"
          # mysqly用户名和密码
          jdbc_user => "xxxx"
          jdbc_password => "xxxx"
          # 驱动配置
          jdbc_driver_library => "/home/es/logstash-7.6.0/myconfig/mysql-connector-java-8.0.9-rc.jar"
          # 驱动类名
          jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
          jdbc_paging_enabled => "true"
          jdbc_page_size => "50000"
          # 执行指定的sql文件
          statement_filepath => "/home/es/logstash-7.6.0/myconfig/user_store.sql"
          # 设置监听 各字段含义 分 时 天 月  年 ,默认全部为*代表含义:每分钟都更新
          schedule => "* * * * *"
          # 索引类型
          type => "user_store"
        }
    }
    
    filter {
        json {
            source => "message"
            remove_field => ["message"]
        }
    }
    
    output {  
            if [type]=="user_store" {
                    elasticsearch {
                    #ESIP地址与端口
                            hosts => "192.168.110.191:9200"
                            #ES索引名称(自己定义的)
                            index => "user_store"
                            #自增ID编号
                            #document_id => "%{id}"
                    }
            }
            if [type]=="live" {
                    elasticsearch {
                    #ESIP地址与端口
                            hosts => "192.168.110.191:9200"
                            #ES索引名称(自己定义的)
                            index => "live"
                            #自增ID编号
                            #document_id => "%{id}"
                    }
            }
            if [type]=="instructor" {
                    elasticsearch {
                    #ESIP地址与端口
                            hosts => "192.168.110.191:9200"
                            #ES索引名称(自己定义的)
                            index => "instructor"
                            #自增ID编号
                            #document_id => "%{id}"
                    }
            }
            if [type]=="commodity" {
                    elasticsearch {
                    #ESIP地址与端口
                            hosts => "192.168.110.191:9200"
                            #ES索引名称(自己定义的)
                            index => "commodity"
                            #自增ID编号
                            #document_id => "%{id}"
                    }
            }
    }
    

    启动Logstash

    cd /home/es/logstash-7.6.0/bin
    ./logstash -f ../myconfig/mysql.conf &

    ]]>
    Elasticsearch集群模式知多少?-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 本文不涉及实战操作,仅限集群原理范围探讨,基于版本7.6.X。

    作者介绍

    李猛,Elastic Stack 深度用户,通过 Elastic 工程师认证,2012年接触 Elasticsearch,对 Elastic Stack 技术栈开发、架构、运维等方面有深入体验,实践过多种大中型项目;为企业提供 Elastic Stack 咨询培训以及调优实施;多年实战经验,爱捣腾各种技术产品,擅长大数据,机器学习,系统架构。

    集群模式

    Elasticsearch节点设计支持多种角色,这个是实现集群最重要的前提,节点角色各司其职,也可以任意组合,职责重合。

    image.png

    节点角色说明:

    • Master,集群管理
    • Voting,投票选举节点
    • Data,数据节点
    • Ingest,数据编辑节点
    • Coordinate,协调节点
    • Machine Learning,集群学习节点

    以下展开各种集群模式

    1.单节点(入门)

    image.png

    单节点模式默认开启所有节点特性,具备一个集群所有节点角色,可以认为是一个进程内部的集群。Elasticsearch在默认情况下,不用任何牌配置也可以运行,这也是它设计的精妙之处,相比其它很多数据产品集群配置,如Mongodb,简化了很多,起步入门容易。

    2.基本高可用(初级)


    image.png

    Elasticsearch集群要达到基本高可用,一般要至少启动3个节点,3个节点互相连接,单个节点包括所有角色,其中任意节点停机集群依然可用。为什么要至少3个节点?因为集群选举算法奇数法则。

    3.数据与管理分离(中级)

    image.png

    Elasticserach管理节点职责是管理集群元数据、索引信息、节点信息等,自身不设计数据存储与查询,资源消耗低;相反数据节点是集群存储与查询的执行节点。

    管理节点与数据节点分离,各司其职,任意数据节点故障或者全部数据节点故障,集群仍可用;管理节点一般至少启动3个,任意节点停机,集群仍正常运行。

    4.数据与协调分离(高级)

    image.png

    Elasticsearch内部执行查询或者更新操作时,需要路由,默认所有节点都具备此职能,特别是大的查询时,协调节点需要分发查询命令到各个数据节点,查询后的数据需要在协调节点合并排序,这样原有数据节点代价很大,所以分离职责,详细技术原理可以观看腾讯课堂《Elastic技术原理:数据查询》,里面讲解了Elastic执行查询的过程。

    5.协调读写分离(高级)

    image.png

    Elasticsearch设置读写分离指的是在协调节点上,不是数据节点上,集群大量的查询需要消耗协调节点很大的内存与CPU合并结果,同时集群大量的数据写入会阻塞协调节点,所以在协调节点上做读写分离很少必要,也很简单,由集群设计搭建时规划好即可。

    6.数据节点标签(高级)

    image.png

    Elasticsearch给数据节点标签,目的是分离索引数据的分布,在一个集群规模中等以上,索引数据用途多种多样,对于数据节点的资源需求不一样,数据节点的配置可以差异化,有的数据节点配置高做实时数据查询,有的数据节点配置低做历史数据查询,有的数据节点做专门做索引重建。

    Elasticsearch集群部署时需要考虑基础硬件条件,集群规模越来越大,需要多个数据中心,多个网络服务、多个服务器机架,多个交换机等组成,索引数据的分布与这些基础硬件条件都密切相关。

    7.主副分片分离(高级)

    image.png

    Elasticsearch集群规模大了之后得考虑集群容灾,若某个机房出现故障,则可以迅速切换到另外的容灾机房。

    8.跨集群操作(高级)

    image.png

    Elasticsearch单个集群规模不能无限增长,理论上可以,实际很危险,通过创建多个分集群分解,集群直接建立直接连接,客户端可以通过一个代理集群访问任意集群,包括代理集群本身数据。

    Elasticsearch集群支持异地容灾,采用的是跨集群复制的机制,与同一集群主分片副本分片分离是不同的概念,2个集群完全是独立部署运行,仅数据同步复制。

    9.跨集群版本操作(高级)

    image.png

    Elasticsearch版本更新很快,已知问题修复很快,新特性新功能推出很快,一日不学,如隔三秋。有的集群数据重要性很高,稳定第一,不能随意升级,有的业务场景刚好需要最新版本新功能新特性支持。

    结语

    经验总结

    Elasticsearch集群模式种类挺多,每种集群模式都有它的应用场景以及解决实际的问题,每种集群模式之间也可以轻易转换。所以说ES玩的好,下班下得早。

    声明:本文由原文作者“李猛”授权转载,对未经许可擅自使用者,保留追究其法律责任的权利。


    image.png

    阿里云Elastic Stack】100%兼容开源ES,独有9大能力,提供免费X-pack服务(单节点价值$6000)

    相关活动


    更多折扣活动,请访问阿里云 Elasticsearch 官网

    阿里云 Elasticsearch 商业通用版,1核2G ,SSD 20G首月免费
    阿里云 Logstash 2核4G首月免费


    image.png

    image.png

    ]]>
    崩溃堆栈还原技术大揭秘-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 0x00 前言

    当应用出现崩溃的时候,程序员的第一反应肯定是:在我这好好的,肯定不是我的问题,不信我拿日志来定位一下,于是千辛万苦找出用户日志,符号表,提取出崩溃堆栈,拿命令开干,折腾好一个多小时,拿到了下面的结果:

    addr2line -ipfCe libxxx.so 007da904 007da9db 007d7895 00002605 007dbdf1
    logging::Logging::~Logging() LINE: logging.cc:856
    logging::ErrLogging::~ErrLogging() LINE: logging..cc:993
    base::internal::XXXX::Free(int) LINE: scoped____.cc:54
    base::___Generic<int, base::internal::_____loseTraits>::_____sary() LINE: scoped_______.h:153
    base::___Generic<int, base::internal::_____loseTraits>::_____eric() LINE: scoped_______.h:90


    如果是接入了岳鹰全景监控平台,场景就完全不一样了。测试同学:发来一个链接,附言研发哥哥,这是你的bug,请注意查收。研发哥哥:点开链接,就可以在平台看到这条崩溃信息啦,如下图:
    image.png


    那么问题来了,岳鹰上有这么多的应用版本,再加上海量的日志,对于Native崩溃,总不能每个崩溃点都用addr2line或者相关的命令去符号化吧?
    岳鹰的符号化系统正是为了解决该问题而设计。岳鹰最初上线的版本1.0,支持同时符号化解析数量有限,对iOS符号化时依赖Mac系统,不支持容器化部署,消耗机器资源较多。
    为了更好的满足用户业务需求,岳鹰在年初启动了2.0版本的改造,并且制定以下目标:

    • 同时解析不限数量的符号表
    • 提升符号化的效率
    • 解除Mac系统依赖,支持全容器化部署


    那这样一个分布式的符号化系统该如何设计呢?接下来小编就来详细介绍下。

    0x01 方案的选择

    结合当前系统设计以及业界常见方案,我们有以下几条路可以走:

    1. 岳鹰1.0方案,用大磁盘,高CPU性能的机器搭建符号化机器,符号文件存放到磁盘,需要符号化时再调用addr2line;
    2. 建立一个中央存储,把符号文件上传到中央存储,符号化机器需要符号化的时候再过去拉,然后用addr2line符号化;
    3. 把符号信息按key-value方式提取出来,存入hbase或者其它中间件,符号化时通过类sql查询实现。

    结合岳鹰2.0的目标,我们对三个方案进行对比:

    对比项 方案1 方案2 方案3
    符号表入库速度
    内存占用 常态高 常态高 入库时高
    CPU占用 常态高 常态高 入库时高
    安全性
    可扩展性
    部署复杂度


    方案1:符号文件上传倒是很快,如果需要高可用,还需要镜像一份到备机,且在做addr2line的时候,会带来高内存及高cpu的占用,而且不支持动态扩容,安全性也几乎没有,拿到机器就拿到了源码;

    方案2:符号文件存放于中央存储,做好备份机制后,能保障文件不会丢失,但机器在符号化时,都需要去中央存储拉符号文件,之后的处理同方案1,查询效率不高,而且安全性也不高;

    方案3:在符号入库时,把符号信息按key-value方式提取出来,然后加密存入hbase,这里要解决符号表全量导出及入库的速度及空间问题。

    结合岳鹰2.0目标,我们对日志处理的及时性,可扩展性,安全性,以及海量版本同时解析的要求,我们选择了方案3。下面我们先给大家简单介绍下原理,再深入看看选择方案3要解决哪些问题。

    0x02 原理(大神请忽略这一节)

    国际惯例,我们先来了解一下原理,符号表是什么?符号表是记录着地址或者混淆代码与源码的对应关系表。下面我们分别用一个小demo程序来讲解符号表及符号化的过程。

    0x02-1 iOS-OC、Android-SO符号化原理

    a.示例源码:

    int add(){
        int a = 1;
        a ++;
        int b = a+3;
        return b;
    }
    int div(){
        int a = 1;
        a ++;
        int b = a/0;                //这里除0会引发崩溃
        return b;
    }
    int _tmain(int argc, _TCHAR* argv[]){
        add();
        sub();
        return 0;
    }

    b.对应符号表,这里简化了符号表,没带行号信息

    0x00F913B0 ~ 0x00F913F0    add()
    0x00F91410 ~ 0x00F91450    div()
    0x00F91A90 ~ 0x00F91ACD    _tmain()

    c.现有一崩溃堆栈

    0x00F9143A
    0x00F91AB0

    d.进行符号化

    0x00F9143A    div()    //查找符号表,地址0x00F9143A的符号名,在0x00F91410 ~ 0x00F91450范围内
    0x00F91AB0    _tmain() //查找符号表,地址0x00F91AB0的符号名,在0x00F91A90 ~ 0x00F91ACD范围内

    0x02-2 Android-Java 符号化原理

    a.示例源码:

    package com.uc.meg.wpk
    class User{
        int count;
        UserDTO userDto;
        UserDTO get(int id){...}
        int set(UserDTO userDto){...} 
    }
    class UserDTO{
        int id;
        String name;
    }

    b.符号表

    com.a.b.c.d -> com.uc.meg.wpk.User
        int count -> a
        com.uc.meg.wpk.UserDTO -> b
        com.uc.meg.wpk.UserDTO get(int) -> c
        int set(com.uc.meg.wpk.UserDTO) -> d
    
    com.a.b.c.e -> com.uc.meg.wpk.UserDTO
        int id -> a
        String name -> b

    c.现有一崩溃堆栈

    com.a.b.c.d.d(com.a.b.c.e)

    d.进行符号化

    //符号化com.a.b.c.d.d(com.a.b.c.e)    
    //查找com.a.b.c.d, 命中com.uc.meg.wpk.User
    //查找com.uc.meg.wpk.User.d 命中 set()
    //查找com.a.b.c.e,命中 com.uc.meg.wpk.UserDTO
    //符号化结果为com.uc.meg.wpk.User.set(com.uc.meg.wpk.UserDTO) 

    0x03 新的难题

    选择方案3后,主要瓶颈在符号表上传之后处理,这里主要工作是要把符号表转换为key-value,然后再写入hbase。现在主流的app开发有android的java及C++,iOS的OC,我们下面主要讨论这三种符号。
    因为android的java符号化有google的开源工具支持,这里就不再展开。
    OC因为是iOS系统,封闭系统,标准统一,上架AppStrore的应用,只用XCode进行编译,没有各种定制的需求。我们原来有一个OC实现的符号表kv提取程序,但是只能用于OSX系统,不便于线上布署,所以我们选择了用java重写了提取符号kv的功能。
    但是对于Android的C++库so符号表,即ELF格式,存在着各种版本,各种定制下不同的编译参数,会大幅增加用java重写的成本,所以我们使用了Java跟C++结合的方式去实现ELF的符号表kv的提取,先用Java程序把ELF的基础信息,地址表读取出来,然后再用addr2line去遍历这个地址表,然后再把结果存入hbase,这个为100%的符号化成功率打下基础。

    0x03-1 addr2line的问题

    改进前后的对比

    改进前 改进后
    应用场景 十几个地址的符号化 批量的地址符号化
    QPS 50 800
    地址传递方式 参数,有限长度 文件,无限长度
    额外内存开销 1 0.7
    多任务模式 不支持 支持

    当然,这个addr2line,是要经过改造才能达到我们的要求,原来的addr2line是给开发者以单条命令去使用,不是给程序做批量查询的,每次查询都是要把整个ELF文件加载到内存,像UC内核,还有一些游戏的so文件,大小要到几百M的级别,每个addr2line进程都要一份独立的内存。假设一个500M的so符号,一台64核的机器,假如用60核去100%跑addr2line,加上其它开销,它就需要35G的内存。
    面对这么高的cpu和内存占用,而且是一个较低的QPS,单核大约100QPS,我们也尝试去优化addr2line的binutils中的bfd部分,但是最终的接口都是调用系统内核的,这条路,短期好像走不通。面对这样的性能问题,期间也多次尝试用Java去重写这部分逻辑,但是最终结果只能实现与addr2line的90%匹配度,而且还有很多未知的兼容性问题,最后还是选择了改造addr2line,改造点主要有以下三点:

    • 从文件读取地址表,使用批量请求去addr2line,减少bfd初始化的次数,因为这个过程中,bfd接口在调用一些特定的地址转换后,会导致qps降到个位数,需要重启进程才行;
    • 减少额外的内存开销;
    • 支持多进程,多容器分布式任务调度,支持动态扩缩容,提高资源利用率。

    改造后,单核的QPS大约提升到800QPS,上面举的500M的so符号的例子,大约需要15分钟,基本能满足我们的需求。

    0x03-2 存储的问题

    解决完提取的问题,接下来就是存储的问题。
    符号表都是经过精心设计的高度压缩的数据结构,我们通过上面的方案把它提取出kv的格式,容量上增加了10+倍,而且很多信息都是重复的,如函数名,文件名这些,虽然空间对于hbase来说不是什么问题,但是在追求极致的面前,我们还可以再折腾折腾。
    前面提到我们因为要考虑数据的安全性,需要把存入hbase的数据做加密,所以不能直接用hbase本身的压缩功能,要求在加密前先做好压缩,如果是按行压缩再加密,总体的压缩比不会太高,我们可以把00006740~000069eb这一段当成一个大段,把它们压缩在一起再加密,这样因为重复信息较多,压缩比会很高,最终的体积可以缩小5+倍,相当于只是比原始符号表大3~4倍。
    hbase rowkey的设计,因为后面的查询会需要用到scan,我们把符号表kv的结束地址作为rowkey的一部分,至于为什么这么设计,往下读,你就明白了。

    0x03-3 查询的问题

    根据0x01原理,对hbase的查询,需要get,scan的支持,get的话相对简单,直接通过rowkey命中就好了,适用于java符号化的场景,对于C++/OC的符号化,就需要scan的支持,因为地址是一个范围,不能用get直接命中,下面用伪代码举例说明scan的流程:

    //1. 扫描libxxx.so符号,地址范围0x00001234 ~ 0xffffffff, 只取一条结果
    //这里利用了scan的特性,我们存的rowkey是符号的结束地址,所以扫描出的第一个,
    //就是最接近0x00001234的一个符号
    raw = scan("libxxx.so", 0x00001234, 0xffffffff, limit=1);
    //2. 解密,解压,判断有效性预处理
    data = pre(raw);
    //3. 精确定位地址,根据0x04-2的打包存入,再做切割拆分
    result = splitData(data);


    旧系统我们只用了应用级的缓存,每次重启缓存就会丢失,为了减小hbase的压力,我们增加一级分布式缓存,使用redis作为缓存,进一步减少了末端的查询QPS。

    0x03-4 如果保证100%的符号化成功率

    我们知道,如果符号化失败,就会出现不一样的崩溃点,这样就不能把这些崩溃点聚合在一起,会把一些严重的问题分散掉,同时会产生很多新的崩溃点,导致开发,测试无法分辨真实的崩溃情况,我们使用以下技术保障成功率:

    • 高并发,低延迟的符号化查询服务,保障解析效率,防止超时出现符号化失败的情况;
    • 多级缓存保障,减少hbase的scan操作;
    • 使用原生addr2line提取符号kv;
    • 重试机制。

    0x04 总结

    0x04-1 符号化系统的核心能力

    通过几个平台的符号化反能力对比,我们可以看到岳鹰2.0取得的阶段性成果。

    对比项 方案1 方案2 方案3
    符号表入库速度
    内存占用 常态高 常态高 入库时高
    CPU占用 常态高 常态高 入库时高
    安全性
    可扩展性
    部署复杂度

    0x04-2 运行效果的提升

    指标 岳鹰1.0到2.0的提升
    CPU核心数 -50%
    平均CPU水位 -40%
    内存 持平
    符号入库速度(OC) +20%
    符号入库速度(Java) 持平
    符号入库速度(SO <= 100M) 持平
    符号入库速度(SO > 100M) 20分钟以内
    符号化响应速度 100ms -> 9ms
    容器化部署 全容器化



    0x05 欢迎免费试用

    岳鹰为阿里集团众多使用UC内核的app(如手淘,支付宝,天猫,钉钉,优酷等)提供内核so的崩溃符号化功能,实现了Java,Native C++的质量监控完整闭环,并在Native C++上的支持上明显优于其它竞品,开发者能快速地还原现场并找出问题,同时整个系统支持动态扩缩容,为更多业务接入打下了坚实的基础。
    更多功能,欢迎来岳鹰平台体验。

    ]]>
    一个秒杀系统的设计思考-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 秒杀大家都不陌生。自2011年首次出现以来,无论是双十一购物还是 12306 抢票,秒杀场景已随处可见。简单来说,秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。从架构视角来看,秒杀系统本质是一个高性能、高一致、高可用的三高系统。而打造并维护一个超大流量的秒杀系统需要进行哪些关注,就是本文讨论的话题。

    整体思考

    首先从高维度出发,整体思考问题。秒杀无外乎解决两个核心问题,一是并发读,一是并发写,对应到架构设计,就是高可用、一致性和高性能的要求。关于秒杀系统的设计思考,本文即基于此 3 层依次推进,简述如下——

    高性能
    秒杀涉及高读和高写的支持,如何支撑高并发,如何抵抗高IOPS?核心优化理念其实是类似的:高读就尽量“少读"或“读少",高写就数据拆分。本文将从动静分离、热点优化以及服务端性能优化 3 个方面展开。
    一致性
    秒杀的核心关注是商品库存,有限的商品在同一时间被多个请求同时扣减,而且要保证准确性,显而易见是一个难题。如何做到既不多又不少?本文将从业界通用的几种减库存方案切入,讨论一致性设计的核心逻辑。
    高可用:
    大型分布式系统在实际运行过程中面对的工况是非常复杂的,业务流量的突增、依赖服务的不稳定、应用自身的瓶颈、物理资源的损坏等方方面面都会对系统的运行带来大大小小的的冲击。如何保障应用在复杂工况环境下还能高效稳定运行,如何预防和面对突发问题,系统设计时应该从哪些方面着手?本文将从架构落地的全景视角进行关注思考。

    高性能

    动静分离
    大家可能会注意到,秒杀过程中你是不需要刷新整个页面的,只有时间在不停跳动。这是因为一般都会对大流量的秒杀系统做系统的静态化改造,即数据意义上的动静分离。动静分离三步走:1、数据拆分;2、静态缓存;3、数据整合。

    **数据拆分
    动静分离的首**要目的是将动态页面改造成适合缓存的静态页面。因此第一步就是分离出动态数据,主要从以下 2 个方面进行:
    1.用户。用户身份信息包括登录状态以及登录画像等,相关要素可以单独拆分出来,通过动态请求进行获取;与之相关的广平推荐,如用户偏好、地域偏好等,同样可以通过异步方式进行加载
    2.时间。秒杀时间是由服务端统一管控的,可以通过动态请求进行获取这里你可以打开电商平台的一个秒杀页面,看看这个页面里都有哪些动静数据。

    静态缓存
    分离出动静态数据之后,第二步就是将静态数据进行合理的缓存,由此衍生出两个问题:1、怎么缓存;2、哪里缓存

    怎么缓存:
    静态化改造的一个特点是直接缓存整个 HTTP 连接而不是仅仅缓存静态数据,如此一来,Web 代理服务器根据请求 URL,可以直接取出对应的响应体然后直接返回,响应过程无需重组 HTTP 协议,也无需解析 HTTP 请求头。而作为缓存键,URL唯一化是必不可少的,只是对于商品系统,URL 天然是可以基于商品 ID 来进行唯一标识的,比如淘宝的 https://item.taobao.com/item.htm?id=xxxx

    哪里缓存:
    静态数据缓存到哪里呢?可以有三种方式:1、浏览器;2、CDN ;3、服务端。
    浏览器当然是第一选择,但用户的浏览器是不可控的,主要体现在如果用户不主动刷新,系统很难主动地把消息推送给用户(注意,当讨论静态数据时,潜台词是 “相对不变”,言外之意是 “可能会变”),如此可能会导致用户端在很长一段时间内看到的信息都是错误的。对于秒杀系统,保证缓存可以在秒级时间内失效是不可或缺的。
    服务端主要进行动态逻辑计算及加载,本身并不擅长处理大量连接,每个连接消耗内存较多,同时 Servlet 容器解析 HTTP 较慢,容易侵占逻辑计算资源;另外,静态数据下沉至此也会拉长请求路径。
    因此通常将静态数据缓存在 CDN,其本身更擅长处理大并发的静态文件请求,既可以做到主动失效,又离用户尽可能近,同时规避 Java 语言层面的弱点。需要注意的是,上 CDN 有以下几个问题需要解决:
    1.失效问题。任何一个缓存都应该是有时效的,尤其对于一个秒杀场景。所以,系统需要保证全国各地的 CDN 在秒级时间内失效掉缓存信息,这实际对 CDN 的失效系统要求是很高的
    2.命中率问题。高命中是缓存系统最为核心的性能要求,不然缓存就失去了意义。如果将数据放到全国各地的 CDN ,势必会导致请求命中同一个缓存的可能性降低,那么命中率就成为一个问题
    因此,将数据放到全国所有的 CDN 节点是不太现实的,失效问题、命中率问题都会面临比较大的挑战。更为可行的做法是选择若干 CDN 节点进行静态化改造,节点的选取通常需要满足以下几个条件:
    临近访问量集中的地区
    距离主站较远的地区
    节点与主站间网络质量良好的地区
    基于以上因素,选择 CDN 的二级缓存比较合适,因为二级缓存数量偏少,容量也更大,访问量相对集中,这样就可以较好解决缓存的失效问题以及命中率问题,是当前比较理想的一种 CDN 化方案。部署方式如下图所示:
    图片1.png

    数据整合
    分离出动静态数据之后,前端如何组织数据页就是一个新的问题,主要在于动态数据的加载处理,通常有两种方案:ESI(Edge Side Includes)方案和 CSI(Client Side Include)方案。
    ESI 方案:Web 代理服务器上请求动态数据,并将动态数据插入到静态页面中,用户看到页面时已经是一个完整的页面。这种方式对服务端性能要求高,但用户体验较好。
    CSI 方案:Web 代理服务器上只返回静态页面,前端单独发起一个异步 JS 请求动态数据。这种方式对服务端性能友好,但用户体验稍差。

    小结
    动静分离对于性能的提升,抽象起来只有两点,一是数据要尽量少,以便减少没必要的请求,二是路径要尽量短,以便提高单次请求的效率。具体方法其实就是基于这个大方向进行的。
    **
    热点优化**
    热点分为热点操作和热点数据,以下分开进行讨论。
    热点操作
    零点刷新、零点下单、零点添加购物车等都属于热点操作。热点操作是用户的行为,不好改变,但可以做一些限制保护,比如用户频繁刷新页面时进行提示阻断。

    热点数据
    热点数据的处理三步走,一是热点识别,二是热点隔离,三是热点优化。

    1、热点识别
    热点数据分为静态热点和动态热点,具体如下:
    1.静态热点:能够提前预测的热点数据。大促前夕,可以根据大促的行业特点、活动商家等纬度信息分析出热点商品,或者通过卖家报名的方式提前筛选;另外,还可以通过技术手段提前预测,例如对买家每天访问的商品进行大数据计算,然后统计出 TOP N 的商品,即可视为热点商品
    2.动态热点:无法提前预测的热点数据。冷热数据往往是随实际业务场景发生交替变化的,尤其是如今直播卖货模式的兴起——带货商临时做一个广告,就有可能导致一件商品在短时间内被大量购买。由于此类商品日常访问较少,即使在缓存系统中一段时间后也会被逐出或过期掉,甚至在 DB 中也是冷数据。瞬时流量的涌入,往往导致缓存被击穿,请求直接到达 DB,引发 DB 压力过大

    因此秒杀系统需要实现热点数据的动态发现能力,一个常见的实现思路是:
    1.异步采集交易链路各个环节的热点 Key 信息,如 Nginx 采集访问 URL 或 Agent 采集热点日志(一些中间件本身已具备热点发现能力),提前识别潜在的热点数据
    2.聚合分析热点数据,达到一定规则的热点数据,通过订阅分发推送到链路系统,各系统根据自身需求决定如何处理热点数据,或限流或缓存,从而实现热点保护

    需要注意的是:
    1.热点数据采集最好采用异步方式,一方面不会影响业务的核心交易链路,一方面可以保证采集方式的通用性
    2.热点发现最好做到秒级实时,这样动态发现才有意义,实际上也是对核心节点的数据采集和分析能力提出了较高的要求

    2、热点隔离
    热点数据识别出来之后,第一原则就是将热点数据隔离出来,不要让 1% 影响到另外的 99%,可以基于以下几个层次实现热点隔离:
    1.业务隔离。秒杀作为一种营销活动,卖家需要单独报名,从技术上来说,系统可以提前对已知热点做缓存预热
    2.系统隔离。系统隔离是运行时隔离,通过分组部署和另外 99% 进行分离,另外秒杀也可以申请单独的域名,入口层就让请求落到不同的集群中
    3.数据隔离。秒杀数据作为热点数据,可以启用单独的缓存集群或者 DB 服务组,从而更好的实现横向或纵向能力扩展
    当然,实现隔离还有很多种办法。比如,可以按照用户来区分,为不同的用户分配不同的 Cookie,入口层路由到不同的服务接口中;再比如,域名保持一致,但后端调用不同的服务接口;又或者在数据层给数据打标进行区分等等,这些措施的目的都是把已经识别的热点请求和普通请求区分开来。

    3、热点优化
    热点数据隔离之后,也就方便对这 1% 的请求做针对性的优化,方式无外乎两种:
    1.缓存:热点缓存是最为有效的办法。如果热点数据做了动静分离,那么可以长期缓存静态数据
    2.限流:流量限制更多是一种保护机制。需要注意的是,各服务要时刻关注请求是否触发限流并及时进行review

    4、小结
    数据的热点优化与动静分离是不一样的,热点优化是基于二八原则对数据进行了纵向拆分,以便进行针对性地处理。热点识别和隔离不仅对“秒杀”这个场景有意义,对其他的高性能分布式系统也非常有参考价值。

    系统优化
    对于一个软件系统,提高性能可以有很多种手段,如提升硬件水平、调优JVM 性能,这里主要关注代码层面的性能优化——

    1.减少序列化:
    减少 Java 中的序列化操作可以很好的提升系统性能。序列化大部分是在 RPC 阶段发生,因此应该尽量减少 RPC 调用,一种可行的方案是将多个关联性较强的应用进行 “合并部署”,从而减少不同应用之间的 RPC 调用(微服务设计规范)

    2.直接输出流数据:
    只要涉及字符串的 I/O 操作,无论是磁盘 I/O 还是网络 I/O,都比较耗费 CPU 资源,因为字符需要转换成字节,而这个转换又必须查表编码。所以对于常用数据,比如静态字符串,推荐提前编码成字节并缓存,具体到代码层面就是通过 OutputStream() 类函数从而减少数据的编码转换;另外,热点方法 toString() 不要直接调用 ReflectionToString 实现,推荐直接硬编码,并且只打印 DO 的基础要素和核心要素

    3.裁剪日志异常堆栈:
    无论是外部系统异常还是应用本身异常,都会有堆栈打出,超大流量下,频繁的输出完整堆栈,只会加剧系统当前负载。可以通过日志配置文件控制异常堆栈输出的深度

    4.去组件框架:
    极致优化要求下,可以去掉一些组件框架,比如去掉传统的 MVC 框架,直接使用 Servlet 处理请求。这样可以绕过一大堆复杂且用处不大的处理逻辑,节省毫秒级的时间,当然,需要合理评估你对框架的依赖程度

    总结一下
    性能优化需要一个基准值,所以系统还需要做好应用基线,比如性能基线(何时性能突然下降)、成本基线(去年大促用了多少机器)、链路基线(核心流程发生了哪些变化),通过基线持续关注系统性能,促使系统在代码层面持续提升编码质量、业务层面及时下掉不合理调用、架构层面不断优化改进。

    一致性

    秒杀系统中,库存是个关键数据,卖不出去是个问题,超卖更是个问题。秒杀场景下的一致性问题,主要就是库存扣减的准确性问题。

    减库存的方式
    电商场景下的购买过程一般分为两步:下单和付款。“提交订单”即为下单,“支付订单”即为付款。基于此设定,减库存一般有以下几个方式:

    1.下单减库存。买家下单后,扣减商品库存。下单减库存是最简单的减库存方式,也是控制最为精确的一种

    2.付款减库存。买家下单后,并不立即扣减库存,而是等到付款后才真正扣减库存。但因为付款时才减库存,如果并发比较高,可能出现买家下单后付不了款的情况,因为商品已经被其他人买走了

    3.预扣库存。这种方式相对复杂一些,买家下单后,库存为其保留一定的时间(如 15 分钟),超过这段时间,库存自动释放,释放后其他买家可以购买
    能够看到,减库存方式是基于购物过程的多阶段进行划分的,但无论是在下单阶段还是付款阶段,都会存在一些问题,下面进行具体分析。

    减库存的问题

    下单减库存
    优势:用户体验最好。下单减库存是最简单的减库存方式,也是控制最精确的一种。下单时可以直接通过数据库事务机制控制商品库存,所以一定不会出现已下单却付不了款的情况。
    劣势:可能卖不出去。正常情况下,买家下单后付款概率很高,所以不会有太大问题。但有一种场景例外,就是当卖家参加某个促销活动时,竞争对手通过恶意下单的方式将该商品全部下单,导致库存清零,那么这就不能正常售卖了——要知道,恶意下单的人是不会真正付款的,这正是 “下单减库存” 的不足之处。

    付款减库存
    优势:一定实际售卖。“下单减库存” 可能导致恶意下单,从而影响卖家的商品销售, “付款减库存” 由于需要付出真金白银,可以有效避免。
    劣势:用户体验较差。用户下单后,不一定会实际付款,假设有 100 件商品,就可能出现 200 人下单成功的情况,因为下单时不会减库存,所以也就可能出现下单成功数远远超过真正库存数的情况,这尤其会发生在大促的热门商品上。如此一来就会导致很多买家下单成功后却付不了款,购物体验自然是比较差的。

    预扣库存
    优势:缓解了以上两种方式的问题。预扣库存实际就是“下单减库存”和 “付款减库存”两种方式的结合,将两次操作进行了前后关联,下单时预扣库存,付款时释放库存。
    劣势:并没有彻底解决以上问题。比如针对恶意下单的场景,虽然可以把有效付款时间设置为 10 分钟,但恶意买家完全可以在 10 分钟之后再次下单。

    小结:
    减库存的问题主要体现在用户体验和商业诉求两方面,其本质原因在于购物过程存在两步甚至多步操作,在不同阶段减库存,容易存在被恶意利用的漏洞。

    实际如何减库存

    业界最为常见的是预扣库存。无论是外卖点餐还是电商购物,下单后一般都有个 “有效付款时间”,超过该时间订单自动释放,这就是典型的预扣库存方案。但如上所述,预扣库存还需要解决恶意下单的问题,保证商品卖的出去;另一方面,如何避免超卖,也是一个痛点。

    卖的出去:恶意下单的解决方案主要还是结合安全和反作弊措施来制止。比如,识别频繁下单不付款的买家并进行打标,这样可以在打标买家下单时不减库存;再比如为大促商品设置单人最大购买件数,一人最多只能买 N 件商品;又或者对重复下单不付款的行为进行次数限制阻断等。

    避免超卖:库存超卖的情况实际分为两种。对于普通商品,秒杀只是一种大促手段,即使库存超卖,商家也可以通过补货来解决;而对于一些商品,秒杀作为一种营销手段,完全不允许库存为负,也就是在数据一致性上,需要保证大并发请求时数据库中的库存字段值不能为负,一般有多种方案:一是在通过事务来判断,即保证减后库存不能为负,否则就回滚;二是直接设置数据库字段类型为无符号整数,这样一旦库存为负就会在执行 SQL 时报错;三是使用 CASE WHEN 判断语句:

    UPDATE item SET inventory
    CASE WHEN inventory
    xxx THEN inventory
    xxx ELSE inventory

    业务手段保证商品卖的出去,技术手段保证商品不会超卖,库存问题从来就不是简单的技术难题,解决问题的视角是多种多样的。

    一致性性能的优化
    库存是个关键数据,更是个热点数据。对系统来说,热点的实际影响就是 “高读” 和 “高写”,也是秒杀场景下最为核心的一个技术难题

    高并发读
    秒杀场景解决高并发读问题,关键词是“分层校验”。即在读链路时,只进行不影响性能的检查操作,如用户是否具有秒杀资格、商品状态是否正常、用户答题是否正确、秒杀是否已经结束、是否非法请求等,而不做一致性校验等容易引发瓶颈的检查操作;直到写链路时,才对库存做一致性检查,在数据层保证最终准确性。

    因此,在分层校验设定下,系统可以采用分布式缓存甚至 LocalCache 来抵抗高并发读。即允许读场景下一定的脏数据,这样只会导致少量原本无库存的下单请求被误认为是有库存的,等到真正写数据时再保证最终一致性,由此做到高可用和一致性之间的平衡。

    实际上,分层校验的核心思想是:不同层次尽可能过滤掉无效请求,只在“漏斗” 最末端进行有效处理,从而缩短系统瓶颈的影响路径。

    高并发写
    高并发写的优化方式,一种是更换 DB 选型,一种是优化 DB 性能,以下分别进行讨论。

    1、更换DB选型
    秒杀商品和普通商品的减库存是有差异的,核心区别在数据量级小、交易时间短,因此能否把秒杀减库存直接放到缓存系统中实现呢,也就是直接在一个带有持久化功能的缓存中进行减库存操作,比如 Redis?

    如果减库存逻辑非常单一的话,比如没有复杂的 SKU 库存和总库存这种联动关系的话,个人认为是完全可以的。但如果有比较复杂的减库存逻辑,或者需要使用到事务,那就必须在数据库中完成减库存操作。

    2、优化DB性能
    库存数据落地到数据库实现其实是一行存储(MySQL),因此会有大量线程来竞争 InnoDB 行锁。但并发越高,等待线程就会越多,TPS 下降,RT 上升,吞吐量会受到严重影响——注意,这里假设数据库已基于上文【性能优化】完成数据隔离,以便于讨论聚焦 。

    解决并发锁的问题,有两种办法:

    应用层排队。
    通过缓存加入集群分布式锁,从而控制集群对数据库同一行记录进行操作的并发度,同时也能控制单个商品占用数据库连接的数量,防止热点商品占用过多的数据库连接

    数据层排队。
    应用层排队是有损性能的,数据层排队是最为理想的。业界中,阿里的数据库团队开发了针对 InnoDB 层上的补丁程序(patch),可以基于 DB 层对单行记录做并发排队,从而实现秒杀场景下的定制优化——注意,排队和锁竞争是有区别的,如果熟悉 MySQL 的话,就会知道 InnoDB 内部的死锁检测,以及 MySQL Server 和 InnoDB 的切换都是比较消耗性能的。另外阿里的数据库团队还做了很多其他方面的优化,如 COMMIT_ON_SUCCESS 和 ROLLBACK_ON_FAIL 的补丁程序,通过在 SQL 里加入提示(hint),实现事务不需要等待实时提交,而是在数据执行完最后一条 SQL 后,直接根据 TARGET_AFFECT_ROW 的结果进行提交或回滚,减少网络等待的时间(毫秒级)。目前阿里已将包含这些补丁程序的 MySQL 开源:AliSQL

    小结:
    高读和高写的两种处理方式大相径庭。读请求的优化空间要大一些,而写请求的瓶颈一般都在存储层,优化思路的本质还是基于 CAP 理论做平衡。
    总结一下:
    当然,减库存还有很多细节问题,例如预扣的库存超时后如何进行回补,再比如第三方支付如何保证减库存和付款时的状态一致性,这些也是很大的挑战。

    高可用

    盯过秒杀流量监控的话,会发现它不是一条蜿蜒而起的曲线,而是一条挺拔的直线,这是因为秒杀请求高度集中于某一特定的时间点。这样一来就会造成一个特别高的零点峰值,而对资源的消耗也几乎是瞬时的。所以秒杀系统的可用性保护是不可或缺的。

    流量削峰
    对于秒杀的目标场景,最终能够抢到商品的人数是固定的,无论 100 人和 10000 人参加结果都是一样的,即有效请求额度是有限的。并发度越高,无效请求也就越多。但秒杀作为一种商业营销手段,活动开始之前是希望有更多的人来刷页面,只是真正开始后,秒杀请求不是越多越好。因此系统可以设计一些规则,人为的延缓秒杀请求,甚至可以过滤掉一些无效请求。

    答题
    早期秒杀只是简单的点击秒杀按钮,后来才增加了答题。为什么要增加答题呢?主要是通过提升购买的复杂度,达到两个目的:
    1.防止作弊。早期秒杀器比较猖獗,存在恶意买家或竞争对手使用秒杀器扫货的情况,商家没有达到营销的目的,所以增加答题来进行限制
    2.延缓请求。零点流量的起效时间是毫秒级的,答题可以人为拉长峰值下单的时长,由之前的 <1s 延长到 <10s。这个时间对于服务端非常重要,会大大减轻高峰期并发压力;另外,由于请求具有先后顺序,答题后置的请求到来时可能已经没有库存了,因此根本无法下单,此阶段落到数据层真正的写也就非常有限了

    排队
    最为常见的削峰方案是使用消息队列,通过把同步的直接调用转换成异步的间接推送缓冲瞬时流量。除了消息队列,类似的排队方案还有很多,例如:
    1.线程池加锁等待
    2.本地内存蓄洪等待
    3.本地文件序列化写,再顺序读
    排队方式的弊端也是显而易见的,主要有两点:
    1.请求积压。流量高峰如果长时间持续,达到了队列的水位上限,队列同样会被压垮,这样虽然保护了下游系统,但是和请求直接丢弃也没多大区别
    2.用户体验。异步推送的实时性和有序性自然是比不上同步调用的,由此可能出现请求先发后至的情况,影响部分敏感用户的购物体验
    排队本质是在业务层将一步操作转变成两步操作,从而起到缓冲的作用,但鉴于此种方式的弊端,最终还是要基于业务量级和秒杀场景做出妥协和平衡。

    过滤
    过滤的核心结构在于分层,通过在不同层次过滤掉无效请求,达到数据读写的精准触发。常见的过滤主要有以下几层:
    1.读限流:对读请求做限流保护,将超出系统承载能力的请求过滤掉
    2.读缓存:对读请求做数据缓存,将重复的请求过滤掉
    3.写限流:对写请求做限流保护,将超出系统承载能力的请求过滤掉
    4.写校验:对写请求做一致性校验,只保留最终的有效数据
    过滤的核心目的是通过减少无效请求的数据 IO 保障有效请求的 IO 性能。

    小结:
    系统可以通过入口层的答题、业务层的排队、数据层的过滤达到流量削峰的目的,本质是在寻求商业诉求与架构性能之间的平衡。另外,新的削峰手段也层出不穷,以业务切入居多,比如零点大促时同步发放优惠券或发起抽奖活动,将一部分流量分散到其他系统,这样也能起到削峰的作用。

    Plan B
    当一个系统面临持续的高峰流量时,其实是很难单靠自身调整来恢复状态的,日常运维没有人能够预估所有情况,意外总是无法避免。尤其在秒杀这一场景下,为了保证系统的高可用,必须设计一个 Plan B 方案来进行兜底。

    高可用建设,其实是一个系统工程,贯穿在系统建设的整个生命周期。
    图片2.png

    具体来说,系统的高可用建设涉及架构阶段、编码阶段、测试阶段、发布阶段、运行阶段,以及故障发生时,逐一进行分析:

    架构阶段:考虑系统的可扩展性和容错性,避免出现单点问题。例如多地单元化部署,即使某个 IDC 甚至地市出现故障,仍不会影响系统运转

    编码阶段:保证代码的健壮性,例如 RPC 调用时,设置合理的超时退出机制,防止被其他系统拖垮,同时也要对无法预料的返回错误进行默认的处理

    测试阶段:保证 CI 的覆盖度以及 Sonar 的容错率,对基础质量进行二次校验,并定期产出整体质量的趋势报告

    发布阶段:系统部署最容易暴露错误,因此要有前置的 checklist 模版、中置的上下游周知机制以及后置的回滚机制

    运行阶段:系统多数时间处于运行态,最重要的是运行时的实时监控,及时发现问题、准确报警并能提供详细数据,以便排查问题

    故障发生:首要目标是及时止损,防止影响面扩大,然后定位原因、解决问题,最后恢复服务

    对于日常运维而言,高可用更多是针对运行阶段而言的,此阶段需要额外进行加强建设,主要有以下几种手段:

    预防:建立常态压测体系,定期对服务进行单点压测以及全链路压测,摸排水位

    管控:做好线上运行的降级、限流和熔断保护。需要注意的是,无论是限流、降级还是熔断,对业务都是有损的,所以在进行操作前,一定要和上下游业务确认好再进行。就拿限流来说,哪些业务可以限、什么情况下限、限流时间多长、什么情况下进行恢复,都要和业务方反复确认

    监控:建立性能基线,记录性能的变化趋势;建立报警体系,发现问题及时预警

    恢复:遇到故障能够及时止损,并提供快速的数据订正工具,不一定要好,但一定要有

    在系统建设的整个生命周期中,每个环节中都可能犯错,甚至有些环节犯的错,后面是无法弥补的或者成本极高的。所以高可用是一个系统工程,必须放到整个生命周期中进行全面考虑。同时,考虑到服务的增长性,高可用更需要长期规划并进行体系化建设。

    总结一下:
    高可用其实是在说 “稳定性”,稳定性是一个平时不重要,但出了问题就要命的事情,然而它的落地又是一个问题——平时业务发展良好,稳定性建设就会降级给业务让路。解决这个问题必须在组织上有所保障,比如让业务负责人背上稳定性绩效指标,同时在部门中建立稳定性建设小组,小组成员由每条线的核心力量兼任,绩效由稳定性负责人来打分,这样就可以把体系化的建设任务落实到具体的业务系统中了。

    个人总结
    一个秒杀系统的设计,可以根据不同级别的流量,由简单到复杂打造出不同的架构,本质是各方面的取舍和权衡。当然,你可能注意到,本文并没有涉及具体的选型方案,因为这些对于架构来说并不重要,作为架构师,应该时刻提醒自己主线是什么。

    同时也在这里抽象、提炼一下,主要是个人对于秒杀设计的提纲式整理,方便各位同学进行参考!

    图片3.png

    ]]>
    展望下一代医疗集成平台-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800  【导读】 医疗信息集成在我国医院信息化的发展中,已经落地实施了将近十年。这十年间,信息集成平台的建设,从一、两家的最佳实践案例到全国医院的大规模实施,再到国家卫健委的互联互通标准化测评,已经经过了行业内的充分论证与实践,取得了蓬勃的发展。那么,究竟集成平台需要具备哪些特性,才能更好地满足:1) 区域共享;2)数据应用;3)资源贯通;4)业务协同?

    集成平台:在线增量备份与任意时间点恢复

    集成平台承载了医院的核心业务,因而从保障业务连续性角度必须做到有“备”而无患,常见的解决方案有双机冷备和双机热备。
    总体说来,双机即两台服务器,一台主机(Master)运行(Active),一台备用(Slave) 机待命(Stand-by)。一旦主机宕机,由备用机临时接管工作。冷备需手动切换到备用机,热备可实现自动切换。 双机热备将数据在主机和备机中自动同步,主机宕机自动切换至副机,保证系统高可用性和业务连续性。

    冷备份, 以及逻辑备份都是某一个时间点的备份, 没有增量的概念。如果数据库在运行过程中发生故障, 使用逻辑备份只能将数据库还原到备份时刻, 无法恢复到故障发生前的那个时刻。并且无法解决在使用过程中由于误操作修改或删除了重要数据, 需要还原到误操作前的那个时刻等类似需求。使用冷备份加上有效的归档文件可以实现任意时间点的恢复。但是冷备份需要停库操作, 无法保障医院的核心业务的连续性。

    所以新一代集成平台需要支持在线的增量备份, 同时又支持基于时间点的恢复。

    集成引擎、ESB、ETL:“三合一”

    无论医院级别大小,各医疗机构系统情况不一,集成需求多样化,对集成+ESB+ETL的混合型业务需求日益增多。

    将强调消息有序性和保证传输的集成引擎,着重服务的ESB、和数据抽取转换上报(ETL)功能三合一至一个中间件,使得医院不必购买多套软件产品,集成平台的使用和维护也变得更加便捷,并且提高了集成平台的综合性能和稳定性。

    内嵌国内CDA标准:涵盖医院和区域

    将国内 CDA 标准(《电子病历共享文档规范》及《卫生信息共享文档》)内嵌至下一代集成平台,提供用户对CDA及数据集进行自定义的功能,满足实际互联互通项目实施时的微调需求。界面包含清晰的互联互通服务的统计信息,进一步助力互联互通测评工作,满足各级各类医院集成平台信息传输与交换层面的规范、统一需求,助力实现医院信息平台跨机构、跨区域交换与共享,有力促进业务协同;

    CDAAAA.jpg

    对大数据系统的内嵌支持:Hadoop, Kafka

    随着医院信息化建设不断发展,医疗数据规模日益增长,医疗服务全面进入“大数据时代”。下一代集成平台需要以临床数据为核心,采用智能化的双向数据采集工具,实时聚集各类医疗业务数据,进行标准化处理,搭建主题数据仓库,形成高质量的大数据资产,结合人工智能算法和数据分析模型,满足医院信息共享与应用的需求。

    数据中心.jpg

    由此可见,集成平台的对大数据系统的支持日显重要。集成平台可内嵌支持对HDFS分布式文件系统的读写访问操作;也可以通过Phoenix进行桥接对Hadoop 系统操作;提供连接Kafka系统的终端实现对Kafka 分布式流平台支持,实现对大数据的支持。

    展望下一代医疗集成平台

    预见到,未来医院和区域信息平台的发展呈现如下趋势:
    分布式集群部署,保障服务稳定,可动态扩展
    完善的标准化原子服务库,满足医院业务需求
    图形化服务配置,快速实现服务封装发布
    支持海量数据实时采集,采用分布式集群模式
    全面整合医院数据资源,形成有效的数据资产,深度挖掘数据价值
    遵循国卫标准,符合HL7、CDA及IHE等标准
    提供丰富的适配器组件,满足各种接入需求

    ]]>
    Istio 网关之南北向流量管理(内含服务网格专家亲自解答)-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 Istio 网关

    网络社区中有一个术语 Ingress,是指入口请求到集群内服务的流量管理。Ingress 指的是源自本地网络之外的流量,指向本地集群网络中的端点。此流量首先路由到公开的入口点,以便通过执行一些本地网络的规则和策略来确认哪些流量被允许进入。如果流量未通过这些入口点,则无法与集群内的任何服务连接。如果入口点允许流量进入,则将其代理到本地网络中的合适节点。Istio 对入口流量的管理是由 Istio 网关进行的。

    Istio 网关的工作原理

    传统上,Kubernetes 使用 Ingress 控制器来处理从外部进入集群的流量。使用 Istio 时,情况不再如此。Istio 网关用新的 Gateway 资源和 VirtualServices 资源来控制入口流量,它们协同工作以将流量路由到网格中。在网格内部不需要 Gateways,因为服务可以通过集群本地服务名称相互访问。

    那么 Istio 网关是怎样工作的?请求如何到达它想要的应用程序?基本步骤如下:

    1.客户端在特定端口上发出请求;
    2.负载均衡器在这个端口上进行侦听,并将请求转发到集群中(在相同或新的端口);
    3.在集群内部,请求被路由到 Istio IngressGateway 服务所侦听的负载均衡器转发过来的端口上;
    4.Istio IngressGateway 服务将请求(在相同或新的端口)转发到对应的 pod 上;
    5.在 IngressGateway pod 上会配置 Gateway 资源和 VirtualService 资源定义。Gateway 会配置端口、协议以及相关安全证书。VirtualService 的路由配置信息用于找到正确的服务;
    6.Istio IngressGateway pod 会根据路由配置信息将请求路由到对应的应用服务上;
    7.应用服务将请求路由到对应的应用 pod 上。

    image.png

    (tio 网关的工作原理)

    Istio 网关的负载均衡作用

    典型的服务网格具有一个或多个负载均衡器,也称为网关(Gateway),它们从外部网络终止 TLS 并允许流量进入网格。然后,流量通过边车网关(Sidecar gateway)流经内部服务。应用程序使用外部服务的场景也很常见,可以直接调用外部服务,或者在某些部署中强制通过专用出口网关(Egress Gateway)离开网格的所有流量。

    Istio 具有入口网关的概念,它扮演网络入口点的角色,负责保护和控制来自集群外部的流量对集群的访问。

    image.png
    (网关在网格中的使用情况)

    此外,Istio 的网关还扮演负载均衡和虚拟主机路由的角色。如图所示,可以看到默认情况下 Istio 使用 Envoy 代理作为入口代理。Envoy 是一个功能强大的服务到服务代理,但它也有负载均衡和路由的功能,可代理的流量包括从服务网格外部到其内部运行的服务,或者从集群内部服务到外部服务。在前面章节中介绍的 Envoy 的所有功能也可以在入口网关中使用。

    image.png
    (Istio 的入口网关服务)

    对于入口流量管理,你可能会问:为什么不直接使用 Kubernetes Ingress API?

    • 第一个原因,Kubernetes Ingress 是一个面向 HTTP 工作负载的非常简单的规范。有 Kubernetes Ingress 的实现(如 Nginx、Heptio Contour 等),但每个都适用于 HTTP 流量。实际上,Ingress 规范只将端口 80 和端口 443 视为入口点。这严重限制了集群运维人员可以允许进入服务网格的流量类型。例如,如果你有 Kafka 工作负载,则可能希望向这些消息代理公开直接 TCP 连接;
    • 第二个原因,Kubernetes Ingress API 无法表达 Istio 的路由需求。Ingress 没有通用的方法来指定复杂的流量路由规则,如流量拆分或流量镜像等。这个领域缺乏规范会导致每个供应商重新设想如何更好地为每种类型的 Ingress 实现(如 HAProxy、Nginx 等)做好配置管理。Ingress 试图在不同的 HTTP 代理之间取一个公共的交集,因此只能支持最基本的 HTTP 路由;
    • 最后一个原因,由于事前没有明确规定,大多数供应商的选择是通过部署上的定制注释来做配置。供应商之间的注释各不相同,并且不可移植,如果 Istio 继续延续这种趋势,那么就会有更多的注释来解释 Envoy 作为边缘网关的所有功能。

    Istio 网关通过将 L4-L6 配置与 L7 配置分离克服了 Ingress 的这些缺点。Istio 网关只用于配置 L4-L6 功能(例如,对外公开的端口、TLS 配置),所有主流的 L7 代理均以统一的方式实现了这些功能。然后,通过在 Gateway 上绑定 VirtualService 的方式,可以使用标准的 Istio 规则来控制进入 Gateway 的 HTTP 和 TCP 流量。负载均衡器可以手动配置或通过服务自动配置其类型,例如 type: LoadBalancer。在这种情况下,由于并非所有云都支持自动配置,假设手动配置负载均衡器以将流量转发到 IngressGateway Service 正在侦听的端口。例如如下的负载均衡器正在监听以下端口:

    • HTTP:端口 80,将流量转发到端口 30080;
    • HTTPS:端口 443,将流量转发到端口 30443;
    • MySQL:端口 3306,将流量转发到端口 30306 确保负载均衡器配置转发到所有工作节点。这将确保即使某些节点关闭也会转发流量。

    入口网关服务

    IngressGateway 服务(入口网关服务)必须监听上节介绍的所有端口,以便能够将流量转发到 IngressGateway pod 上。Kubernetes 服务不是“真正的”服务,该请求将由 Kubernetes 提供的 kube-proxy 转发到具有运行对应 pod 的节点上。在节点上,IP table 配置将请求转发到适当的 pod:

    ports:

    • name: http2
      nodePort: 30000
      port: 80
      protocol: TCP
    • name: https
      nodePort: 30443
      port: 443
      protocol: TCP
    • name: mysql
      nodePort: 30306
      port: 3306
      protocol: TCP

    入口网关部署

    IngressGateway 部署是一个基于 Envoy 代理的封装,它的配置方式与服务网格中使用的 Sidecar 配置相同(实际上是同样的容器镜像)。当我们创建或更改一个 Gateway 或 VirtualService 时,Istio Pilot 控制器会检测到这些变更,并将这些变更信息转换为 Envoy 配置,然后将 Envoy 配置信息发送给相关 Envoy 代理,包括内部的 Envoy 和 IngressGateway 中的 Envoy。

    注意:这里不要混淆 IngressGateway 与 Gateway,Gateway 资源是用于配置 IngressGateway 的一种 Kubernetes 的自定义资源。

    由于不必在 Kubernetes pod 或部署中声明容器端口,因此我们不必在 IngressGateway Deployment 中声明端口。但是,如果查看部署内部,可以看到声明的许多端口。另外,在 IngressGateway 部署中需要关注 SSL 证书,为了能够访问 Gateway 资源内的证书,请确保已正确加载这些证书。

    网关资源

    网关资源用来配置 Envoy 的端口,前面的示例中已经使用该服务公开了三个端口,因此需要在 Envoy 中处理这些端口。此外,可以通过声明一个或多个 Gateways 来支持多端口能力。下面的示例中使用单个 Gateway,但可以分为两个或三个分别定义:

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
    name: default-gateway
    namespace: istio-system
    spec:
    selector:

    istio: ingressgateway

    servers:

    • hosts:

      • '*'
        port:

      name: http
      number: 80
      protocol: HTTP

    • hosts:

      • '*'
        port:

      name: https
      number: 443
      protocol: HTTPS
      tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

    • hosts: # For TCP routing this fields seems to be ignored, but it is matched

      • '' # with the VirtualService, I use since it will match anything.
        port:

      name: mysql
      number: 3306
      protocol: TCP

    网关虚拟服务

    VirtualService 资源与 Gateway 资源相互配合支持 Envoy 的配置。下面是一个支持 HTTP 服务的网关虚拟服务的基本配置:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
    name: counter
    spec:
    gateways:

    • default-gateway.istio-system.svc.cluster.local
      hosts:
    • counter.lab.example.com
      http:
    • match:

      • uri:
        prefix: /

      route:

      • destination:

        host: counter
        port:
          number: 80
        

    现在,当我们添加一个 Gateway 和一个 VirtualService 时,路由已在 Envoy 配置中创建。要查看此内容,你可以使用如下命令:

    kubectl port-forward istio-ingressgateway-xxxx-yyyy-n istio-system 15000

    调试入口网关

    调试网络问题有时很困难,所以这里总结一些有用的命令用于调试。端口转发到第一个 istio-ingressgateway pod:

    kubectl -n istio-system port-forward $(kubectl -n istio-system get pods
    -listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") 15000

    然后,可以从端口转发的入口网关 pod 中获得 http 路由:

    Curl --silent http://localhost:15000/config_dump |jq .configs[3].dynamic_route_configs[].route_config.virtual_hosts[]

    image.png
    (端口转发的入口网关 pod)

    查看上述端口转发的入口网关 pod 的日志信息:

    kubectl -n istio-system logs $(kubectl -n istio-system get pods
    -listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") --tail=300

    查看 Pilot pod 的日志信息:

    kubectl -n istio-system logs $(kubectl -n istio-system get pods
    -listio=pilot -o=jsonpath="{.items[0].metadata.name}") discovery --tail=300

    当启动端口转发到入口网关 istio-ingressgateway 之后,可以执行更多操作以获取更多信息,例如:

    关于 Istio 的一些 Q&A

    Q1:Istio 在实际生产环境实践中都会遇到哪些瓶颈,常见的优化手段又都有哪些?
    A1:阿里云之所以推出服务网格 ASM 这个产品,就是把过去一两年支持客户使用 Istio 的过程中遇到的太多问题,总结成了经验并落地到产品中。所以多关注下这个产品的能力就会看到具体解决了哪些问题。在此就不一一赘述了。

    Q2:Istio 会导致性能消耗增加吗?
    A2:这个问题需要一个上下文,这就像问 Java 虚拟机会导致性能消耗吗。任何解耦总会带来一定的通信消耗。建议使用 Istio 前先判断下自己的应用是否适合解耦、服务化以及容器化,然后再看是否适合采用 Istio 的哪些功能。

    Q3:Service Mesh 是很好的工具,但是痛点也很明显,引入 Istio 会让运维更加复杂,阿里云服务网格产品 ASM 这方面有做什么改进?
    A3:阿里云服务网格 ASM 提供了一个全托管式的服务网格平台,兼容于社区 Istio 开源服务网格,用于简化服务的治理,并提供了简单易用的控制台,托管模式下让用户解脱控制面的复杂管理,极大地减轻开发与运维的工作负担。具体可以参考这个入门教程了解一下:https://help.aliyun.com/document_detail/149552.html

    Q4:最近在研究 Istio,有真正落地使用的例子吗?
    A4:过去一两年我们已经支持了大量客户使用 Istio,譬如有客户使用 Istio 流量管理来做应用的灰度发布,有客户使用它的统一的声明式的方式来管理入口网关,包括入口网关的 tls 透传功能、tls 终止以及动态加载证书的能力等等。

    Q5:目前阿里服务网格产品 ASM 针对 Istio 采用什么样的监控?
    A5:阿里云服务网格 ASM 的可观测性能力从三个维度提供了不同的能力,包括:

    Q6:阿里的 ASM 的 Proxy 会采用 MOSN 吗?期待 MOSN 成为 Istio 可选数据平面之一。
    A6:阿里云服务网格 ASM 从一开始的设计就是兼容于社区 Istio 开源服务网格,只要符合与 Istio 控制面规约要求的数据面代理,从理论上都是可以支持的。当然一个新代理的适配是需要一定量的开发工作,这儿我们也想了解下客户对于这方面的诉求。

    Q7:Istio 也有类似 Linkerd 的 mutls 功能吗?
    A7:Istio 默认已经提供了双向 tls 认证的功能,而且支持渐进式,包括 permissive 和 strict 两种方式。

    本文转自<阿里巴巴云原生技术圈>——阿里巴巴云原生小助手

    ]]>
    做深基础,助力新基建,阿里云多款存储产品正式发布-阿里云开发者社区 Sat, 04 Jul 2020 09:33:04 +0800 6月23日,阿里云存储新品发布会再次来袭,在数字新基建时代,阿里云存储产品将沿着“做深基础”的再生长方向,全面助力客户的数字化转型之路。
    lADPD2eDMulZQEnNAe3NAww_780_493.jpg

    1、日志服务SLS,进一步打造AI-DevOps的平台与生态

    阿里云推出的日志服务SLS已经成为行业领先的日志大数据平台,提供一站式数据采集、清洗、存储、分析、可视化和告警的功能。此次,日志服务SLS的时序监控与诊断平台正式发布,除了提供海量日志处理能力,还支持了时序监控数据存储与分析,提供更加便捷、高性能、低成本的时序监控诊断解决方案。
    日志.png

    同时,日志服务SLS发布了SIEM(Security information and event management ) 和 SOC(Security Operations Center)开放对接能力,企业客户可以利用日志服务SLS的日志统一采集和清洗能力,将云上系统的合规、安全等相关日志,统一导入到现有的安全运营中心(SOC)。本次,日志服务SLS的日志审计功能,也新增更多产品的覆盖,并提供修改删除保护策略,支持多账号、多地域、多产品的日志统一采集,并且开放与第三方SOC对接,更好地服务企业构建日志统一审计中心。此外,日志服务SLS还发布了K8S事件中心,满足客户在微服务、容器的技术趋势下,一站式对Kurbernets事件的实时采集、分析、告警和可视化需求。

    日志服务SLS已支持20多款云产品日志支持一键接入,并提供了分析模板、内置报表。本次发布,日志服务新增了IoT、Redis、MaxCompute日志源一键接入与分析,满足用户对IoT设备状态、Redis审计或慢请求和错误请求、MaxCompute操作日志的分析、异常告警、统计报表等需要。

    2、对象存储OSS,支持国密算法

    在安全这方面,合规监管以及安全性的要求将越来越严格,为了满足安全合规方面的诉求,对象存储OSS在原有的服务端加密功能的基础上,全面支持了国密算法。

    阿里云对象存储在加密方面的功能十分完善,不仅能支持用户可见、可管理的BYOK加密,同时能支持全托管加密方式以及基于KMS平台管理的加密方式,基于这三种不同的加密方式,在原有的仅支持AES256算法的基础上,又进一步的开发了对国密算法的支持,丰富了阿里云对象存储对加密算法的支持度,更好的满足了企业客户在安全合规上多维度的需求。

    除新的加密算法之外,对象存储OSS还针对数据湖场景中,临时目录中的文件重命名功能进行了优化,当对象存储接收到数据重命名的指令时,直接快速更新对象对应的元数据,而对象本身不做任何的操作,从而快速的实现文件的重命名动作,并达到亚秒级别的数据返回效率,实现“瞬时拷贝”。
    瞬间拷贝.jpg

    阿里云对象存储OSS还推出了Bucket 清单功能,只需要在控制台做简单的配置就可以定期地获取到针对Bucket粒度所有Object的列表,同时可以针对某个目录级别(前缀)来做分目录的清单导出,数据导出后可以根据业务诉求来做针对性的分析与处理。除此之外,Bucket 清单功能还能够与阿里云日志服务SLS结合使用实现业务数据分析的智能化与可视化。

    3、表格存储Tablestore,支持投递OSS,全面进入数据湖生态

    表格存储Tablestore是基于共享存储的高性能、低成本、易扩展、全托管的结构化大数据存储平台,支撑互联网、物联网等数据的高效计算与分析。目前,表格存储Tablestore作为承载钉钉核心消息系统的存储产品,经受住了移动办公浪潮的艰巨考验。

    此次,表格存储Tablestore发布了数据投递对象存储OSS功能,打造了一个可实现数据分层的数据湖方案。

    表格存储.png

    数据投递对象存储OSS兼容开源生态标准,支持按照Parquet等格式存储,支持Hive命名约定,无缝兼容Spark等计算生态。同时数据投递自动实时同步,可一键完成配置,无需维护复杂的datapipeline。基于这些特点,一方面针对近期的数据,表格存储Tablestore可以保证数据的实时可见性,支持数据点查与多维度检索,以及近期数据的分析查询;另一方面针对离线数据,投递对象存储OSS数据湖,实现分析的高效与成本的可控。

    在这样的数据湖方案中,表格存储Tablestore可以更好的发挥应用中数据的价值,广泛在电商、短视频、新闻等需要支持海量结构化数据存储、实时或离线分析的应用场景中,帮助客户更快、更省地对数据进行应用与分析。

    4、混合云存储网关,让上云更简单

    云存储网关以阿里云对象存储OSS为后端存储,为企业应用提供行业标准的文件存储(NFS/SMB)和iSCSI块存储等服务。云存储网关可以部署在客户数据中心,也可以部署在阿里云上,帮助客户简化存储管理,实现企业应用和阿里云存储服务的无缝对接。

    首先,云存储网关基于对象存储OSS,提供海量存储空间、智能对接低频/归档存储,冷热数据分层以及灵活的付费方式进一步降低TCO;其次,企业应用无需改造平滑上云,端到端数据加密保证客户数据安全;再次,在企业数据平滑上云、文件应用对接云存储、备份/归档、视频监控、机器学习等场景,云存储网关具有广泛的应用;最后,云存储网关集成了智能缓存算法,自动识别冷热数据,将热数据保留本地在本地缓存,保证数据访问体验,无感知的将海量云存储接入本地数据中心,拓展存储空间。同时在云端保留全量数据(冷+热)保证数据的一致性。

    在实际工作中,企业的分支机构之间数据的及时共享以及协作一直以来都是很大的挑战,云存储网关在配合对象存储OSS,同时借助传输加速等方案,帮助客户解决了多站点数据共享的问题,实现了全球多站点文件共享(Multi-site Sync and Sharing)。
    网关.png

    首先,实现跨区域部署,全局统一命名空间,多站点文件共享与协同;其次,文件属性即时同步,文件数据按需拉取;第三,支持多个文件网关间数据亚秒级同步。目前,该方案已经满足某自动驾驶公司将新增数十万张图片由总部分发到不同地域做AI计算的实际需求。

    5、ESSD云盘新规格发布,降低全闪门槛

    全闪存储已成趋势,但使用门槛仍然很高,阿里云此次全新发布的入门级全闪云盘规格——ESSD PL0。
    ESSD云盘.png

    ESSD PL0作为ESSD系列入门级规格,采用与ESSD系列相同的技术架构,同样拥有亚毫秒级别的延时,单卷最大支持10000的IOPS。相比于上一代入门级云盘,每月仅需多花0.15元/GB,即可使用全闪云盘,大幅降低了全闪存储的使用门槛,并且可以与阿里云第六代增强型实例完美搭配。

    ESSD PL0适用于多种业务场景。例如:小型数据库场景、DevOps场景、系统盘场景。线上实测“搭载ESSD PL0的六代增强型实例”启动速度提升了60%以上;此外针对DevOps场景,基于ESSD系列云盘的“本地快照”特性,能够在数十秒内快速完成快照创建以及云盘创建操作,将业务等待时间缩短至分钟级别;针对小型数据库场景,基于ESSD PL0云盘搭建的数据库实测TPS性能相比于高效云盘提升2倍以上。

    此次全新发布的ESSD PL0 采用NVMe存储介质,最大程度上释放阿里云的技术红利。这也是业内唯一一款基于“RDMA网络架构+NVMe存储介质”的入门级云盘。ESSD PL0的发布使得ESSD系列的使用门槛降低50%,且后续支持无损变配到ESSD系列更高规格,普惠阿里云上百万客户。目前ESSD PL0已经在北京、杭州区域公测上线。

    ]]>
    【其他】6月30日DDoS防护能力调整通知 Sat, 04 Jul 2020 09:33:04 +0800 【阿里云】【DDoS高防】【防护能力调整通知

    调整时间:北京时间2020年6月30日 23:00 - 24:00

    调整内容:DDoS高防(旧版)防护能力调整后,最大支持300G防护能力,不再提供保底和弹性大于300G的防护服务
    调整影响:调整期间,业务无影响。如果您正在使用DDoS高防(旧版)并且需要大于300G防护能力,我们提供平滑切换到DDoS高防(新BGP)的免费迁移服务,DDoS高防(新BGP)可以满足您大于300G的防护能力需求。给您带来的不便敬请谅解,有任何问题,可随时通过工单或服务电话95187联系反馈。


    ]]>
    在 Eclipse 中使用 Cloud Toolkit 快速部署应用至 ECS 集群_使用工具部署应用_应用部署_ECS集群用户指南_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 在 Eclipse 中使用 Cloud Toolkit 快速部署应用至 ECS 集群

    更新时间:2020-06-08 10:54:43

    本页目录

    您在本地完成应用的开发、调试和测试后,可以使用在本地 IDE (现已支持 Eclipse、IntelliJ IDEA)中安装的 Cloud Toolkit 插件连接到云端部署环境并将应用快速部署到 EDAS 的 ECS 集群中。本文档将向您介绍如何在 Eclipse 中安装 Cloud Toolkit,并使用 Cloud Toolkit 快速部署一个应用到 EDAS。

    前提条件

    步骤一:安装 Cloud Toolkit

    1. 启动 Eclipse。
    2. 在菜单栏中选择Help > Install New Software
    3. Available Software 对话框的 Work with 文本框中输入 Cloud Toolkit for Eclipse 的 URL http://toolkit.aliyun.com/eclipse/
    4. 在下面的列表区域中勾选需要的组件 Alibaba Cloud Toolkit CoreAlibaba Cloud Toolkit Deployment Tools,并在下方 Details 区域中不勾选 Connect all update sites during install to find required software。完成组件选择之后,单击Nextedas-cloudtoolkit-installconfig.png
    5. 按照 Eclipse 安装页面的提示,完成后续安装步骤。

      注意 安装过程中可能会提示没有数字签名,选择 Install anyway 即可。

    6. Cloud Toolkit 插件安装完成后,重启 Eclipse,您可以在工具栏看到 Alibaba Cloud Toolkit 的图标。 edas-cloudtoolkit-toolbaricon.png

    步骤二:配置 Cloud Toolkit 账号

    您需使用 Access Key ID 和 Access Key Secret 来配置 Cloud Toolkit 的账号。

    1. 启动 Eclipse。
    2. 在工具栏单击 Alibaba Cloud Toolkit 图标右侧的下拉按钮,在下拉菜单中单击 Alibaba Cloud Preference
    3. Preference (Filtered) 对话框的左侧导航栏中单击 Accounts
    4. Accounts 界面中设置 Access Key IDAccess Key Secret,然后单击 OK

      注意 如果您使用子账号的Access Key ID和Access Key Secret,请确认该子账号至少拥有部署应用的权限,具体操作方式请参见子账号管理

      edas-cloudtoolkit-config-AK-SK.png
      • 如果您已经注册过阿里云账号,在 Accounts 界面中单击 Manage existing Acount,进入阿里云登录页面。用已有账号登录后,跳转至安全信息管理页面,获取 Access Key IDAccess Key Secret
      • 如果您还没有阿里云账号,在 Accounts 界面中单击 Sign up,进入阿里云账号注册页面,注册账号。注册完成后按照上述方式获取 Access Key IDAccess Key Secret

      说明 如果使用 EDAS 专有云企业版,还需要按以下步骤在 Cloud Toolkit 中配置 Endpoint。其中,Endpoint 请联系 EDAS 技术支持获取。

      1. Preference (Filtered) 对话框的左侧导航栏中选择 Appearance & BehaviorEndpoint
      2. Endpoint 界面中设置 Endpoint,配置完成后,单击 Apply and Close

    步骤三:将应用部署到 EDAS

    目前支持使用 Cloud Toolkit 插件将应用通过 WAR 包或 JAR 包部署到 EDAS。

    1. 在 Eclipse 界面左侧的Package Explorer 中右键单击您的应用工程名,在弹出的下拉菜单中选择Alibaba Cloud > Deploy to EDAS
    2. Deploy to EDAS 的运行配置页面,配置应用部署参数,然后单击 Deploy

      说明 如果您还没有在 EDAS 上创建应用,在对话框右上角单击 Create application on EDAS console…,跳转到 EDAS 控制台创建应用。

      edas-cloudtoolkit-eclipse-config-APP.png

      在配置页面中根据您的实际需求选择应用的 RegionNamespaceApplicationGroup

      • Region:应用所在地域。
      • Namespace:应用所在命名空间。
      • Application:应用名称。
      • Group:应用分组。

      注意 如果在应用列表中获取不到应用,请参见常见问题:应用列表获取不到应用进行操作排查。

      1. 设置构建方式。
        • Maven Build:选择 Maven Build 方式来构建应用时,系统会默认添加一个 Maven 任务来构建部署包。
        • Upload File:选择 Upload File 方式来构建应用时,选择上传您的 WAR 包或者 JAR 包,然后进行部署。
      2. 设置应用的版本描述信息和分批部署信息。
        • Version:部署版本。
        • Description:部署信息描述。
        • Batch:分批数。如果您的应用有多个分组,并且在部署时选择部署全部分组,那么将会自动按照分组粒度来分批,Batch 值不用设置。
        • BatchWaitTime:分批部署等待时间,单位为分钟。

        注意 如果您的插件界面没有分批部署设置模块,请将您的插件升级至最新版本。

    3. 部署开始后,Eclipse 的 Console 区域会打印部署日志。您可以根据日志信息检查部署结果。

    步骤四:终止 Cloud Toolkit 插件运行

    在插件运行过程中,如果想停止插件运行,可以在 Progress 页面终止 EDAS-deploy 进程。

    Progress

    常见问题:应用列表获取不到应用

    通常出现这种情况为使用子账号来部署应用,且子账号没有同步到 EDAS 系统或者没有进行正确授权,从而导致在应用列表下拉框中看不到应用。您可以通过 RAM 授权或 EDAS 子账号授权来确保子账号已经同步到 EDAS 并且得到授权。

    RAM 授权

    该授权方式可使子账号访问 EDAS 的所有资源。

    1. RAM 控制台左侧导航栏中选择人员管理 > 用户
    2. 用户页面上找到需要授权的子用户,单击操作列中的添加权限
    3. 添加权限面板的选择权限区域中,搜索 AliyunEDASFullAccess 权限,单击权限策略将其添加至右侧的已选择列表中,然后单击确定
    4. 添加权限授权结果页面上,查看授权信息摘要,并单击完成
    5. 使用主账号登录 EDAS 控制台,在左侧导航栏选择系统管理 > 子账号,单击子账号页面右上角的同步子账号

    EDAS 子账号授权

    该授权方式可使子账号细粒度授权访问 EDAS 的资源。

    1. 使用主账号登录 EDAS 控制台
    2. 在左侧导航栏选择系统管理 > 角色,单击角色页面右上角的创建角色
    3. 输入一个角色名称,在可选权限区域框中,选择应用管理 > 应用列表 > 基本信息 > 部署应用,单击添加将部署应用角色添加到已选权限,然后单击确定
    4. 在左侧导航栏选择系统管理 > 子账号,单击子账号页面右上角的同步子账号
    5. 选择需进行授权的子账号,在操作列单击管理角色,在左侧搜索框中搜索并选择上面创建的角色,将该角色添加到右侧已选角色列表中,然后单击确定
    6. 选择需进行授权的子账号,在操作列单击授权应用,选择应用添加到右侧列表进行授权,然后单击确定

    问题反馈

    • 若您在使用 Cloud Toolkit 的过程中遇到问题,请首先查看常见问题并自助排查。

    • 若您需要进一步的帮助或想参与 Cloud Toolkit 的开发和升级,请加入我们的创造营。加入方式如下:

      • 使用钉钉扫描以下二维码,或搜索群号(30028976)加入钉钉群。钉钉群二维码4群
      • 使用微信扫描以下二维码,或搜索微信账号(nichao862)添加好友,待验证通过后产品经理将拉您进入微信群。微信二维码

    ]]> ALIYUN::ECS::LaunchTemplate_ECS_资源类型_资源编排-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ALIYUN::ECS::LaunchTemplate

    更新时间:2020-02-25 10:39:39

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    ALIYUN::ECS::LaunchTemplate类型可用于创建ECS实例启动模板。

    语法

    {
      "Type": "ALIYUN::ECS::LaunchTemplate",
      "Properties": {
        "LaunchTemplateName": String,
        "VersionDescription": String,
        "ImageId": String,
        "InstanceType": String,
        "SecurityGroupId": String,
        "NetworkType": String,
        "VSwitchId": String,
        "InstanceName": String,
        "Description": String,
        "InternetMaxBandwidthIn": Integer,
        "InternetMaxBandwidthOut": Integer,
        "HostName": String,
        "ZoneId": String,
        "SystemDiskCategory": String,
        "SystemDiskSize": Number,
        "SystemDiskDiskName": String,
        "SystemDiskDescription": String,
        "IoOptimized": String,
        "InternetChargeType": String,
        "UserData": String,
        "KeyPairName": String,
        "RamRoleName": String,
        "AutoReleaseTime": String,
        "SpotStrategy": String,
        "SpotPriceLimit": String,
        "SecurityEnhancementStrategy": String,
        "DiskMappings": List,
        "NetworkInterfaces": List,
        "Tags": List,
        "TemplateTags": List
      }
    }

    属性

    属性名称 类型 必须 允许更新 描述 约束
    LaunchTemplateName String 实例启动模板名称。 长度为[2, 128]个英文或中文字符。必须以大小字母或中文开头,不能以http://和https://开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。
    VersionDescription String 实例启动模板版本1描述。 长度为[2, 256]个英文或中文字符,不能以http://和https://开头。
    ImageId String 镜像ID。
    InstanceType String 实例类型。
    SecurityGroupId String 安全组ID。
    NetworkType String 实例网络类型。

    取值范围:

    classic:经典网络。

    vpc:VPC网络。

    VSwitchId String 创建VPC类型实例时需要指定虚拟交换机ID。
    InstanceName String 实例名称。 长度为[2, 128]个英文或中文字符。必须以大小字母或中文开头,不能以http://和https://开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。
    Description String 实例描述。 长度为[2, 256]个英文或中文字符,不能以http://和https://开头。
    InternetMaxBandwidthIn Integer 公网入带宽最大值,单位为Mbit/s。 取值范围:[1,200]。
    InternetMaxBandwidthOut Integer 公网出带宽最大值,单位为Mbit/s。 取值范围:[0, 100]。
    HostName String 实例主机名。

    点号(.)和短横线(-)不能作为首尾字符,更不能连续使用。

    Windows实例:

    字符长度为[2, 15],不支持点号(.),不能全是数字。允许大小写英文字母、数字和短横线(-)。

    其他类型实例(Linux等):

    字符长度为[2, 64],支持多个点号(.),点之间为一段,每段允许大小写英文字母、数字和短横线(-)。

    ZoneId String 实例所属的可用区ID。
    SystemDiskCategory String 系统盘的磁盘种类。 取值范围:

    cloud:普通云盘。

    cloud_efficiency:高效云盘。

    cloud_ssd:SSD云盘。

    ephemeral_ssd:本地SSD盘。

    SystemDiskSize Number 系统盘大小,单位为GiB。 取值范围:[20, 500]
    SystemDiskDiskName String 系统盘名称。 长度为[2, 128]个英文或中文字符。必须以大小字母或中文开头,不能以http://和https://开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。
    SystemDiskDescription String 系统盘描述。 长度为[2, 256]个英文或中文字符,不能以http://和https://开头。
    IoOptimized String 是否为I/O优化实例。

    取值范围:

    none:非I/O优化。

    optimized:I/O优化。

    InternetChargeType String 网络付费类型。

    取值范围:

    PayByBandwidth:按带宽计费。

    PayByTraffic:按流量计费。

    UserData String 实例自定义数据。 需要以Base64方式编码,原始数据最多为16 KB。
    KeyPairName String 密钥对名称。 Windows实例,忽略该参数。默认为空。即使填写了该参数,仍旧只执行Password的内容。Linux实例的密码登录方式会被初始化成禁止。
    RamRoleName String 实例RAM角色名称。
    AutoReleaseTime String 实例自动释放时间。 按照ISO8601标准表示,并需要使用UTC时间,格式为yyyy-MM-ddTHH:mm:ssZ。
    SpotStrategy String 后付费实例的抢占策略。

    当创建实例接口中的InstanceChargeType参数取值为PostPaid时为生效。

    取值范围:

    NoSpot:正常按量付费实例。

    SpotWithPriceLimit:设置上限价格的抢占式实例。

    SpotAsPriceGo:系统自动出价,最高按量付费价格。

    SpotPriceLimit String 设置实例的每小时最高价格。 支持最多3位小数。
    SecurityEnhancementStrategy String 是否开启安全加固。

    取值范围:

    Active:启用。

    Deactive:不启用。

    DiskMappings List 数据盘列表。 最多16个。
    NetworkInterfaces List 弹性网卡列表。 最多8个。
    Tags List 实例、安全组、磁盘和网卡的标签列表 最多20个
    TemplateTags List 启动模板的标签列表。 最多20个。

    DiskMappings语法

    "DiskMappings": [
      {
        "Category": String,
        "DiskName": String,
        "Description": String,
        "SnapshotId": String,
        "Size": String,
        "Encrypted": String,
        "DeleteWithInstance": String
      }
    ]

    DiskMappings属性

    属性名称 类型 必须 允许更新 描述 约束
    Category String 数据盘的磁盘种类。

    取值范围:

    cloud:普通云盘。

    cloud_efficiency:高效云盘。

    cloud_ssd:SSD云盘。

    ephemeral_ssd:本地SSD盘。

    DiskName String 数据盘名称。 长度为[2, 128]个英文或中文字符。必须以大小字母或中文开头,不能以http://和https://开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。
    Description String 数据盘描述。 长度为[2, 256]个英文或中文字符,不能以http://和https://开头。
    SnapshotId String 创建数据盘使用的快照。
    Size String 系统盘大小,单位为GiB。

    取值范围:

    cloud:[5, 2000]。

    cloud_efficiency:[20, 32768]。

    cloud_ssd:[20, 32768]。

    ephemeral_ssd:[5, 800]。

    Encrypted Boolean 是否加密数据盘。
    DeleteWithInstance Boolean 数据盘是否随实例释放而释放。

    NetworkInterfaces语法

    "NetworkInterfaces": [
      {
        "PrimaryIpAddress": String,
        "VSwitchId": String,
        "SecurityGroupId": String,
        "NetworkInterfaceName": String,
        "Description": String
      }
    ]

    NetworkInterfaces属性

    属性名称 类型 必须 允许更新 描述 约束
    PrimaryIpAddress String 弹性网卡的主私有IP地址。
    VSwitchId String 弹性网卡所属的虚拟交换机ID。
    SecurityGroupId String 弹性网卡所属的安全组ID。
    NetworkInterfaceName String 弹性网卡名称。
    Description String 弹性网卡描述信息。 长度为[2, 256]个英文或中文字符,不能以http://和https://开头。

    Tags语法

    "Tags": [
      {
        "Value": String,
        "Key": String
      }
    ]

    Tags属性

    属性名称 类型 必须 允许更新 描述 约束
    key String
    value String

    TemplateTags语法

    "TemplateTags": [
      {
        "Value": String,
        "Key": String
      }
    ]

    TemplateTags属性

    属性名称 类型 必须 允许更新 描述 约束
    key String
    value String

    返回值

    Fn::GetAtt
    • LaunchTemplateId: 实例启动模板ID。
    • LaunchTemplateName:实例启动模板名称。
    • DefaultVersionNumber:实例启动模板默认版本号。
    • LatestVersionNumber:实例启动模板最新版本号。

    示例

    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "Template1": {
          "Type": "ALIYUN::ECS::LaunchTemplate",
          "Properties": {
            "LaunchTemplateName": "MyTemplate",
            "VersionDescription": "Launch template with all properties set",
            "ImageId": "m-2ze9uqi7wo61hwep5q52",
            "InstanceType": "ecs.n4.small",
            "SecurityGroupId": "sg-2ze8yxgempcdsq3iucsi",
            "NetworkType": "vpc",
            "VSwitchId": "vsw-2zei67xd9nhcqxzec7qt7",
            "InstanceName": "InstanceName",
            "Description": "Description of template",
            "InternetMaxBandwidthIn": 100,
            "InternetMaxBandwidthOut": 200,
            "HostName": "tttinfo",
            "ZoneId": "cn-beijing-a",
            "SystemDiskCategory": "cloud_ssd",
            "SystemDiskSize": "40",
            "SystemDiskDiskName": "TheSystemDiskName",
            "SystemDiskDescription": "The system disk description",
            "IoOptimized": "optimized",
            "InternetChargeType": "PayByBandwidth",
            "UserData": "dGhpcyBpcyBhIHVzZXIgZGF0YSBleG1hcGxl",
            "KeyPairName": "ThisIsKeyPair",
            "RamRoleName": "ThisIsRamRole",
            "AutoReleaseTime": "2050-10-01T00:00:00Z",
            "SpotStrategy": "SpotWithPriceLimit",
            "SpotPriceLimit": "100.001",
            "SecurityEnhancementStrategy": "Active",
            "DiskMappings": [
              {
                "Category": "cloud_ssd",
                "Size": 40,
                "SnapshotId": "s-2ze1fr2bipove27bn9mz",
                "Encrypted": true,
                "DiskName": "dataDisk1",
                "Description": "I am data disk 1",
                "DeleteWithInstance": true
          },
          {
                "Category": "cloud_efficiency",
                "Size": 20,
                "SnapshotId": "s-2ze4k0w8b33mlsqu4tl6",
                "Encrypted": false,
                "DiskName": "dataDisk2",
                "Description": "I am data disk 2",
                "DeleteWithInstance": true
           }
         ],
         "NetworkInterfaces": [
           {
                "PrimaryIpAddress": "10.10.1.1",
                "VSwitchId": "vsw-2zetgeiqlemyok9z5j2em",
                "SecurityGroupId": "sg-2ze8yxgempcdsq3iucsi",
                "NetworkInterfaceName": "my-eni1",
                "Description": "My eni 1"
            },
         ],
         "Tags": [
              {
                "Key": "key1",
                "Value": "value1"
              },
              {
                "Key": "key2",
                "Value": "value2"
              }
             ],
         "TemplateTags": [
           {
                "Key": "templateKey1",
                "Value": "templateValue1"
                 },
               {
                "Key": "templateKey2",
                "Value": "templateValue2"
               }
           ]
           }
         }
      },
      "Outputs": {
          "LaunchTemplateId": {
              "Value": {"Fn::GetAtt": ["Template1","LaunchTemplateId"]}
        },
       "LaunchTemplateName": {
            "Value": {"Fn::GetAtt": ["Template1","LaunchTemplateName"]}
        },
       "DefaultVersionNumber": {
              "Value": {"Fn::GetAtt": ["Template1","DefaultVersionNumber"]}
        },
       "LatestVersionNumber": {
              "Value": {"Fn::GetAtt": ["Template1","LatestVersionNumber"]}
        }
      }
    }

    ]]> 云监控ECS的Windows主机CPU监控数值异常_技术分享_常见问题_云监控-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 云监控ECS的Windows主机CPU监控数值异常

    更新时间:2020-04-16 16:37:49

    编辑 · 

    新浪微博 微信 钉钉

    本页目录

    本文为您介绍云监控ECS的Windows主机CPU监控数值异常的原因及解决办法。

    云监控中的ECS CPU监控数值如果出现为0或者负数(实际CPU使用率不是0),其他监控值都正常。这个问题主要出现在Windows的机器上,一般原因是Windows内部的性能计数器损坏了。

    可以通过typeperf "Processor(_Total)% Processor Time"查看计数器是否正常。如果提示“错误:没有有效计数器”,则说明计数器已损坏,可通过lodctr /r命令进行修复。

    相关截图如下:查看计数器

    ]]> 禁用ECS的内网后不能使用云监控_技术分享_常见问题_云监控-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 禁用ECS的内网后不能使用云监控

    更新时间:2020-06-18 16:09:52

    编辑 · 

    新浪微博 微信 钉钉

    本页目录

    本文为您介绍为何禁用ECS的内网后不能使用云监控。

    ECS服务器使用云监控服务,是不能禁用内网的。

    因为云监控的通讯地址open.cms.aliyun.com是解析在内网上的,通过内网来进行通讯获取数据,如果禁用了内网,云监控服务会出现无法正常使用,所以为了能够正常的使用云监控服务,必须要确保在服务器上能连通open.cms.aliyun.com的80端口。Telnet

    ]]> 云虚拟主机可以升级ECS吗_升级/续费_产品定价_云虚拟主机-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 云虚拟主机可以升级ECS吗

    更新时间:2017-07-17 09:09:54

    本页目录

    云虚拟主机无法无缝升级到云服务器 ECS如果您需要将网站迁移到 ECS,需要您配置站点,将数据迁移到新的服务器上,将环境配置好后,将您的域名解析指向新服务器 IP

    如您自行迁移数据遇到困难,可到阿里云云市场联系网站迁移服务商进行咨询。

    ]]> 如何安装 ECS 云助手?_常见问题_Alibaba Cloud Toolkit-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 如何安装 ECS 云助手?

    更新时间:2019-09-11 13:52:47

    本页目录

    若您在使用 Cloud Toolkit 部署应用时出现以下报错,可能原因是您的 ECS 实例没有安装云助手客户端。 error

    2017 年 12 月 01 日之后使用公共镜像创建的ECS实例,默认预装云助手客户端。如果您的实例是 2017 年 12 月 01 日之前购买的,若需要使用 Cloud Toolkit,则需自行安装云助手客户端。

    解决方案如下:

    1. 安装云助手客户端,请参见云助手客户端
    2. 启动云助手客户端,请参见停止或启动客户端

    ]]> Java应用部署到ECS_Java入门_快速入门_云效-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 Java应用部署到ECS

    更新时间:2020-03-18 10:03:05

    本页目录

    本文档会帮助您在云效创建一个 Java Spring Boot 的代码库,并部署到阿里云 ECS 服务器。

    创建企业

    首次进入云效,会提示您创建企业。输入企业名称,点击【立即创建】。

    java-ecs-1

    创建流水线

    1. 进入企业后,从页面顶栏点击【研发】->【流水线】,进入流水线列表。

      java-ecs-2

    2. 点击右上角【新建流水线】,进入流水线创建向导页面。

      java-ecs-3

    新建代码库

    1. 在源码设置页面中,选择阿里云Code,点击代码仓库右侧【新建代码库】。

      java-ecs-4

    2. 在弹窗中选择或创建代码组,输入新建代码仓库名称,点击【下一步】。

      java-ecs-5

    3. 在代码模板中选择 Java 和 spring-boot ,取消勾选【生成Dockerfile】,点击【确认】。您可以点击代码模板图标下的预览按钮查看即将生成的代码库文件内容。

      java-ecs-6

    4. 代码库创建完成后会恢复到代码库选择页面并回填刚才创建代码库的信息,为了在代码提交时候触发持续集成,打开【开启监听】,然后点击【下一步】。

      java-ecs-7

    编辑流水线

    1. 云效会识别代码库语言并推荐相应流水线模板,使用默认置顶选中的【Java构建,测试,部署到主机】流水线模板,然后点击【创建】。

      java-ecs-8

    2. 填写流水线名称,点击【下一步】。

      java-ecs-9

    3. 部署配置。点击阶段【部署】阶段进行部署配置,在任务列表中选择【主机部署】,选择由构建环节产出的待部署【制品】。

      java-ecs-10

    4. 新建应用。在【应用】下拉框中选择【新建应用】填写应用名称,点击【确认】。

      java-ecs-11

    5. 新建环境。在【环境】下拉框中选择【新建环境】,填写环境名称,点击【机器配置】。

      java-ecs-12

    6. 机器配置。点击【使用临时模板机器】,稍等片刻会获得一台用于测试的机器。

      java-ecs-13java-ecs-14

    7. 获取临时机器成功后点击【刷新】按钮,会在机器配置页面左边看到刚才创建的机器。选中并添加到右侧,点击【确认】完成环境创建。

      java-ecs-15java-ecs-16

    运行流水线

    1. 点击右上角的【运行】,即可保存并触发流水线。

      java-ecs-17

    2. 运行成功。

      java-ecs-18

    查看测试报告

    1. Java 规约扫描。点击阶段里的点击链接可以查看报告预览,点击预览中的【链接】可以查看完整报告。

      java-ecs-19

    2. 点击测试构建阶段里的【更多】,通过【版本信息】可以查看和下载用于部署的软件包,点击【单元测试】可以展开测试结果预览,点击预览里的【链接】可以查看测试报告详情。

      java-ecs-20

    查看部署结果

    1. 点击【部署详情】可以查看部署单。在部署单中可以查看每台机器的部署情况和日志。

      java-ecs-21

    2. 访问 ECS 的公网 IP 的 8080 端口,可以看到服务运行起来了。

      java-ecs-22

    ]]> ALIYUN::ECS::Invocation_ECS_资源类型_资源编排-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ALIYUN::ECS::Invocation

    更新时间:2019-06-24 11:45:02

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    ALIYUN::ECS::Invocation类型用于为一台或多台ECS实例触发一条云助手命令。

    语法

    {
      "Type": "ALIYUN::ECS::Invocation",
      "Properties": {
        "Timed": Boolean,
        "Frequency": String,
        "CommandId": String,
        "InstanceIds": List
      }
    }

    属性

    属性名称 类型 必须 允许更新 描述 约束
    Timed Boolean 命令是否为周期执行。默认值:False
    Frequency String 周期任务的执行周期。该参数值结构以 Cron 表达式 为准。
    CommandId String 命令 ID。
    InstanceIds List 执行命令的实例列表。最多能指定20台实例ID。

    返回值

    Fn::GetAtt

    • InvokeId: 命令进程执行 ID。

    示例

    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "Timed": {
          "Type": "Boolean",
          "Description": "Whether it is timed execution. Default is False.",
          "AllowedValues": [
            "True",
            "true",
            "False",
            "false"
          ]
        },
        "Frequency": {
          "Type": "String",
          "Description": "The frequency of timing execution (the shortest frequency is performed every 1 minute). It iss mandatory when Timing is True.The value rule follows the rules of the cron expression. "
        },
        "CommandId": {
          "Type": "String",
          "Description": "The id of command."
        },
        "InstanceIds": {
          "Type": "CommaDelimitedList",
          "Description": "The instance id list. Select up to 20 instances at a time.Instances selected network type must be VPC network, status must be running"
        }
      },
      "Resources": {
        "Invocation": {
          "Type": "ALIYUN::ECS::Invocation",
          "Properties": {
            "Timed": {
              "Ref": "Timed"
            },
            "Frequency": {
              "Ref": "Frequency"
            },
            "CommandId": {
              "Ref": "CommandId"
            },
            "InstanceIds": {
              "Fn::Split": [
                ",",
                {
                  "Ref": "InstanceIds"
                },
                {
                  "Ref": "InstanceIds"
                }
              ]
            }
          }
        }
      },
      "Outputs": {
        "InvokeId": {
          "Description": "The id of command execution.",
          "Value": {
            "Fn::GetAtt": [
              "Invocation",
              "InvokeId"
            ]
          }
        }
      }
    }

    ]]> 将已绑定EIP的ECS实例加入共享带宽_最佳实践_共享带宽-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 将已绑定EIP的ECS实例加入共享带宽

    更新时间:2019-09-27 14:44:03

    本页目录

    您可以将已绑定EIP的ECS实例加入共享带宽中,复用共享带宽中的带宽

    前提条件

    操作前,请确保满足以下条件:
    • 您已经注册了阿里云账号。如还未注册,请先完成账号注册。详细信息,请参见账号注册
    • 您已经创建了共享带宽实例。详细信息,请参见创建共享带宽实例

    操作步骤

    1. 登录专有网络管理控制台
    2. 在左侧导航栏,单击共享带宽
    3. 共享带宽页面,找到目标共享带宽实例,单击操作列下的添加IP
    4. 添加IP页面,单击从已有EIP列表选取页签。
    5. 选择已绑定ECS实例的EIP,然后单击确定

      说明 EIP添加到共享带宽后,EIP的带宽峰值将变为共享带宽的带宽峰值。同时EIP会停止之前的计费,按流量计费的EIP不再收取流量费用,按带宽计费的EIP不再收取带宽费用。

    ]]> ECS实例与MongoDB实例网络类型不同时如何连接_连接实例_用户指南_云数据库 MongoDB-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ECS实例与MongoDB实例网络类型不同时如何连接

    更新时间:2019-10-29 14:23:49

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    当ECS实例是经典网络而MongoDB实例是专有网络(VPC),或者MongDB实例是经典网络而ECS实例是专有网络,您可根据本文中的办法快速实现不同网络类型的ECS实例连接至MongoDB实例的需求。

    前提条件

    • ECS实例和MongoDB实例在同一阿里云账号中,且属于同一地域。
    • 已将ECS实例的IP地址加入MongoDB实例的白名单中,详情请参见设置白名单

      说明 关于获取ECS实例IP地址信息,请参见如何查询ECS实例的IP地址

    经典网络的ECS实例连接专有网络的MongoDB实例

    经典网络的ECS连接专有网络的MongoDB

    通过下述三种方法均可以实现经典网络的ECS实例连接专有网络的MongoDB实例,您可以根据业务规划自行选择。

    • 将ECS实例迁移至MongoDB实例所属的专有网络中,详情请参见将ECS实例迁移至专有网络
    • 将MongoDB实例的网络类型切换为经典网络,详情请参见从专有网络切换为经典网络
    • 使用ClassicLink实现互通。

      说明 基于ClassicLink互访方案为特殊情况下的临时解决方案,生产环境中为了实现高速连接,建议您将ECS实例和MongoDB实例创建在同一VPC网络内。

      在建立ClassicLink前确保您已经了解建立连接的限制,详情请参见ClassicLink

      开启ClassicLink操作步骤:

      1. 登录专有网络管理控制台
      2. 选择目标专有网络的地域,然后单击目标专有网络的ID。
      3. 专有网络详情页面,单击开启ClassicLink, 然后在弹出的对话框,单击确定
      4. 登录ECS管理控制台
      5. 在左侧导航栏,单击目标实例
      6. 在页面左上角选择实例的所属地域。
      7. 在目标ECS实例(经典网络)的操作列中,单击更多 > 网络和安全组 > 设置专有网络连接状态
      8. 在弹出的对话框中选择MongoDB实例所属的专有网络,单击确定
      9. 在新弹出的连接专有网络对话框中,单击前往实例安全组列表添加classicLink安全组规则经典网络的ECS连接专有网络
      10. 单击添加ClassicLink安全组规则,根据以下信息配置ClassicLink安全组规则,然后单击确定
        配置 说明
        经典网络安全组 显示经典网络安全组的名称。
        选择专有网络安全组 选择专有网络的安全组。
        授权方式 选择一种授权方式:
        • 经典网络 <=> 专有网络:相互授权访问,推荐使用这种授权方式。
        • 经典网络 => 专有网络:授权经典网络ECS访问专有网络内的云资源。
        • 专有网络 => 经典网络:授权专有网络内的云资源访问经典网络ECS。
        协议类型 选择授权通信的协议和端口。
        端口范围 端口的输入格式为xx/xx,此处放通的端口为MongoDB实例的端口3717,填入3717/3717
        优先级 设置该规则的优先级。数字越小,优先级越高。
        描述 填入安全组描述,长度为2-256个字符,不能以 http:// 或 https:// 开头。

    专有网络的ECS实例连接经典网络的MongDB实例

    专有网络的ECS连接经典网络的MongoDB

    将MongoDB实例切换到ECS实例所属的专有网络中,详情请参见从经典网络切换为专有网络

    说明

    • 单节点实例暂不支持切换网络类型。
    • 切换网络时,实例将会出现一次闪断。请您尽量在业务低峰期执行切换操作,或确保您的应用有自动重连机制,以避免闪断造成的影响。

    ]]> 扩容部署在 ECS 集群中的应用_ECS 集群应用生命周期管理_应用管理_ECS集群用户指南_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 扩容部署在 ECS 集群中的应用

    更新时间:2019-12-11 17:37:38

    本页目录

    当部署应用的 ECS 实例负载过高或者应用内没有实例时,可以通过添加实例来扩容。现EDAS 支持三种扩容方式:从该应用部署的集群选择、基于现有实例规格购买和基于实例启动模板购买。

    扩容实例的运行状态说明

    扩容的实例的运行状态是根据所在应用的运行状态而定的。

    • 如果扩容的时候应用已经部署并处于运行状态,那么扩容的实例会自动部署应用、启动、运行应用。
    • 如果扩容的时候应用已经部署并处于停止状态,那么扩容的实例仍然会自动部署应用、启动、运行应用。
    • 如果扩容的时候应用实例未部署,那么扩容的实例不会自动部署,也不会启动、运行应用,扩容的实例会处于停止状态。

    进入应用扩容功能

    1. 在应用详情页面右上角单击应用扩容。在购买实例对话框的扩容方式页签内选择扩容的目标分组
    2. 选择扩容方式,并分别参照以下扩容方式完成后续扩容步骤。

    从该应用部署的集群选择

    该扩容方式是从应用所在集群内选择空闲的实例添加到应用来实现扩容。

    1. 扩容方式勾选从该应用部署的集群选择
    2. 在实例列表中勾选用于扩容的空闲实例,然后单击扩容

      从该应用部署的集群选择

      页面上出现扩容成功的提示后,进入应用实例部署信息页面,查看扩容实例的运行状态,如果显示运行正常则说明扩容成功。

    基于现有实例规格购买

    该扩容方式是以所在集群内的任意一个实例作为规格模板,来配置购买实例实现扩容。

    1. 扩容方式勾选基于现有实例规格购买,该页面内会罗列出应用所在集群内的所有实例。
    2. 勾选您想作为规格模板的实例,选择回收模式,然后单击下一步

      说明 此次 ECS 实例代购默认会复制所选择 ECS 实例的规格、磁盘、网络、userdata、标签等基本信息。

      基于现有实例规格购买

    3. 购买信息页面,配置购买数量登录密钥,并勾选《云服务器 ECS 服务条款》 | 《镜像商品使用条款》,然后单击下一步
    4. 确认扩容页面查看代购的实例信息,然后单击确认扩容

      页面上方会出现已触发自动购买的流程,请查看变更流程获取实时信息的提示。

    5. 进入应用的实例部署信息页面,查看扩容实例的运行状态,如果显示运行正常则说明扩容成功。

    说明

    • 基于现有 ECS 规格购买机器分为两个变更流程进行,第一个变更流程是 EDAS 从 ECS 为您代购 ECS实例;第二个变更流程是将代购后的 ECS 实例自动扩容进应用中。
    • 从您提交请求到应用开始扩容所需实例,前后约三分钟;两个变更流程执行相隔约10秒。
    • 所有计费信息均按照 ECS 与 EDAS 的正常计费进行,此次操作不会产生额外的费用。
    • ECS 中默认的登录信息均以您自行设定的 KeyPair 进行,EDAS 不会触碰您的任何私密信息。

    基于实例启动模板购买

    使用实例启动模板购买需您提前在 ECS 控制台创建实例启动模板,然后在 EDAS 控制台上基于您创建的模板来购买实例。创建启动模板的具体操作请参见创建实例启动模板

    注意 您所创建的启动模板必须和您的应用在同一个 VPC 内,否则所创建的启动模板无法被有效选择。

    1. 扩容方式勾选基于实例启动模板购买
    2. 选择绑定模板和模板版本,选择回收模式,然后单击下一步
      • 使用绑定模板:在实例分组中绑定的启动模板,具体文档请参见绑定实例启动模板
      • 使用指定模板:在 ECS 控制台创建的模板。如果您创建过多个模板,需要选择具体模板版本
    3. 购买信息页面选择购买数量并勾选《《云服务器 ECS 服务条款》 | 《镜像商品使用条款》,然后单击下一步
    4. 确认扩容页面,检查需要购买的 ECS 数量和启动模板信息。确认无误后,单击确认扩容

      页面上方会出现已触发自动购买的流程,请查看变更流程获取实时信息的提示。

    5. 进入应用的实例部署信息页面,查看扩容实例的运行状态,如果显示运行正常则说明扩容成功。

    更多信息

    ]]> 创建ECS实例_ECS_资源管理_ECS集群用户指南_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 创建ECS实例

    更新时间:2020-06-01 14:35:02

    本页目录

    如果您还没有ECS实例,请参考本文档创建ECS实例,以便部署应用。

    前提条件

    在创建ECS实例前,请先确认您要创建实例的网络:
    • 如果您在2017年6月14日17:00 (UTC+8)之后,第一次购买ECS实例,不能再选择经典网络,只能选择专有网络(VPC)。在此之前创建的经典网络的ECS实例可以继续使用。
    • 在VPC创建ECS实例,需要选择VPC,且选择VPC之后,该ECS实例不能再转移到其它VPC中。所以请确认您要创建ECS实例的VPC。如果没有VPC,请先创建VPC,具体操作步骤请参见搭建IPv4专有网络

    操作步骤

    1. 登录EDAS控制台
    2. 在左侧导航栏中选择资源管理 > ECS
    3. ECS页面选择您要创建ECS实例的地域命名空间(可选),在页面右上角单击创建实例
    4. 在ECS购买页面,根据您的需要,参考创建ECS实例,完成ECS的规格配置和支付。

      注意 在EDAS控制台使用和管理ECS实例需要在ECS实例上安装EDAS Agent。在购买ECS实例时,通过选择EDAS基础镜像自动安装EDAS Agent。

      1. 镜像一栏中,选择镜像市场,然后单击从镜像市场获取更多选择(含操作系统)
      2. 在镜像市场对话框的搜索框中输入EDAS,单击搜索
      3. 在搜索结果中选择EDAS JAVA环境(普通ECS)版本(默认选择当前最新版本)和单击使用

    结果验证

    单击管理控制台返回云服务器管理控制台,一般需要1~5分钟完成实例创建。单击刷新按钮,新建的ECS实例状态变为运行中,表示实例创建成功。

    ]]> 金融云ECS云服务器互联网互通说明_常见问题_产品常见问题_金融云-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 金融云ECS云服务器互联网互通说明

    更新时间:2018-01-03 11:24:41

    本页目录

    一、适用范围

    本说明仅仅针对阿里金融云,不适用于公共云或其它行业云。


    二、综述

    如下图所示,ECS主动访问互联网和被动接受互联网访问,两条数据通道彼此隔离,互相不重叠,不交叉,计量和收费亦独立进行。

    如ECS云服务器没有主动访问互联网的需求,无需购买公网带宽。反之,如有访问需求,则必须购买公网带宽,否则无法主动发起互联网访问。

    因为金融行业的安全合规特殊性,目前经典网络限制互联网直接访问ECS任何端口,VPC的弹性公网IP限制2W以下敏感端口。如ECS云服务网需要对互联网提供服务,建议购买SLB(负载均衡),然后进入ECS云服务器的内网IP(端口)实现。

    SLB(负载均衡)创建后,默认ECS所在安全组对SLB(负载均衡)内网IP地址段开放访问权限,无需单独配置。

    安全说明:金融云目前的安全策略由外部网络设备控制,但从安全实践出发我们还是建议用户在ECS上做好安全组的配置,在安全组上禁止公网测不合理的访问需求,以保证多层的安全防护体系。

     

    三、数据通道图示


    图1:



    四、ECS云服务器主动访问互联网

    1)数据通道

    见图1右侧:ECS云服务器公网IP(vpc中就是弹性公网IP)———->防火墙———->互联网server,然后数据沿原路返回。

    2)计费方式

    该通道可以采用按带宽计费或按照固定带宽计费模式。

     

    五、ECS云服务器提供web服务给互联网用户

    1)数据通道

    见图1左侧:互联网用户———->SLB(负载均衡)———->ECS云服务器内网IP,然后数据沿原路返回。

    2)计费方式

    该通道可以采用按带宽计费或按照固定带宽计费模式。

     

    六、是否存在重复计费?

    不存在。因为, ECS公网IP和SLB,都只按照流量的下行方向计费,即从ECS往外的流量计费。

    例:某ECS往外的流量是5M,其中2M是ECS主动访问互联网所产生,3M是互联网用户访问ECS,ECS回包所产生。无论是都通过ECS公网IP进出(图3),还是部分走SLB、部分走ECS 公网IP(图2),总的下行流量5M不会变。

     

    图2:


    图3:

     

    七、SLB(负载均衡)相关

    购买入口

    http://buy.aliyun.com/SLB

    帮助中心SLB(负载均衡)入口

    http://help.aliyun.com/all/11108234.html

     



    ]]> 跨账号同步ECS主机名_用户指南_云解析 PrivateZone-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 跨账号同步ECS主机名

    更新时间:2020-03-17 14:28:58

    本页目录

    什么是同步ECS主机名

    同步ECS主机名,是指通过PrivateZone自动获取ECS服务器实例信息中的主机名配置,然后根据ECS主机名在privateZone中一键生成相应的内网DNS解析记录(即主机名记录)。

    什么是跨账号同步ECS主机名

    跨账号同步ECS主机名是指,例如有阿里云账号A和B时,可实现将B账号下的ECS主机名同步到A账号下。

    适用场景

    当企业有多个阿里云账号,如果ECS分布在不同的账号,在使用PrivateZone管理内网DNS时,需要用户在每个账号下都创建一遍相同Zone名称、并操作ECS主机名同步,来生成主机名记录。这种管理操作繁琐不便且影响运维人员的工作效率,基于上述场景,我们为用户提供了PrivateZone可以跨账号同步ECS主机名功能。

    设置方法

    示例:以有阿里云账号A和账号B,期望结果是需要把账号B下的ECS主机名同步到账号A下。

    配置RAM角色

    在使用跨账号同步ECS主机名前,需要在B账号下先配置RAM角色,如未配置,则无法正常使用跨账号同步ECS功能。

    1、用 B账号 登录阿里云 RAM产品控制台

    2、菜单选择 RAM角色管理,单击 新建RAM角色 按钮,选择类型 请选中 阿里云服务,并点击 下一步;参考 示例图1

    3、配置角色 的角色名称请按规则输入 AssumeRoleFor12345,其中12345是示例,代表账号B的Uid(适用主账号)。选择授信服务 请选择 云服务器,并单击 完成,参考 示例图2

    4、 单击 为角色授权按钮,在系统权限策略中,检索 ECS,选中 AliyunECSReadOnlyAccess, 点击 确定,参考 示例图3

    5、返回RAM角色列表页,点击角色 AssumeRoleFor12345 ,选中 信任策略管理 ,单击 修改信任策略 按钮。请修改 Service,将里面的ecs.aliyuncs.com替换为账号A(适用主账号),输入规则为 Uid@pvtz.aliyuncs.com 。例如账号 AUid 是 345678,那么 sevice 就修改为 345678@pvtz.aliyuncs.com。参考示例图4

    示例图1

    新建RAM角色按钮


    选择阿里云服务


    示例图2

    示例图2


    示例图3

    为角色授权


    添加权限

    示例图4

    修改信任策略按钮
    修改策略

    跨账号同步ECS主机名

    1、 用 A账号 登录 云解析DNS控制台, 单击左侧菜单 PrivateZone

    2、 单击 添加zone,输入自定义的私有域名。

    添加zone

    3、 单击 zone名称,进入解析设置页面,选择 主机名记录 页签,单击 自动同步配置 按钮,选择当前账号下的 ECS区域做同步。

    同步主机名

    自动同步配置

    4、 如需同步 B账号下的 ECS主机名,需要先单击 添加账户

    添加账号

    5、 在添加账户的弹出框中,输入B账号的登录邮箱或用户名;单击发送验证码,验证码会同时发送到账号B的邮箱和手机中。

    添加账户

    6、验证通过后,在选择账号的下拉框中选中 账号B,然后选择需要同步主机名的ECS区域,点击确认,即完成跨账号同步ECS主机名。

    选择关联账号

    7、最后返回PrivateZone列表页,单击 关联VPC,选择账号下默认显示为当前账号下的VPC列表,完成 关联VPC

    关联VPC

    ]]> ECS小时数据_计量域_阿里云交易和账单管理API-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ECS小时数据

    更新时间:2019-07-08 09:10:36

    本页目录

    接口名

    QueryUserOmsData

    描述

    查询ECS产品按小时计量的数据信息。

    请求参数

    名称 类型 是否必填 说明
    Table String ecs
    DataType String 计量数据时间类型。Hour:小时
    StartTime String 请求的开始时间。日期格式按照ISO8601标准标示,并需要使用UTC时间。格式:yyyy-mm-ddThh:mm:ssZ
    EndTime String 请求的结束时间。日期格式按照ISO8601标准标示,并需要使用UTC时间。格式:yyyy-mm-ddThh:mm:ssZ
    Maker String 设定结果从NextToken之后按字母排序的第一个开始返回。默认从头返回
    PageSize Integer 分页查询每页行数,1~200,默认100行

    返回参数

    名称 类型 说明
    HostId String 用户所属站点,cn为国内站
    CPUs Integer 用户购买的CPU Core数量
    InstanceId String 实例ID
    OsDiskSize Integer 用户购买的OS盘大小,单位Bytes
    ImageOS String 镜像OS类型
    NetworkIn Integer 在StartTime和EndTime时间段内发生的从外部网络流入ECS的数据量,单位Bytes
    Disk Integer 用户购买的数据盘容量,单位Bytes
    NetworkOut Integer 在StartTime和EndTime时间段内发生的从ECS流出到外部网络的数据量,单位Bytes
    InstanceTypeName String 实例类型名称
    DataDiskSize Integer 数据盘大小,单位:GB
    IoOptimized Integer 创建的 ECS 是否 I/O 优化
    ImageSize Integer 镜像大小
    Memory Integer 用户购买的内存容量,单位Bytes
    Region String 地域
    OsDiskType String 用户购买的OS盘类型
    TmpDataDiskSize Integer 用户购买的本地磁盘容量,单位Bytes
    ProviderId String 产品供应商对应编号,默认26842
    SsdDataDiskSize Integer 用户购买的本地ssd磁盘容量,单位Bytes
    CloudDataDiskSize Integer 用户购买的云磁盘容量,单位Bytes
    Bandwidth Integer 用户购买的带宽,单位bps
    EndTime String 计费数据发生结束时间
    StartTime String 计费数据发生开始时间

    请求示例

    示例(按小时):

    1. https://business.aliyuncs.com/? Action=QueryUserOmsData
    2. &DataType=Hour
    3. &EndTime=2019-04-18T09:15:54Z
    4. &StartTime=2019-01-01T09:15:54Z
    5. &Table=ecs
    6. &<公共请求参数>

    返回示例

    示例(按小时):

    1. {
    2. "Data": {
    3. "OmsData": [
    4. {
    5. "CPUs": "1",
    6. "InstanceId": "i-bp1hmito9v058zbua0eb",
    7. "OsDiskSize": "42949672960",
    8. "NetworkIn": "0",
    9. "NetworkOut": "0",
    10. "ImageOS": "Windows Server 2016",
    11. "Disk": "0",
    12. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    13. "DataDiskSize": "0",
    14. "IoOptimized": "true",
    15. "ImageSize": "42949672960",
    16. "Memory": "536870912",
    17. "Region": "cn-hangzhou-dg-a01",
    18. "OsDiskType": "cloud_efficiency",
    19. "TmpDataDiskSize": "0",
    20. "ProviderId": "26842",
    21. "EndTime": "2019-01-01T11:00:00Z",
    22. "SsdDataDiskSize": "0",
    23. "StartTime": "2019-01-01T10:00:00Z",
    24. "CloudDataDiskSize": "0",
    25. "Bandwidth": "1048576"
    26. },
    27. {
    28. "CPUs": "1",
    29. "InstanceId": "i-bp1hmito9v058zbua0eb",
    30. "OsDiskSize": "42949672960",
    31. "NetworkIn": "0",
    32. "NetworkOut": "0",
    33. "ImageOS": "Windows Server 2016",
    34. "Disk": "0",
    35. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    36. "DataDiskSize": "0",
    37. "IoOptimized": "true",
    38. "ImageSize": "42949672960",
    39. "Memory": "536870912",
    40. "Region": "cn-hangzhou-dg-a01",
    41. "OsDiskType": "cloud_efficiency",
    42. "TmpDataDiskSize": "0",
    43. "ProviderId": "26842",
    44. "EndTime": "2019-01-01T12:00:00Z",
    45. "SsdDataDiskSize": "0",
    46. "StartTime": "2019-01-01T11:00:00Z",
    47. "CloudDataDiskSize": "0",
    48. "Bandwidth": "1048576"
    49. },
    50. {
    51. "CPUs": "1",
    52. "InstanceId": "i-bp1hmito9v058zbua0eb",
    53. "OsDiskSize": "42949672960",
    54. "NetworkIn": "0",
    55. "NetworkOut": "0",
    56. "ImageOS": "Windows Server 2016",
    57. "Disk": "0",
    58. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    59. "DataDiskSize": "0",
    60. "IoOptimized": "true",
    61. "ImageSize": "42949672960",
    62. "Memory": "536870912",
    63. "Region": "cn-hangzhou-dg-a01",
    64. "OsDiskType": "cloud_efficiency",
    65. "TmpDataDiskSize": "0",
    66. "ProviderId": "26842",
    67. "EndTime": "2019-01-01T13:00:00Z",
    68. "SsdDataDiskSize": "0",
    69. "StartTime": "2019-01-01T12:00:00Z",
    70. "CloudDataDiskSize": "0",
    71. "Bandwidth": "1048576"
    72. },
    73. {
    74. "CPUs": "1",
    75. "InstanceId": "i-bp1hmito9v058zbua0eb",
    76. "OsDiskSize": "42949672960",
    77. "NetworkIn": "0",
    78. "NetworkOut": "0",
    79. "ImageOS": "Windows Server 2016",
    80. "Disk": "0",
    81. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    82. "DataDiskSize": "0",
    83. "IoOptimized": "true",
    84. "ImageSize": "42949672960",
    85. "Memory": "536870912",
    86. "Region": "cn-hangzhou-dg-a01",
    87. "OsDiskType": "cloud_efficiency",
    88. "TmpDataDiskSize": "0",
    89. "ProviderId": "26842",
    90. "EndTime": "2019-01-01T14:00:00Z",
    91. "SsdDataDiskSize": "0",
    92. "StartTime": "2019-01-01T13:00:00Z",
    93. "CloudDataDiskSize": "0",
    94. "Bandwidth": "1048576"
    95. },
    96. {
    97. "CPUs": "1",
    98. "InstanceId": "i-bp1hmito9v058zbua0eb",
    99. "OsDiskSize": "42949672960",
    100. "NetworkIn": "0",
    101. "NetworkOut": "0",
    102. "ImageOS": "Windows Server 2016",
    103. "Disk": "0",
    104. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    105. "DataDiskSize": "0",
    106. "IoOptimized": "true",
    107. "ImageSize": "42949672960",
    108. "Memory": "536870912",
    109. "Region": "cn-hangzhou-dg-a01",
    110. "OsDiskType": "cloud_efficiency",
    111. "TmpDataDiskSize": "0",
    112. "ProviderId": "26842",
    113. "EndTime": "2019-01-01T15:00:00Z",
    114. "SsdDataDiskSize": "0",
    115. "StartTime": "2019-01-01T14:00:00Z",
    116. "CloudDataDiskSize": "0",
    117. "Bandwidth": "1048576"
    118. },
    119. {
    120. "CPUs": "1",
    121. "InstanceId": "i-bp1hmito9v058zbua0eb",
    122. "OsDiskSize": "42949672960",
    123. "NetworkIn": "0",
    124. "NetworkOut": "0",
    125. "ImageOS": "Windows Server 2016",
    126. "Disk": "0",
    127. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    128. "DataDiskSize": "0",
    129. "IoOptimized": "true",
    130. "ImageSize": "42949672960",
    131. "Memory": "536870912",
    132. "Region": "cn-hangzhou-dg-a01",
    133. "OsDiskType": "cloud_efficiency",
    134. "TmpDataDiskSize": "0",
    135. "ProviderId": "26842",
    136. "EndTime": "2019-01-01T16:00:00Z",
    137. "SsdDataDiskSize": "0",
    138. "StartTime": "2019-01-01T15:00:00Z",
    139. "CloudDataDiskSize": "0",
    140. "Bandwidth": "1048576"
    141. },
    142. {
    143. "CPUs": "1",
    144. "InstanceId": "i-bp1hmito9v058zbua0eb",
    145. "OsDiskSize": "42949672960",
    146. "NetworkIn": "0",
    147. "NetworkOut": "0",
    148. "ImageOS": "Windows Server 2016",
    149. "Disk": "0",
    150. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    151. "DataDiskSize": "0",
    152. "IoOptimized": "true",
    153. "ImageSize": "42949672960",
    154. "Memory": "536870912",
    155. "Region": "cn-hangzhou-dg-a01",
    156. "OsDiskType": "cloud_efficiency",
    157. "TmpDataDiskSize": "0",
    158. "ProviderId": "26842",
    159. "EndTime": "2019-01-01T17:00:00Z",
    160. "SsdDataDiskSize": "0",
    161. "StartTime": "2019-01-01T16:00:00Z",
    162. "CloudDataDiskSize": "0",
    163. "Bandwidth": "1048576"
    164. },
    165. {
    166. "CPUs": "1",
    167. "InstanceId": "i-bp1hmito9v058zbua0eb",
    168. "OsDiskSize": "42949672960",
    169. "NetworkIn": "0",
    170. "NetworkOut": "0",
    171. "ImageOS": "Windows Server 2016",
    172. "Disk": "0",
    173. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    174. "DataDiskSize": "0",
    175. "IoOptimized": "true",
    176. "ImageSize": "42949672960",
    177. "Memory": "536870912",
    178. "Region": "cn-hangzhou-dg-a01",
    179. "OsDiskType": "cloud_efficiency",
    180. "TmpDataDiskSize": "0",
    181. "ProviderId": "26842",
    182. "EndTime": "2019-01-01T18:00:00Z",
    183. "SsdDataDiskSize": "0",
    184. "StartTime": "2019-01-01T17:00:00Z",
    185. "CloudDataDiskSize": "0",
    186. "Bandwidth": "1048576"
    187. },
    188. {
    189. "CPUs": "1",
    190. "InstanceId": "i-bp1hmito9v058zbua0eb",
    191. "OsDiskSize": "42949672960",
    192. "NetworkIn": "0",
    193. "NetworkOut": "0",
    194. "ImageOS": "Windows Server 2016",
    195. "Disk": "0",
    196. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    197. "DataDiskSize": "0",
    198. "IoOptimized": "true",
    199. "ImageSize": "42949672960",
    200. "Memory": "536870912",
    201. "Region": "cn-hangzhou-dg-a01",
    202. "OsDiskType": "cloud_efficiency",
    203. "TmpDataDiskSize": "0",
    204. "ProviderId": "26842",
    205. "EndTime": "2019-01-01T19:00:00Z",
    206. "SsdDataDiskSize": "0",
    207. "StartTime": "2019-01-01T18:00:00Z",
    208. "CloudDataDiskSize": "0",
    209. "Bandwidth": "1048576"
    210. },
    211. {
    212. "CPUs": "1",
    213. "InstanceId": "i-bp1hmito9v058zbua0eb",
    214. "OsDiskSize": "42949672960",
    215. "NetworkIn": "0",
    216. "NetworkOut": "0",
    217. "ImageOS": "Windows Server 2016",
    218. "Disk": "0",
    219. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    220. "DataDiskSize": "0",
    221. "IoOptimized": "true",
    222. "ImageSize": "42949672960",
    223. "Memory": "536870912",
    224. "Region": "cn-hangzhou-dg-a01",
    225. "OsDiskType": "cloud_efficiency",
    226. "TmpDataDiskSize": "0",
    227. "ProviderId": "26842",
    228. "EndTime": "2019-01-01T20:00:00Z",
    229. "SsdDataDiskSize": "0",
    230. "StartTime": "2019-01-01T19:00:00Z",
    231. "CloudDataDiskSize": "0",
    232. "Bandwidth": "1048576"
    233. },
    234. {
    235. "CPUs": "1",
    236. "InstanceId": "i-bp1hmito9v058zbua0eb",
    237. "OsDiskSize": "42949672960",
    238. "NetworkIn": "0",
    239. "NetworkOut": "0",
    240. "ImageOS": "Windows Server 2016",
    241. "Disk": "0",
    242. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    243. "DataDiskSize": "0",
    244. "IoOptimized": "true",
    245. "ImageSize": "42949672960",
    246. "Memory": "536870912",
    247. "Region": "cn-hangzhou-dg-a01",
    248. "OsDiskType": "cloud_efficiency",
    249. "TmpDataDiskSize": "0",
    250. "ProviderId": "26842",
    251. "EndTime": "2019-01-01T21:00:00Z",
    252. "SsdDataDiskSize": "0",
    253. "StartTime": "2019-01-01T20:00:00Z",
    254. "CloudDataDiskSize": "0",
    255. "Bandwidth": "1048576"
    256. },
    257. {
    258. "CPUs": "1",
    259. "InstanceId": "i-bp1hmito9v058zbua0eb",
    260. "OsDiskSize": "42949672960",
    261. "NetworkIn": "0",
    262. "NetworkOut": "0",
    263. "ImageOS": "Windows Server 2016",
    264. "Disk": "0",
    265. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    266. "DataDiskSize": "0",
    267. "IoOptimized": "true",
    268. "ImageSize": "42949672960",
    269. "Memory": "536870912",
    270. "Region": "cn-hangzhou-dg-a01",
    271. "OsDiskType": "cloud_efficiency",
    272. "TmpDataDiskSize": "0",
    273. "ProviderId": "26842",
    274. "EndTime": "2019-01-01T22:00:00Z",
    275. "SsdDataDiskSize": "0",
    276. "StartTime": "2019-01-01T21:00:00Z",
    277. "CloudDataDiskSize": "0",
    278. "Bandwidth": "1048576"
    279. },
    280. {
    281. "CPUs": "1",
    282. "InstanceId": "i-bp1hmito9v058zbua0eb",
    283. "OsDiskSize": "42949672960",
    284. "NetworkIn": "0",
    285. "NetworkOut": "0",
    286. "ImageOS": "Windows Server 2016",
    287. "Disk": "0",
    288. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    289. "DataDiskSize": "0",
    290. "IoOptimized": "true",
    291. "ImageSize": "42949672960",
    292. "Memory": "536870912",
    293. "Region": "cn-hangzhou-dg-a01",
    294. "OsDiskType": "cloud_efficiency",
    295. "TmpDataDiskSize": "0",
    296. "ProviderId": "26842",
    297. "EndTime": "2019-01-01T23:00:00Z",
    298. "SsdDataDiskSize": "0",
    299. "StartTime": "2019-01-01T22:00:00Z",
    300. "CloudDataDiskSize": "0",
    301. "Bandwidth": "1048576"
    302. },
    303. {
    304. "CPUs": "1",
    305. "InstanceId": "i-bp1hmito9v058zbua0eb",
    306. "OsDiskSize": "42949672960",
    307. "NetworkIn": "0",
    308. "NetworkOut": "0",
    309. "ImageOS": "Windows Server 2016",
    310. "Disk": "0",
    311. "InstanceTypeName": "ecs.t5-lc2m1.nano",
    312. "DataDiskSize": "0",
    313. "IoOptimized": "true",
    314. "ImageSize": "42949672960",
    315. "Memory": "536870912",
    316. "Region": "cn-hangzhou-dg-a01",
    317. "OsDiskType": "cloud_efficiency",
    318. "TmpDataDiskSize": "0",
    319. "ProviderId": "26842",
    320. "EndTime": "2019-01-02T00:00:00Z",
    321. "SsdDataDiskSize": "0",
    322. "StartTime": "2019-01-01T23:00:00Z",
    323. "CloudDataDiskSize": "0",
    324. "Bandwidth": "1048576"
    325. }
    326. ],
    327. "HostId": "cn",
    328. "Marker": "079:00000000000000002895:r:01_1711245632317223:02_vm:03_26842:04_i-bp1hmito9v058zbua0eb:05_000000000001546696800:"
    329. },
    330. "Message": "Successful!",
    331. "RequestId": "9A1F6898-EFAA-4C16-A38E-AA3A98FBF232",
    332. "Success": true,
    333. "Code": "Success"
    334. }

    ]]> 导出镜像_自定义镜像_镜像_云服务器 ECS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 导出镜像

    更新时间:2020-06-01 16:23:44

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    创建自定义镜像后,您可以导出镜像到OSS存储空间(OSS Bucket),并下载到本地使用。本文介绍导出自定义镜像的操作步骤及相关注意事项。

    前提条件

    • 自定义镜像所在地域中已有可用的OSS Bucket。

      若尚未创建OSS Bucket,请先创建存储空间

      说明 导出自定义镜像会产生一定的OSS存储和下载的流量费用。计费详情,请参见计量项和计费项

    • 待导出的自定义镜像满足以下限制条件:
      • 不是基于镜像市场镜像创建的自定义镜像。
      • 不能包含Windows Server系列操作系统。
      • 不能包含四块以上数据盘快照,单块数据盘容量最大不能超过500GiB。

    背景信息

    导出自定义镜像的注意事项如下:

    • 导出镜像所需时间取决于自定义镜像文件的大小和当前导出任务的并发数,需要您耐心等待。
    • 导出的自定义镜像包含数据盘快照时,您的OSS Bucket中会出现多个文件。

      文件名带有system的表示系统盘快照,文件名带有data的表示数据盘快照。数据盘快照会有与数据盘对应的标识,即数据盘的挂载点,如xvdb或者xvdc。

    • 使用导出的全镜像创建相同配置的Linux系统时,您需要确认/etc/fstab中记录的文件设备是否与导出的数据盘快照信息互相对应。
    • 如果创建自定义镜像时云盘内无数据,那么导出镜像后解压缩也无数据。

    操作步骤

    1. 登录ECS管理控制台
    2. 在左侧导航栏,单击实例与镜像 > 镜像
    3. 在顶部菜单栏左上角处,选择地域。
    4. 授权ECS服务访问OSS的权限。
      1. 在自定义镜像的操作列中,单击更多 > 导出镜像
      2. 导出镜像对话框里,单击提示信息里的确认地址

        导出镜像

      3. 云资源访问授权对话框,单击同意授权授权ECS服务访问您的OSS资源。
    5. 在左侧导航栏,单击实例与镜像 > 镜像
    6. 自定义镜像列表页签,选择目标镜像,在操作列中,再次单击更多 > 导出镜像
    7. 导出镜像对话框中,配置如下参数:

      • 选择镜像导出的格式,支持RAW、VHD、QCOW2、VDI和VMDK。

        说明 选择镜像导出格式功能正在逐步开放中。

      • 选择一个与自定义镜像所属地域相同的OSS Bucket。
      • 为自定义镜像的Object名称设置一个前辍。例如,您可以将Demo设为前辍,则导出的自定义镜像文件,在OSS Bucket中的名称即为Demo-[系统自动生成的文件名]

    8. 单击确定,开始导出自定义镜像。

      在任务完成前,您都可以通过任务管理,在相应地域下找到导出自定义镜像的任务,取消导出自定义镜像。

    后续步骤

    下载自定义镜像。具体操作步骤,请参见下载自定义镜像文件

    说明 如果您选择RAW作为镜像格式,导出后镜像文件扩展名默认为.raw.tar.gz,解压后扩展名为.raw。如果您的本地计算机为Mac OS X系统,推荐您使用gnu-tar解压工具。

    ]]> 独享云虚拟主机、共享云虚拟主机、云服务器 ECS 的区别?_产品概述_产品简介_云虚拟主机-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 独享云虚拟主机、共享云虚拟主机、云服务器 ECS 的区别?

    更新时间:2018-03-16 10:57:13

    本页目录

    产品特点

    共享云虚拟主机:共享虚拟主机即一台服务器被划分成多个一定大小的空间,每个空间都给予单独的 FTP 权限和 Web 访问权限,多个用户共同平均使用这台服务器的硬件资源。

    独享云虚拟主机:与共享云虚拟主机相比,最大的不同是资源独享。享有整个服务器的软硬件资源,即每台轻云服务器的 CPU、内存、带宽、硬盘均为独享,且不限流量,具有独立 IP,预装了网站应用环境就和数据库环境,同时具备共享云虚拟主机和云服务器的优势。提供可视化操作的控制面板环境,操作简单,即买即用。

    云服务器:是一种弹性计算服务,支持各种应用软件灵活扩展,需要有专业技术人员来维护。

    注意: 虚拟主机不支持远程登录,包括SSH方式,远程桌面RDP方式等。如果您需要远程桌面权限管理,建议您购买云服务器 ECS 。

    适用用户

    共享云虚拟主机:资源共享,空间较大,固定流量,经济实惠,满足基本建站。

    独享云虚拟主机:独享资源,空间超大,不限流量,更高配置,企业建站首选。

    云服务器 ECS  :有技术实力、懂得服务器配置及维护的用户及开发者。

    主要配置

    主要配置

    虚拟主机

    独享版虚拟主机

    云服务器ECS

    网页空间

    M/G级空间

    G级空间

    独享整块硬盘

    CPU

    共享

    独享

    独享

    内存

    共享

    独享

    独享

    带宽

    共享

    独享

    独享

    流量

    有限制

    无限制

    无限制

    主机管理控制台

    支持

    支持

    不支持

    付费方式

    年付

    月付/年付

    月付/年付

    下一篇:什么是临时域名

    相关文档

    相关产品

    • 云虚拟主机

      阿里云虚拟主机主要用于搭建网站,提供预装网站运行环境,赠送正版数据库,可通过图形化控制面板管理,包括独享系列虚机和共享系列虚机。独享系列适合企业建站客户,提供独享的服务器资源,无资源争抢更稳定,不限流量更快速、独立IP更易推广;共享系列适合于开发者、个人站长建站,多客户共享服务器硬件资源,价格优惠,简单易用

    • 云服务器 ECS

      云服务器(Elastic Compute Service,简称 ECS)是一种简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本,使您更专注于核心业务创新。

    • 云解析 DNS

      云解析DNS(Alibaba Cloud DNS)是一种安全、快速、稳定、可扩展的权威DNS服务,云解析DNS为企业和开发者将易于管理识别的域名转换为计算机用于互连通信的数字IP地址,从而将用户的访问路由到相应的网站或应用服务器。

    以上内容是否对您有帮助?

    在文档使用中是否遇到以下问题

    • 内容错误

    • 更新不及时

    • 链接错误

    • 缺少代码/图片示例

    • 太简单/步骤待完善

    • 其他

    • 内容错误

    • 更新不及时

    • 链接错误

    • 缺少代码/图片示例

    • 太简单/步骤待完善

    • 其他

    更多建议

    匿名提交

    感谢您的打分,是否有意见建议想告诉我们?

    感谢您的反馈,反馈我们已经收到

    文档反馈

    ]]>
    ALIYUN::ECS::Command_ECS_资源类型_资源编排-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ALIYUN::ECS::Command

    更新时间:2020-02-25 10:06:55

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    ALIYUN::ECS::Command 类型用于新建云助手命令。

    语法

    {
      "Type": "ALIYUN::ECS::Command",
      "Properties": {
        "Name": String,
        "WorkingDir": String,
        "CommandContent": String,
        "Timeout": Integer,
        "Type": String,
        "Description": String
      }
    }

    属性

    属性名称 类型 必须 允许更新 描述 约束
    Name String 命令名称,支持全字符集。长度不得超过 30 个字符。
    WorkingDir String 您创建的命令在 ECS 实例中运行的目录。
    CommandContent String

    命令 Base64 编码后的内容。

    当您传入请求参数 Type 后,必须同时传入该参数。

    该参数的值必须使用 Base64 编码后传输,且脚本内容的大小在 Base64 编码之后不能超过 16 KB。

    Timeout Integer

    您创建的命令在 ECS 实例中执行时最大的超时时间,单位为秒。

    当因为某种原因无法运行您创建的命令时,会出现超时现象;超时后,会强制终止命令进程,即取消命令的 PID。

    默认值:3600

    Type String

    命令的类型。

    取值范围:
    • RunBatScript:创建一个在 Windows 实例中运行的 Bat 脚本
    • RunPowerShellScript:创建一个在 Windows 实例中运行的 PowerShell 脚本
    • RunShellScript:创建一个在 Linux 实例中运行的 Shell 脚本
    Description String 命令描述,支持全字符集。长度不得超过100个字符。

    返回值

    Fn::GetAtt

    • CommandId:命令 ID。

    示例

    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "WorkingDir": {
          "Type": "String",
          "Description": "The path where command will be executed in the instance."
        },
        "CommandContent": {
          "Type": "String",
          "Description": "The content of command. Content requires base64 encoding. Maximum size support 16KB."
        },
        "Type": {
          "Type": "String",
          "Description": "The type of command."
        },
        "Description": {
          "Type": "String",
          "Description": "The description of command."
        },
        "Timeout": {
          "Type": "Number",
          "Description": "Total timeout when the command is executed in the instance. Input the time unit as second. Default is 3600s."
        },
        "Name": {
          "Type": "String",
          "Description": "The name of command."
        }
      },
      "Resources": {
        "Command": {
          "Type": "ALIYUN::ECS::Command",
          "Properties": {
            "WorkingDir": {
              "Ref": "WorkingDir"
            },
            "CommandContent": {
              "Ref": "CommandContent"
            },
            "Type": {
              "Ref": "Type"
            },
            "Description": {
              "Ref": "Description"
            },
            "Timeout": {
              "Ref": "Timeout"
            },
            "Name": {
              "Ref": "Name"
            }
          }
        }
      },
      "Outputs": {
        "CommandId": {
          "Description": "The id of command created.",
          "Value": {
            "Fn::GetAtt": [
              "Command",
              "CommandId"
            ]
          }
        }
      }
    }

    ]]> 更换源站ECS公网IP_接入DDoS高防_DDoS高防(新BGP&国际)_DDoS防护-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 更换源站ECS公网IP

    更新时间:2020-05-29 09:36:26

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    若您的源站IP已暴露,建议您更换阿里云ECS云服务器的公网IP,防止黑客绕过DDoS高防直接攻击源站。您可以在DDoS高防管理控制台更换后端ECS的IP,每个账号最多可更换10次。

    背景信息

    更换ECS IP功能仅支持使用经典网络公网IP的ECS更换IP。

    操作步骤

    1. 登录DDoS高防控制台
    2. 在顶部导航栏,选择服务所在地域:
      • 中国内地:DDoS高防(新BGP)服务
      • 非中国内地:DDoS高防(国际)服务
    3. 在左侧导航栏,单击接入管理 > 域名接入
    4. 域名接入页面右上方,单击更换ECS IP

      注意 更换ECS IP会使您的业务暂时中断几分钟,建议您在操作前先备份好数据。

    5. 更换ECS IP需要将ECS停机,若您已将需要更换IP的ECS停机,请直接跳转到步骤6。在更换ECS IP对话框,单击前往ECS,并在ECS管理控制台将需要更换IP的ECS实例停机。
      1. 在实例列表中找到目标ECS实例,单击其实例ID。
      2. 在实例详情页,单击停止
      3. 选择停止方式,并单击确定

        注意 停止ECS实例是敏感操作,稳妥起见,需要您输入手机校验码。

      4. 等待ECS实例状态变成已停止
    6. 返回更换ECS IP对话框,输入ECS实例ID,并单击下一步
    7. 确认当前ECS实例信息准确无误(尤其是ECS IP)后,单击释放IP
    8. 成功释放原IP后,单击下一步,为该ECS实例自动分配新的IP。
    9. ECS IP更换成功后,单击确认,完成操作。

      说明 更换IP成功后,请将新的IP隐藏在DDoS高防后面,不要对外暴露。

    ]]> ECS实例与MongoDB实例地域不同时如何连接_连接实例_用户指南_云数据库 MongoDB-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ECS实例与MongoDB实例地域不同时如何连接

    更新时间:2020-04-21 14:44:03

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    当ECS实例与MongoDB实例的地域不同时,您可根据本文中的办法快速实现两者之间的连接。

    方法一:将MongoDB实例迁移至ECS实例所属地域

    本方法通过数据传输服务DTS(Data Transmission Service)的数据迁移功能,实现迁移MongoDB实例至ECS实例所属地域的目的,例如将MongoDB实例从华北1迁移至华东1。

    迁移MongoDB至其他地域
    1. 在ECS所属地域创建MongoDB实例,详情请参见创建实例,如果已创建可跳过本步骤。
    2. 将源地域下的MongoDB数据库迁移至目标MongoDB实例,详情请参见迁移MongoDB实例至其他地域
    3. 将ECS实例的IP地址加入目标MongoDB实例的白名单中,详情请参见设置白名单

      说明 关于获取ECS实例IP地址信息,请参见如何查询ECS实例的IP地址

    方法二:将ECS实例迁移至MongoDB实例所属地域

    下述两种方法分别通过自定义镜像和迁云工具,实现迁移ECS实例数据至MongoDB实例所属地域的目的,例如将ECS实例从华北1迁移至华东1。

    迁移ECS地域

    ]]> ECS自建库录入_实例列表_实例管理_数据管理 DMS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ECS自建库录入

    更新时间:2020-06-18 10:29:00

    本页目录

    需求背景

    • 目前云上除了云数据库外,也有用户通过ECS自己搭建的各种数据库。本文主要描述ECS自建库如何快速录入进行管理。

    关键步骤

    基本录入步骤需要提供信息可参见:实例管理

    1. 在填写完基本信息点击【测试连接】,会遇到如下错误。

      测试连接

    2. 此时需要前往ECS控制台进行白名单的添加,注意“授权对象”为报错弹层上的DMS服务器白名单地址(含网段)。

      添加

    3. 按照步骤2完成入口方向、出口方向,双向配置【注:仅单向配置会无法使用】。

      • 入口方向入口

      • 出口方向出口

    4. 完成出口、入口配置后,再测试连接即可访问进入保存环节【注:ECS白名单策略添加后可能存在轻微的延迟,建议稍后1-3分钟再到DMS企业版内重试连接】。

    ]]> 对ECS集群中的应用进行弹性伸缩_应用管理_ECS集群用户指南_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 对ECS集群中的应用进行弹性伸缩

    更新时间:2020-04-08 14:19:41

    本页目录

    在分布式应用管理中,弹性伸缩是很重要的一个运维能力。弹性伸缩能够感知应用内各个实例的状态,并根据状态动态实现应用扩容、缩容。在保证服务质量的同时,提升应用的可用率。

    弹性伸缩简介

    互联网、游戏类等应用在促销活动期间容易出现突发性流量洪流,SLA 和资源成本不易平衡,极易造成系统响应延迟、系统瘫痪等问题。EDAS 继承阿里巴巴应对双 11 的流量洪流技术,提供秒级自动弹性功能,保证 SLA 的同时也节省机器保有成本。多适用于互联网、游戏以及社交平台等行业。

    弹性伸缩适用于在ECS集群中创建的应用。在单实例环境中,弹性伸缩可确保始终有一个正在运行的实例。在流量变化很快的环境中,通过弹性伸缩配置要运行的实例数范围,EDAS 将根据设置的负载规则按需添加或删除实例。

    弹性伸缩功能根据应用实例的以下指标来判断并实现自动扩容或者缩容:

    • CPU:CPU 使用率,以百分比表示。
    • RT:对请求作出的响应时间,单位为 ms 。
    • Load:应用实例的负载大小,以正整数表示。

    自动弹性伸缩

    弹性伸缩包括自动扩容和自动缩容,可以分别配置扩容规则或者缩容规则。下面以配置扩容规则为例来展示操作步骤。

    说明

    • 同时配置扩容和缩容规则的时候,缩容规则的指标不能大于扩容规则的指标,否则,在单击保存的时候会弹出错误提示。
    • 若使用了弹性资源,缩容时会优先释放弹性资源提供的实例。

    1. 登录 EDAS 控制台,在页面左上角选择所需地域。
    2. 在左侧导航栏中选择应用管理 > 应用列表 ,在应用列表页面单击具体的应用名称。
    3. 在应用详情页面左侧的导航栏中,单击弹性伸缩
    4. 扩容规则区域右上角打开开关启用扩容规则。
    5. 配置扩容规则参数,然后在弹性伸缩页面右下角单击保存
      1. 配置触发指标:设置 CPU、RT 和 Load 指标的阈值。当超过阈值时,触发扩容。
      2. 选择触发条件

        • 任一指标:表示设定的指标中任意一个指标被触发都会引起扩容。
        • 所有指标:表示设定所有指标必须全部被触发才能引发自动扩容操作。

      3. 持续时间超过:指标持续被触发的时间,单位为分钟。表示在持续时间内,指标每分钟的平均值持续达到设置的阈值,就会引起扩容操作,您可根据集群服务能能力的灵敏度酌情配置。
      4. 配置应用来源

        • 已有资源:自动扩容时会从当前应用所在集群选择指定数量的闲置 ECS 实例扩容到该应用。

          说明 当所在集群中现有的 ECS 实例数量不够,无法满足扩容需求时,EDAS 会根据已有实例数量来进行扩容。

        • 弹性资源:基于现有实例规格或实例启动模版来代购实例,然后自动将代购的实例导入所在集群并用于应用扩容。ECS集群中代购实例用于弹性伸缩
          参数 描述
          创建方式
          • 基于现有实例规格购买:从所在集群内已有的实例规格中选择一个作为模板来代购实例。
          • 基于实例启动模版购买:会基于您在 ECS 控制台创建的实例启动模版来代购实例。
          模板主机/启动模板 选择一个现有实例规格或者选择一个启动模板作为模板来代购实例。
          登录密钥 当选择基于现有实例规格购买时,需要选择登录密钥。
          服务协议 勾选《云服务器 ECS 服务条款》 | 《镜像商品使用条款》
          高级选项(可选)
          • 基于现有实例规格购买:输入登录密码后,新创建的 ECS 实例将以此密钥对作为 SSH 登录认证方式。
          • 基于实例启动模版购买网络类型为您需要扩容的当前应用所在的网络,不可更改。如果当前网络为 VPC 网络,需要指定新创建实例连接的虚拟交换机;若指定多个虚拟交换机,EDAS 将通过多可用区扩缩容策略来进行自动分配。
        • 已有资源优先:自动扩容时优先使用集群内空闲实例,如果集群内的空闲实例不足,则使用弹性伸缩功能为您代购实例。

      5. 设置每次扩容的实例数:每次触发扩容操作后,自动增加的实例个数。
      6. 设置分组最大实例数:当集群内服务器数量达到配置的最大实例数后,不再继续扩容,请根据您的资源限额配置。

    查看弹性伸缩结果

    设置了弹性伸缩规则后,如果发生了自动扩容或者自动缩容操作后,您可以通过以下方式来查看伸缩结果:

    • 在应用的基本信息页面中查看实例数量是否增加或者减少。
    • 在应用详情页面的左侧导航栏单击变更记录。对于变更类型为应用扩容应用缩容,且来源是auto_scale的变更记录,在操作列单击查看进入变更详情页面查看变更明细。弹性伸缩变更记录

    ]]> 在自定义环境中代购的 ECS 实例上部署微服务应用_快速创建 Demo 微服务应用_快速入门_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 在自定义环境中代购的 ECS 实例上部署微服务应用

    更新时间:2019-09-18 19:36:26

    本页目录

    为方便您快速开始使用 EDAS,EDAS 为您准备了基于不同应用框架(Spring Cloud、Dubbo 和 HSF)的微服务应用 Demo,您可以将应用 Demo 快速部署到 EDAS 中。本文介绍如何在自定义环境中(指定 VPC 和集群)中代购 ECS 实例快速部署 Spring Cloud 微服务应用 Demo。

    前提条件

    在默认环境中代购的 ECS 实例中部署应用前,请先完成以下工作:

    操作步骤

    微服务应用 Demo 中都会包含一个服务提供者和服务消费者。下面以服务提供者为例介绍如何创建,在创建完服务提供者之后,请按照操作步骤再创建服务消费者。

    创建服务提供者的步骤如下:

    1. 登录 EDAS 控制台。

    2. 概览页面应用数上方单击创建新应用

      创建新应用

    3. 创建应用页面的应用基本信息页签中选择集群类型应用运行环境,输入应用名称应用描述(可选),然后单击下一步

      应用基本信息-Spring Cloud

      • 集群类型:选择 ECS 集群
      • 应用运行环境:针对不同应用框架,EDAS 提供了不同的应用运行环境,您可以根据您的应用框架选择,本示例中选择 Java

        Java 环境:选择 Open JDK 8

      • 应用名称:输入应用名称,如 app-demo-springCloud-provider
    4. 应用配置页签中选择部署包来源Demo 类型实例,然后单击下一步

      应用配置-SC-自定义环境

      • 部署包来源:选择官方 Demo

      • Demo 类型:在下拉列表中选择具体的应用 Demo,如 Spring Cloud 服务端应用

      • 实例:选择自定义

        选择自定义后,界面会根据您的账号当前的资源情况有所不同。

        • 网络和环境

          • 如果您当前没有 VPC、命名空间和集群,EDAS 会为您创建默认环境。

          • 如果您已经创建过 VPC、命名空间和集群等资源,会显示对应资源的选择列表。您可以在下拉列表中选择对应资源。

        • 实例

          • 选择实例规格:选择实例规格,如超小规格实例
          • 购买数量:选择要购买的实例数量,如 1
          • 服务协议:勾选《云服务器 ECS 服务条款》 | 《镜像商品使用条款》
    5. 应用高级配置页签中输入版本应用健康检查(可选),然后单击创建应用

      • 版本:EDAS 配置使用当前时间戳作为版本,格式如 yyyymmdd:hhmmss。您也可以设置其它版本标识。
      • 应用健康检查:设置健康检查的 URL,用来检测应用是否健康运行。
    6. 应用创建完成页签确认应用基本信息、应用配置和应用高级设置,确认无误后,单击确定创建应用

      应用创建完成

    结果验证

    在服务端应用和客户端应用创建后,EDAS 将为该应用自动创建一条变更记录,您可以通过变更详情查看该应用创建的进度和状态。应用创建成功后,变更记录显示执行成功

    1. 应用创建成功后,返回该应用的基本信息页面,查看应用的相关信息,应该和创建时保持一致。

      结果验证-基本信息

    2. 单击实例部署信息查看该应用的状态,运行状态应为运行正常,变更状态(即第一次创建、部署)应为成功。同时,显示代购的 ECS 实例的 ID、IP、规格及 VPC 信息。

      结果验证-实例部署信息

    1. 验证应用 Demo 的调用是否成功。

      说明:验证调用需要按结果验证的步骤 1 和 2 确保服务端应用和客户端应用都部署成功。

      1. 进入客户端应用的详情页,在左侧导航栏单击基本信息,然后在实例部署信息页面单击 ECS 的 IP 地址。

      2. SC 客户端 页面的 Echo this String 文本框中输入任意字符串,如 test,然后单击 点击此处

        结果验证-调用

      3. SC 客户端 页面下方可以看到调用结果,返回了 test 字符串,说明调用成功。

        结果验证-调用成功

    ]]> 阿里云NTP服务器_同步服务器本地时间_管理实例_实例_云服务器 ECS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 阿里云NTP服务器

    更新时间:2020-04-22 08:38:31

    编辑 我的收藏

    新浪微博 微信 钉钉

    本页目录

    阿里云提供了内网和公网NTP服务器,用于同步各网络中ECS实例的本地时间。

    内网和公网NTP服务器

    NTP是用于同步网络中计算机时间的协议,全称为网络时间协议(Network Time Protocol)。

    时区和时间一致性对于云服务器ECS非常重要,有时会直接影响到任务执行的结果。例如,您在更新数据库或者分析日志时,时间顺序对结果有很大影响。为避免在ECS实例上运行业务时出现逻辑混乱和网络请求错误等问题,您需要统一相关ECS实例的时区设置。另外,您还可以通过NTP服务同步各网络中ECS实例的本地时间。

    云服务器ECS为您提供了高精度的时间参考NTP服务器,其中ntp.cloud.aliyuncs.com服务器提供分布式的一级时钟源,适用于金融、通讯、科研和天文等以时间精度核心的生产行业。阿里云NTP服务也用于同步ECS实例和其它云产品的本地时间。各网络下的阿里云NTP服务器地址如下表所示。

    经典网络内网 专有网络VPC内网 公网
    - ntp.cloud.aliyuncs.com ntp.aliyun.com
    ntp1.cloud.aliyuncs.com ntp7.cloud.aliyuncs.com ntp1.aliyun.com
    ntp2.cloud.aliyuncs.com ntp8.cloud.aliyuncs.com ntp2.aliyun.com
    ntp3.cloud.aliyuncs.com ntp9.cloud.aliyuncs.com ntp3.aliyun.com
    ntp4.cloud.aliyuncs.com ntp10.cloud.aliyuncs.com ntp4.aliyun.com
    ntp5.cloud.aliyuncs.com ntp11.cloud.aliyuncs.com ntp5.aliyun.com
    ntp6.cloud.aliyuncs.com ntp12.cloud.aliyuncs.com ntp6.aliyun.com
    - - ntp7.aliyun.com

    其他互联网基础服务

    阿里云还提供了其他的互联网基础服务,如下表所示。

    公共服务 描述
    公共DNS:223.5.5.5 / 223.6.6.6 域名:http://www.alidns.com
    公共镜像站:https://developer.aliyun.com/mirror 镜像同步频率:每天凌晨2:00−4:00。覆盖了大多数开源软件及Linux发行版。

    相关操作

    ]]> ECS迁移到时空_数据迁移_用户指南_时空数据库_时序时空数据库 TSDB-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 ECS迁移到时空

    更新时间:2019-05-06 19:09:38

    本页目录

    前提条件

    • ECS上自建基于PostgreSQL的PostGIS数据库或Timescale数据库
    • 已完成时空数据库的准备,包括数据库,账号,密码创建等。参见: 账号管理

    准备数据

    1. 登录云服务器ECS
    2. 执行pg_dump命令,备份数据

      1. pg_dump -U username -h hostname -p port databasename -f filename
      2. # 例如:使用postgres用户,备份gaia数据库,备份文件是gaia.sql
      3. pg_dump -U postgres -h localhost -p 5432 gaia -f gaia.sql

      参数说明如下:

      • username:ECS数据库用户名
      • hostname:ECS数据库主机名,如果是在本地ECS数据库主机登录,可以使用localhost
      • port:ECS数据库端口号
      • databasename:要备份的数据库名
      • filename:要生成的备份文件名称

    迁移到时空数据库

    1. 通过PostgreSQL客户端,执行如下命令将数据导入到时空数据库中

      1. psql -U username -h ip -d databasename -p port -f filename
      2. # 一个例子:其中47.110.145.173:3242是时空数据库地址
      3. psql -U postgres -h 47.110.145.173 -d postgres -p 3242 -f gaia.sql

      参数说明如下:

      • username:时空数据库用户名
      • ip:时空数据库地址
      • port:时空数据库端口号
      • databasename:时空数据库名
      • filename:ECS上备份的数据文件名

    ]]> 限制不同交换机下的ECS间的互通_最佳实践_网络ACL_专有网络 VPC-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 限制不同交换机下的ECS间的互通

    更新时间:2020-04-23 17:30:06

    本页目录

    本文为您介绍如何通过网络ACL功能限制不同交换机下的ECS的互通关系。

    前提条件

    操作前,请确保满足以下条件。
    • 已经注册了阿里云账号。如还未注册,请先完成账号注册。详细信息,请参见账号注册
    • 已经创建了VPC和交换机。详细信息,请参见创建专有网络
    • 已经在交换机中创建了ECS实例。详细信息,请参见使用向导创建实例

    背景信息

    某公司在云上创建了VPC,在VPC中创建了两个交换机,交换机1下创建了ECS1实例(192.168.1.206),交换机2下创建了ECS2实例(192.168.0.229)和ECS3实例(192.168.0.230)。因公司业务需要,要求ECS实例间、ECS与互联网间必须满足以下互通关系。

    • 禁止ECS1实例、ECS2实例、ECS3实例与互联网互通。
    • 禁止ECS1与ECS3互通。
    • 允许ECS1与ECS2互通。

    网络ACL场景

    如上图,您可以通过自定义设置网络ACL规则,并将网络ACL与交换机绑定,实现对交换机中ECS的流量的访问控制。

    配置流程图如下:网络ACL使用流程

    步骤一:创建网络ACL

    完成以下操作,创建网络ACL。

    1. 登录专有网络管理控制台
    2. 在左侧导航栏,单击网络ACL
    3. 在顶部状态栏处,选择网络ACL的地域。

      说明 目前,仅华北1(青岛)、华北2(北京)、华北5(呼和浩特)、西南1(成都)、华东1(杭州)、华东2(上海)、华南1(深圳)、华南2(河源)、中国香港、英国(伦敦)、美国(硅谷)、新加坡、德国(法兰克福)、印度(孟买)地域支持网络ACL功能。

    4. 网络ACL页面,单击创建网络ACL
    5. 创建网络ACL对话框中,根据以下信息配置网络ACL,然后单击确定

      • 专有网络:选择网络ACL所属的专有网络。
      • 名称:输入网络ACL的名称。
      • 描述:输入网络ACL的描述。

    步骤二:绑定交换机

    完成以下操作,将交换机1、交换机2绑定到网络ACL。

    1. 登录专有网络管理控制台
    2. 在左侧导航栏,单击网络ACL
    3. 在顶部状态栏处,选择网络ACL的地域。
    4. 网络ACL页面,找到目标网络ACL,单击操作列下的管理
    5. 已绑定资源页签下,单击关联资源
    6. 关联资源对话框,选择交换机1和交换机2,然后单击确定

    步骤三:添加网络ACL规则

    完成以下操作,为网络ACL添加入方向规则和出方向规则。

    1. 登录专有网络管理控制台
    2. 在左侧导航栏,单击网络ACL
    3. 在顶部状态栏处,选择网络ACL的地域。
    4. 网络ACL页面,找到目标网络ACL,单击操作列下的设置入方向规则
    5. 设置入方向规则页签下,单击创建入方向规则
    6. 创建入方向规则对话框,根据以下信息配置入方向规则,然后单击确定

      名称 生效顺序 策略 协议类型 源地址 目的端口范围
      允许来自ECS2的流量 1 允许 all 192.168.0.229/32 -1/-1
      允许来自ECS1的流量 2 允许 all 192.168.1.206/32 -1/-1
      拒绝来自所有地址的流量 3 拒绝 all 0.0.0.0/0 -1/-1

    7. 单击出方向规则页签,然后单击创建出方向规则
    8. 创建出方向规则对话框,根据以下信息配置出方向规则,然后单击确定

      名称 生效顺序 策略 协议类型 目的地址 目的端口范围
      允许去往ECS2的流量 1 允许 all 192.168.0.229/32 -1/-1
      允许去往ECS1的流量 2 允许 all 192.168.1.206/32 -1/-1
      拒绝去往所有地址的流量 3 拒绝 all 0.0.0.0/0 -1/-1

    步骤四:测试连通性

    完成以下操作,测试ECS间、ECS与互联网间的连通性。

    1. 登录ECS1实例。
    2. 通过ping命令分别pingECS2实例、ECS3实例、任意公网IP地址,验证通信是否正常。

      经验证,ECS1实例能访问ECS2实例,但不能访问ECS3实例和互联网。

      图 1. ECS1实例能访问ECS2实例
      ECS1实例能访问ECS2实例
      图 2. ECS1实例不能访问ECS3实例
      ECS1实例不能访问ECS3实例
      图 3. ECS1实例不能访问互联网
      ECS1实例不能访问互联网

    ]]> 创建 ECS 集群_集群_资源管理_ECS集群用户指南_企业级分布式应用服务 EDAS-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 创建 ECS 集群

    更新时间:2019-11-04 20:15:12

    本页目录

    在 EDAS 中创建一个 ECS 集群后,可以进入集群中直接购买 ECS 实例或导入已购买的 ECS 实例。 ##创建 ECS 集群

    创建 ECS 集群

    1. 登录 EDAS 控制台,在页面左上角选择地域。
    2. 在左侧导航栏中,选择资源管理 > 集群
    3. 集群页面上方选择命名空间,然后在右侧单击创建集群
    4. 创建集群对话框中设置集群参数,然后单击创建

      EDAS资源管理之创建ECS集群

      • 集群名称:输入集群名称。名字仅支持字母、数字、下划线(_)、中划线(-)和点(.),且长度不能超过64个字符。
      • 集群类型:选择 ECS
      • 集群网络类型:包括经典网络和 VPC 网络。根据实际需求在下拉菜单中选择网络类型。

      • VPC 网络:在下拉菜单中选择 VPC。

        说明:如果没有可选 VPC 网络,请单击创建 VPC 跳转到 VPC 控制台创建。

      • 命名空间:显示在集群列表页面选择的命名空间,不可配置。如果未选择,则默认显示地域。

      集群创建成功后当前页面右上角会出现创建成功的提示,同时新创建的集群会在集群列表中显示。

    添加 ECS 实例

    在 ECS 集群中添加 ECS 实例有两种方式:

    购买 ECS 实例

    1. 在集群列表选择 EDAS 集群页签,单击创建的 ECS 集群名称进入集群详情页面。
    2. 集群详情页面中右侧单击购买 ECS 扩容
    3. 集群扩容页面选择扩容方式,设置完成后单击下一步

      • 基于现有实例规格购买EDAS资源管理之创建ECS集群购买 ECS 实例
        1. 勾选集群中现有的实例作为规格模板,然后单击下一步
        2. 购买信息页签,选择计费方式购买数量,然后单击下一步
        3. 确认扩容页签,确认扩容信息,然后单击确认扩容
      • 基于启动实例模板购买: EDAS资源管理之创建ECS集群基于启动实例模板购买
        1. 扩容方式页签,选择启动模板和版本,然后单击下一步
        2. 购买信息页签,选择计费方式购买数量,然后单击下一步
        3. 确认扩容页签,确认扩容信息,然后单击确认扩容

    4. 执行完扩容操作后,会在页面上方提示已触发自动购买的流程,请查看变更流程获取实时信息。当实例导入完成后,返回集群详情页,实例的健康检查显示为运行中则表示实例购买成功。

    导入 ECS 实例

    EDAS 集群中导入 ECS 实例目前有两种操作分支:

    • 直接导入:无需镜像转化。
    • 转化后导入:使用 EDAS 官方镜像重装系统。重装后,实例中的所有数据都会被删除,并且需要设置新的实例登录密码。 ECS 实例满足以下任一情况,则不能直接导入:

      • 2017年12月1日之前创建的实例
      • 向经典网络的集群中导入的经典网络实例
      • 实例没有运行(已停止、启动中或停止中)
      • Windows 系统实例或不支持简单 shell 命令的实例
      • 非 ECS 集群间导入的实例
    1. 在集群列表选择 EDAS 集群页签,单击创建的 ECS 集群名称进入集群详情页面。
    2. 集群详情页面中右侧单击购买 ECS 扩容右侧的下拉按钮,在下拉列表中单击添加已有 ECS
    3. 添加ECS实例页面的实例列表中,选择导入方式和 ECS 实例,然后单击下一步
      • 导入 ECS:命名空间和导入集群不可配置,从该地域下默认的命名空间向集群中导入。
      • 从已有集群选择:在该地域下,选择命名空间以及源集群。然后将页面左侧列表中的 ECS 实例添加到右侧列表中。EDAS资源原理导入ECS之从已有集群选择

        说明 如果没有符合条件的实例,在页面右上角单击创建 ECS 实例,跳转到阿里云官网 ECS 购买页面,购买并创建新的 ECS 实例。详情请参考创建 ECS 实例

    4. 准备导入页面,查看实例的导入状态,确认实例信息,单击确认并导入
      • 直接导入:在准备导入页面,查看选择的实例信息,单击确认并导入
      • 转化后导入:在准备导入页面,查看选择的实例信息,勾选同意对以上需要导入的实例进行转化,并已知转化后原有系统中的数据将会丢失。并输入转化后系统 root 用户登录的新密码,然后单击确认并导入
    5. 进行导入页面上查看实例的导入状态。当实例导入完成后,返回集群详情页,实例的健康检查显示为运行中则表示导入成功。
      • 直接导入:会显示直接导入成功
      • 转化后导入:开始导入时,会显示为正在转化中,转化操作预计耗时五分钟

    移除 ECS 实例

    1. 在页面 ECS 实例和应用区域实例列表的操作列中,单击移除
    2. 移除 ECS 实例对话框中确认要移除的实例信息,单击移除

      在移除过程中,实例的健康检查状态会显示删除中并显示移除进度的百分比。当删除成功后,该实例将会从实例列表中移除。

    ]]> OOS操作ECS分组资源的权限策略管理_权限配置_最佳实践_运维编排服务-阿里云 Sat, 04 Jul 2020 09:33:04 +0800 OOS操作ECS分组资源的权限策略管理

    更新时间:2019-11-15 12:18:25

    本页目录

    背景

    阿里云账号分为主账号(用户)和子账号(用户)两类,主账号为注册阿里云时的账号,其权限为root,出于安全考虑,建议实际操作时采用子账号。而操作员工的职责不同,不同子账号需要的权限也不同。此时,子账号权限策略的有效管理就很重要。
    本文将介绍下,当某员工通过子账号,使用运维编排服务(OOS)执行某模版,来完成一些例行运维任务时,如何既使子账号顺利完成相应操作,又最大程度保障账号的安全。

    场景介绍

    某公司账号下购买了若干台ECS实例,其中2台被打上标签TagKey:TagValue进行了分组,某员工甲被分配的子账号为subUser1ForOOS,甲定期通过该账号在OOS中执行一个模版T,模版执行的任务是对标签TagKey:TagValue分组下的ECS实例批量执行shell指令。即该员工具有对模版T的只读和执行权限,以及有模版任务涉及API(如RunCommand)的操作权限,且可操作的API仅对标签TagKey:TagValue分组下的实例有效。

    解决方案

    为满足上述场景,权限管理要分两方面,即OOS资源操作和ECS资源操作。
    OOS方面权限策略包括对模版的只读权限、对模版T的执行权限、对执行的查询权限。
    ECS方面权限策略为对标签TagKey:TagValue下实例的操作权限,且操作权限仅限于模版中涉及的API。
    以上的权限策略成功创建后,将其授权给员工甲使用的RAM子用户即可(或具有员工甲相同职责的用户组)。

    操作步骤

    步骤如下

    • ECS实例的分组
    • 创建OOS模版
    • 创建子账号(用户)
    • 创建自定义权限策略
    • 为子账号授权
    • 子账号执行OOS模版
    • 权限策略的补充验证

    ECS实例的分组

    1. 使用阿里云主账号(或管理员账号)登录到ECS控制台oos
    2. 选择2台实例,在操作菜单下选择更多 > 实例设置 > 编辑标签
    3. 单击新建标签,输入标签键标签值,单击确定
      本文中标签键设为TagKey,标签值设为TagValue。oos
    4. 单击确定
    5. 打开实例列表栏,在搜索框中输入TagKey:TagValue,单击放大镜图标。 oos
    6. 确认搜索结果为刚刚打标签TagKey:TagValue的实例。 oos

    创建OOS模版

    1. 使用阿里云主账号(或管理员账号)登录到运维编排控制台
    2. 单击我的模版,单击创建模版,选取空白模版,单击YAML
      本文中模版格式选择YAML。 oos
    3. 将附件中YAML的模版内容复制到空白模版中(若您对实例分组的标签键值不是TagKey:TagValue,请根据实际情况对模版中TagKey和TagValue进行修改)。

      oos

    4. 模版任务如下,请确认模版将执行的任务。

      1. 验证指定标签下是否存在实例。
      2. 根据标签下是否存在停止的实例选择后续任务。
      3. 如果标签下存在停止的实例,则启动这些实例。
      4. 为标签下所有实例安装云助手。
      5. 在标签下所有实例中运行Shell命令。
    5. 填写模板名称,单击创建模版
      本文中,模版名称设为TestOperatingByGroups。oos

    6. 我的模版栏,可查看成功创建的模版TestOperatingByGroups。

    创建子账号(用户)

    1. 使用阿里云主账号(或管理员账号)登录RAM控制台
    2. 在左侧导航栏的人员管理菜单下,单击用户 > 新建用户
    3. 输入登录名称显示名称
      本文中的登录名称及显示名称均设为subUser1ForOOS。
    4. 勾选控制台密码登录,单击自定义登录密码并填写要设置的子账号密码。 oos
    5. 单击确定
    6. 用户栏中可查看成功创建的新账号。oos

    创建自定义权限策略

    1. 使用阿里云主账号登录RAM控制台
    2. 在左侧导航栏的权限管理菜单下,单击权限策略管理
    3. 单击新建权限策略
      创建第一条策略用来管理OOS资源操作。
    4. 填写策略名称备注
      本文中策略名称设置为OOSResourceManage。
    5. 配置模式选择脚本配置,并将下述的第一段JSON策略样例拷贝到策略内容区域,并根据实际情况进行修改(将JSON中所有以$为前缀的变量名替换掉)。
      将第一段JSON中的$AliyunMasterAccountID、$RegionID、$TemplateName1修改为您所使用的阿里云主账号ID、OOS及ECS资源所在地域ID(本文中为cn-hangzhou)、允许子账号可执行的模版名称(本文中为TestOperatingByGroups。))。
      oos
      操作OOS的策略
      该段策略表示:被授权RAM用户具有对$RegionID地域下模版的只读权限、对模版$TemplateName1的执行权限、对$RegionID地域下OOS执行的查询权限。

      1. {
      2. "Statement": [
      3. {
      4. "Action": [
      5. "oos:StartExecution",
      6. "oos:List*",
      7. "oos:Get*"
      8. ],
      9. "Resource": [
      10. "acs:oos:$RegionID:$AliyunMasterAccountID:template/$TemplateName1",
      11. "acs:oos:$RegionID:$AliyunMasterAccountID:execution/*"
      12. ],
      13. "Effect": "Allow"
      14. },
      15. {
      16. "Action": [
      17. "oos:List*",
      18. "oos:Get*"
      19. ],
      20. "Resource": [
      21. "acs:oos:$RegionID:$AliyunMasterAccountID:template/*"
      22. ],
      23. "Effect": "Allow"
      24. }
      25. ],
      26. "Version": "1"
      27. }
    6. 单击确定

    7. 单击新建权限策略,创建第二条策略用来管理ECS资源操作。
    8. 填写策略名称备注
    9. 配置模式选择脚本配置,将下述的第二段JSON策略样例拷贝到策略内容区域,并根据实际情况进行修改(将JSON中所有以$为前缀的变量名替换掉)。
      将第二段JSON中的$AliyunMasterAccountID、$TagKey、$TagValue、$RegionID修改为您所使用的阿里云主账号ID、实例所属标签键和标签值(本文中根据ECS实例的分组,键及值应设为TagKey和TagValue)、OOS及ECS资