• 关于

    匹配不确定性不可用

    的搜索结果

回答

web数据集成技术可以从web上自动获取数据,但是获取的信息存在着大量的脏数据,比如滥用缩写词,惯用语,数据输入错误,重复记录,丢失值,拼写变化,不同的计量单位。这些数据是没有意义的,根本就不可能为以后的数据挖掘决策分析提供任何支持。数据清洗主要是提高数据的可用性,目前,数据清洗主要应用于三个领域: 1 数据仓库(DW) 2数据库中的知识发现(KDD) 3数据质量管理(TDQM) 我在公司里的第一个项目就是数据质量管理,在这里在说下数据质量管理: 通过制定、实施数据质量检核,暴露各系统数据质量问题。持续监控各系统数据质量波动情况及数据质量规则占比分析,定期生成各系统关键数据质量报告,掌握系统数据质量状况。结合系统提供的清洗组件以及数据质量问题处理流程为各系统数据质量提升提供有效支撑。数据质量(DataQuality)管理是贯穿数据生命周期的全过程,覆盖质量评估,数据去噪,数据监控,数据探查,数据清洗,数据诊断等方面。数据度量和变化频度提供了衡量数据质量好坏的手段。数据度量主要包括完整性、唯一性、一致性、准确性、合法性。变化频度主要包括业务系统数据的变化周期和实体数据的刷新周期。数据质量管理准则包括测量、提高组织数据的质量和整合性的方法。数据质量处理包括数据标准化、匹配、生存和质量监测。数据必须具备适当的质量,以解决业务要求问题。 结合大数据的参考框架及数据处理实际需求情况,数据质量管理系统主要功能定位为:数据发现、质量管理、元数据、主数据管理和信息政策管理。在数据生命周期中,数据的获取和使用周期包括系列活动:评估,分析,调整,丢弃数据,目前数据清洗的模型: 基于粗糙集理论数据清洗 基于聚式模式数据清洗 基于模糊匹配数据清洗模型 基于遗传神经网络数据清洗 基于专家系统体系结构等数据校验及转换 数据校验的目的是确保抽取数据本身的正确性和完整性, 数据转换的目的是保证数据的一致性数据清洗流程1数据预处理: 包括数据元素化,保准化 2确定清洗方法: 3校验清洗方法:先验证所用的清洗方法是否合适,抽取小样本进行验证,判断其召回率和准确率 4执行清洗工具: 5数据归档:将新旧数据源进行归档处理,方便以后的清洗一般情况下,模式中反应的元数据对应判断一个数据源的质量远远不够,因此通过具体实例来获得有关数据熟悉和不寻常模式的元数据很重要。这些元数据可以帮助发现数据质量问题,也有助于发现属性间的依赖关系,
xuning715 2019-12-02 01:12:15 0 浏览量 回答数 0

问题

错误码表:常见错误码表

简介 为了方便您在使用阿里云产品时查找报错原因,并了解怎么解决报错,我们对错误码表进行了优化。本文档列出了您在使用 API 过程中可能遇到的报错信息以及其描述和推荐的解决方法。 以下常见的错误码表会持续更新&...
行者武松 2019-12-01 22:00:58 2728 浏览量 回答数 0

问题

API常见错误码表上线-就帮你到这里了

为了方便您在使用阿里云产品时查找报错原因,并了解怎么解决报错,阿里云对错误码表进行了优化。 本文档列出了您在使用 API 过程中可能遇到的报错信息以及其描述和推荐的解决方法。 下面咱们就来看看这个表ÿ...
仙游 2019-12-01 21:00:08 5576 浏览量 回答数 1

问题

新时代DevOps需求下,我们该如何保障服务的安全?

【编者按】时下,传统安全策略显然已无法支撑 DevOps 环境的敏捷需求。那么,对于一个决策者来说,你又该如何实现 DevOps 速度与安全的兼得?本篇译自 Dzone 的一篇运维文章...
忆远0711 2019-12-01 21:56:45 8122 浏览量 回答数 1

回答

本教程介绍了如何利用弹性伸缩搭建可自动伸缩的Web应用,快速响应业务的峰谷波动,稳定承载日常业务的同时,轻松应对活动期间突增的流量。 前提条件 使用本教程进行操作前,请确保您已经注册了阿里云账号。如还未注册,请先完成账号注册。 为应用的ECS实例创建了自定义镜像,具体操作请参见使用实例创建自定义镜像。 业务场景 某电商平台为吸引用户,除定期推出优惠活动外,还会在节假日、会员日、购物节开展大促。为保证顺利承载活动带来的流量,运维人员可以分析活动历史数据,提前预估新活动所需的计算资源。但如果高峰期流量超出预估,仍需要临时手动创建ECS实例,不仅操作仓促,而且可能因操作不及时影响应用可用性。 假设您的应用具有以下特征,也可以采用类似解决方案: 采用集群方式部署,且集群拥有1台以上的服务器。 存在临时业务突增,但突增业务周期不长,例如每天不超过9个小时、每月不超过20天。 解决方案 弹性伸缩可以实现计算资源随业务峰谷自动伸缩,无需您提前预估和手动干预即可确保应用可用性。尤其针对双十一等大促活动,弹性伸缩具备几分钟内交付上千台ECS实例的能力,自动及时地应对突增流量,提升业务的可靠性。 您可以采用以下方案: 针对日常业务流量,购买包年包月ECS实例。 针对计划外突增流量,通过弹性伸缩监控负载变化并实现自动创建ECS实例。 示意图如下: 业务收益 利用弹性伸缩应对突增流量,您可以获得以下收益: 零备机成本 弹性伸缩可自动创建和释放ECS实例,实现按需取用,无需备机。您只需针对日常业务流量保有计算资源。 零运维成本 您只需提前配置扩缩容策略。负载增加时,弹性伸缩自动创建ECS实例,并将ECS实例添加到RDS实例的白名单和SLB实例的后端服务器组;负载降低时,弹性伸缩自动将ECS实例从SLB实例的后端服务器组和RDS实例的白名单中移除,然后释放ECS实例。整个过程自动触发和完成,无需人工干预。 灵活智能 弹性伸缩提供多种伸缩模式,您可以根据业务波动规律组合使用,达到最佳业务匹配度。例如您的Web应用流量大体稳定,但存在临时突增,可以采用基于云监控指标的动态模式,监控平均CPU使用率,及时地自动响应流量变化。 操作步骤 请根据您的业务架构评估业务模块,并执行以下操作实现指定业务模块的自动扩缩容: 步骤一:使用自定义镜像创建包年包月ECS实例 步骤二:创建并启用伸缩组 步骤三:添加包年包月ECS实例并设置自动伸缩策略 步骤一:使用自定义镜像创建包年包月ECS实例 创建指定数量的包年包月ECS实例,用于添加到伸缩组,满足业务模块的日常业务要求。 登录ECS管理控制台。 在左侧导航栏,单击实例与镜像 > 镜像。 在顶部状态栏左上角处,选择地域。 找到Web应用实例的自定义镜像,在操作列中,单击创建实例。 配置实例信息并完成实例创建。 付费模式设置为包年包月。 地域和镜像信息已自动填充。 请根据需要配置其它信息,详细信息请参见使用向导创建实例。 步骤二:创建并启用伸缩组 为需要弹性扩缩容的业务模块创建伸缩组,并为伸缩配置选择Web应用实例的自定义镜像,确保自动创建出的ECS实例符合Web应用的要求。 登录弹性伸缩控制台。 单击创建伸缩组。 配置伸缩组信息并完成伸缩组创建。 伸缩组内最小实例数设置为0。 组内实例配置信息来源设置为自定义伸缩配置。 多可用区扩容模式设置为均衡分布策略。 回收模式设置为释放模式。 绑定当前业务模块所使用的SLB实例和RDS实例。 请根据需要配置其它信息,详细信息请参见创建伸缩组。 单击创建伸缩配置。 配置伸缩配置信息并完成伸缩配置创建。 镜像设置为Web应用实例的自定义镜像。 请根据需要配置其它信息,详细信息请参见创建伸缩配置。 确定启用伸缩配置。 确定启用伸缩组。 步骤三:添加包年包月ECS实例并设置自动伸缩策略 将包年包月ECS实例添加至伸缩组,并创建目标追踪规则,实现根据业务峰谷自动伸缩,应对突增流量。 在弹性伸缩管理控制台中,找到创建好的伸缩组,在伸缩组名称/ID列中,单击伸缩组名称。 前往ECS实例列表界面,将创建好的包年包月ECS实例添加至伸缩组。 将包年包月ECS实例转为保护状态,保证日常业务正常运行。 前往基本信息界面,根据业务需求,修改伸缩组的最小实例数和最大实例数。 前往伸缩规则界面,创建一条目标追踪规则。 伸缩规则类型设置为目标追踪规则。 指标类型设置为平均CPU使用率。 目标值设置为50%。 请根据需要配置其它信息,详细信息请参见创建伸缩规则。 执行结果 包年包月ECS实例已被转为保护状态,用于承载日常业务。处于保护中状态的ECS实例不会被移除伸缩组,而且负载均衡权重不受影响。 伸缩组自动将ECS实例的平均CPU使用率维持在50%左右,高于50%时自动创建ECS实例分担流量,低于50%时自动释放ECS实例节省成本。ECS实例数量始终大于等于最小实例数,且小于等于最大实例数,保证满足业务需求且成本不会超出期望范围。
1934890530796658 2020-03-23 09:43:38 0 浏览量 回答数 0

回答

本教程介绍云服务器ECS的成本构成和优势,并提供成本管理的推荐方案,帮助您通过成本管理节约成本,在保障业务快速发展的同时按照预算支出费用,获得最大成本收益。 成本构成 使用云服务器ECS时,成本包括两个方面: 拥有成本:各类资源和资源包的成本。 运维成本:使用云服务器ECS过程中产生的人力成本。 ECS成本构成 上云的成本优势 自建数据中心时,除硬件、网络、电力、机房、人力运维成本等直接成本外,还需要考虑升级、扩容等带来的规模成本,以及备份数据、实现高可用等带来的风险成本。随着业务发展扩大数据中心规模时,单位资源成本和数据中心复杂度会不断增长,而且容错率低。如果在业务变化时选型失误,更会增加额外的支出。 相比自建数据中心,使用云上资源时无须投入硬件、物理环境人力等成本,单位资源成本相对线性,所有资源按需取用,交付便利。除资源成本的优势外,云上资源还支持多种付费模式,方便进一步优化成本。 成本优化建议 使用云服务器ECS时,推荐您从以下方面管理成本: 归集成本 优化资源 升级换代 具备节约意识 实现自动化运维 归集成本 在用户中心,您可以查看费用账单中的信息了解消费情况,从多个维度追踪成本并确定优化对象。 使用费用账单的账单总览功能,查看账号消费趋势、产品消费分布等信息,把握整体消费情况。 使用资源组、标签等功能,从业务、部门、项目的等维度分类资源,以便统计相应成本。 使用费用账单的账单明细功能,查看详细的资源消费情况。通过设置的资源组和标签,在更细粒度汇总各类资源的成本。 例如,创建标签部门:研发、部门:财务、部门:IT,并为ECS实例绑定标签。在查看账单明细时,通过标签筛选对应部门使用的资源,汇总成本用于确定优化对象。 优化资源 发现成本偏高的资源后,您可以从多个角度监控资源的情况,确定成本偏高的原因,然后采取针对性的优化措施。 监控资源的使用情况。 监控资源利用率,评估当前配置是否过高。例如CPU、内存、云盘、带宽等资源的利用率。 监控闲置的资源,避免浪费。例如升配但未重启的实例、未匹配实例的预留实例券、未挂载的云盘、未关联的EIP等。 监控资源使用周期。如果长期使用按量付费实例、云盘等资源,考虑以更实惠的方式购买,例如包年包月、资源包等。 监控资源生命周期,了解包年包月资源的到期日,及时续费。例如包年包月实例、预留实例券、存储容量单位包等。 选择合适的实例规格。 实例规格对云服务器ECS成本有较大影响,根据业务场景选择最佳性价比的实例规格,并调整合适的数量。在满足业务需求的同时追求高资源利用率,降低成本。 例如针对短视频场景,目前使用d1ne.14xlarge(60台),监控ECS实例发现内存使用率合理,但CPU相对空闲。因此可以采取以下方案: 适当降低CPU和内存比,满足业务需求的同时提高CPU利用率。查看实例规格详情发现d1ne实例为1:4,d2实例为1:5.5左右。使用d2s.8xlarge(85台)替换d1ne.14xlarge(60台),规格从14xlarge降为8xlarge,约节省23%的成本。 更多实例配置选型的介绍,请参见选型配置。 组合多种付费模式。 不同类型的业务对资源使用周期有不同要求。为每一类业务确定合适的付费模式,灵活组合达到最优效果。 针对稳定业务负载,使用包年包月、预留实例券。 针对有状态且动态变化的业务负载,使用按量付费。 针对无状态且可容错的业务负载,使用抢占式实例。 利用DDH复用ECS实例资源。 针对CPU绝对稳定性要求不严苛的场景,例如开发测试环境,使用超分型DDH部署更多同等规格的ECS实例,降低单位部署成本。 部署在DDH上的ECS实例停机时不占用资源,您也可以在生产环境业务流量的低峰期停止部分ECS实例,使用生产环境的空闲资源运行可预期周期的测试任务,例如离线计算、自动化测试等。 升级换代 处理器等硬件持续更新换代,提高性能的同时降低成本。云服务器ECS也会持续升级,为您提供性价比更高的产品。 新实例规格性价比优于老实例规格。例如,从g5.2xlarge升级到g6.2xlarge的性能和价格对比如下: 性能 价格 整形运算性能提升40% 浮点运算性能提升30% 内存带宽提升15% 内存空闲延迟降低40% 内网带宽提升220% 预付费包年成本降低6% 按量付费成本降低43% 为保证您可以及时使用新一代实例规格,建议您: 设计的应用具备鲁棒性,在不同实例规格上可以正常运行。 关注阿里云官网中实例规格的发布情况,及时评估是否需要更换。 升级换代示例 按照以下参考替换方案,保证CPU、内存配置相同的前提下,可以提升性能并至少节约15%的实例成本: 当前实例规格族 首选推荐 备选推荐 sn1、sn2 c6 g6 r6 c5、sn1ne g5、sn2ne r5、se1ne c4 hfc6、c6 hfc5、c5 ce4 r6 r5、se1ne cm4 hfc6 hfc5、g5 n1、n2、e3 c6 g6 r6 c5、sn1ne g5、sn2ne r5、se1ne t1 s1、s2、s3 m1、m2 c1、c2 c6 g6 r6 c5、sn1ne g5、sn2ne r5、se1ne 具备节约意识 云上资源的一个特点是按需取用,避免了自建数据中心所需的高昂一次性投入。针对按需取用的特点,您需要将成本优化融入到日常工作中,持续推进才能获得理想的优化成果。下面列举几个典型操作,您可以以此为模板进一步细化,形成贴合自身情况的方案。 定期召开成本会议。定期和成本相关方(例如财务、研发等团队)评审预算执行情况,评估优化成果,改进优化策略。 强制使用标签。利用标签按业务、环境、责任人等维度标记资源,便于日常成本追踪。 分类资源并定制合适的使用方式。例如针对短期项目的开发测试环境,优先选用按量付费实例部署,项目结束后及时释放实例。 避免资源闲置。定期盘点资源使用情况,明确闲置资源的通知和处置流程。 及时续费。对包年包月资源,提前申请预算,避免到期释放后重新购买部署增加额外成本。 实现自动化运维 阿里云也提供了丰富的运维类产品,帮助您提高运维效率,降低运维的人力成本。例如: 弹性伸缩:持续维护跨付费模式、跨可用区、跨实例规格的实例集群。适合业务负载存在峰谷波动的场景。 弹性供应:一键部署跨付费模式、跨可用区和跨实例规格的实例集群。适合需要快速交付稳定算力,同时使用抢占式实例降低成本的场景。 运维编排:以模板的方式定义一组运维操作,高效执行运维任务。适合事件驱动运维、定时运维、批量运维、跨地域运维等场景。 资源编排:一键部署并维护包含多种云资源和依赖关系的资源栈。适合交付整体系统、克隆环境等场景。
1934890530796658 2020-03-26 09:53:47 0 浏览量 回答数 0

问题

【教程免费下载】信息物理融合系统(CPS)设计

前言        “我”上次发表著作是在一千九百年前。“我”很高兴从退休中复出,对以本人名字命名的工程(Ptolemy工程)发表自己的看法。与“我”以往在天文和地理方面的工作相似ÿ...
玄学酱 2019-12-01 22:08:06 1332 浏览量 回答数 1

回答

我们都知道虚拟机的内存划分了多个区域,并不是一张大饼。那么为什么要划分为多块区域呢,直接搞一块区域,所有用到内存的地方都往这块区域里扔不就行了,岂不痛快。是的,如果不进行区域划分,扔的时候确实痛快,可用的时候再去找怎么办呢,这就引入了第一个问题,分类管理,类似于衣柜,系统磁盘等等,为了方便查找,我们会进行分区分类。另外如果不进行分区,内存用尽了怎么办呢?这里就引入了内存划分的第二个原因,就是为了方便内存的回收。如果不分,回收内存需要全部内存扫描,那就慢死了,内存根据不同的使用功能分成不同的区域,那么内存回收也就可以根据每个区域的特定进行回收,比如像栈内存中的栈帧,随着方法的执行栈帧进栈,方法执行完毕就出栈了,而对于像堆内存的回收就需要使用经典的回收算法来进行回收了,所以看起来分类这么麻烦,其实是大有好处的。 提到虚拟机的内存结构,可能首先想起来的就是堆栈。对象分配到堆上,栈上用来分配对象的引用以及一些基本数据类型相关的值。但是·虚拟机的内存结构远比此要复杂的多。除了我们所认识的(还没有认识完全)的堆栈以外,还有程序计数器,本地方法栈和方法区。我们平时所说的栈内存,一般是指的栈内存中的局部变量表。 从图中可以看到有5大内存区域,按照是否被线程所共享可分为两部分,一部分是线程独占区域,包括Java栈,本地方法栈和程序计数器。还有一部分是被线程所共享的,包括方法区和堆。什么是线程共享和线程独占呢,非常好理解,我们知道每一个Java进行都会有多个线程同时运行,那么线程共享区的这片区域就是被所有线程一起使用的,不管有多少个线程,这片空间始终就这一个。而线程的独占区,是每个线程都有这么一份内存空间,每个线程的这片空间都是独有的,有多少个线程就有多少个这么个空间。上图的区域的大小并不代表实际内存区域的大小,实际运行过程中,内存区域的大小也是可以动态调整的。下面来具体说说每一个区域的主要功能。 程序计数器,我们在写代码的过程中,开发工具一般都会给我们标注行号方便查看和阅读代码。那么在程序在运行过程中也有一个类似的行号方便虚拟机的执行,就是程序计数器,在c语言中,我们知道会有一个goto语句,其实就是跳转到了指定的行,这个行号就是程序计数器。存储的就是程序下一条所执行的指令。这部分区域是线程所独享的区域,我们知道线程是一个顺序执行流,每个线程都有自己的执行顺序,如果所有线程共用一个程序计数器,那么程序执行肯定就会出乱子。为了保证每个线程的执行顺序,所以程序计数器是被单个线程所独显的。程序计数器这块内存区域是唯一一个在jvm规范中没有规定内存溢出的。 java虚拟机栈,java虚拟机栈是程序运行的动态区域,每个方法的执行都伴随着栈帧的入栈和出栈。 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。栈帧中包括了局部变量表,操作数栈,方法返回地址以及额外的一些附加信息,在编译过程中,局部变量表的大小已经确定,操作数栈深度也已经确定,因此栈帧在运行的过程中需要分配多大的内存是固定的,不受运行时影响。对于没有逃逸的对象也会在栈上分配内存,对象的大小其实在运行时也是确定的,因此即使出现了栈上内存分配,也不会导致栈帧改变大小。 一个线程中,可能调用链会很长,很多方法都同时处于执行状态。对于执行引擎来讲,活动线程中,只有栈顶的栈帧是最有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法。执行引擎所运行的字节码指令仅对当前栈帧进行操作。Ft5rk58GfiJxcdcCzGeAt8fjkFPkMRdf 局部变量表:我们平时所说的栈内存一般就是指栈内存中的局部变量表。这里主要是存储变量所用。对于基本数据类型直接存储其值,对于引用数据类型则存储其地址。局部变量表的最小存储单位是Slot,每个Slot都能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据。 既然前面提到了数据类型,在此顺便说一下,一个Slot可以存放一个32位以内的数据类型,Java中占用32位以内的数据类型有boolean、byte、char、short、int、float、reference和returnAddress八种类型。前面六种不需要多解释,大家都认识,而后面的reference是对象的引用。虚拟机规范既没有说明它的长度,也没有明确指出这个引用应有怎样的结构,但是一般来说,虚拟机实现至少都应当能从此引用中直接或间接地查找到对象在Java堆中的起始地址索引和方法区中的对象类型数据。而returnAddress是为字节码指令jsr、jsr_w和ret服务的,它指向了一条字节码指令的地址。 对于64位的数据类型,虚拟机会以高位在前的方式为其分配两个连续的Slot空间。Java语言中明确规定的64位的数据类型只有long和double两种(reference类型则可能是32位也可能是64位)。值得一提的是,这里把long和double数据类型读写分割为两次32读写的做法类似。不过,由于局部变量表建立在线程的堆栈上,是线程私有的数据,无论读写两个连续的Slot是否是原子操作,都不会引起数据安全问题。 操作数栈是一个后入先出(Last In First Out, LIFO)栈。同局部变量表一样,操作数栈的最大深度也在编译的时候被写入到字节码文件中,关于字节码文件,后面我会具体的来描述。操作数栈的每一个元素可以是任意的Java数据类型,包括long和double。32位数据类型所占的栈容量为1,64位数据类型所占的栈容量为2。在方法执行的任何时候,操作数栈的深度都不会超过在max_stacks数据项中设定的最大值。 当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令向操作数栈中写入和提取内容,也就是入栈出栈操作。例如,在做算术运算的时候是通过操作数栈来进行的,又或者在调用其他方法的时候是通过操作数栈来进行参数传递的。 举个例子,整数加法的字节码指令iadd在运行的时候要求操作数栈中最接近栈顶的两个元素已经存入了两个int型的数值,当执行这个指令时,会将这两个int值和并相加,然后将相加的结果入栈。 操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,在编译程序代码的时候,编译器要严格保证这一点,在类校验阶段的数据流分析中还要再次验证这一点。再以上面的iadd指令为例,这个指令用于整型数加法,它在执行时,最接近栈顶的两个元素的数据类型必须为int型,不能出现一个long和一个float使用iadd命令相加的情况。 本地方法栈 与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。 方法区经常会被人称之为永久代,但这俩并不是一个概念。首先永久代的概念仅仅在HotSpot虚拟机中存在,不幸的是,在jdk8中,Hotspot去掉了永久代这一说法,使用了Native Memory,也就是Metaspace空间。那么方法区是干嘛的呢?我们可以这么理解,我们要运行Java代码,首先需要编译,然后才能运行。在运行的过程中,我们知道首先需要加载字节码文件。也就是说要把字节码文件加载到内存中。好了,问题就来了,字节码文件放到内存中的什么地方呢,就是方法区中。当然除了编译后的字节码之外,方法区中还会存放常量,静态变量以及及时编译器编译后的代码等数据。 堆,一般来讲堆内存是Java虚拟机中最大的一块内存区域,同方法区一样,是被所有线程所共享的区域。此区域所存在的唯一目的就存放对象的实例(对象实例并不一定全部在堆中创建)。堆内存是垃圾收集器主要光顾的区域,一般来讲根据使用的垃圾收集器的不同,堆中还会划分为一些区域,比如新生代和老年代。新生代还可以再划分为Eden,Survivor等区域。另外为了性能和安全性的角度,在堆中还会为线程划分单独的区域,称之为线程分配缓冲区。更细致的划分是为了让垃圾收集器能够更高效的工作,提高垃圾收集的效率。 如果想要了解更多的关于虚拟机的内容,可以观看录制的<深入理解Java虚拟机>这套视频教程。
zwt9000 2019-12-02 00:21:07 0 浏览量 回答数 0

回答

92题 一般来说,建立INDEX有以下益处:提高查询效率;建立唯一索引以保证数据的唯一性;设计INDEX避免排序。 缺点,INDEX的维护有以下开销:叶节点的‘分裂’消耗;INSERT、DELETE和UPDATE操作在INDEX上的维护开销;有存储要求;其他日常维护的消耗:对恢复的影响,重组的影响。 需要建立索引的情况:为了建立分区数据库的PATITION INDEX必须建立; 为了保证数据约束性需要而建立的INDEX必须建立; 为了提高查询效率,则考虑建立(是否建立要考虑相关性能及维护开销); 考虑在使用UNION,DISTINCT,GROUP BY,ORDER BY等字句的列上加索引。 91题 作用:加快查询速度。原则:(1) 如果某属性或属性组经常出现在查询条件中,考虑为该属性或属性组建立索引;(2) 如果某个属性常作为最大值和最小值等聚集函数的参数,考虑为该属性建立索引;(3) 如果某属性经常出现在连接操作的连接条件中,考虑为该属性或属性组建立索引。 90题 快照Snapshot是一个文件系统在特定时间里的镜像,对于在线实时数据备份非常有用。快照对于拥有不能停止的应用或具有常打开文件的文件系统的备份非常重要。对于只能提供一个非常短的备份时间而言,快照能保证系统的完整性。 89题 游标用于定位结果集的行,通过判断全局变量@@FETCH_STATUS可以判断是否到了最后,通常此变量不等于0表示出错或到了最后。 88题 事前触发器运行于触发事件发生之前,而事后触发器运行于触发事件发生之后。通常事前触发器可以获取事件之前和新的字段值。语句级触发器可以在语句执行前或后执行,而行级触发在触发器所影响的每一行触发一次。 87题 MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。具体原因为:MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。 86题 建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合。如果需要建立联合索引的话,还需要考虑联合索引中的顺序。此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力。这些都和实际的表结构以及查询方式有关。 85题 存储过程是一组Transact-SQL语句,在一次编译后可以执行多次。因为不必重新编译Transact-SQL语句,所以执行存储过程可以提高性能。触发器是一种特殊类型的存储过程,不由用户直接调用。创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行。 84题 存储过程是用户定义的一系列SQL语句的集合,涉及特定表或其它对象的任务,用户可以调用存储过程,而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值并且不涉及特定用户表。 83题 减少表连接,减少复杂 SQL,拆分成简单SQL。减少排序:非必要不排序,利用索引排序,减少参与排序的记录数。尽量避免 select *。尽量用 join 代替子查询。尽量少使用 or,使用 in 或者 union(union all) 代替。尽量用 union all 代替 union。尽量早的将无用数据过滤:选择更优的索引,先分页再Join…。避免类型转换:索引失效。优先优化高并发的 SQL,而不是执行频率低某些“大”SQL。从全局出发优化,而不是片面调整。尽可能对每一条SQL进行 explain。 82题 如果条件中有or,即使其中有条件带索引也不会使用(要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引)。对于多列索引,不是使用的第一部分,则不会使用索引。like查询是以%开头。如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。如果mysql估计使用全表扫描要比使用索引快,则不使用索引。例如,使用<>、not in 、not exist,对于这三种情况大多数情况下认为结果集很大,MySQL就有可能不使用索引。 81题 主键不能重复,不能为空,唯一键不能重复,可以为空。建立主键的目的是让外键来引用。一个表最多只有一个主键,但可以有很多唯一键。 80题 空值('')是不占用空间的,判断空字符用=''或者<>''来进行处理。NULL值是未知的,且占用空间,不走索引;判断 NULL 用 IS NULL 或者 is not null ,SQL 语句函数中可以使用 ifnull ()函数来进行处理。无法比较 NULL 和 0;它们是不等价的。无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。NULL 值可以使用 <=> 符号进行比较,该符号与等号作用相似,但对NULL有意义。进行 count ()统计某列的记录数的时候,如果采用的 NULL 值,会被系统自动忽略掉,但是空值是统计到其中。 79题 HEAP表是访问数据速度最快的MySQL表,他使用保存在内存中的散列索引。一旦服务器重启,所有heap表数据丢失。BLOB或TEXT字段是不允许的。只能使用比较运算符=,<,>,=>,= <。HEAP表不支持AUTO_INCREMENT。索引不可为NULL。 78题 如果想输入字符为十六进制数字,可以输入带有单引号的十六进制数字和前缀(X),或者只用(Ox)前缀输入十六进制数字。如果表达式上下文是字符串,则十六进制数字串将自动转换为字符串。 77题 Mysql服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。 76题 在缺省模式下,MYSQL是autocommit模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,mysql是不支持事务的。但是如果你的MYSQL表类型是使用InnoDB Tables 或 BDB tables的话,你的MYSQL就可以使用事务处理,使用SET AUTOCOMMIT=0就可以使MYSQL允许在非autocommit模式,在非autocommit模式下,你必须使用COMMIT来提交你的更改,或者用ROLLBACK来回滚你的更改。 75题 它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。 74题 创建索引的时候尽量使用唯一性大的列来创建索引,由于使用b+tree做为索引,以innodb为例,一个树节点的大小由“innodb_page_size”,为了减少树的高度,同时让一个节点能存放更多的值,索引列尽量在整数类型上创建,如果必须使用字符类型,也应该使用长度较少的字符类型。 73题 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下: 限定数据的范围: 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内。读/写分离: 经典的数据库拆分方案,主库负责写,从库负责读。垂直分区: 根据数据库里面数据表的相关性进行拆分。简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。水平分区: 保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。水平拆分可以支撑非常大的数据量。 72题 乐观锁失败后会抛出ObjectOptimisticLockingFailureException,那么我们就针对这块考虑一下重试,自定义一个注解,用于做切面。针对注解进行切面,设置最大重试次数n,然后超过n次后就不再重试。 71题 一致性非锁定读讲的是一条记录被加了X锁其他事务仍然可以读而不被阻塞,是通过innodb的行多版本实现的,行多版本并不是实际存储多个版本记录而是通过undo实现(undo日志用来记录数据修改前的版本,回滚时会用到,用来保证事务的原子性)。一致性锁定读讲的是我可以通过SELECT语句显式地给一条记录加X锁从而保证特定应用场景下的数据一致性。 70题 数据库引擎:尤其是mysql数据库只有是InnoDB引擎的时候事物才能生效。 show engines 查看数据库默认引擎;SHOW TABLE STATUS from 数据库名字 where Name='表名' 如下;SHOW TABLE STATUS from rrz where Name='rrz_cust';修改表的引擎alter table table_name engine=innodb。 69题 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);哈希索引也不支持多列联合索引的最左匹配规则;B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。 68题 decimal精度比float高,数据处理比float简单,一般优先考虑,但float存储的数据范围大,所以范围大的数据就只能用它了,但要注意一些处理细节,因为不精确可能会与自己想的不一致,也常有关于float 出错的问题。 67题 datetime、timestamp精确度都是秒,datetime与时区无关,存储的范围广(1001-9999),timestamp与时区有关,存储的范围小(1970-2038)。 66题 Char使用固定长度的空间进行存储,char(4)存储4个字符,根据编码方式的不同占用不同的字节,gbk编码方式,不论是中文还是英文,每个字符占用2个字节的空间,utf8编码方式,每个字符占用3个字节的空间。Varchar保存可变长度的字符串,使用额外的一个或两个字节存储字符串长度,varchar(10),除了需要存储10个字符,还需要1个字节存储长度信息(10),超过255的长度需要2个字节来存储。char和varchar后面如果有空格,char会自动去掉空格后存储,varchar虽然不会去掉空格,但在进行字符串比较时,会去掉空格进行比较。Varbinary保存变长的字符串,后面不会补\0。 65题 首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。 64题 建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合。如果需要建立联合索引的话,还需要考虑联合索引中的顺序。此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力。这些都和实际的表结构以及查询方式有关。 63题 存储过程是一些预编译的SQL语句。1、更加直白的理解:存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。2、存储过程是一个预编译的代码块,执行效率比较高,一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率,可以一定程度上确保数据安全。 62题 密码散列、盐、用户身份证号等固定长度的字符串应该使用char而不是varchar来存储,这样可以节省空间且提高检索效率。 61题 推荐使用自增ID,不要使用UUID。因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降。总之,在数据量大一些的情况下,用自增主键性能会好一些。 60题 char是一个定长字段,假如申请了char(10)的空间,那么无论实际存储多少内容。该字段都占用10个字符,而varchar是变长的,也就是说申请的只是最大长度,占用的空间为实际字符长度+1,最后一个字符存储使用了多长的空间。在检索效率上来讲,char > varchar,因此在使用中,如果确定某个字段的值的长度,可以使用char,否则应该尽量使用varchar。例如存储用户MD5加密后的密码,则应该使用char。 59题 一. read uncommitted(读取未提交数据) 即便是事务没有commit,但是我们仍然能读到未提交的数据,这是所有隔离级别中最低的一种。 二. read committed(可以读取其他事务提交的数据)---大多数数据库默认的隔离级别 当前会话只能读取到其他事务提交的数据,未提交的数据读不到。 三. repeatable read(可重读)---MySQL默认的隔离级别 当前会话可以重复读,就是每次读取的结果集都相同,而不管其他事务有没有提交。 四. serializable(串行化) 其他会话对该表的写操作将被挂起。可以看到,这是隔离级别中最严格的,但是这样做势必对性能造成影响。所以在实际的选用上,我们要根据当前具体的情况选用合适的。 58题 B+树的高度一般为2-4层,所以查找记录时最多只需要2-4次IO,相对二叉平衡树已经大大降低了。范围查找时,能通过叶子节点的指针获取数据。例如查找大于等于3的数据,当在叶子节点中查到3时,通过3的尾指针便能获取所有数据,而不需要再像二叉树一样再获取到3的父节点。 57题 因为事务在修改页时,要先记 undo,在记 undo 之前要记 undo 的 redo, 然后修改数据页,再记数据页修改的 redo。 Redo(里面包括 undo 的修改) 一定要比数据页先持久化到磁盘。 当事务需要回滚时,因为有 undo,可以把数据页回滚到前镜像的状态,崩溃恢复时,如果 redo log 中事务没有对应的 commit 记录,那么需要用 undo把该事务的修改回滚到事务开始之前。 如果有 commit 记录,就用 redo 前滚到该事务完成时并提交掉。 56题 redo log是物理日志,记录的是"在某个数据页上做了什么修改"。 binlog是逻辑日志,记录的是这个语句的原始逻辑,比如"给ID=2这一行的c字段加1"。 redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。 redo log是循环写的,空间固定会用完:binlog 是可以追加写入的。"追加写"是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。 最开始 MySQL 里并没有 InnoDB 引擎,MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog日志只能用于归档。而InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统,也就是 redo log 来实现 crash-safe 能力。 55题 重做日志(redo log)      作用:确保事务的持久性,防止在发生故障,脏页未写入磁盘。重启数据库会进行redo log执行重做,达到事务一致性。 回滚日志(undo log)  作用:保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。 二进 制日志(binlog)    作用:用于主从复制,实现主从同步;用于数据库的基于时间点的还原。 错误日志(errorlog) 作用:Mysql本身启动,停止,运行期间发生的错误信息。 慢查询日志(slow query log)  作用:记录执行时间过长的sql,时间阈值可以配置,只记录执行成功。 一般查询日志(general log)    作用:记录数据库的操作明细,默认关闭,开启后会降低数据库性能 。 中继日志(relay log) 作用:用于数据库主从同步,将主库发来的bin log保存在本地,然后从库进行回放。 54题 MySQL有三种锁的级别:页级、表级、行级。 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 死锁: 是指两个或两个以上的进程在执行过程中。因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。 那么对应的解决死锁问题的关键就是:让不同的session加锁有次序。死锁的解决办法:1.查出的线程杀死。2.设置锁的超时时间。3.指定获取锁的顺序。 53题 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性(脏读,不可重复读,幻读等),可能产生死锁。 乐观锁:乐观锁不是数据库自带的,需要我们自己去实现。 悲观锁:在进行每次操作时都要通过获取锁才能进行对相同数据的操作。 共享锁:加了共享锁的数据对象可以被其他事务读取,但不能修改。 排他锁:当数据对象被加上排它锁时,一个事务必须得到锁才能对该数据对象进行访问,一直到事务结束锁才被释放。 行锁:就是给某一条记录加上锁。 52题 Mysql是关系型数据库,MongoDB是非关系型数据库,数据存储结构的不同。 51题 关系型数据库优点:1.保持数据的一致性(事务处理)。 2.由于以标准化为前提,数据更新的开销很小。 3. 可以进行Join等复杂查询。 缺点:1、为了维护一致性所付出的巨大代价就是其读写性能比较差。 2、固定的表结构。 3、高并发读写需求。 4、海量数据的高效率读写。 非关系型数据库优点:1、无需经过sql层的解析,读写性能很高。 2、基于键值对,数据没有耦合性,容易扩展。 3、存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,而关系型数据库则只支持基础类型。 缺点:1、不提供sql支持,学习和使用成本较高。 2、无事务处理,附加功能bi和报表等支持也不好。 redis与mongoDB的区别: 性能:TPS方面redis要大于mongodb。 可操作性:mongodb支持丰富的数据表达,索引,redis较少的网络IO次数。 可用性:MongoDB优于Redis。 一致性:redis事务支持比较弱,mongoDB不支持事务。 数据分析:mongoDB内置了数据分析的功能(mapreduce)。 应用场景:redis数据量较小的更性能操作和运算上,MongoDB主要解决海量数据的访问效率问题。 50题 如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。 49题 分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。 48题 除了缓存服务器自带的缓存失效策略之外(Redis默认的有6种策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种: 1.定时去清理过期的缓存; 2.当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。 两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,可以根据应用场景来权衡。 47题 Redis提供了两种方式来作消息队列: 一个是使用生产者消费模式模式:会让一个或者多个客户端监听消息队列,一旦消息到达,消费者马上消费,谁先抢到算谁的,如果队列里没有消息,则消费者继续监听 。另一个就是发布订阅者模式:也是一个或多个客户端订阅消息频道,只要发布者发布消息,所有订阅者都能收到消息,订阅者都是平等的。 46题 Redis的数据结构列表(list)可以实现延时队列,可以通过队列和栈来实现。blpop/brpop来替换lpop/rpop,blpop/brpop阻塞读在队列没有数据的时候,会立即进入休眠状态,一旦数据到来,则立刻醒过来。Redis的有序集合(zset)可以用于实现延时队列,消息作为value,时间作为score。Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。当 key 存在但不是有序集类型时,返回一个错误。 45题 1.热点数据缓存:因为Redis 访问速度块、支持的数据类型比较丰富。 2.限时业务:expire 命令设置 key 的生存时间,到时间后自动删除 key。 3.计数器:incrby 命令可以实现原子性的递增。 4.排行榜:借助 SortedSet 进行热点数据的排序。 5.分布式锁:利用 Redis 的 setnx 命令进行。 6.队列机制:有 list push 和 list pop 这样的命令。 44题 一致哈希 是一种特殊的哈希算法。在使用一致哈希算法后,哈希表槽位数(大小)的改变平均只需要对 K/n 个关键字重新映射,其中K是关键字的数量, n是槽位数量。然而在传统的哈希表中,添加或删除一个槽位的几乎需要对所有关键字进行重新映射。 43题 RDB的优点:适合做冷备份;读写服务影响小,reids可以保持高性能;重启和恢复redis进程,更加快速。RDB的缺点:宕机会丢失最近5分钟的数据;文件特别大时可能会暂停数毫秒,或者甚至数秒。 AOF的优点:每个一秒执行fsync操作,最多丢失1秒钟的数据;以append-only模式写入,没有任何磁盘寻址的开销;文件过大时,不会影响客户端读写;适合做灾难性的误删除的紧急恢复。AOF的缺点:AOF日志文件比RDB数据快照文件更大,支持写QPS比RDB支持的写QPS低;比RDB脆弱,容易有bug。 42题 对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。Redis的操作之所以是原子性的,是因为Redis是单线程的。而在程序中执行多个Redis命令并非是原子性的,这也和普通数据库的表现是一样的,可以用incr或者使用Redis的事务,或者使用Redis+Lua的方式实现。对Redis来说,执行get、set以及eval等API,都是一个一个的任务,这些任务都会由Redis的线程去负责执行,任务要么执行成功,要么执行失败,这就是Redis的命令是原子性的原因。 41题 (1)twemproxy,使用方式简单(相对redis只需修改连接端口),对旧项目扩展的首选。(2)codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数改变情况下,旧节点数据可恢复到新hash节点。(3)redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。(4)在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key进行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的代替算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。 40题 (1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 (4) 尽量避免在压力很大的主库上增加从库 (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。 39题 比如订单管理,热数据:3个月内的订单数据,查询实时性较高;温数据:3个月 ~ 12个月前的订单数据,查询频率不高;冷数据:1年前的订单数据,几乎不会查询,只有偶尔的查询需求。热数据使用mysql进行存储,需要分库分表;温数据可以存储在ES中,利用搜索引擎的特性基本上也可以做到比较快的查询;冷数据可以存放到Hive中。从存储形式来说,一般情况冷数据存储在磁带、光盘,热数据一般存放在SSD中,存取速度快,而温数据可以存放在7200转的硬盘。 38题 当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。 37题 分层架构设计,有一条准则:站点层、服务层要做到无数据无状态,这样才能任意的加节点水平扩展,数据和状态尽量存储到后端的数据存储服务,例如数据库服务或者缓存服务。显然进程内缓存违背了这一原则。 36题 更新数据的时候,根据数据的唯一标识,将操作路由之后,发送到一个 jvm 内部队列中。读取数据的时候,如果发现数据不在缓存中,那么将重新读取数据+更新缓存的操作,根据唯一标识路由之后,也发送同一个 jvm 内部队列中。一个队列对应一个工作线程,每个工作线程串行拿到对应的操作,然后一条一条的执行。 35题 redis分布式锁加锁过程:通过setnx向特定的key写入一个随机值,并同时设置失效时间,写值成功既加锁成功;redis分布式锁解锁过程:匹配随机值,删除redis上的特点key数据,要保证获取数据、判断一致以及删除数据三个操作是原子的,为保证原子性一般使用lua脚本实现;在此基础上进一步优化的话,考虑使用心跳检测对锁的有效期进行续期,同时基于redis的发布订阅优雅的实现阻塞式加锁。 34题 volatile-lru:当内存不足以容纳写入数据时,从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。 volatile-ttl:当内存不足以容纳写入数据时,从已设置过期时间的数据集中挑选将要过期的数据淘汰。 volatile-random:当内存不足以容纳写入数据时,从已设置过期时间的数据集中任意选择数据淘汰。 allkeys-lru:当内存不足以容纳写入数据时,从数据集中挑选最近最少使用的数据淘汰。 allkeys-random:当内存不足以容纳写入数据时,从数据集中任意选择数据淘汰。 noeviction:禁止驱逐数据,当内存使用达到阈值的时候,所有引起申请内存的命令会报错。 33题 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。 32题 缓存击穿,一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。如何避免:在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。 31题 缓存雪崩,是指在某一个时间段,缓存集中过期失效。大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。而缓存服务器某个节点宕机或断网,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。如何避免:1.redis高可用,搭建redis集群。2.限流降级,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。3.数据预热,在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间。 30题 缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。一些恶意的请求会故意查询不存在的 key,请求量很大,对数据库造成压力,甚至压垮数据库。 如何避免:1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。2:对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。 29题 1.memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型。 2.redis 的速度比 memcached 快很多。 3.redis 可以持久化其数据。 4.Redis支持数据的备份,即master-slave模式的数据备份。 5.Redis采用VM机制。 6.value大小:redis最大可以达到1GB,而memcache只有1MB。 28题 Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通过spring提供的@ImportResource来加载xml配置。例如:@ImportResource({"classpath:some-context.xml","classpath:another-context.xml"}) 27题 Spring像一个大家族,有众多衍生产品例如Spring Boot,Spring Security等等,但他们的基础都是Spring的IOC和AOP,IOC提供了依赖注入的容器,而AOP解决了面向切面的编程,然后在此两者的基础上实现了其他衍生产品的高级功能。Spring MVC是基于Servlet的一个MVC框架,主要解决WEB开发的问题,因为 Spring的配置非常复杂,各种xml,properties处理起来比较繁琐。Spring Boot遵循约定优于配置,极大降低了Spring使用门槛,又有着Spring原本灵活强大的功能。总结:Spring MVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包。 26题 YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。YAML 的配置文件后缀为 .yml,是一种人类可读的数据序列化语言,可以简单表达清单、散列表,标量等数据形态。它通常用于配置文件,与属性文件相比,YAML文件就更加结构化,而且更少混淆。可以看出YAML具有分层配置数据。 25题 Spring Boot有3种热部署方式: 1.使用springloaded配置pom.xml文件,使用mvn spring-boot:run启动。 2.使用springloaded本地加载启动,配置jvm参数-javaagent:<jar包地址> -noverify。 3.使用devtools工具包,操作简单,但是每次需要重新部署。 用
游客ih62co2qqq5ww 2020-03-27 23:56:48 0 浏览量 回答数 0

问题

Web测试方法

在Web工程过程中,基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同,它不但需要检查和验证是否按照设计的要求运行,而且还要测试系统在不同用户的浏...
技术小菜鸟 2019-12-01 21:41:32 7022 浏览量 回答数 1

回答

阿里云容器服务 Kubernetes 集群支持通过界面创建 StatefultSet 类型的应用,满足您快速创建有状态应用的需求。本例中将创建一个 nginx 的有状态应用,并演示 StatefulSet 应用的特性。 前提条件 您已成功创建一个 Kubernetes 集群。参见创建Kubernetes集群。 您已成功创建一个云盘存储卷声明,参见创建持久化存储卷声明。 您已连接到 Kubernetes 集群的 Master 节点,参见通过kubectl连接Kubernetes集群。 背景信息 StatefulSet 包括如下特性: 场景 说明 Pod 一致性 包含次序(启动、停止次序)、网络一致性。此一致性与 Pod 相关,与被调度到哪个 node 节点无关。 稳定的持久化存储 通过 VolumeClaimTemplate 为每个 Pod 创建一个 PV。删除、减少副本,不会删除相关的卷。 稳定的网络标志 Pod 的 hostname 模式为:(statefulset名称)−(序号)。 稳定的次序 对于N个副本的 StatefulSet,每个 Pod 都在 [0,N)的范围内分配一个数字序号,且是唯一的。 操作步骤 登录容器服务管理控制台。 在 Kubernetes 菜单下,单击左侧导航栏中的应用 > 有状态,然后单击页面右上角的使用镜像创建。 在应用基本信息页面进行设置,然后单击下一步 进入应用配置页面。 应用名称:设置应用的名称。 部署集群:设置应用部署的集群。 命名空间:设置应用部署所处的命名空间,默认使用 default 命名空间。 副本数量:即应用包含的 Pod 数量。 类型:可选择无状态(Deployment)和有状态(StatefulSet)两种类型。 说明 本例中选择有状态类型,创建 StatefulSet 类型的应用。 标签:为该应用添加一个标签,标识该应用。 注解:为该应用添加一个注解(annotation)。 应用配置页面 设置容器配置。 说明 您可为应用的 Pod 设置多个容器。 设置容器的基本配置。 镜像名称:您可以单击选择镜像,在弹出的对话框中选择所需的镜像并单击确定,本例中为 nginx。 您还可以填写私有 registry。填写的格式为domainname/namespace/imagename:tag 镜像版本:您可以单击选择镜像版本 选择镜像的版本。若不指定,默认为 latest。 总是拉取镜像:为了提高效率,容器服务会对镜像进行缓存。部署时,如果发现镜像 Tag 与本地缓存的一致,则会直接复用而不重新拉取。所以,如果您基于上层业务便利性等因素考虑,在做代码和镜像变更时没有同步修改 Tag ,就会导致部署时还是使用本地缓存内旧版本镜像。而勾选该选项后,会忽略缓存,每次部署时重新拉取镜像,确保使用的始终是最新的镜像和代码。 镜像密钥:单击设置镜像密钥设置镜像的密钥。对于私有仓库访问时,需要设置密钥,具体可以参见使用镜像密钥。 资源限制:可指定该应用所能使用的资源上限,包括 CPU 和内存两种资源,防止占用过多资源。其中,CPU 资源的单位为 millicores,即一个核的千分之一;内存的单位为 Bytes,可以为 Gi、Mi 或 Ki。 所需资源:即为该应用预留资源额度,包括 CPU 和内存两种资源,即容器独占该资源,防止因资源不足而被其他服务或进程争夺资源,导致应用不可用。 Init Container:勾选该项,表示创建一个Init Container,Init Container 包含一些实用的工具,具体参见https://kubernetes.io/docs/concepts/workloads/pods/init-containers/。 设置容器基本信息 可选: 配置环境变量。 支持通过键值对的形式为 Pod 配置环境变量。用于给 Pod 添加环境标志或传递配置等,具体请参见 Pod variable。 可选: 配置健康检查。 支持存活检查(liveness)和就绪检查(Readiness)。存活检查用于检测何时重启容器;就绪检查确定容器是否已经就绪,且可以接受流量。关于健康检查的更多信息,请参见https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes。 请求类型 配置说明 HTTP请求 即向容器发送一个HTTPget 请求,支持的参数包括: 协议:HTTP/HTTPS。 路径:访问HTTP server 的路径。 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535。 HTTP头:即HTTPHeaders,HTTP请求中自定义的请求头,HTTP允许重复的header。支持键值对的配置方式。 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为3秒。 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 TCP连接 即向容器发送一个 TCP Socket,kubelet 将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。支持的参数包括: 端口:容器暴露的访问端口或端口名,端口号必须介于 1~65535。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为 15 秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 命令行 通过在容器中执行探针检测命令,来检测容器的健康情况。支持的参数包括: 命令行:用于检测容器健康情况的探测命令。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为5秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 可选: 配置生命周期。 您可以为容器的生命周期配置启动执行、启动后处理和停止前处理。具体参见https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/。 启动执行:为容器设置预启动命令和参数。 启动后处理:为容器设置启动后的命令。 停止前处理:为容器设置预结束命令。 配置生命周期 配置数据卷信息。 支持配置本地存储和云存储。 本地存储:支持主机目录(hostpath)、配置项(configmap)、保密字典(secret)和临时目录,将对应的挂载源挂载到容器路径中。更多信息参见 volumes。 云存储:支持云存储。 本例中配置了一个云存储类型的数据卷声明 disk-ssd,将其挂载到容器的 /tmp 路径下。 配置数据卷 可选: 配置日志服务,您可进行采集配置和自定义 Tag 设置。 说明 请确保已部署 Kubernetes 集群,并且在此集群上已安装日志插件。 您可对日志进行采集配置: 日志库:即在日志服务中生成一个对应的 logstore,用于存储采集到的日志。 容器内日志路径:支持 stdout 和文本日志。 stdout: stdout 表示采集容器的标准输出日志。 文本日志:表示收集容器内指定路径的日志,本例中表示收集/var/log/nginx 下所有的文本日志,也支持通配符的方式。 您还可设置自定义 tag,设置 tag 后,会将该 tag 一起采集到容器的日志输出中。自定义 tag 可帮助您给容器日志打上 tag,方便进行日志统计和过滤等分析操作。 配置日志采集 完成容器配置后,单击 下一步。 进行高级设置。本例中仅进行访问设置。 设置访问设置。 您可以设置暴露后端 Pod 的方式,最后单击创建。本例中选择 ClusterIP 服务和路由(Ingress),构建一个公网可访问的 nginx 应用。 说明 针对应用的通信需求,您可灵活进行访问设置: 内部应用:对于只在集群内部工作的应用,您可根据需要创建 ClusterIP 或 NodePort 类型的服务,来进行内部通信。 外部应用:对于需要暴露到公网的应用,您可以采用两种方式进行访问设置: 创建 LoadBalancer 类型的服务:使用阿里云提供的负载均衡服务(Server Load Balancer,SLB),该服务提供公网访问能力。 创建路由(Ingress):通过路由(Ingress)提供公网访问能力,详情参见https://kubernetes.io/docs/concepts/services-networking/ingress/。 访问设置 在服务栏单击创建,在弹出的对话框中进行配置,最后单击创建。 创建服务 名称:您可自主设置,默认为 applicationname-svc。 类型:您可以从下面 3 种服务类型中进行选择。 虚拟集群 IP:即 ClusterIP,指通过集群的内部 IP 暴露服务,选择该项,服务只能够在集群内部访问。 节点端口:即 NodePort,通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 : ,可以从集群的外部访问一个 NodePort 服务。 负载均衡:即 LoadBalancer,是阿里云提供的负载均衡服务,可选择公网访问或内网访问。负载均衡可以路由到 NodePort 服务和 ClusterIP 服务。 端口映射:您需要添加服务端口和容器端口,若类型选择为节点端口,还需要自己设置节点端口,防止端口出现冲突。支持 TCP/UDP 协议。 注解:为该服务添加一个注解(annotation),支持负载均衡配置参数,参见通过负载均衡(Server Load Balancer)访问服务。 标签:您可为该服务添加一个标签,标识该服务。 在路由栏单击创建,在弹出的对话框中,为后端 Pod 配置路由规则,最后单击创建。更多详细的路由配置信息,请参见路由配置说明。 说明 通过镜像创建应用时,您仅能为一个服务创建路由(Ingress)。本例中使用一个虚拟主机名称作为测试域名,您需要在 hosts 中添加一条记录。在实际工作场景中,请使用备案域名。 101.37.224.146 foo.bar.com #即ingress的IP 创建路由 在访问设置栏中,您可看到创建完毕的服务和路由,您可单击变更和删除进行二次配置。 变更或删除路由 可选: 容器组水平伸缩。 您可勾选是否开启容器组水平伸缩,为了满足应用在不同负载下的需求,容器服务支持服容器组 Pod 的弹性伸缩,即根据容器 CPU 和内存资源占用情况自动调整容器组数量。 说明 若要启用自动伸缩,您必须为容器设置所需资源,否则容器自动伸缩无法生效。参见容器基本配置环节。 指标:支持 CPU 和内存,需要和设置的所需资源类型相同。 触发条件:资源使用率的百分比,超过该使用量,容器开始扩容。 最大副本数量:该 StatefulSet 可扩容的容器数量上限。 最小副本数量:该 StatefulSet 可缩容的容器数量下限。 可选: 设置调度设置。 您可设置升级方式、节点亲和性、应用亲和性和应用非亲和性,详情参见https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity。 说明 亲和性调度依赖节点标签和 Pod 标签,您可使用内置的标签进行调度;也可预先为节点、Pod 配置相关的标签。 设置升级方式。 升级方式包括滚动升级(rollingupdate)和替换升级(recreate),详细请参见https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/ 设置节点亲和性,通过 Node 节点的 Label 标签进行设置。 节点亲和性 节点调度支持硬约束和软约束(Required/Preferred),以及丰富的匹配表达式(In, NotIn, Exists, DoesNotExist. Gt, and Lt): 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution,效果与 NodeSelector 相同。本例中 Pod 只能调度到具有对应标签的 Node 节点。您可以定义多条硬约束规则,但只需满足其中一条。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。本例中,调度会尽量不调度 Pod 到具有对应标签的 Node 节点。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。您可定义多条软约束规则,但必须满足全部约束,才会进行调度。 设置应用亲和性调度。决定应用的 Pod 可以和哪些 Pod 部署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一个主机)中,减少它们之间的网络延迟。 应用亲和性调度 根据节点上运行的 Pod 的标签(Label)来进行调度,支持硬约束和软约束,匹配的表达式有:In, NotIn, Exists, DoesNotExist。 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution,Pod 的亲和性调度必须要满足后续定义的约束条件。 命名空间:该策略是依据 Pod 的 Label 进行调度,所以会受到命名空间的约束。 拓扑域:即 topologyKey,指定调度时作用域,这是通过 Node 节点的标签来实现的,例如指定为 kubernetes.io/hostname,那就是以 Node 节点为区分范围;如果指定为 beta.kubernetes.io/os,则以 Node 节点的操作系统类型来区分。 选择器:单击选择器右侧的加号按钮,您可添加多条硬约束规则。 查看应用列表:单击应用列表,弹出对话框,您可在此查看各命名空间下的应用,并可将应用的标签导入到亲和性配置页面。 硬约束条件:设置已有应用的标签、操作符和标签值。本例中,表示将待创建的应用调度到该主机上,该主机运行的已有应用具有 app:nginx 标签。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。Pod 的亲和性调度会尽量满足后续定义的约束条件。对于软约束规则,您可配置每条规则的权重,其他配置规则与硬约束规则相同。 说明 权重:设置一条软约束规则的权重,介于 1-100,通过算法计算满足软约束规则的节点的权重,将 Pod 调度到权重最大的节点上。 设置应用非亲和性调度,决定应用的 Pod 不与哪些 Pod 部署在同一拓扑域。应用非亲和性调度的场景包括: 将一个服务的 Pod 分散部署到不同的拓扑域(如不同主机)中,提高服务本身的稳定性。 给予 Pod 一个节点的独占访问权限来保证资源隔离,保证不会有其它 Pod 来分享节点资源。 把可能会相互影响的服务的 Pod 分散在不同的主机上。 说明 应用非亲和性调度的设置方式与亲和性调度相同,但是相同的调度规则代表的意思不同,请根据使用场景进行选择。 最后单击创建。 创建成功后,默认进入创建完成页面,会列出应用包含的对象,您可以单击查看应用详情进行查看。 查看详情1 默认进入有状态副本集详情页面。 查看副本详情 然后单击左上角返回列表,进入有状态副本集列表页面,查看创建的 StatefulSet 应用。 查看应用 可选: 选择所需的 nginx 应用,单击右侧伸缩,验证服务伸缩性。 在弹出的对话框中,将容器组数量设置为 3,您可发现扩容时,扩容容器组的排序依次递增;反之,进行缩容时,先按 Pod 次序从高到低进行缩容。这体现 StatefulSet 中 Pod 的次序稳定性。 验证服务伸缩 单击左侧导航栏中的应用 > 存储声明,您可发现,随着应用扩容,会随着 Pod 创建新的云存储卷;缩容后,已创建的 PV/PVC 不会删除。 存储声明 后续步骤 连接到 Master 节点,执行以下命令,验证持久化存储特性。 在云盘中创建临时文件: kubectl exec nginx-1 ls /tmp #列出该目录下的文件 lost+found kubectl exec nginx-1 touch /tmp/statefulset #增加一个临时文件statefulset kubectl exec nginx-1 ls /tmp lost+found statefulset 删除 Pod,验证数据持久性: kubectl delete pod nginx-1 pod"nginx-1" deleted 过一段时间,待Pod自动重启后,验证数据持久性,证明 StatefulSet 应用的高可用性。 kubectl exec nginx-1 ls /tmp #数据持久化存储 lost+found statefulset 想要了解更多信息,参见Kubernetes有状态服务-StatefulSet使用最佳实践。
1934890530796658 2020-03-31 15:46:45 0 浏览量 回答数 0

回答

阿里云容器服务 Kubernetes 集群支持通过界面创建 StatefultSet 类型的应用,满足您快速创建有状态应用的需求。本例中将创建一个 nginx 的有状态应用,并演示 StatefulSet 应用的特性。 前提条件 您已成功创建一个 Kubernetes 集群。参见创建 Kubernetes 集群。 您已成功创建一个云盘存储卷声明,参见创建持久化存储卷声明。 您已连接到 Kubernetes 集群的 Master 节点,参见通过 kubectl 连接 Kubernetes 集群。 背景信息 StatefulSet 包括如下特性: 场景 说明 Pod 一致性 包含次序(启动、停止次序)、网络一致性。此一致性与 Pod 相关,与被调度到哪个 node 节点无关。 稳定的持久化存储 通过 VolumeClaimTemplate 为每个 Pod 创建一个 PV。删除、减少副本,不会删除相关的卷。 稳定的网络标志 Pod 的 hostname 模式为:(statefulset名称)−(序号)。 稳定的次序 对于N个副本的 StatefulSet,每个 Pod 都在 [0,N)的范围内分配一个数字序号,且是唯一的。 操作步骤 登录容器服务管理控制台。 在 Kubernetes 菜单下,单击左侧导航栏中的应用 > 有状态,然后单击页面右上角的使用镜像创建。 在应用基本信息页面进行设置,然后单击下一步 进入应用配置页面。 应用名称:设置应用的名称。 部署集群:设置应用部署的集群。 命名空间:设置应用部署所处的命名空间,默认使用 default 命名空间。 副本数量:即应用包含的 Pod 数量。 类型:可选择无状态(Deployment)和有状态(StatefulSet)两种类型。 说明 本例中选择有状态类型,创建 StatefulSet 类型的应用。 标签:为该应用添加一个标签,标识该应用。 注解:为该应用添加一个注解(annotation)。 应用配置页面 设置容器配置。 说明 您可为应用的 Pod 设置多个容器。 设置容器的基本配置。 镜像名称:您可以单击选择镜像,在弹出的对话框中选择所需的镜像并单击确定,本例中为 nginx。 您还可以填写私有 registry。填写的格式为domainname/namespace/imagename:tag 镜像版本:您可以单击选择镜像版本 选择镜像的版本。若不指定,默认为 latest。 总是拉取镜像:为了提高效率,容器服务会对镜像进行缓存。部署时,如果发现镜像 Tag 与本地缓存的一致,则会直接复用而不重新拉取。所以,如果您基于上层业务便利性等因素考虑,在做代码和镜像变更时没有同步修改 Tag ,就会导致部署时还是使用本地缓存内旧版本镜像。而勾选该选项后,会忽略缓存,每次部署时重新拉取镜像,确保使用的始终是最新的镜像和代码。 镜像密钥:单击设置镜像密钥设置镜像的密钥。对于私有仓库访问时,需要设置密钥,具体可以参见使用镜像密钥。 资源限制:可指定该应用所能使用的资源上限,包括 CPU 和内存两种资源,防止占用过多资源。其中,CPU 资源的单位为 millicores,即一个核的千分之一;内存的单位为 Bytes,可以为 Gi、Mi 或 Ki。 所需资源:即为该应用预留资源额度,包括 CPU 和内存两种资源,即容器独占该资源,防止因资源不足而被其他服务或进程争夺资源,导致应用不可用。 Init Container:勾选该项,表示创建一个Init Container,Init Container 包含一些实用的工具,具体参见https://kubernetes.io/docs/concepts/workloads/pods/init-containers/。 设置容器基本信息 可选: 配置环境变量。 支持通过键值对的形式为 Pod 配置环境变量。用于给 Pod 添加环境标志或传递配置等,具体请参见 Pod variable。 可选: 配置健康检查。 支持存活检查(liveness)和就绪检查(Readiness)。存活检查用于检测何时重启容器;就绪检查确定容器是否已经就绪,且可以接受流量。关于健康检查的更多信息,请参见https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes。 请求类型 配置说明 HTTP请求 即向容器发送一个HTTPget 请求,支持的参数包括: 协议:HTTP/HTTPS。 路径:访问HTTP server 的路径。 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535。 HTTP头:即HTTPHeaders,HTTP请求中自定义的请求头,HTTP允许重复的header。支持键值对的配置方式。 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为3秒。 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 TCP连接 即向容器发送一个 TCP Socket,kubelet 将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。支持的参数包括: 端口:容器暴露的访问端口或端口名,端口号必须介于 1~65535。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为 15 秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 命令行 通过在容器中执行探针检测命令,来检测容器的健康情况。支持的参数包括: 命令行:用于检测容器健康情况的探测命令。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为5秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 可选: 配置生命周期。 您可以为容器的生命周期配置启动执行、启动后处理和停止前处理。具体参见https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/。 启动执行:为容器设置预启动命令和参数。 启动后处理:为容器设置启动后的命令。 停止前处理:为容器设置预结束命令。 配置生命周期 配置数据卷信息。 支持配置本地存储和云存储。 本地存储:支持主机目录(hostpath)、配置项(configmap)、保密字典(secret)和临时目录,将对应的挂载源挂载到容器路径中。更多信息参见 volumes。 云存储:支持云存储。 本例中配置了一个云存储类型的数据卷声明 disk-ssd,将其挂载到容器的 /tmp 路径下。 配置数据卷 可选: 配置日志服务,您可进行采集配置和自定义 Tag 设置。 说明 请确保已部署 Kubernetes 集群,并且在此集群上已安装日志插件。 您可对日志进行采集配置: 日志库:即在日志服务中生成一个对应的 logstore,用于存储采集到的日志。 容器内日志路径:支持 stdout 和文本日志。 stdout: stdout 表示采集容器的标准输出日志。 文本日志:表示收集容器内指定路径的日志,本例中表示收集/var/log/nginx 下所有的文本日志,也支持通配符的方式。 您还可设置自定义 tag,设置 tag 后,会将该 tag 一起采集到容器的日志输出中。自定义 tag 可帮助您给容器日志打上 tag,方便进行日志统计和过滤等分析操作。 配置日志采集 完成容器配置后,单击 下一步。 进行高级设置。本例中仅进行访问设置。 设置访问设置。 您可以设置暴露后端 Pod 的方式,最后单击创建。本例中选择 ClusterIP 服务和路由(Ingress),构建一个公网可访问的 nginx 应用。 说明 针对应用的通信需求,您可灵活进行访问设置: 内部应用:对于只在集群内部工作的应用,您可根据需要创建 ClusterIP 或 NodePort 类型的服务,来进行内部通信。 外部应用:对于需要暴露到公网的应用,您可以采用两种方式进行访问设置: 创建 LoadBalancer 类型的服务:使用阿里云提供的负载均衡服务(Server Load Balancer,SLB),该服务提供公网访问能力。 创建路由(Ingress):通过路由(Ingress)提供公网访问能力,详情参见https://kubernetes.io/docs/concepts/services-networking/ingress/。 访问设置 在服务栏单击创建,在弹出的对话框中进行配置,最后单击创建。 创建服务 名称:您可自主设置,默认为 applicationname-svc。 类型:您可以从下面 3 种服务类型中进行选择。 虚拟集群 IP:即 ClusterIP,指通过集群的内部 IP 暴露服务,选择该项,服务只能够在集群内部访问。 节点端口:即 NodePort,通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 : ,可以从集群的外部访问一个 NodePort 服务。 负载均衡:即 LoadBalancer,是阿里云提供的负载均衡服务,可选择公网访问或内网访问。负载均衡可以路由到 NodePort 服务和 ClusterIP 服务。 端口映射:您需要添加服务端口和容器端口,若类型选择为节点端口,还需要自己设置节点端口,防止端口出现冲突。支持 TCP/UDP 协议。 注解:为该服务添加一个注解(annotation),支持负载均衡配置参数,参见通过负载均衡(Server Load Balancer)访问服务。 标签:您可为该服务添加一个标签,标识该服务。 在路由栏单击创建,在弹出的对话框中,为后端 Pod 配置路由规则,最后单击创建。更多详细的路由配置信息,请参见路由配置说明。 说明 通过镜像创建应用时,您仅能为一个服务创建路由(Ingress)。本例中使用一个虚拟主机名称作为测试域名,您需要在 hosts 中添加一条记录。在实际工作场景中,请使用备案域名。 101.37.224.146 foo.bar.com #即ingress的IP 创建路由 在访问设置栏中,您可看到创建完毕的服务和路由,您可单击变更和删除进行二次配置。 变更或删除路由 可选: 容器组水平伸缩。 您可勾选是否开启容器组水平伸缩,为了满足应用在不同负载下的需求,容器服务支持服容器组 Pod 的弹性伸缩,即根据容器 CPU 和内存资源占用情况自动调整容器组数量。 说明 若要启用自动伸缩,您必须为容器设置所需资源,否则容器自动伸缩无法生效。参见容器基本配置环节。 指标:支持 CPU 和内存,需要和设置的所需资源类型相同。 触发条件:资源使用率的百分比,超过该使用量,容器开始扩容。 最大副本数量:该 StatefulSet 可扩容的容器数量上限。 最小副本数量:该 StatefulSet 可缩容的容器数量下限。 可选: 设置调度设置。 您可设置升级方式、节点亲和性、应用亲和性和应用非亲和性,详情参见https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity。 说明 亲和性调度依赖节点标签和 Pod 标签,您可使用内置的标签进行调度;也可预先为节点、Pod 配置相关的标签。 设置升级方式。 升级方式包括滚动升级(rollingupdate)和替换升级(recreate),详细请参见https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/ 设置节点亲和性,通过 Node 节点的 Label 标签进行设置。 节点亲和性 节点调度支持硬约束和软约束(Required/Preferred),以及丰富的匹配表达式(In, NotIn, Exists, DoesNotExist. Gt, and Lt): 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution,效果与 NodeSelector 相同。本例中 Pod 只能调度到具有对应标签的 Node 节点。您可以定义多条硬约束规则,但只需满足其中一条。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。本例中,调度会尽量不调度 Pod 到具有对应标签的 Node 节点。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。您可定义多条软约束规则,但必须满足全部约束,才会进行调度。 设置应用亲和性调度。决定应用的 Pod 可以和哪些 Pod 部署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一个主机)中,减少它们之间的网络延迟。 应用亲和性调度 根据节点上运行的 Pod 的标签(Label)来进行调度,支持硬约束和软约束,匹配的表达式有:In, NotIn, Exists, DoesNotExist。 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution,Pod 的亲和性调度必须要满足后续定义的约束条件。 命名空间:该策略是依据 Pod 的 Label 进行调度,所以会受到命名空间的约束。 拓扑域:即 topologyKey,指定调度时作用域,这是通过 Node 节点的标签来实现的,例如指定为 kubernetes.io/hostname,那就是以 Node 节点为区分范围;如果指定为 beta.kubernetes.io/os,则以 Node 节点的操作系统类型来区分。 选择器:单击选择器右侧的加号按钮,您可添加多条硬约束规则。 查看应用列表:单击应用列表,弹出对话框,您可在此查看各命名空间下的应用,并可将应用的标签导入到亲和性配置页面。 硬约束条件:设置已有应用的标签、操作符和标签值。本例中,表示将待创建的应用调度到该主机上,该主机运行的已有应用具有 app:nginx 标签。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。Pod 的亲和性调度会尽量满足后续定义的约束条件。对于软约束规则,您可配置每条规则的权重,其他配置规则与硬约束规则相同。 说明 权重:设置一条软约束规则的权重,介于 1-100,通过算法计算满足软约束规则的节点的权重,将 Pod 调度到权重最大的节点上。 设置应用非亲和性调度,决定应用的 Pod 不与哪些 Pod 部署在同一拓扑域。应用非亲和性调度的场景包括: 将一个服务的 Pod 分散部署到不同的拓扑域(如不同主机)中,提高服务本身的稳定性。 给予 Pod 一个节点的独占访问权限来保证资源隔离,保证不会有其它 Pod 来分享节点资源。 把可能会相互影响的服务的 Pod 分散在不同的主机上。 说明 应用非亲和性调度的设置方式与亲和性调度相同,但是相同的调度规则代表的意思不同,请根据使用场景进行选择。 最后单击创建。 创建成功后,默认进入创建完成页面,会列出应用包含的对象,您可以单击查看应用详情进行查看。 查看详情1 默认进入有状态副本集详情页面。 查看副本详情 然后单击左上角返回列表,进入有状态副本集列表页面,查看创建的 StatefulSet 应用。 查看应用 可选: 选择所需的 nginx 应用,单击右侧伸缩,验证服务伸缩性。 在弹出的对话框中,将容器组数量设置为 3,您可发现扩容时,扩容容器组的排序依次递增;反之,进行缩容时,先按 Pod 次序从高到低进行缩容。这体现 StatefulSet 中 Pod 的次序稳定性。 验证服务伸缩 单击左侧导航栏中的应用 > 存储声明,您可发现,随着应用扩容,会随着 Pod 创建新的云存储卷;缩容后,已创建的 PV/PVC 不会删除。 存储声明 后续步骤 连接到 Master 节点,执行以下命令,验证持久化存储特性。 在云盘中创建临时文件: kubectl exec nginx-1 ls /tmp #列出该目录下的文件 lost+found kubectl exec nginx-1 touch /tmp/statefulset #增加一个临时文件statefulset kubectl exec nginx-1 ls /tmp lost+found statefulset 删除 Pod,验证数据持久性: kubectl delete pod nginx-1 pod"nginx-1" deleted 过一段时间,待Pod自动重启后,验证数据持久性,证明 StatefulSet 应用的高可用性。 kubectl exec nginx-1 ls /tmp #数据持久化存储 lost+found statefulset 想要了解更多信息,参见Kubernetes有状态服务-StatefulSet使用最佳实践。
1934890530796658 2020-03-26 11:41:16 0 浏览量 回答数 0

回答

您可以在安全沙箱容器Kubernetes集群中使用镜像创建一个可公网访问的nginx应用。 前提条件 创建一个安全沙箱容器集群。详情请参见创建安全沙箱容器集群。 操作步骤 登录容器服务管理控制台。 在Kubernetes菜单下,单击左侧导航栏中的应用 > 无状态,然后单击页面右上角的使用镜像创建。 设置应用名称、部署集群 、 命名空间、副本数量、类型、容器运行时、注解和标签,副本数量即应用包含的Pod数量。然后单击下一步 进入容器配置页面。 说明 本例中选择无状态类型,即Deployment类型。 容器运行时:可选择runc和runv,如果没有选择,默认为runc。创建安全沙箱容器应用时,需要选择为runv。 如果您不设置命名空间,系统会默认使用 default 命名空间。 应用基本信息 设置容器配置。 说明 您可为应用的Pod设置多个容器。 设置容器的基本配置。 镜像名称:您可以单击选择镜像,在弹出的对话框中选择所需的镜像并单击确定,本例中为 nginx。 您还可以填写私有 registry。填写的格式为domainname/namespace/imagename:tag 镜像版本:您可以单击选择镜像版本 选择镜像的版本。若不指定,默认为 latest。 总是拉取镜像:为了提高效率,容器服务会对镜像进行缓存。部署时,如果发现镜像 Tag 与本地缓存的一致,则会直接复用而不重新拉取。所以,如果您基于上层业务便利性等因素考虑,在做代码和镜像变更时没有同步修改 Tag ,就会导致部署时还是使用本地缓存内旧版本镜像。而勾选该选项后,会忽略缓存,每次部署时重新拉取镜像,确保使用的始终是最新的镜像和代码。 镜像密钥:单击设置镜像密钥设置镜像的密钥。对于私有仓库访问时,需要设置密钥,具体可以参见使用镜像密钥 资源限制:可指定该应用所能使用的资源上限,包括 CPU 和内存两种资源,防止占用过多资源。其中,CPU 资源的单位为 cores,即一个核;内存的单位为 Bytes,可以为 Mi 。 所需资源:即为该应用预留资源额度,包括 CPU 和内存两种资源,即容器独占该资源,防止因资源不足而被其他服务或进程争占资源,导致应用不可用。 Init Container:勾选该项,表示创建一个Init Container,Init Container包含一些实用的工具,具体参见https://kubernetes.io/docs/concepts/workloads/pods/init-containers/。 基本信息配置 可选: 配置环境变量。 支持通过键值对的形式为 Pod 配置环境变量。用于给 Pod 添加环境标志或传递配置等,具体请参见 Pod variable。 可选: 设置健康检查 支持存活检查(liveness)和就绪检查(Readiness)。存活检查用于检测何时重启容器;就绪检查确定容器是否已经就绪,且可以接受流量。关于健康检查的更多信息,请参见https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes。 健康检查 请求类型 配置说明 HTTP请求 即向容器发送一个HTTPget 请求,支持的参数包括: 协议:HTTP/HTTPS 路径:访问HTTP server 的路径 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535。 HTTP头:即HTTPHeaders,HTTP请求中自定义的请求头,HTTP允许重复的header。支持键值对的配置方式。 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为3秒。 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10s,最小为1s。 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。 TCP连接 即向容器发送一个TCP Socket,kubelet将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。支持的参数包括: 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535。 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为15秒。 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10s,最小为1s。 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。 命令行 通过在容器中执行探针检测命令,来检测容器的健康情况。支持的参数包括: 命令行:用于检测容器健康情况的探测命令。 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为5秒。 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10s,最小为1s。 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。 配置生命周期。 您可以为容器的生命周期配置容器启动项、启动执行、启动后处理和停止前处理。具体参见https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/。 启动执行:为容器设置预启动命令和参数。 启动后处理:为容器设置启动后的命令。 停止前处理:为容器设置预结束命令。 配置生命周期 可选: 配置数据卷信息。 支持配置本地存储和云存储。 本地存储:支持主机目录(hostpath)、配置项(configmap)、保密字典(secret)和临时目录,将对应的挂载源挂载到容器路径中。更多信息参见 volumes。 云存储:支持云盘/NAS/OSS三种云存储类型。 本例中配置了一个云盘类型的数据卷,将该云盘挂载到容器中/tmp 路径下,在该路径下生成的容器数据会存储到云盘中。 配置数据卷 完成容器配置后,单击 下一步。 进行高级设置。 设置访问设置。 您可以设置暴露后端Pod的方式,最后单击创建。本例中选择ClusterIP服务和路由(Ingress),构建一个可公网访问的nginx应用。 说明 针对应用的通信需求,您可灵活进行访问设置: 内部应用:对于只在集群内部工作的应用,您可根据需要创建ClusterIP或NodePort类型的服务,来进行内部通信。 外部应用:对于需要暴露到公网的应用,您可以采用两种方式进行访问设置: 创建LoadBalancer类型的服务:使用阿里云提供的负载均衡服务(Server Load Balancer,SLB),该服务提供公网访问能力。 创建ClusterIP、NodePort类型的服务,以及路由(Ingress):通过路由提供公网访问能力,详情参见https://kubernetes.io/docs/concepts/services-networking/ingress/。 创建应用1 在服务栏单击创建,在弹出的对话框中进行配置,最后单击创建。 创建应用2 名称:您可自主设置,默认为applicationname-svc。 类型:您可以从下面 3 种服务类型中进行选择。 虚拟集群 IP:即 ClusterIP,指通过集群的内部 IP 暴露服务,选择该项,服务只能够在集群内部访问。 节点端口:即 NodePort,通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。 负载均衡:即 LoadBalancer,是阿里云提供的负载均衡服务,可选择公网访问或内网访问。负载均衡可以路由到 NodePort 服务和 ClusterIP 服务。 端口映射:您需要添加服务端口和容器端口,若类型选择为节点端口,还需要自己设置节点端口,防止端口出现冲突。支持 TCP/UDP 协议。 注解:为该服务添加一个注解(annotation),支持负载均衡配置参数,参见通过负载均衡(Server Load Balancer)访问服务。 标签:您可为该服务添加一个标签,标识该服务。 在路由栏单击创建,在弹出的对话框中,为后端Pod配置路由规则,最后单击创建。更多详细的路由配置信息,请参见路由配置说明。 说明 通过镜像创建应用时,您仅能为一个服务创建路由(Ingress)。本例中使用一个虚拟主机名称作为测试域名,您需要在hosts中添加一条记录。在实际工作场景中,请使用备案域名。 101.37.224.146 foo.bar.com #即ingress的IP 配置路由规则 在访问设置栏中,您可看到创建完毕的服务和路由,您可单击变更和删除进行二次配置。 变更和删除路由 可选: 容器组水平伸缩。 您可勾选是否开启容器组水平伸缩,为了满足应用在不同负载下的需求,容器服务支持服容器组(Pod)的弹性伸缩,即根据容器 CPU 和内存资源占用情况自动调整容器组数量。 容器组水平伸缩 说明 若要启用自动伸缩,您必须为容器设置所需资源,否则容器自动伸缩无法生效。参见容器基本配置环节。 指标:支持CPU和内存,需要和设置的所需资源类型相同。 触发条件:资源使用率的百分比,超过该使用量,容器开始扩容。 最大容器数量:该Deployment可扩容的容器数量上限。 最小容器数量:该Deployment可缩容的容器数量下限。 可选: 设置调度设置。 您可设置升级方式、节点亲和性、应用亲和性和应用非亲和性,详情参见https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity。 说明 亲和性调度依赖节点标签和Pod标签,您可使用内置的标签进行调度;也可预先为节点、Pod配置相关的标签。 设置升级方式。 升级方式包括滚动升级(rollingupdate)和替换升级(recreate),详细请参见https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/ 设置节点亲和性,通过Node节点的Label标签进行设置。 设置节点亲和性 节点调度支持硬约束和软约束(Required/Preferred),以及丰富的匹配表达式(In, NotIn, Exists, DoesNotExist. Gt, and Lt): 必须满足,即硬约束,一定要满足,对应requiredDuringSchedulingIgnoredDuringExecution,效果与NodeSelector相同。本例中Pod只能调度到具有对应标签的Node节点。您可以定义多条硬约束规则,但只需满足其中一条。 尽量满足,即软约束,不一定满足,对应preferredDuringSchedulingIgnoredDuringExecution。本例中,调度会尽量不调度Pod到具有对应标签的Node节点。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。您可定义多条软约束规则,但必须满足全部约束,才会进行调度。 设置应用亲和性调度。决定应用的Pod可以和哪些Pod部署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一个主机)中,减少它们之间的网络延迟。 应用亲和性调度 根据节点上运行的Pod的标签(Label)来进行调度,支持硬约束和软约束,匹配的表达式有:In, NotIn, Exists, DoesNotExist。 必须满足,即硬约束,一定要满足,对应requiredDuringSchedulingIgnoredDuringExecution,Pod的亲和性调度必须要满足后续定义的约束条件。 命名空间:该策略是依据Pod的Label进行调度,所以会受到命名空间的约束。 拓扑域:即topologyKey,指定调度时作用域,这是通过Node节点的标签来实现的,例如指定为kubernetes.io/hostname,那就是以Node节点为区分范围;如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分。 选择器:单击选择器右侧的加号按钮,您可添加多条硬约束规则。 查看应用列表:单击应用列表,弹出对话框,您可在此查看各命名空间下的应用,并可将应用的标签导入到亲和性配置页面。 硬约束条件:设置已有应用的标签、操作符和标签值。本例中,表示将待创建的应用调度到该主机上,该主机运行的已有应用具有app:nginx标签。 尽量满足,即软约束,不一定满足,对应preferredDuringSchedulingIgnoredDuringExecution。Pod的亲和性调度会尽量满足后续定义的约束条件。对于软约束规则,您可配置每条规则的权重,其他配置规则与硬约束规则相同。 说明 权重:设置一条软约束规则的权重,介于1-100,通过算法计算满足软约束规则的节点的权重,将Pod调度到权重最大的节点上。 设置应用非亲和性调度,决定应用的Pod不与哪些Pod部署在同一拓扑域。应用非亲和性调度的场景包括: 将一个服务的Pod分散部署到不同的拓扑域(如不同主机)中,提高服务本身的稳定性。 给予Pod一个节点的独占访问权限来保证资源隔离,保证不会有其它Pod来分享节点资源。 把可能会相互影响的服务的Pod分散在不同的主机上。 说明 应用非亲和性调度的设置方式与亲和性调度相同,但是相同的调度规则代表的意思不同,请根据使用场景进行选择。 最后单击创建。 创建成功后,默认进入创建完成页面,会列出应用包含的对象,您可以单击查看应用详情进行查看。 查看详情 默认进入新建的nginx-deployment的详情页面。 查看详情2 说明 您也可以通过以下操作创建路由与服务。如上图所示,在访问方式页签。 单击服务右侧的创建,也可以进行服务创建,操作步骤同6.i.a。 您单击路由右侧的创建,进行路由的创建,操作同6.i.b。 单击左侧导航栏的路由与负载均衡 > 路由,可以看到路由列表下出现一条规则。 路由规则 在浏览器中访问路由测试域名,您可访问 nginx 欢迎页。 访问nginx
1934890530796658 2020-03-27 10:03:36 0 浏览量 回答数 0

问题

随手科技拥抱OneAPM:打造高标准真实用户体验

近期OneAPM 与随手科技达成战略合作。OneAPM 通过探针技术帮助随手科技实现对产品整个系统的全面监控,并帮助开发人员快速解决移动应用的性能瓶颈。 据了解,随手科技是国内最大的个人理财应用服务提供商。旗下拥...
sunny夏筱 2019-12-01 21:42:04 7083 浏览量 回答数 4

回答

Spring Cloud 学习笔记(一)——入门、特征、配置 0 放在前面 0.1 参考文档 http://cloud.spring.io/spring-cloud-static/Brixton.SR7/ https://springcloud.cc/ http://projects.spring.io/spring-cloud/ 0.2 maven配置 org.springframework.boot spring-boot-starter-parent 1.5.2.RELEASE org.springframework.cloud spring-cloud-dependencies Dalston.RELEASE pom import org.springframework.cloud spring-cloud-starter-config org.springframework.cloud spring-cloud-starter-eureka 0.3 简介 Spring Cloud为开发人员提供了快速构建分布式系统中的一些通用模式(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式 会话,群集状态)。 分布式系统的协调引出样板模式(boiler plate patterns),并且使用Spring Cloud开发人员可以快速地实现这些模式来启动服务和应用程序。 它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心和受管平台,如Cloud Foundry。 Version: Brixton.SR7 1 特征 Spring Cloud专注于为经典用例和扩展机制提供良好的开箱即用 分布式/版本配置 服务注册与发现 路由选择 服务调用 负载均衡 熔断机制 全局锁 领导人选举和集群状态 分布式消息 2 原生云应用程序 原生云是应用程序开发的一种风格,鼓励在持续交付和价值驱动领域的最佳实践。 Spring Cloud的很多特性是基于Spring Boot的。更多的是由两个库实现:Spring Cloud Context and Spring Cloud Commons。 2.1 Spring Cloud Context: 应用上下文服务 Spring Boot关于使用Spring构建应用有硬性规定:通用的配置文件在固定的位置,通用管理终端,监控任务。建立在这个基础上,Spring Cloud增加了一些额外的特性。 2.1.1 引导应用程序上下文 Spring Cloud会创建一个“bootstrap”的上下文,这是主应用程序的父上下文。对应的配置文件拥有最高优先级,并且,默认不能被本地配置文件覆盖。对应的文件名bootstrap.yml或bootstrap.properties。 可通过设置spring.cloud.bootstrap.enabled=false来禁止bootstrap进程。 2.1.2 应用上下文层级结构 当用SpringApplication或SpringApplicationBuilder创建应用程序上下文时,bootstrap上下文将作为父上下文被添加进去,子上下文将继承父上下文的属性。 子上下文的配置信息可覆盖父上下文的配置信息。 2.1.3 修改Bootstrap配置文件位置 spring.cloud.bootstrap.name(默认是bootstrap),或者spring.cloud.bootstrap.location(默认是空) 2.1.4 覆盖远程配置文件的值 spring.cloud.config.allowOverride=true spring.cloud.config.overrideNone=true spring.cloud.config.overrideSystemProperties=false 2.1.5 定制Bootstrap配置 在/META-INF/spring.factories的key为org.springframework.cloud.bootstrap.BootstrapConfiguration,定义了Bootstrap启动的组件。 在主应用程序启动之前,一开始Bootstrap上下文创建在spring.factories文件中的组件,然后是@Beans类型的bean。 2.1.6 定制Bootstrap属性来源 关键点:spring.factories、PropertySourceLocator 2.1.7 环境改变 应用程序可通过EnvironmentChangedEvent监听应用程序并做出响应。 2.1.8 Refresh Scope Spring的bean被@RefreshScope将做特殊处理,可用于刷新bean的配置信息。 注意 需要添加依赖“org.springframework.boot.spring-boot-starter-actuator” 目前我只在@Controller测试成功 需要自己发送POST请求/refresh 修改配置文件即可 2.1.9 加密和解密 Spring Cloud可对配置文件的值进行加密。 如果有"Illegal key size"异常,那么需要安装JCE。 2.1.10 服务点 除了Spring Boot提供的服务点,Spring Cloud也提供了一些服务点用于管理,注意都是POST请求 /env:更新Environment、重新绑定@ConfigurationProperties跟日志级别 /refresh重新加载配置文件,刷新标记@RefreshScope的bean /restart重启应用,默认不可用 生命周期方法:/pause、/resume 2.2 Spring Cloud Commons:通用抽象 服务发现、负载均衡、熔断机制这种模式为Spring Cloud客户端提供了一个通用的抽象层。 2.2.1 RestTemplate作为负载均衡客户端 通过@Bean跟@LoadBalanced指定RestTemplate。注意URI需要使用虚拟域名(如服务名,不能用域名)。 如下: @Configuration public class MyConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } } public class MyClass { @Autowired private RestTemplate restTemplate; public String doOtherStuff() { String results = restTemplate.getForObject(" http://stores/stores", String.class); return results; } } 2.2.2 多个RestTemplate对象 注意@Primary注解的使用。 @Configuration public class MyConfiguration { @LoadBalanced @Bean RestTemplate loadBalanced() { return new RestTemplate(); } @Primary @Bean RestTemplate restTemplate() { return new RestTemplate(); } } public class MyClass { @Autowired private RestTemplate restTemplate; @Autowired @LoadBalanced private RestTemplate loadBalanced; public String doOtherStuff() { return loadBalanced.getForObject(" http://stores/stores", String.class); } public String doStuff() { return restTemplate.getForObject(" http://example.com", String.class); } } 2.2.3 忽略网络接口 忽略确定名字的服务发现注册,支持正则表达式配置。 3 Spring Cloud Config Spring Cloud Config提供服务端和客户端在分布式系统中扩展配置。支持不同环境的配置(开发、测试、生产)。使用Git做默认配置后端,可支持配置环境打版本标签。 3.1 快速开始 可通过IDE运行或maven运行。 默认加载property资源的策略是克隆一个git仓库(at spring.cloud.config.server.git.uri')。 HTTP服务资源的构成: /{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties application是SpringApplication的spring.config.name,(一般来说'application'是一个常规的Spring Boot应用),profile是一个active的profile(或者逗号分隔的属性列表),label是一个可选的git标签(默认为"master")。 3.1.1 客户端示例 创建以Spring Boot应用即可,添加依赖“org.springframework.cloud:spring-cloud-starter-config”。 配置application.properties,注意URL为配置服务端的地址 spring.cloud.config.uri: http://myconfigserver.com 3.2 Spring Cloud Config 服务端 针对系统外的配置项(如name-value对或相同功能的YAML内容),该服务器提供了基于资源的HTTP接口。使用@EnableConfigServer注解,该服务器可以很容易的被嵌入到Spring Boot 系统中。使用该注解之后该应用系统就是一个配置服务器。 @SpringBootApplication @EnableConfigServer public class ConfigApplicion { public static void main(String[] args) throws Exception { SpringApplication.run(ConfigApplicion.class, args); } } 3.2.1 资源库环境 {application} 对应客户端的"spring.application.name"属性 {profile} 对应客户端的 "spring.profiles.active"属性(逗号分隔的列表) {label} 对应服务端属性,这个属性能标示一组配置文件的版本 如果配置库是基于文件的,服务器将从application.yml和foo.yml中创建一个Environment对象。高优先级的配置优先转成Environment对象中的PropertySource。 3.2.1.1 Git后端 默认的EnvironmentRepository是用Git后端进行实现的,Git后端对于管理升级和物理环境是很方便的,对审计配置变更也很方便。也可以file:前缀从本地配置库中读取数据。 这个配置库的实现通过映射HTTP资源的{label}参数作为git label(提交id,分支名称或tag)。如果git分支或tag的名称包含一个斜杠 ("/"),此时HTTP URL中的label需要使用特殊字符串"(_)"来替代(为了避免与其他URL路径相互混淆)。如果使用了命令行客户端如 curl,请谨慎处理URL中的括号(例如:在shell下请使用引号''来转义它们)。 Git URI占位符 Spring Cloud Config Server支持git库URL中包含针对{application}和 {profile}的占位符(如果你需要,{label}也可包含占位符, 不过要牢记的是任何情况下label只指git的label)。所以,你可以很容易的支持“一个应用系统一个配置库”策略或“一个profile一个配置库”策略。 模式匹配和多资源库 spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo repos: simple: https://github.com/simple/config-repo special: pattern: special*/dev*,special/dev* uri: https://github.com/special/config-repo local: pattern: local* uri: file:/home/configsvc/config-repo 如果 {application}/{profile}不能匹配任何表达式,那么将使用“spring.cloud.config.server.git.uri”对应的值。在上例子中,对于 "simple" 配置库, 匹配模式是simple/* (也就说,无论profile是什么,它只匹配application名称为“simple”的应用系统)。“local”库匹配所有application名称以“local”开头任何应用系统,不管profiles是什么(来实现覆盖因没有配置对profile的匹配规则,“/”后缀会被自动的增加到任何的匹配表达式中)。 Git搜索路径中的占位符 spring.cloud.config.server.git.searchPaths 3.2.1.2 版本控制后端文件系统使用 伴随着版本控制系统作为后端(git、svn),文件都会被check out或clone 到本地文件系统中。默认这些文件会被放置到以config-repo-为前缀的系统临时目录中。在Linux上,譬如应该是/tmp/config-repo- 目录。有些操作系统routinely clean out放到临时目录中,这会导致不可预知的问题出现。为了避免这个问题,通过设置spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir参数值为非系统临时目录。 3.2.1.3 文件系统后端 使用本地加载配置文件。 需要配置:spring.cloud.config.server.native.searchLocations跟spring.profiles.active=native。 路径配置格式:classpath:/, classpath:/config,file:./, file:./config。 3.2.1.4 共享配置给所有应用 基于文件的资源库 在基于文件的资源库中(i.e. git, svn and native),这样的文件名application 命名的资源在所有的客户端都是共享的(如 application.properties, application.yml, application-*.properties,etc.)。 属性覆盖 “spring.cloud.config.server.overrides”添加一个Map类型的name-value对来实现覆盖。 例如 spring: cloud: config: server: overrides: foo: bar 会使所有的配置客户端应用程序读取foo=bar到他们自己配置参数中。 3.2.2 健康指示器 通过这个指示器能够检查已经配置的EnvironmentRepository是否正常运行。 通过设置spring.cloud.config.server.health.enabled=false参数来禁用健康指示器。 3.2.3 安全 你可以自由选择任何你觉得合理的方式来保护你的Config Server(从物理网络安全到OAuth2 令牌),同时使用Spring Security和Spring Boot 能使你做更多其他有用的事情。 为了使用默认的Spring Boot HTTP Basic 安全,只需要把Spring Security 增加到classpath中(如org.springframework.boot.spring-boot-starter-security)。默认的用户名是“user”,对应的会生成一个随机密码,这种情况在实际使用中并没有意义,一般建议配置一个密码(通过 security.user.password属性进行配置)并对这个密码进行加密。 3.2.4 加密与解密 如果远程属性包含加密内容(以{cipher}开头),这些值将在通过HTTP传递到客户端之前被解密。 使用略 3.2.5 密钥管理 配置服务可以使用对称(共享)密钥或者非对称密钥(RSA密钥对)。 使用略 3.2.6 创建一个测试密钥库 3.2.7 使用多密钥和循环密钥 3.2.8 加密属性服务 3.3 可替换格式服务 配置文件可加后缀".yml"、".yaml"、".properties" 3.4 文本解释服务 /{name}/{profile}/{label}/{path} 3.5 嵌入配置服务器 一般配置服务运行在单独的应用里面,只要使用注解@EnableConfigServer即可嵌入到其他应用。 3.6 推送通知和总线 添加依赖spring-cloud-config-monitor,激活Spring Cloud 总线,/monitor端点即可用。 当webhook激活,针对应用程序可能已经变化了的,配置服务端将发送一个RefreshRemoteApplicationEvent。 3.7 客户端配置 3.7.1 配置第一次引导 通过spring.cloud.config.uri属性配置Config Server地址 3.7.2 发现第一次引导 如果用的是Netflix,则用eureka.client.serviceUrl.defaultZone进行配置。 3.7.3 配置客户端快速失败 在一些例子里面,可能希望在没有连接配置服务端时直接启动失败。可通过spring.cloud.config.failFast=true进行配置。 3.7.4 配置客户端重试 添加依赖spring-retry、spring-boot-starter-aop,设置spring.cloud.config.failFast=true。默认的是6次重试,初始补偿间隔是1000ms,后续补偿为1.1指数乘数,可通过spring.cloud.config.retry.*配置进行修改。 3.7.5 定位远程配置资源 路径:/{name}/{profile}/{label} "name" = ${spring.application.name} "profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles()) "label" = "master" label对于回滚到之前的版本很有用。 3.7.6 安全 通过spring.cloud.config.password、spring.cloud.config.username进行配置。 答案来源于网络
养狐狸的猫 2019-12-02 02:18:34 0 浏览量 回答数 0

回答

您可以使用镜像创建一个可公网访问的 nginx 应用。 前提条件 创建一个 Kubernetes 集群。详情请参见创建 Kubernetes 集群。 操作步骤 登录容器服务管理控制台。 在 Kubernetes 菜单下,单击左侧导航栏中的应用 > 无状态,然后单击页面右上角的使用镜像创建。 设置应用名称、部署集群 、命名空间、副本数量、类型、注解和标签,副本数量即应用包含的 Pod 数量。然后单击下一步 进入容器配置页面。 说明 本例中选择无状态类型,即 Deployment 类型。 如果您不设置命名空间,系统会默认使用 default 命名空间。 基本配置 设置容器配置。 说明 您可为应用的Pod设置多个容器。 设置容器的基本配置。 镜像名称:您可以单击选择镜像,在弹出的对话框中选择所需的镜像并单击确定,本例中为 nginx。 您还可以填写私有 registry。填写的格式为domainname/namespace/imagename:tag 镜像版本:您可以单击选择镜像版本 选择镜像的版本。若不指定,默认为 latest。 总是拉取镜像:为了提高效率,容器服务会对镜像进行缓存。部署时,如果发现镜像 Tag 与本地缓存的一致,则会直接复用而不重新拉取。所以,如果您基于上层业务便利性等因素考虑,在做代码和镜像变更时没有同步修改 Tag ,就会导致部署时还是使用本地缓存内旧版本镜像。而勾选该选项后,会忽略缓存,每次部署时重新拉取镜像,确保使用的始终是最新的镜像和代码。 镜像密钥:单击设置镜像密钥设置镜像的密钥。对于私有仓库访问时,需要设置密钥,具体可以参见使用镜像密钥 资源限制:可指定该应用所能使用的资源上限,包括 CPU 和内存两种资源,防止占用过多资源。其中,CPU 资源的单位为 cores,即一个核;内存的单位为 Bytes,可以为 Mi 。 所需资源:即为该应用预留资源额度,包括 CPU 和内存两种资源,即容器独占该资源,防止因资源不足而被其他服务或进程争占资源,导致应用不可用。 Init Container:勾选该项,表示创建一个 Init Container,Init Container 包含一些实用的工具,具体参见https://kubernetes.io/docs/concepts/workloads/pods/init-containers/。 基本信息配置 可选: 配置环境变量。 支持通过键值对的形式为 Pod 配置环境变量。用于给 Pod 添加环境标志或传递配置等,具体请参见 Pod variable。 可选: 设置健康检查 支持存活检查(liveness)和就绪检查(Readiness)。存活检查用于检测何时重启容器;就绪检查确定容器是否已经就绪,且可以接受流量。关于健康检查的更多信息,请参见https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes。 健康检查 请求类型 配置说明 HTTP请求 即向容器发送一个 HTTPget 请求,支持的参数包括: 协议:HTTP/HTTPS。 路径:访问 HTTP server 的路径。 端口:容器暴露的访问端口或端口名,端口号必须介于 1~65535。 HTTP 头:即 HTTPHeaders,HTTP 请求中自定义的请求头,HTTP 允许重复的 header。支持键值对的配置方式。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为 3 秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 TCP连接 即向容器发送一个 TCP Socket,kubelet 将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。支持的参数包括: 端口:容器暴露的访问端口或端口名,端口号必须介于 1~65535。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为 15 秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为 1 秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 命令行 通过在容器中执行探针检测命令,来检测容器的健康情况。支持的参数包括: 命令行:用于检测容器健康情况的探测命令。 延迟探测时间(秒):即 initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为 5秒。 执行探测频率(秒):即 periodSeconds,指执行探测的时间间隔,默认为 10 秒,最小为1秒。 超时时间(秒):即 timeoutSeconds,探测超时时间。默认 1 秒,最小 1 秒。 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,最小值是 1。对于存活检查(liveness)必须是 1。 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。 配置生命周期。 您可以为容器的生命周期配置容器启动项、启动执行、启动后处理和停止前处理。具体参见 https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/。 启动执行:为容器设置预启动命令和参数。 启动后处理:为容器设置启动后的命令。 停止前处理:为容器设置预结束命令。 配置生命周期 可选: 配置数据卷信息。 支持配置本地存储和云存储。 本地存储:支持主机目录(hostpath)、配置项(configmap)、保密字典(secret)和临时目录,将对应的挂载源挂载到容器路径中。更多信息参见 volumes。 云存储:支持云存储。 本例中配置了一个云存储类型的数据卷,将该云盘挂载到容器中 /tmp 路径下。 配置数据卷 可选: 配置日志服务,您可进行采集配置和自定义 Tag 设置。 说明 请确保已部署 Kubernetes 集群,并且在此集群上已安装日志插件。 您可对日志进行采集配置: 日志库:即在日志服务中生成一个对应的 logstore,用于存储采集到的日志。 容器内日志路径:支持 stdout 和文本日志。 stdout:stdout 表示采集容器的标准输出日志。 文本日志:表示收集容器内指定路径的日志,本例中表示收集 /var/log/nginx 下所有的文本日志,也支持通配符的方式。 您还可设置自定义 tag,设置 tag 后,会将该 tag 一起采集到容器的日志输出中。自定义 tag 可帮助您给容器日志打上 tag,方便进行日志统计和过滤等分析操作。 日志采集配置 完成容器配置后,单击 下一步。 进行高级设置。 设置访问设置。 您可以设置暴露后端 Pod 的方式,最后单击创建。本例中选择 ClusterIP 服务和路由(Ingress),构建一个可公网访问的 nginx 应用。 说明 针对应用的通信需求,您可灵活进行访问设置: 内部应用:对于只在集群内部工作的应用,您可根据需要创建 ClusterIP 或 NodePort 类型的服务,来进行内部通信。 外部应用:对于需要暴露到公网的应用,您可以采用两种方式进行访问设置: 创建 LoadBalancer 类型的服务:使用阿里云提供的负载均衡服务(Server Load Balancer,SLB),该服务提供公网访问能力。 创建路由(Ingress):通过路由(Ingress)提供公网访问能力,详情参见https://kubernetes.io/docs/concepts/services-networking/ingress/。 创建应用1 在服务栏单击创建,在弹出的对话框中进行配置,最后单击创建。 名称:您可自主设置,默认为 applicationname-svc。 类型:您可以从下面 3 种服务类型中进行选择。 虚拟集群 IP:即 ClusterIP,指通过集群的内部 IP 暴露服务,选择该项,服务只能够在集群内部可以访问。 节点端口:即 NodePort,通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 : ,可以从集群的外部访问一个 NodePort 服务。 负载均衡:即 LoadBalancer,是阿里云提供的负载均衡服务,可选择公网访问或内网访问。负载均衡可以路由到 NodePort 服务和 ClusterIP 服务。 端口映射:您需要添加服务端口和容器端口,若类型选择为节点端口,还需要自己设置节点端口,防止端口出现冲突。支持 TCP/UDP 协议。 注解:为该服务添加一个注解(annotation),支持负载均衡配置参数,参见通过负载均衡(Server Load Balancer)访问服务。 标签:您可为该服务添加一个标签,标识该服务。 在路由栏单击创建,在弹出的对话框中,为后端 Pod 配置路由规则,最后单击创建。更多详细的路由配置信息,请参见路由配置说明。 说明 通过镜像创建应用时,您仅能为一个服务创建路由(Ingress)。本例中使用一个虚拟主机名称作为测试域名,您需要在 hosts 中添加一条记录。在实际工作场景中,请使用备案域名。 101.37.224.146 foo.bar.com #即ingress的IP 配置路由规则 在访问设置栏中,您可看到创建完毕的服务和路由,您可单击变更和删除进行二次配置。 变更和删除路由 可选: 容器组水平伸缩。 您可勾选是否开启容器组水平伸缩,为了满足应用在不同负载下的需求,容器服务支持容器组(Pod)的弹性伸缩,即根据容器 CPU 和内存资源占用情况自动调整容器组数量。 容器组水平伸缩 说明 若要启用自动伸缩,您必须为容器设置所需资源,否则容器自动伸缩无法生效。参见容器基本配置环节。 指标:支持 CPU 和内存,需要和设置的所需资源类型相同。 触发条件:资源使用率的百分比,超过设置的Pod request值,容器开始扩容。 最大容器数量:该 Deployment 可扩容的容器数量上限。 最小容器数量:该 Deployment 可缩容的容器数量下限。 可选: 设置调度设置。 您可设置升级方式、节点亲和性、应用亲和性和应用非亲和性,详情参见https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity。 说明 亲和性调度依赖节点标签和 Pod 标签,您可使用内置的标签进行调度;也可预先为节点、Pod 配置相关的标签。 设置升级方式。 升级方式包括滚动升级(rollingupdate)和替换升级(recreate),详细请参见https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/ 设置节点亲和性,通过 Node 节点的 Label 标签进行设置。 设置节点亲和性 节点调度支持硬约束和软约束(Required/Preferred),以及丰富的匹配表达式(In, NotIn, Exists, DoesNotExist. Gt, and Lt): 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution,效果与 NodeSelector 相同。本例中 Pod 只能调度到具有对应标签的 Node 节点。您可以定义多条硬约束规则,但只需满足其中一条。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。本例中,调度会尽量不调度 Pod 到具有对应标签的 Node 节点。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。您可定义多条软约束规则,但必须满足全部约束,才会进行调度。 设置应用亲和性调度。决定应用的 Pod 可以和哪些 Pod 部署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一个主机)中,减少它们之间的网络延迟。 应用亲和性调度 根据节点上运行的 Pod 的标签(Label)来进行调度,支持硬约束和软约束,匹配的表达式有:In, NotIn, Exists, DoesNotExist。 必须满足,即硬约束,一定要满足,对应 requiredDuringSchedulingIgnoredDuringExecution ,Pod 的亲和性调度必须要满足后续定义的约束条件。 命名空间:该策略是依据 Pod 的 Label 进行调度,所以会受到命名空间的约束。 拓扑域:即 topologyKey,指定调度时作用域,这是通过 Node 节点的标签来实现的,例如指定为kubernetes.io/hostname,那就是以 Node 节点为区分范围;如果指定为 beta.kubernetes.io/os,则以 Node 节点的操作系统类型来区分。 选择器:单击选择器右侧的加号按钮,您可添加多条硬约束规则。 查看应用列表:单击应用列表,弹出对话框,您可在此查看各命名空间下的应用,并可将应用的标签导入到亲和性配置页面。 硬约束条件:设置已有应用的标签、操作符和标签值。本例中,表示将待创建的应用调度到该主机上,该主机运行的已有应用具有 app:nginx 标签。 尽量满足,即软约束,不一定满足,对应 preferredDuringSchedulingIgnoredDuringExecution。Pod 的亲和性调度会尽量满足后续定义的约束条件。对于软约束规则,您可配置每条规则的权重,其他配置规则与硬约束规则相同。 说明 权重:设置一条软约束规则的权重,介于 1-100,通过算法计算满足软约束规则的节点的权重,将 Pod 调度到权重最大的节点上。 设置应用非亲和性调度,决定应用的 Pod 不与哪些 Pod 部署在同一拓扑域。应用非亲和性调度的场景包括: 将一个服务的 Pod 分散部署到不同的拓扑域(如不同主机)中,提高服务本身的稳定性。 给予 Pod 一个节点的独占访问权限来保证资源隔离,保证不会有其它 Pod 来分享节点资源。 把可能会相互影响的服务的 Pod 分散在不同的主机上。 说明 应用非亲和性调度的设置方式与亲和性调度相同,但是相同的调度规则代表的意思不同,请根据使用场景进行选择。 最后单击创建。 创建成功后,默认进入创建完成页面,会列出应用包含的对象,您可以单击查看应用详情进行查看。 查看详情 默认进入新建的 nginx-deployment 的详情页面。 查看详情2 说明 您也可以通过以下操作创建路由与服务。如上图所示,在访问方式页签。 单击服务右侧的创建,也可以进行服务创建,操作步骤同 6.i.a。 您单击路由右侧的创建,进行路由的创建,操作同 6.i.b。 单击左侧导航栏的路由与负载均衡 > 路由,可以看到路由列表下出现一条规则。 路由规则 在浏览器中访问路由测试域名,您可访问 nginx 欢迎页。 访问nginx
1934890530796658 2020-03-26 11:41:33 0 浏览量 回答数 0

回答

调用CreateScalingConfiguration创建一个伸缩配置。 调试 您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。 调试 请求参数 名称 类型 是否必选 示例值 描述 Action String 否 CreateScalingConfiguration 系统规定参数。取值: CreateScalingConfiguration。 ScalingGroupId String 是 asg-bp14wlu85wrpchm0**** 伸缩配置所属的伸缩组的ID。 ImageId String 否 centos6u5_64_20G_aliaegis****.vhd 镜像文件ID,自动创建实例时使用的镜像资源。 ImageName String 否 myimage 镜像文件名称,同一个地域内镜像名称唯一。如果设置了ImageId, ImageName将被忽略。 不支持通过ImageName设置镜像市场镜像。 InstanceType String 否 ecs.t1.xsmall ECS实例的实例规格,更多信息请参见实例规格族。 Cpu Integer 否 2 vCPU个数。 同时指定CPU和Memory可以定义实例规格范围,例如,CPU=2且Memory=16可以定义配置为2 vCPU和16 GiB的所有实例规格。弹性伸缩会结合IO优化、可用区等因素确定可用实例规格集合,并根据价格排序为您创建价格最低的实例。 说明 该区间配置效果仅在成本优化模式下且伸缩配置未设置实例规格时生效。 Memory Integer 否 16 内存大小。 同时指定CPU和Memory可以定义实例规格范围,例如,CPU=2且Memory=16可以定义配置为2 vCPU和16 GiB的所有实例规格。弹性伸缩会结合IO优化、可用区等因素确定可用实例规格集合,并根据价格排序为您创建价格最低的实例。 说明 该区间配置效果仅在成本优化模式下且伸缩配置未设置实例规格时生效。 DeploymentSetId String 否 ds-bp1frxuzdg87zh4pz**** ECS实例所属的部署集的ID。 InstanceTypes.N RepeatList 否 ecs.t1.xsmall.1 多实例规格参数。如果使用了InstanceTypes.N,InstanceType将被忽略,其中N的取值范围:1~10,即一个伸缩配置内最多可以设置10种实例规格。 N代表当前伸缩配置中实例规格的优先级,编号为1的实例规格优先级最高,实例规格优先级随着编号的增大依次降低。当无法根据优先级较高的实例规格创建出实例时,弹性伸缩服务会自动选择下一优先级的实例规格来创建实例。 SecurityGroupId String 否 sg-280ih**** ECS实例所属的安全组的ID,同一个安全组内的ECS实例可以互相访问。 IoOptimized String 否 optimized 是否为I/O优化实例。已停售的实例规格实例默认值是none,其他实例规格默认值是optimized。取值范围: none:非I/O优化实例。 optimized:I/O优化实例。 InternetChargeType String 否 PayByTraffic 网络计费类型,取值范围: PayByBandwidth:按带宽计费。此时InternetMaxBandwidthOut即为所选的固定带宽值。 PayByTraffic:按流量计费。此时InternetMaxBandwidthOut只是一个带宽上限,计费以实际产生的网络流量为依据。 如果未指定该参数,经典网络下默认值为PayByBandwidth,专有网络VPC下默认值为PayByTraffic。 InternetMaxBandwidthIn Integer 否 100 公网入带宽最大值,单位为Mbps (Mega bit per second),取值范围:1~200。 如果您没有指定该参数,则入带宽将自动被设置为200Mbps。实例的入数据流量免费,该参数在任何情况下都不涉及计费。 InternetMaxBandwidthOut Integer 否 50 公网出带宽最大值,单位为Mbps (Mega bit per second),取值范围: 按带宽计费:0~100,如果您没有指定该参数,则出带宽将自动被设置为0Mbps。 按流量计费:0~100,如果您没有指定该参数,则会出现报错。 SystemDisk.Category String 否 cloud_ssd 系统盘的磁盘种类。取值范围: cloud:普通云盘 cloud_efficiency:高效云盘 cloud_ssd:SSD云盘 ephemeral_ssd:本地SSD盘 cloud_essd:ESSD云盘 InstanceType为系列I的实例规格且实例属于非I/O优化实例时,默认值:cloud。否则,默认值:cloud_efficiency。 SystemDisk.Size Integer 否 100 系统盘的大小,单位:GiB。取值范围: cloud:20~500 cloud_efficiency:20~500 cloud_ssd:20~500 cloud_essd:20~500 ephemeral_ssd:20~500 默认值:max{40, ImageSize}。 指定该参数后,系统盘大小必须大于等于max{20, ImageSize}。 SystemDisk.DiskName String 否 cloud_ssdSystem 系统盘的名称。长度为2~128个英文或中文字符。必须以大小字母或中文开头,不能以 http:// 和 https:// 开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。 默认值:空。 SystemDisk.Description String 否 FinanceDept 系统盘的描述。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 SystemDisk.AutoSnapshotPolicyId String 否 sp-bp12m37ccmxvbmi5**** 系统盘使用的自动快照策略ID。 ScalingConfigurationName String 否 test-sc 伸缩配置的名称,2~64英文或中文字符,以数字、大小写字母或中文开头,可包含数字、下划线(_)、连字符(-)或点号(.)。 在同一地域下同一伸缩组内伸缩配置名称唯一。如果您没有指定该参数,则默认使用伸缩配置的ID。 DataDisk.N.Size Integer 否 100 数据盘N的磁盘大小,N的取值范围:1~16,内存单位为GiB。取值范围: cloud:5~2000 cloud_efficiency:20~32768 cloud_ssd:20~32768 cloud_essd:20~32768 ephemeral_ssd:5~800 指定该参数后,磁盘大小必须大于等于快照大小(快照通过SnapshotId指定)。 DataDisk.N.SnapshotId String 否 s-280s7**** 创建数据盘时使用的快照,N的取值范围:1~16。指定该参数后,DataDisk.N.Size会被忽略,实际创建的磁盘大小为指定快照的大小。 如果该快照创建于2013年7月15日或之前,调用会被拒绝,返回参数中会提示InvalidSnapshot.TooOld。 DataDisk.N.Category String 否 cloud_ssd 数据盘N的磁盘种类,N的取值范围:1~16。该参数取值范围: cloud:普通云盘。随实例创建的普通云盘的DeleteWithInstance属性为true。 cloud_efficiency:高效云盘 cloud_ssd:SSD云盘 ephemeral_ssd:本地SSD盘 cloud_essd:ESSD云盘 对于I/O优化实例,默认值为cloud_efficiency。对于非I/O优化实例,默认值为cloud。 DataDisk.N.Device String 否 /dev/xvdb 数据盘挂载点,N的取值范围:1~16。如果您没有指定该参数,则默认在自动创建ECS实例时由系统分配,从/dev/xvdb开始,到/dev/xvdz结束。 DataDisk.N.DeleteWithInstance Boolean 否 true 指定数据盘是否随实例释放,N的取值范围:1~16。该参数取值范围: true:释放实例时,该磁盘随实例一起释放。 false:释放实例时,该磁盘保留不释放。 默认值:true。 该参数只可对独立云盘设置(DataDisk.N.Category为cloud、cloud_efficiency、cloud_ssd或cloud_essd),否则会出现报错。 DataDisk.N.Encrypted String 否 false 数据盘N是否加密,N的取值范围:1~16。该参数取值范围: true:加密 false:不加密 默认值:false。 DataDisk.N.KMSKeyId String 否 0e478b7a-4262-4802-b8cb-00d3fb40**** 数据盘对应的KMS密钥的ID,N的取值范围:1~16。 DataDisk.N.DiskName String 否 cloud_ssdData 数据盘的名称,N的取值范围:1~16。长度为2~128个英文或中文字符。必须以大小字母或中文开头,不能以 http:// 和 https:// 开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。 默认值:空。 DataDisk.N.Description String 否 FinanceDept 数据盘的描述,N的取值范围:1~16。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 DataDisk.N.AutoSnapshotPolicyId String 否 sp-bp19nq9enxqkomib**** 数据盘使用的自动快照策略ID,N的取值范围:1~16。 LoadBalancerWeight Integer 否 50 后端服务器的权重,取值范围:1~100。 默认值:50。 Tags String 否 {"key1":"value1","key2":"value2", ... "key5":"value5"} ECS实例的标签。标签以键值对方式传入,最多可以使用5组标签。Key和Value的使用要求如下: Key最多支持64个字符,不能以aliyun和acs:开头,不能包含 http:// 或者 https:// 。一旦使用标签,Key不允许为空字符串。 Value最多支持128个字符,不能以aliyun和acs:开头,不能包含 http:// 或者 https:// 。Value可以为空字符串。 UserData String 否 echo hello ecs! ECS实例的自定义数据,需要以Base64方式编码,编码前的原始数据最多为16KB。 KeyPairName String 否 KeyPairTest 登录ECS实例时使用的密钥对的名称。 对Windows实例,该参数将被忽略,默认为空。 对Linux实例,密码登录方式会被初始化成禁止。 RamRoleName String 否 RamRoleTest ECS实例的RAM角色名称。RAM角色名称由RAM提供和维护,您可调用ListRoles查询可用的RAM角色。创建RAM角色的方法请参见CreateRole。 SecurityEnhancementStrategy String 否 Active 是否开启安全加固。取值范围: Active:启用安全加固,只对公共镜像生效。 Deactive:不启用安全加固,对所有镜像类型生效。 InstanceName String 否 Instance**** 使用本伸缩配置自动创建的ECS实例的名称。 HostName String 否 Host**** 云服务器的主机名。点号(.)或连字符(-)不能作为首尾字符,不能连续使用点号(.)或连字符(-)。另外,不同类型实例的命名要求如下: Windows实例:主机名长度为2~15,可以包含大小写字母、数字和连字符(-)。不能包含点号(.),不能全是数字。 其他类型实例(Linux等):主机名长度为2~64,可以包含多个点号(.)。两个点号(.)之间为一段,每段可以包含大小写字母、数字和连字符(-)。 SpotStrategy String 否 NoSpot 后付费实例的抢占策略。取值范围: NoSpot:普通的按量付费实例。 SpotWithPriceLimit:设置上限价格的抢占式实例。 SpotAsPriceGo:系统自动出价,跟随当前市场实际价格。 默认值:NoSpot。 PasswordInherit Boolean 否 false 是否使用镜像预设的密码。使用该参数时,您需要确保使用的镜像已经设置了密码。 SpotPriceLimit.N.InstanceType String 否 ecs.t1.xsmall 抢占式实例的实例规格,N的取值范围:1~10。SpotStrategy取值为SpotWithPriceLimit时生效。 SpotPriceLimit.N.PriceLimit Float 否 0.5 抢占式实例对应的出价,N的取值范围:1~10。SpotStrategy取值为SpotWithPriceLimit时生效。 Password String 否 123-abcABC ECS实例的密码。长度为8至30个字符,必须同时包含大小写英文字母、数字和特殊符号中的三类字符。特殊符号可以是: ()` ~!@#$%^&*-_+=|{}[]:;'<>,.?/ 其中,Windows实例不能以斜线号(/)为密码首字符。 说明 如果传入Password参数,建议您使用HTTPS协议发送请求,避免密码泄露。 ResourceGroupId String 否 rg-resource**** ECS实例所属资源组的ID。 SecurityGroupIds.N RepeatList 否 sg-bp18kz60mefs**** 将ECS实例同时加入多个安全组。N的取值范围与实例能够加入安全组上限有关。更多详情,请参见使用限制下的安全组章节。 说明 不支持同时指定SecurityGroupId和SecurityGroupIds.N。 HpcClusterId String 否 hpc-clusterid ECS实例所属的EHPC集群的ID。 InstanceDescription String 否 FinaceDept ECS实例的描述。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 ClientToken String 否 123e4567-e89b-12d3-a456-42665544**** 保证请求幂等性。从您的客户端生成一个参数值,确保不同请求间该参数值唯一。只支持ASCII字符,且不能超过64个字符。更多详情,请参见如何保证幂等性。 Ipv6AddressCount Integer 否 1 为弹性网卡指定随机生成的IPv6地址数量。 返回数据 名称 类型 示例值 描述 ScalingConfigurationId String asc-bp1ffogfdauy0nu5**** 伸缩配置ID。 RequestId String 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E 请求ID。 示例 请求示例 http(s)://[Endpoint]/?Action=CreateScalingConfiguration &ScalingGroupId=asg-bp14wlu85wrpchm0**** &SecurityGroupId=sg-280ih**** &<公共请求参数> 正常返回示例 XML 格式 asc-bp1ffogfdauy0nu5**** 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E JSON 格式 { "RequestId": "473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E", "ScalingConfigurationId": "asc-bp1ffogfdauy0nu5****" } 错误码 访问错误中心查看更多错误码。 HttpCode 错误码 错误信息 描述 400 InstanceType.Mismatch The specified scaling configuration and existing active scaling configuration have different instance type. 指定的伸缩配置的实例规格与当前的伸缩配置的实例规格不匹配。 404 InvalidDataDiskSnapshotId.NotFound Snapshot “XXX” does not exist. 不存在指定的快照。 400 InvalidDataDiskSnapshotId.SizeNotSupported The capacity of snapshot “XXX” exceeds the size limit of the specified disk category. 指定快照的大小超过了磁盘大小的限制。 403 InvalidDevice.InUse Device “XXX” has been occupied. 数据盘挂载点重复。 400 InvalidImageId.InstanceTypeMismatch The specified image does not support the specified instance type. 不允许在指定的实例规格下使用该镜像。 404 InvalidImageId.NotFound The specified image does not exist. 该账号下不存在指定的镜像。 400 InvalidKeyPairName.NotFound The specified KeyPairName does not exist in our records. 指定的KeyPairName不存在。 400 InvalidNetworkType.ForRAMRole RAMRole can't be used For classic instance. 经典网络实例不支持RamRoleName参数。 400 InvalidParameter The specified value of parameter KeyPairName is not valid. Windows系统不支持KeyPairName参数。 400 InvalidParameter.Conflict The value of parameter SystemDisk.Category and parameter DataDisk.N.Category are conflict. 指定的系统盘类型和数据盘类型冲突。 400 InvalidRamRole.NotFound The specified RamRoleName does not exist. 不存在指定的RamRoleName。 400 InvalidScalingConfigurationName.Duplicate The specified value of parameter ScalingConfigurationName is duplicated. 已存在相同伸缩配置名。 404 InvalidScalingGroupId.NotFound The specified scaling group does not exist. 该账号下不存在指定的伸缩组。 400 InvalidSecurityGroupId.IncorrectNetworkType The network type of specified security Group does not support this action. 指定的安全组与伸缩组指定网络类型不一致。 404 InvalidSecurityGroupId.NotFound The specified security group does not exist. 该账号下不存在指定的安全组。 400 InvalidSecurityGroupId.VPCMismatch The specified security group and the specified virtual switch are not in the same VPC. 指定的安全组和虚拟交换机不属于同一个虚拟专有网络。 403 InvalidSnapshot.TooOld This operation is denied because the specified snapshot is created before 2013-07-15. 该快照创建于2013年7月15日或之前,调用被拒绝。 403 InvalidSystemDiskCategory.ValueUnauthorized The system disk category is not authorized. 没有创建临时磁盘系统盘的权限。 400 InvalidUserData.Base64FormatInvalid The specified parameter UserData must be base64 encoded. UserData不符合Base64编码规范。 400 InvalidUserData.SizeExceeded The specified parameter UserData exceeds the size. 指定的UserData过长。 403 QuotaExceeded.EphemeralDiskSize Ephemeral disk size quota exceeded. 临时磁盘数据盘总容量超过2TiB(2048GiB)。 400 QuotaExceeded.ScalingConfiguration Scaling configuration quota exceeded in the specified scaling group. 您目前拥有的伸缩配置个数已经达到上限。 400 QuotaExceeded.SecurityGroupInstance Instance quota exceeded in the specified security group. 指定的安全组中添加的ECS实例个数已经达到上限。 调用DescribeScalingConfigurations查询现有的伸缩配置。 调试 您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。 调试 请求参数 名称 类型 是否必选 示例值 描述 Action String 否 DescribeScalingConfigurations 系统规定参数,取值:DescribeScalingConfigurations。 RegionId String 是 cn-qingdao 伸缩配置所属伸缩组的地域ID。 PageNumber Integer 否 1 伸缩配置列表的页码。起始值:1。 默认值:1 。 PageSize Integer 否 50 分页查询时设置的每页行数。最大值:50。 默认值:10。 ScalingGroupId String 否 asg-bp17pelvl720x3v7**** 伸缩组的ID,您可以查询该伸缩组下所有的伸缩配置。 ScalingConfigurationId.1 String 否 asc-bp17pelvl720x5ub**** ScalingConfigurationId.N为待查询伸缩配置的ID,N的取值范围:1~10。查询结果包括生效和失效的伸缩配置,并通过返回参数LifecycleState进行标识。 ScalingConfigurationName.1 String 否 c1908dd1-690f-4c9b-ab73-350f1f06**** ScalingConfigurationName.N为待查询伸缩配置的名称,N的取值范围:1~10。查询结果会忽略失效的伸缩配置名称,并且不报错。 返回数据 名称 类型 示例值 描述 TotalCount Integer 1 伸缩配置的总数。 PageNumber Integer 1 当前页码。 PageSize Integer 50 每页行数。 RequestId String 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E 请求ID。 ScalingConfigurations Array 伸缩配置信息的集合。 示例 请求示例 http(s)://[Endpoint]/?Action=DescribeScalingConfigurations &RegionId=cn-qingdao &<公共请求参数> 正常返回示例 XML 格式 804F240A-8D3E-40A1-BD68-6B333DEA2CA8 1 1 50 2014-08-14T10:58Z centos6u5_64_20G_aliaegis_20140703.vhd ecs.t1.xsmall PayByTraffic 200 0 Active asc-bp1ezrfgoyn5kijl**** c1908dd1-690f-4c9b-ab73-350f1f06**** sg-280ih**** sg-bp18kz60mefs**** cloud 200 cloud s-280s7**** /dev/xvdb JSON 格式 { "RequestId": "804F240A-8D3E-40A1-BD68-6B333DEA2CA8", "TotalCount": "1", "PageNumber": "1", "PageSize": "50", "ScalingConfigurations": { "ScalingConfiguration": { "CreationTime": "2014-08-14T10:58Z", "ImageId": "centos6u5_64_20G_aliaegis_20140703.vhd", "InstanceType": "ecs.t1.xsmall", "InternetChargeType": "PayByTraffic", "InternetMaxBandwidthIn": "200", "InternetMaxBandwidthOut": "0", "LifecycleState": "Active", "ScalingConfigurationId": "asc-bp1ezrfgoyn5kijl****", "ScalingConfigurationName": "c1908dd1-690f-4c9b-ab73-350f1f06****", "ScalingGroupId": "sg-280ih****", "SecurityGroupId": "sg-bp18kz60mefs****", "SystemDiskCategory": "cloud", "DataDisks": { "DataDisk": { "Size": "200", "Category": "cloud", "SnapshotId": "s-280s7****", "Device": "/dev/xvdb" } } } } } 错误码 访问错误中心查看更多错误码。调用DeleteScalingConfiguration删除一个伸缩配置。 接口说明 以下情况不能删除伸缩配置: 伸缩配置在伸缩组中处于生效状态。 伸缩组中仍然存在使用该伸缩配置创建的ECS实例。 调试 您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。 调试 请求参数 名称 类型 是否必选 示例值 描述 ScalingConfigurationId String 是 eOs27Kb0oXvQcUYjEGel**** 待删除伸缩配置的ID。 Action String 否 DeleteScalingConfiguration 系统规定参数,取值:DeleteScalingConfiguration。 返回数据 名称 类型 示例值 描述 RequestId String 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E 请求 ID。无论调用接口成功与否,我们都会返回请求 ID。 示例 请求示例 http://ess.aliyuncs.com/?Action=DeleteScalingConfiguration &ScalingConfigurationId=eOs27Kb0oXvQcUYjEGel**** &<公共请求参数> 正常返回示例 XML 格式 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E JSON 格式 { "RequestId":"473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E" } 错误码 访问错误中心查看更多错误码。 HttpCode 错误码 错误信息 描述 404 InvalidScalingConfigurationId.NotFound The specified scaling configuration does not exist. 指定的伸缩配置在该用户账号下不存在。 400 IncorrectScalingConfigurationLifecycleState The current lifecycle state of specified scaling configuration does not support this action. 指定的伸缩配置未处于Inactive状态。 400 InstanceInUse You cannot delete a scaling configuration or scaling group while there is an instance associated with it. 指定的伸缩配置还有关联的ECS实例未被删除。调用ModifyScalingConfiguration修改一个伸缩配置。 接口说明 如果修改伸缩配置的名称,请注意同一伸缩组下不能存在名称相同的伸缩配置。 调试 您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。 调试 请求参数 名称 类型 是否必选 示例值 描述 ScalingConfigurationId String 是 asc-**** 待修改伸缩配置的ID。 Action String 否 ModifyScalingConfiguration 系统规定参数,取值: ModifyScalingConfiguration。 Cpu Integer 否 2 vCPU个数。 同时指定CPU和Memory可以定义实例规格范围,例如,CPU=2且Memory=16可以定义配置为2 vCPU和16 GiB的所有实例规格。弹性伸缩会结合IO优化、可用区等因素确定可用实例规格集合,并根据价格排序为您创建价格最低的实例。 说明 该区间配置效果仅在成本优化模式下且伸缩配置未设置实例规格时生效。 DataDisk.N.AutoSnapshotPolicyId String 否 sp-bp19nq9enxqkomib**** 数据盘使用的自动快照策略ID,N的取值范围:1~16。 DataDisk.N.Category String 否 cloud_ssd 数据盘N的磁盘种类,N的取值范围:1~16。该参数取值范围: cloud:普通云盘。随实例创建的普通云盘的DeleteWithInstance属性为true。 cloud_efficiency:高效云盘 cloud_ssd:SSD云盘 cloud_essd:ESSD云盘 ephemeral_ssd:本地SSD盘 DataDisk.N.DeleteWithInstance Boolean 否 true 指定数据盘是否随实例释放,N的取值范围:1~16。该参数取值范围: true:释放实例时,该磁盘随实例一起释放。 false:释放实例时,该磁盘保留不释放。 该参数只可对独立云盘设置(DataDisk.N.Category为cloud、cloud_efficiency、cloud_ssd或cloud_essd),否则会出现报错。 DataDisk.N.Description String 否 FinanceDept 数据盘的描述,N的取值范围:1~16。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 DataDisk.N.Device String 否 /dev/xvdb 数据盘挂载点,N的取值范围:1~16。如果您没有指定该参数,则默认在自动创建ECS实例时由系统分配,从/dev/xvdb开始,到/dev/xvdz结束。 DataDisk.N.DiskName String 否 cloud_ssdData 数据盘的名称,N的取值范围:1~16。长度为2~128个英文或中文字符。必须以大小字母或中文开头,不能以 http:// 和 https:// 开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。 DataDisk.N.Encrypted String 否 false 数据盘N是否加密,N的取值范围:1~16。该参数取值范围: true:加密 false:不加密 DataDisk.N.KMSKeyId String 否 0e478b7a-4262-4802-b8cb-00d3fb40**** 数据盘对应的KMS密钥的ID,N的取值范围:1~16。 DataDisk.N.Size Integer 否 100 数据盘N的磁盘大小,N的取值范围:1~16,内存单位为GiB。取值范围: cloud:5~2000 cloud_efficiency:20~32768 cloud_ssd:20~32768 cloud_essd:20~32768 ephemeral_ssd:5~800 指定该参数后,磁盘大小必须大于等于快照大小(快照通过SnapshotId指定)。 DataDisk.N.SnapshotId String 否 s-snapshot**** 创建数据盘时使用的快照,N的取值范围:1~16。指定该参数后,DataDisk.N.Size会被忽略,实际创建的磁盘大小为指定快照的大小。 如果该快照创建于2013年7月15日或之前,调用会被拒绝,返回参数中会提示InvalidSnapshot.TooOld。 DeploymentSetId String 否 ds-bp13v7bjnj9gis**** ECS实例所属的部署集的ID。 HostName String 否 Joshu**** 云服务器的主机名。点号(.)或连字符(-)不能作为首尾字符,不能连续使用点号(.)或连字符(-)。另外,不同类型实例的命名要求如下: Windows实例:主机名长度为2~15,可以包含大小写字母、数字和连字符(-)。不能包含点号(.),不能全是数字。 其他类型实例(Linux等):主机名长度为2~64,可以包含多个点号(.)。两个点号(.)之间为一段,每段可以包含大小写字母、数字和连字符(-)。 HpcClusterId String 否 hpc-clusterid ECS实例所属的EHPC集群的ID。 ImageId String 否 centos6u5_64_20G_aliaegis_20140703.vhd 镜像文件ID,自动创建实例时使用的镜像资源。 ImageName String 否 suse11sp3_64_20G_aliaegis_20150428.vhd 镜像文件名称,同一个地域内镜像名称唯一。如果设置了ImageId, ImageName将被忽略。 不支持通过ImageName设置镜像市场镜像。 InstanceDescription String 否 FinaceDept ECS实例的描述。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 InstanceName String 否 Joshu**** 使用本伸缩配置自动创建的ECS实例的名称。 InstanceTypes.N RepeatList 否 ecs.t1.xsmall 多实例规格参数。如果使用了InstanceTypes.N,InstanceType将被忽略,其中N的取值范围:1~10,即一个伸缩配置内最多可以设置10种实例规格。 N代表当前伸缩配置中实例规格的优先级,编号为1的实例规格优先级最高,实例规格优先级随着编号的增大依次降低。当无法根据优先级较高的实例规格创建出实例时,弹性伸缩服务会自动选择下一优先级的实例规格来创建实例。 InternetChargeType String 否 PayByBandwidth 网络计费类型,取值范围: PayByBandwidth:按带宽计费。此时InternetMaxBandwidthOut即为所选的固定带宽值。 PayByTraffic:按流量计费。此时InternetMaxBandwidthOut只是一个带宽上限,计费以实际产生的网络流量为依据。 InternetMaxBandwidthOut Integer 否 50 公网出带宽最大值,单位为Mbps (Mega bit per second),取值范围: 按带宽计费:0~100,如果您没有指定该参数,则出带宽将自动被设置为0Mbps。 按流量计费:0~100,如果您没有指定该参数,则会出现报错。 IoOptimized String 否 none 是否为I/O优化实例。取值范围: none:非I/O优化实例。 optimized:I/O优化实例。 KeyPairName String 否 null 登录ECS实例时使用的密钥对的名称。 对Windows实例,该参数将被忽略,默认为空。 对Linux实例,密码登录方式会被初始化成禁止。 LoadBalancerWeight Integer 否 50 后端服务器的权重,取值范围:0~100。 Memory Integer 否 16 内存大小。 同时指定CPU和Memory可以定义实例规格范围,例如,CPU=2且Memory=16可以定义配置为2 vCPU和16 GiB的所有实例规格。弹性伸缩会结合IO优化、可用区等因素确定可用实例规格集合,并根据价格排序为您创建价格最低的实例。 说明 该区间配置效果仅在成本优化模式下且伸缩配置未设置实例规格时生效。 Override Boolean 否 true 是否覆盖。取值范围: true false PasswordInherit Boolean 否 false 是否使用镜像预设的密码。使用该参数时,您需要确保使用的镜像已经设置了密码。 RamRoleName String 否 RamRoleTest ECS实例的RAM角色名称。RAM角色名称由RAM提供和维护,您可调用ListRoles查询可用的RAM角色。创建RAM角色的方法请参见CreateRole。 ResourceGroupId String 否 abcd1234abcd**** ECS实例所属资源组的ID。 ScalingConfigurationName String 否 test-modify 伸缩配置的名称,2~64个英文或中文字符,以数字、大小写字母或中文开头,可包含数字、下划线(_)、连字符(-)或点号(.)。 在同一地域下同一伸缩组内伸缩配置名称唯一。如果您没有指定该参数,则默认使用伸缩配置的ID。 SecurityGroupId String 否 sg-F876F**** ECS实例所属的安全组的ID,同一个安全组内的ECS实例可以互相访问。 SecurityGroupIds.N RepeatList 否 sg-bp18kz60mefs**** 将ECS实例同时加入多个安全组。N的取值范围与实例能够加入安全组上限有关。更多详情,请参见使用限制下的安全组章节。 说明 不支持同时指定SecurityGroupId和SecurityGroupIds.N。 SpotPriceLimit.N.InstanceType String 否 ecs.t1.small 抢占式实例的实例规格,N的取值范围:1~10。SpotStrategy取值为SpotWithPriceLimit时生效。 SpotPriceLimit.N.PriceLimit Float 否 0.125 抢占式实例对应的出价,N的取值范围:1~10。SpotStrategy取值为SpotWithPriceLimit时生效。 SpotStrategy String 否 NoSpot 后付费实例的抢占策略。取值范围: NoSpot:普通的按量付费实例。 SpotWithPriceLimit:设置上限价格的抢占式实例。 SpotAsPriceGo:系统自动出价,跟随当前市场实际价格。 SystemDisk.AutoSnapshotPolicyId String 否 sp-bp12m37ccmxvbmi5**** 系统盘使用的自动快照策略ID。 SystemDisk.Category String 否 cloud_efficiency 系统盘的磁盘种类。取值范围: cloud:普通云盘 cloud_efficiency:高效云盘 cloud_ssd:SSD云盘 cloud_essd:ESSD云盘 ephemeral_ssd:本地SSD盘 SystemDisk.Description String 否 FinanceDept 系统盘的描述。长度为2~256个英文或中文字符,不能以 http:// 和 https:// 开头。 SystemDisk.DiskName String 否 cloud_ssdSystem 系统盘的名称。长度为2~128个英文或中文字符。必须以大小字母或中文开头,不能以 http:// 和 https:// 开头。可以包含数字、半角冒号(:)、下划线(_)或者连字符(-)。 SystemDisk.Size Integer 否 50 系统盘的大小,单位:GiB。取值范围: cloud:20~500 cloud_efficiency:20~500 cloud_ssd:20~500 cloud_essd:20~500 ephemeral_ssd:20~500 指定该参数后,系统盘大小必须大于等于max{20, ImageSize}。 Tags String 否 “key1”:”value1” ECS实例的标签。标签以键值对方式传入,最多可以使用5组标签。Key和Value的使用要求如下: Key最多支持64个字符,不能以aliyun和acs:开头,不能包含 http:// 或者 https:// 。一旦使用标签,Key不允许为空字符串。 Value最多支持128个字符,不能以aliyun和acs:开头,不能包含 http:// 或者 https:// 。Value可以为空字符串。 UserData String 否 echo hello ecs! ECS实例的自定义数据,需要以Base64方式编码,编码前的原始数据最多为16KB。 返回数据 名称 类型 示例值 描述 RequestId String 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E 请求ID。 示例 请求示例 http(s)://[Endpoint]/?Action=ModifyScalingConfiguration &ScalingConfigurationId=asc-**** &<公共请求参数> 正常返回示例 XML 格式 473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E JSON 格式 { "requestId":"473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E" } 错误码 访问错误中心查看更多错误码。 HttpCode 错误码 错误信息 描述 403 Forbidden.Unauthorized A required authorization for the specified action is not supplied. 未授权操作当前Action。 404 InvalidDataDiskSnapshotId.NotFound Snapshot “XXX” does not exist. 不存在指定的快照。 400 InvalidDataDiskSnapshotId.SizeNotSupported The capacity of snapshot “XXX” exceeds the size limit of the specified disk category. 指定快照的大小超过了磁盘大小的限制。 404 InvalidImageId.NotFound The specified image does not exist. 指定的镜像不存在。 400 InvalidKeyPairName.NotFound The specified KeyPairName does not exist in our records. 指定的KeyPairName不存在。 400 InvalidNetworkType.ForRAMRole RAMRole can’t be used For classic instance. 经典网络实例不支持RamRoleName参数。 400 InvalidParamter The specified value of parameter is not valid. 指定的参数值无效。 400 InvalidScalingConfigurationName.Duplicate The specified value of parameter is duplicated. 伸缩配置名已存在。 400 InvalidSecurityGroupId.IncorrectNetworkType The network type of specified Security Group does not support this action. 指定的安全组与伸缩组指定网络类型不一致。 400 InvalidSecurityGroupId.VPCMismatch The specified security group and the specified virtual switch are not in the same VPC. 指定的安全组和虚拟交换机不属于同一个虚拟专有网络。 400 InvalidTags.KeyValue The specified tags key/value cannot be empty. 必须指定Tags参数。 400 InvalidTags.ListSize The specified tags list size cannot be more than “5”. Tags列表长度超过限制长度。 400 InvalidUserData.Base64FormatInvalid The specified parameter UserData must be base64 encoded. UserData不符合Base64编码规范。 400 InvalidUserData.SizeExceeded The specified parameter UserData exceeds the size. 指定的UserData过长。
1934890530796658 2020-03-25 10:04:36 0 浏览量 回答数 0

问题

【阿里云产品公测】以开发者角度看ACE服务『ACE应用构建指南』

评测介绍 评测产品: 云引擎ACE服务开发语言: PHP评测人: mr_wid评测时间: 2014年10月13日-19日 评测概要 非常有幸能够申请到ACE的公测资格, 在本篇评测中, 笔者将以一个开发者的角度来对云引擎...
mr_wid 2019-12-01 21:10:06 20092 浏览量 回答数 6

问题

Git 改变了分布式 Web 开发规则:报错

版本控制系统是大部分开发项目的核心组件,无论是开发应用程序、网站还是操作系统。大部分项目都涉及多个开发人员,往往位于不同的位置。分布式版本控制系统并不是新事物,但是 Git 版本控制系统为开发人员之...
kun坤 2020-06-08 11:09:24 3 浏览量 回答数 1

回答

"主题前提 多语言站点包含三个不同方面: 界面翻译 内容 网址路由 尽管它们都以不同的方式互连,但是从CMS的角度来看,它们是使用不同的UI元素进行管理的,并且存储方式也不同。您似乎对自己的实现和对前两个的理解充满信心。问题是关于后一个方面的问题:“ URL转换?我们应该这样做吗?应该以什么方式进行?” URL可以由什么组成? 一个非常重要的事情是,不要对IDN感兴趣。取而代之的是支持音译(也:转录和罗马化)。乍一看,IDN似乎是国际URL的可行选择,但实际上,它不能按广告宣传工作,原因有两个: 某些浏览器会将非ASCII字符(例如'ч'或)'ž'转换为'%D1%87'和'%C5%BE' 如果用户具有自定义主题,则主题的字体很可能没有这些字母的符号 实际上,几年前,我在一个基于Yii的项目(可怕的框架,恕我直言)中尝试了IDN方法。在抓取该解决方案之前,我遇到了上述两个问题。另外,我怀疑这可能是攻击媒介。 可用选项...如我所见。 基本上,您有两个选择,可以抽象为: http://site.tld/[:query]:[:query]决定语言和内容选择的地方 http://site.tld/[:language]/[:query]:[:language]URL的一部分定义语言的选择,[:query]仅用于标识内容 查询是Α和Ω.. 假设您选择http://site.tld/[:query]。 在这种情况下,您有一种主要的语言来源:[:query]段的内容;以及另外两个来源: $_COOKIE['lang']该特定浏览器的价值 HTTP Accept-Language (1),(2)标头中的语言列表 首先,您需要将查询与定义的路由模式之一进行匹配(如果您选择的是Laravel,请在此处阅读)。成功匹配模式后,您需要查找语言。 您将必须遍历模式的所有部分。找到所有这些片段的潜在翻译,并确定使用哪种语言。当(不是“如果”)发生冲突时,将使用两个其他来源(cookie和标头)来解决路由冲突。 例如:http://site.tld/blog/novinka。 那是音译""блог, новинка"",在英语中大约是""blog"", ""latest""。 您已经注意到,俄语中的“блог”将译为“博客”。这意味着对于您的第一部分[:query](在最佳情况下),最终会['en', 'ru']列出可能的语言。然后您进入下一个片段-“ novinka”。可能的列表中可能只有一种语言:['ru']。 当列表中有一项时,您已经成功找到该语言。 但是,如果最终得到2种(例如:俄语和乌克兰语)或更多种可能性..或0种可能性(视情况而定)。您将必须使用Cookie和/或标题才能找到正确的选项。 如果其他所有方法均失败,则选择站点的默认语言。 语言作为参数 替代方法是使用URL,可以将其定义为http://site.tld/[:language]/[:query]。在这种情况下,翻译查询时,您无需猜测语言,因为此时您已经知道要使用哪种语言。 还有另一种语言来源:cookie值。但是,这里没有必要弄乱Accept-Language标头,因为在“冷启动”的情况下(当用户第一次使用自定义查询打开网站时),您不会处理未知数量的可能的语言。 相反,您有3个简单的优先选项: 如果[:language]设置了细分,请使用它 如果$_COOKIE['lang']设置,使用它 使用默认语言 使用该语言时,您只需尝试翻译查询,如果翻译失败,请对该特定段使用“默认值”(基于路由结果)。 这不是第三种选择吗? 是的,从技术上讲,您可以将两种方法结合使用,但这会使过程复杂化,并且只适合那些想要手动更改URL http://site.tld/en/news到http://site.tld/de/news并希望新闻页面更改为德语的人员。 但是即使是这种情况,也可以使用cookie值(其中包含有关先前选择语言的信息)缓解,以减少魔术和希望。 使用哪种方法? 您可能已经猜到了,我建议您将其http://site.tld/[:language]/[:query]作为更明智的选择。 同样在真实的单词情况下,URL中将包含第三大部分:“标题”。如在线商店中的产品名称或新闻站点中的文章标题。 例: http://site.tld/en/news/article/121415/EU-as-global-reserve-currency 在这种情况下'/news/article/121415'将是查询,而'EU-as-global-reserve-currency'标题是。纯粹用于SEO。 可以在Laravel中完成吗? Kinda,但默认情况下不是。 我不太熟悉它,但是据我所知,Laravel使用简单的基于模式的路由机制。要实现多语言URL,您可能必须扩展核心类,因为多语言路由需要访问不同形式的存储(数据库,缓存和/或配置文件)。 已路由。现在怎么办? 结果,您最终将获得两条有价值的信息:当前语言和查询的翻译段。然后,这些值可用于调度将产生结果的类。 基本上,以下网址:(http://site.tld/ru/blog/novinka或不含的版本'/ru')变成了类似 $parameters = [ 'language' => 'ru', 'classname' => 'blog', 'method' => 'latest', ]; 您仅用于调度的对象: $instance = new {$parameter['classname']}; $instance->{'get'.$parameters['method']}( $parameters ); ..或它的某些变体,具体取决于特定的实现。"来源:stack overflow
保持可爱mmm 2020-05-18 10:09:50 0 浏览量 回答数 0

回答

ECS磁盘 我想在ECS 跨服务器进行数据拷贝,有没有知道实现方法的? Linux系统服务器重启或初始化系统之后,再登录服务器执行df -h查看磁盘挂载,发现数据不见了。这是为什么?能不能找回来? 重启服务器后发现/alidata目录所有数据丢失。怎么才能找回来呢? ECS Linux扩容格式化磁盘提示magic number in super-block while trying to open /dev/xvdb1 ? Linux 实例初始化系统盘后,怎样才能重新挂载数据盘? 如何在ECS 利用快照创建磁盘实现无损扩容数据盘? ECS云服务器磁盘FAQ云服务器磁盘I/O速度是多少? Linux 购买了数据盘,但是系统中看不到怎么办? ECS系统盘和数据盘二次分区FAQ,系统盘能否再次划分出一个分区用作数据存储? ECS系统盘和数据盘二次分区FAQ,数据盘能否再次划分出一个分区用作数据存储? ECS系统盘和数据盘二次分区FAQ,划分了多个分区的磁盘,做快照时是针对该分区的,还是针对磁盘的? ECS系统盘和数据盘二次分区FAQ,磁盘二次分区有哪些注意事项? ECS系统盘和数据盘二次分区FAQ,数据盘进行二次分区后,此时回滚快照后,数据盘是几个分区? 什么是可用区? 怎么根据服务器应用需求选择可用区? 按量付费云盘和云盘有什么区别? 按量付费云盘和普通云盘的性能和数据安全性一样吗,磁盘性能会有提升吗? 可以使用用户快照创建按量付费云盘吗? 什么是挂载点? 一块按量付费云盘可以挂载到多个 ECS 实例上吗? 一台 ECS 实例能同时挂载多少块按量付费云盘吗? 按量付费云盘能够挂载到包年包月和按量付费 ECS 实例上吗? 为什么挂载按量付费云盘时找不到我想挂载的 ECS 实例? 购买按量付费云盘后,挂载到目标 ECS 实例的挂载点是否还需要执行磁盘挂载操作? 我已经操作过续费变配,在续费变配期内是否还能将普通云盘转为按量付费云盘? ECS快照 为什么我的按量付费云盘没有自动快照了? 重新初始化磁盘时,我的快照会丢失吗? 更换系统盘时,我的快照会丢失吗? 卸载按量付费云盘时,我的磁盘会丢数据吗? 我能够卸载系统盘吗? 什么是独立云磁盘? 什么是可用区? 独立云磁盘跟现在的磁盘有什么区别? 服务器应用与可用区选择的选择关系是怎么样的? 独立云磁盘怎么收费? 独立云磁盘能够挂载到包年包月实例上吗? 独立云磁盘和普通云磁盘的磁盘性能和数据安全性一样吗,磁盘性能会有提升吗? 我的包年包月实例上不需要的磁盘能不能卸载? 为什么我的独立云磁盘和我的实例一起释放了? 为什么独立云磁盘挂载时找不到我想挂载的实例? 为什么我在本实例列表中选择独立云磁盘挂载时找不到我想要挂载的磁盘? 我删除磁盘的时候,快照会被保留吗? 为什么我的独立云磁盘没有自动快照了? 为什么我不能购买独立云磁盘? 一台实例能挂载多少块独立云磁盘? 卸载独立云磁盘时,我的磁盘会丢数据吗? 我的系统盘能够卸载吗? 什么是设备名? 为什么我在控制台上找不到重置磁盘,更换操作系统,回滚快照的操作了? 重新初始化磁盘时,我的快照会丢失吗? 更换系统盘时,我的快照会丢失吗? 为什么我的数据盘不能选择临时磁盘 独立云磁盘服务器的应用场景有哪些? 可以使用用户快照创建独立云磁盘吗? 独立云磁盘购买后挂载到目标实例的挂载点后,是否还需要执行磁盘挂载操作? 本地SSD盘“本地”是指? 本地SSD盘适合的用户场景有哪些? SSD盘相对之前的普通云盘性能提升多少,是否可以提供具体参数? 本地SSD盘是否支持在原ECS上进行添加或者将原云磁盘更换成本地SSD盘? 本地SSD盘购买后是否支持升级? SSD 云盘具备怎样的 I/O 性能? SSD云盘的数据可靠性是怎样的? SSD 云盘适合的应用场景有哪些? SSD 云盘相对普通云盘性能提升多少?是否可以提供具体参数? I/O 优化是什么概念?能将存量的 ECS 实例升级为 I/O 优化的实例吗? 是否支持将原普通云盘更换成 SSD 云盘? 如何购买 SSD 云盘,I/O 优化的实例及 SSD 云盘的价格是多少? 为什么 I/O 优化的实例有时启动比较耗时? 有些自定义镜像不支持创建 I/O 优化的实例,我该如何操作? 购买SSD云盘后是否支持升级? 使用了 I/O 优化实例和 SSD 云盘之后,Linux 系统在分区挂载的时候报错。 为什么我用 fio 测试性能时,会导致实例宕机? 云盘参数和性能测试工具及方法有推荐的吗? 我想扩容系统盘,求详细步骤! 所有块存储都支持系统盘扩容吗?有地域限制吗? 包年包月和按量付费的ECS实例都支持系统盘扩容吗? 新购ECS时,系统盘开始单独收费?老用户存量的系统盘如何收费? 新购ECS时,系统盘开始单独收费?老用户存量的系统盘如何收费?系统盘扩容是否需要停机操作? 系统盘扩容上线后,系统盘的容量范围多少? 哪些镜像支持系统盘扩容? 云服务器续费变配后,不支持更换系统盘时指定系统盘容量? 系统盘扩容之后是否支持再缩容? 扩容系统盘应注意的问题? 回滚磁盘报错,进行快照回滚的时候,出现如下错误提示: 执行回滚磁盘需要停止实例,并确保当前磁盘没有创建中的快照和没有更换过操作系统。 这是什么原因? 普通云盘和SSD云盘添加挂载信息时有哪些要注意的事项? 申请公测资格 什么是共享块存储? 共享块存储适用于哪些行业和业务场景? 为什么需要共享块存储? 如何正确使用共享块存储? 我能跨地域挂载共享块存储吗? 共享块存储产品规格有哪些? 我想知道阿里云产品的售卖模式和公测范围! 公测购买入口是哪,求链接! 有没有谁分享下共享块存储性能测试命令? 数据盘挂载问题导致数据无法访问,我要怎么排查问题? 我要怎样才能在Linux和Windows主机之间挂载ntfs格式云盘? 为什么ECS实例里文件系统和快照空间大小不一致?在ECS实例内删除文件后再打快照,发现快照容量并没有变小。 ECS实例如何优化快照使用成本? 在ECS实例里什么是快照商业化? 在ECS实例里,快照商业化后过渡优惠期是什么时候? 在ECS实例里,快照商业化的用户范围包括有哪些? 在ECS实例里,如果我已经开通了 OSS,快照会自动存到我的 OSS Bucket 吗?是否需要重新再创建一个 Bucket 来存储快照? 已经购买了 OSS 预付费存储包,同时在使用快照和 OSS 服务,那么存储包会优先抵扣哪个产品? 快照商业化之后,我希望继续使用,需要购买哪个产品,云盘还是对象存储OSS资源包? 快照商业化的收费模式是怎样的? 快照费用的计算方法是怎样的? 快照收费后,不停止自动快照是否就开始收取费用? 快照要收费了,之前的快照要被删除吗? 如果不想付费,之前的快照能继续使用吗? 快照收费后,之前创建的手动快照和自动快照都会收费吗? 快照收费前停止快照策略,需手动删除历史快照吗?正式收费后会直接删除我的历史快照吗? 快照收费以后,账户欠费对快照有什么影响? 如果账号欠费,有关联关系(创建过磁盘或者镜像)的快照,在欠费15天之后是否会被删除? 快照服务和块存储服务的关系,在收费方面的关系是什么? 快照容量是如何计算的,是等于磁盘大小吗? ECS实例内删除文件会减少空间占用吗? 为什么快照容量大于文件系统内看到的数据量? 参考快照增量说明,如中间快照被删除,后面的快照能否使用? 如何开通快照服务? 快照和镜像的关系? 如何在保留关联实例和磁盘的情况下,删除快照跟镜像,快照、实例、镜像之间的关系? 快照和块存储、OSS对象存储是什么关系? 一块云盘能否设置多个快照策略? 快照 2.0 服务包括哪些内容? 快照有什么用途? 快照 2.0 服务支持的云盘类型? 快照数量有什么限制? 快照保留时长怎样? 打快照对块存储 I/O 性能有多少影响? 快照怎么收费? 老的自动快照策略什么时候不可用? 老的快照策略产生的快照什么时候删除? 自动快照功能细节有哪些? 用户的自定义快照和自动快照有冲突吗? 我能保留其中想要的自动快照而让系统不删除吗? 如果一个自动快照被引用(用户创建自定义镜像或者磁盘),会导致自动快照策略执行失败吗? 我如果什么都没有设置,自动快照会启动吗? 自动快照能够删除吗? 自动快照具体在什么时间创建能看到吗? 我如何区分哪些快照是自动快照和用户快照? 更换系统盘、云服务器 ECS 到期后或手动释放磁盘时,自动快照会不会释放? 未随磁盘释放和更换系统盘释放的自动快照会一直保留吗? 云服务器 ECS 到期后或手动释放磁盘时,手工快照会不会释放? 我能单独制定某几块磁盘执行或取消自动快照吗? 云服务器 ECS 有没有自动备份? 磁盘无快照是否能够回滚或数据恢复? 快照回滚能否单独回滚某个分区或部分数据? 系统盘快照回滚是否会影响数据盘? 更换系统后,快照能否回滚? 在回滚快照前,有哪些注意事项? 怎样使ECS回滚快照后同步数据? 如何通过API配置定时自定义快照? 超出预付费存储包的流量,会怎么收费? ECS镜像 Aliyun Linux 17.01 特性有哪些,有说明文档吗? 云市场镜像有哪些功能? 镜像能带来哪些便利? 目前镜像支持哪些服务器环境和应用场景? 镜像是否安全? 选择了镜像后能更换吗? 镜像安装使用过程中出问题了怎么办? Docker私有镜像库是什么? 自定义镜像如何查看数据盘? 自定义镜像,如何卸载和删除 disk table 里的数据? 如何确认已经卸载数据盘,并可以新建自定义镜像? ECS 实例释放后,自定义镜像是否还存在? ECS 实例释放后,快照是否还存在? 用于创建自定义镜像的云服务器 ECS 实例到期或释放数据后,创建的自定义镜像是否受影响?使用自定义镜像开通的云服务器 ECS 实例是否受影响? 使用自定义镜像创建的 ECS 实例是否可以更换操作系统?更换系统后原来的自定义镜像是否还可以使用? 更换系统盘时另选操作系统,是否可以使用自定义镜像? 已创建的自定义镜像,是否可以用于更换另一台云服务器 ECS 的系统盘数据? 是否可以升级自定义镜像开通的云服务器 ECS 的 CPU、内存、带宽、硬盘等? 是否可以跨地域使用自定义镜像? 包年包月云服务器 ECS 的自定义镜像,是否可以用于开通按量付费的云服务器 ECS? ECS Windows企业版和标准版区别 什么情况下需要复制镜像? 可以复制哪些镜像? 当前有哪些支持镜像复制功能的地域? 复制一个镜像大概需要多久? 复制镜像怎么收费的? 在复制镜像过程中,源镜像和目标镜像有什么限制? 怎么复制我的云账号的镜像资源到其他云账号的其他地域? 复制镜像有镜像容量限制吗? 如何购买镜像市场镜像? 按次购买的镜像的使用期限是多久? 镜像市场的镜像支持退款吗? 镜像市场商业化后,还有免费的镜像市场镜像吗? 在杭州买了一个镜像市场的镜像,能否在北京创建ECS实例或者更换系统盘? ECS实例使用镜像市场的镜像,升级和续费ECS实例,需要为镜像继续付费吗? ECS实例使用镜像市场的镜像,实例释放后,继续购买ECS实例还可以免费使用该镜像吗? 使用镜像市场镜像创建ECS实例,该实例创建一个自定义镜像,使用该自定义镜像创建ECS实例需要为该镜像付费吗? 来源于镜像市场的镜像复制到其他地域创建ECS实例,是否需要为该镜像付费? 如果把来源于镜像市场的自定义镜像共享给其他账号(B)创建ECS实例,账号B是否需要为该镜像付费? 如果使用镜像市场的镜像或者来源于镜像市场的镜像进行更换系统盘,需要付费吗? ECS实例正在使用镜像市场的镜像,进行重置系统盘需要收费吗? 怎么调用ECS API,使用镜像市场镜像或者来源镜像市场的自定义镜像或者共享镜像,创建ECS实例和更换系统盘? 如果没有购买镜像市场的镜像或者来源于镜像市场的镜像,在调用ECS API 使用该镜像创建ECS实例和更换系统盘,会报错吗? 我的ESS是自动创建机器的,并且量是不固定,设置最小值为10台,最大值为100台,那么使用镜像市场的镜像如何保证我的的需求实例能正常弹出来? 镜像市场的镜像是否支持批量购买? 如果之前使用的镜像市场的镜像,已不存在该商品(如:jxsc000010、jxsc000019),怎能保证已经设置的弹性伸缩组的机器的正常弹出? 1个product code能否支持不同region的镜像? 我买了100 product code同样值的镜像,是否可以支持在所有的地域可用? 为什么有的ECS云服务器无法选择Windows操作系统? 操作系统是否要收费? 我能否自己安装或者升级操作系统? 服务器的登录用户名密码是什么? 能否更换或升级操作系统? 操作系统是否有图形界面? 如何选择操作系统? 操作系统自带 FTP 上传吗? 每个用户最多可以获得多少个共享镜像? 每个镜像最多可以共享给多少个用户? 使用共享镜像是否占用我的镜像名额? 使用共享镜像创建实例的时候存不存在地域限制? 我曾把自己账号中的某个自定义镜像共享给其他账号,现在我可以删除这个镜像吗 我把某个自定义镜像(M)的共享账号(A)给删除了,会有什么影响? 使用共享镜像创建实例存在什么样的风险? 我把自定义镜像共享给其他账号,存在什么风险? 我能把别人共享给我的镜像再共享给他人吗? 我把镜像共享给他人,还能使用该镜像创建实例吗? ECS Windows服务器桌面分辨率过高导致VNC花屏处理方法通过 管理终端 进入服务器后,把 Windows 服务器桌面分辨率设置过高,确定后,WebVNC 出现花屏。 ECS创建自定义镜像创建服务器为何需要注释挂载项 勾选"IO优化实例"选项导致购买ECS实例时无法选择云市场镜像 如何为 Linux 服务器安装 GRUB 历史Linux镜像的问题修复方案 如何处理 CentOS DNS 解析超时? 什么是镜像市场的包年包月和按周付费镜像? 预付费镜像能与哪种 ECS 实例搭配使用? 怎么购买预付费镜像?可以单独购买吗? 预付费镜像怎么付费? 预付费镜像到期了就不能用了吗?怎么继续使用? 购买预付费镜像后,如果我不想再使用这个镜像,能要求退款吗? 退款时,费用怎么结算? 预付费镜像能转换为按量付费镜像吗? 预付费镜像与其它镜像之间能互换吗?更换后费用怎么计算? 在哪里查看并管理我购买的预付费镜像? 使用预付费镜像制作的自定义镜像会收费吗?预付费镜像过期对于自定义镜像有什么影响? ECS 实例操作系统选择说明 阿里云支持哪些 SUSE 版本? SUSE 操作系统提供哪些服务支持? ECS安全组 如何检查 TCP 80 端口是否正常工作? 什么是安全组? 为什么在购买 ECS 实例的时候选择安全组? 安全组配置错误会造成哪些影响? 专有网络实例设置安全组规则时为什么不能设置公网规则? 创建 ECS 实例时我还没创建安全组怎么办? 为什么无法访问 25 端口? 为什么我的安全组里自动添加了很多规则? 为什么有些安全组规则的优先级是 110? 为什么我在安全组里放行了 TCP 80 端口,还是无法访问 80 端口? ECS安全组被添加内网ip地址了,是怎么回事? 能说明下ECS安全组中规则的优先级执行匹配顺序吗? ECS实例安全组默认的公网规则被删除导致无法ping通,ECS 服务器无法ping通,排查防火墙、网卡IP配置无误,回滚系统后仍然无法ping通。 我刚购买了ECS实例,如何选择及配置安全组? 没有添加默认安全组访问规则-导致通过API创建的ECS实例断网,要怎么恢复? 使用ECS安全组工具撤销之前账号间互通的操作 ECS网络 带宽与上传、下载速度峰值的有什么关系? 弹性公网IP在哪里可以查看流量和带宽监控信息? 我用的是ECS Ubuntu系统,要怎么单独禁用和启动内外网卡? ECS 实例子网划分和掩码是什么? ECS 实例网络带宽是否独享? 带宽单线还是双线,电信还是网通? 5 Mbps 带宽怎么理解? 带宽的价格是多少? 不同地域的 ECS 实例之间的内网是通的吗? 为何新建的 ECS 实例就有 200 Kbps 左右入网流量? 我的 ECS 实例经常能在 Web 日志中看到大量的恶意 IP 访问我的网站,疑有刷流量和恶意访问的嫌疑,询问云盾是否有屏蔽 IP 的功能? 包月ECS新购时是否可以选择带宽按照使用流量计费? 包月ECS带宽按流量计费是如何计费的? 目前使用的固定带宽计费,是否可以转换为带宽按流量计费? 是否可以随时调整流量带宽峰值? 续费变更配置时(比如到期时间为2015年3月31日,续费一个月到4月30日),如果将包月ECS按固定带宽计费改成按流量付费计费,操作以后在未生效前(3月31日前),是否还可以升级带宽? 续费变更配置时候将包月ECS带宽按流量计费改成按固定带宽计费,为什么我的带宽服务停掉了? 如果账号没有足够余额,欠费怎么办?ECS实例也会停掉吗? 带宽流量欠费是否有短信通知? 当带宽按照流量计费欠费时,是否可以对实例进行升级 CPU、内存操作? 欠费充值后带宽是自动恢复的吗? 包月带宽转流量计费后,流量价格是多少? ECS 服务器出现了异地登录怎么办? 爱哪里可以查看云服务器 ECS 公网流量统计总和? 我的ECS 实例对外 DDoS 攻击导致被锁定了,要如何处理 ? 什么是云服务器 ECS 的入网带宽和出网带宽? ECS云服务器如何禁用公网IP? ECS 实例停止(关机)后按量付费带宽仍产生流量,ECS 实例在控制台上状态为已停止,但按量付费的带宽每小时仍会产生不小的费用,且此时 ECS 实例正在遭受攻击,云盾控制台中 DDoS 防护中 ECS 的状态为清洗中。 访问ECS服务器的网站提示“由于你访问的URL可能对网站造成安全威胁,您的访问被阻断”,这是什么原因? 服务器黑洞是什么?求科普! 如果想确认该服务器的IP信息和地理位置,要在哪里去查询? 我想知道客户端本地到ECS服务器是不是丢包,要怎么测试? 内网和公共 NTP 服务器是什么?它们两个有什么区别 我能 ping 通但端口不通,这是端口的问题吗? 如何通过防火墙策略限制对外扫描行为? 我想用手机移动端网络路由跟踪探测,可以吗? 云监控中的ECS带宽和ECS控制台中看到的带宽不一致是什么原因? 云服务器ECS三张网卡有什么区别? Ubuntu系统ECS使用“如何通过防火墙策略限制对外扫描行为”脚本之后出现无法远程、数据库连接不上。 什么业务场景需要在专有网络(VPC)类型ECS购买PublicIP? 怎么购买专有网络(VPC)类型分配 PublicIP 的 ECS? 专有网络(VPC)类型 ECS 的 PublicIP 和 EIP 的区别? 专有网络(VPC)类型ECS的 PublicIP 的可以升级带宽吗? 专有网络(VPC)类型ECS的 PublicIP 可以解绑吗? 如果购买网络(VPC)类型 ECS 的时候,没有分配公网 IP,该怎么才能分配一个公网 IP? 怎么查询专有网络(VPC)类型 ECS 的 PublicIP 的监控数据? 怎么查询专有网络(VPC)类型ECS的按流量付费的 PublicIP 的账单? 专有网络和经典网络的 PublicIP 异同? 专有网络(VPC)类型 ECS 购买 PublicIP 的付费方式? ECS API 如何通过 API / SDK 实现不同账号 ECS 实例的内网通信? ECS API绑定公网IP报错:The IP is already in use分析 ECS API修改实例带宽不能指定时间范围吗? 所在可用区不支持相应磁盘类型-导致ECS API创建实例报错 用ECS API创建实例的时候,返回如下错误信息: "Code": "InvalidDataDiskCategory.NotSupported" 如何创建有公网 IP 的 ECS 实例? 通过API或SDK查询安全组规则无法显示所有的规则,这是怎么回事? 如何通过OpenAPI创建ECS实例的流程状态描述? 数据传输服务DTS实时同步功能,我想只同步表结构,要怎么做? 如何获取控制台RequestId? 阿里云中国站部分地域实例什么时候降价? ECS Linux 实例怎么设置 Locale 变量? 克隆ECS服务器的方法 其它国家和地区是否都可以提供经典网络和专有网络的类型呢?网络类型是否可以变更呢? 各个地域的网络覆盖范围是什么呢? 其他相关问题 不同地域的实例,价格一样吗? 如果我使用其它国家和地区的实例搭建了一个网站,我的用户将通过域名访问网站,这个域名需要 ICP 备案吗? 为什么有些实例规格只能在中国大陆地域购买,而在其它国家和地区无法购买? 可否将中国大陆地域的实例迁移到其它国家和地区呢? 如何在其它国家和地区部署 ECS 实例? 我要买其它国家和地区的实例,需要单独申请一个国际站账号吗? ——更多ECS相关问题—— · ECS故障处理百问合集
问问小秘 2020-01-02 15:49:17 0 浏览量 回答数 0

回答

遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?Java 中 List 遍历的最佳实践是什么? 遍历方式有以下几种: for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。 迭代器遍历,Iterator。Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。 foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明 Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过程中操作数据集合,例如删除、替换。 最佳实践:Java Collections 框架中提供了一个 RandomAccess 接口,用来标记 List 实现是否支持 Random Access。 如果一个数据集合实现了该接口,就意味着它支持 Random Access,按位置读取元素的平均时间复杂度为 O(1),如ArrayList。如果没有实现该接口,表示不支持 Random Access,如LinkedList。 推荐的做法就是,支持 Random Access 的列表可用 for 循环遍历,否则建议用 Iterator 或 foreach 遍历。 说一下 ArrayList 的优缺点 ArrayList的优点如下: ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。ArrayList 在顺序添加一个元素的时候非常方便。 ArrayList 的缺点如下: 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。插入元素的时候,也需要做一次元素复制操作,缺点同上。 ArrayList 比较适合顺序添加、随机访问的场景。 如何实现数组和 List 之间的转换? 数组转 List:使用 Arrays. asList(array) 进行转换。List 转数组:使用 List 自带的 toArray() 方法。 代码示例: ArrayList 和 LinkedList 的区别是什么? 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。内存空间占用:LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; 综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。 补充:数据结构基础之双向链表 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。 ArrayList 和 Vector 的区别是什么? 这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合 线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。性能:ArrayList 在性能方面要优于 Vector。扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次会增加 1 倍,而 ArrayList 只会增加 50%。 Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector的话代码要在同步操作上耗费大量的时间。 Arraylist不是同步的,所以在不需要保证线程安全时时建议使用Arraylist。 插入数据时,ArrayList、LinkedList、Vector谁速度较快?阐述 ArrayList、Vector、LinkedList 的存储性能和特性? ArrayList、LinkedList、Vector 底层的实现都是使用数组方式存储数据。数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。 Vector 中的方法由于加了 synchronized 修饰,因此 Vector 是线程安全容器,但性能上较ArrayList差。 LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但插入数据时只需要记录当前项的前后项即可,所以 LinkedList 插入速度较快。 多线程场景下如何使用 ArrayList? ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用。例如像下面这样: 为什么 ArrayList 的 elementData 加上 transient 修饰? ArrayList 中的数组定义如下: private transient Object[] elementData; 再看一下 ArrayList 的定义: public class ArrayList extends AbstractList implements List<E>, RandomAccess, Cloneable, java.io.Serializable 可以看到 ArrayList 实现了 Serializable 接口,这意味着 ArrayList 支持序列化。transient 的作用是说不希望 elementData 数组被序列化,重写了 writeObject 实现: 每次序列化时,先调用 defaultWriteObject() 方法序列化 ArrayList 中的非 transient 元素,然后遍历 elementData,只序列化已存入的元素,这样既加快了序列化的速度,又减小了序列化之后的文件大小。 List 和 Set 的区别 List , Set 都是继承自Collection 接口 List 特点:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。 Set 特点:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及 TreeSet。 另外 List 支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。 Set和List对比 Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。 List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变 Set接口 说一下 HashSet 的实现原理? HashSet 是基于 HashMap 实现的,HashSet的值存放于HashMap的key上,HashMap的value统一为PRESENT,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值。 HashSet如何检查重复?HashSet是如何保证数据不可重复的? 向HashSet 中add ()元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合equles 方法比较。 HashSet 中的add ()方法会使用HashMap 的put()方法。 HashMap 的 key 是唯一的,由源码可以看出 HashSet 添加进去的值就是作为HashMap 的key,并且在HashMap中如果K/V相同时,会用新的V覆盖掉旧的V,然后返回旧的V。所以不会重复( HashMap 比较key是否相等是先比较hashcode 再比较equals )。 以下是HashSet 部分源码: hashCode()与equals()的相关规定: 如果两个对象相等,则hashcode一定也是相同的 两个对象相等,对两个equals方法返回true 两个对象有相同的hashcode值,它们也不一定是相等的 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖 hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。 ** ==与equals的区别** ==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同 ==是指对内存地址进行比较 equals()是对字符串的内容进行比较3.==指引用是否相同 equals()指的是值是否相同 HashSet与HashMap的区别 Queue BlockingQueue是什么? Java.util.concurrent.BlockingQueue是一个队列,在进行检索或移除一个元素的时候,它会等待队列变为非空;当在添加一个元素时,它会等待队列中的可用空间。BlockingQueue接口是Java集合框架的一部分,主要用于实现生产者-消费者模式。我们不需要担心等待生产者有可用的空间,或消费者有可用的对象,因为它都在BlockingQueue的实现类中被处理了。Java提供了集中BlockingQueue的实现,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,、SynchronousQueue等。 在 Queue 中 poll()和 remove()有什么区别? 相同点:都是返回第一个元素,并在队列中删除返回的对象。 不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。 代码示例: Queue queue = new LinkedList (); queue. offer("string"); // add System. out. println(queue. poll()); System. out. println(queue. remove()); System. out. println(queue. size()); Map接口 说一下 HashMap 的实现原理? HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 HashMap的数据结构: 在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。 HashMap 基于 Hash 算法实现的 当我们往Hashmap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。 需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn) HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底层实现 在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做拉链法的方式可以解决哈希冲突。 JDK1.8之前 JDK1.8之前采用的是拉链法。拉链法:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。 JDK1.8之后 相比于之前的版本,jdk1.8在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。 JDK1.7 VS JDK1.8 比较 JDK1.8主要解决或优化了一下问题: resize 扩容优化引入了红黑树,目的是避免单条链表过长而影响查询效率,红黑树算法请参考解决了多线程死循环问题,但仍是非线程安全的,多线程时可能会造成数据丢失问题。 HashMap的put方法的具体流程? 当我们put的时候,首先计算 key的hash值,这里调用了 hash方法,hash方法实际是让key.hashCode()与key.hashCode()>>>16进行异或操作,高16bit补0,一个数和0异或不变,所以 hash 函数大概的作用就是:高16bit不变,低16bit和高16bit做了一个异或,目的是减少碰撞。按照函数注释,因为bucket数组大小是2的幂,计算下标index = (table.length - 1) & hash,如果不做 hash 处理,相当于散列生效的只有几个低 bit 位,为了减少散列的碰撞,设计者综合考虑了速度、作用、质量之后,使用高16bit和低16bit异或来简单处理减少碰撞,而且JDK8中用了复杂度 O(logn)的树结构来提升碰撞下的性能。 putVal方法执行流程图 ①.判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容; ②.根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建节点添加,转向⑥,如果table[i]不为空,转向③; ③.判断table[i]的首个元素是否和key一样,如果相同直接覆盖value,否则转向④,这里的相同指的是hashCode以及equals; ④.判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值对,否则转向⑤; ⑤.遍历table[i],判断链表长度是否大于8,大于8的话把链表转换为红黑树,在红黑树中执行插入操作,否则进行链表的插入操作;遍历过程中若发现key已经存在直接覆盖value即可; ⑥.插入成功后,判断实际存在的键值对数量size是否超多了最大容量threshold,如果超过,进行扩容。 HashMap的扩容操作是怎么实现的? ①.在jdk1.8中,resize方法是在hashmap中的键值对大于阀值时或者初始化时,就调用resize方法进行扩容; ②.每次扩展的时候,都是扩展2倍; ③.扩展后Node对象的位置要么在原位置,要么移动到原偏移量两倍的位置。 在putVal()中,我们看到在这个函数里面使用到了2次resize()方法,resize()方法表示的在进行第一次初始化时会对其进行扩容,或者当该数组的实际大小大于其临界值值(第一次为12),这个时候在扩容的同时也会伴随的桶上面的元素进行重新分发,这也是JDK1.8版本的一个优化的地方,在1.7中,扩容之后需要重新去计算其Hash值,根据Hash值对其进行分发,但在1.8版本中,则是根据在同一个桶的位置中进行判断(e.hash & oldCap)是否为0,重新进行hash分配后,该元素的位置要么停留在原始位置,要么移动到原始位置+增加的数组大小这个位置上 HashMap是怎么解决哈希冲突的? 答:在解决这个问题之前,我们首先需要知道什么是哈希冲突,而在了解哈希冲突之前我们还要知道什么是哈希才行; 什么是哈希? Hash,一般翻译为“散列”,也有直接音译为“哈希”的,这就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值);这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 所有散列函数都有如下一个基本特性**:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同**。 什么是哈希冲突? 当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把它叫做碰撞(哈希碰撞)。 HashMap的数据结构 在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做链地址法的方式可以解决哈希冲突: 这样我们就可以将拥有相同哈希值的对象组织成一个链表放在hash值所对应的bucket下,但相比于hashCode返回的int类型,我们HashMap初始的容量大小DEFAULT_INITIAL_CAPACITY = 1 << 4(即2的四次方16)要远小于int类型的范围,所以我们如果只是单纯的用hashCode取余来获取对应的bucket这将会大大增加哈希碰撞的概率,并且最坏情况下还会将HashMap变成一个单链表,所以我们还需要对hashCode作一定的优化 hash()函数 上面提到的问题,主要是因为如果使用hashCode取余,那么相当于参与运算的只有hashCode的低位,高位是没有起到任何作用的,所以我们的思路就是让hashCode取值出的高位也参与运算,进一步降低hash碰撞的概率,使得数据分布更平均,我们把这样的操作称为扰动,在JDK 1.8中的hash()函数如下: static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);// 与自己右移16位进行异或运算(高低位异或) } 这比在JDK 1.7中,更为简洁,相比在1.7中的4次位运算,5次异或运算(9次扰动),在1.8中,只进行了1次位运算和1次异或运算(2次扰动); JDK1.8新增红黑树 通过上面的链地址法(使用散列表)和扰动函数我们成功让我们的数据分布更平均,哈希碰撞减少,但是当我们的HashMap中存在大量数据时,加入我们某个bucket下对应的链表有n个元素,那么遍历时间复杂度就为O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn); 总结 简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的: 使用链地址法(使用散列表)来链接拥有相同hash值的数据;使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均;引入红黑树进一步降低遍历的时间复杂度,使得遍历更快; **能否使用任何类作为 Map 的 key? **可以使用任何类作为 Map 的 key,然而在使用之前,需要考虑以下几点: 如果类重写了 equals() 方法,也应该重写 hashCode() 方法。 类的所有实例需要遵循与 equals() 和 hashCode() 相关的规则。 如果一个类没有使用 equals(),不应该在 hashCode() 中使用它。 用户自定义 Key 类最佳实践是使之为不可变的,这样 hashCode() 值可以被缓存起来,拥有更好的性能。不可变的类也可以确保 hashCode() 和 equals() 在未来不会改变,这样就会解决与可变相关的问题了。 为什么HashMap中String、Integer这样的包装类适合作为K? 答:String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率 都是final类型,即不可变性,保证key的不可更改性,不会存在获取hash值不同的情况 内部已重写了equals()、hashCode()等方法,遵守了HashMap内部的规范(不清楚可以去上面看看putValue的过程),不容易出现Hash值计算错误的情况; 如果使用Object作为HashMap的Key,应该怎么办呢? 答:重写hashCode()和equals()方法 重写hashCode()是因为需要计算存储数据的存储位置,需要注意不要试图从散列码计算中排除掉一个对象的关键部分来提高性能,这样虽然能更快但可能会导致更多的Hash碰撞; 重写equals()方法,需要遵守自反性、对称性、传递性、一致性以及对于任何非null的引用值x,x.equals(null)必须返回false的这几个特性,目的是为了保证key在哈希表中的唯一性; HashMap为什么不直接使用hashCode()处理后的哈希值直接作为table的下标 答:hashCode()方法返回的是int整数类型,其范围为-(2 ^ 31)~(2 ^ 31 - 1),约有40亿个映射空间,而HashMap的容量范围是在16(初始化默认值)~2 ^ 30,HashMap通常情况下是取不到最大值的,并且设备上也难以提供这么多的存储空间,从而导致通过hashCode()计算出的哈希值可能不在数组大小范围内,进而无法匹配存储位置; 那怎么解决呢? HashMap自己实现了自己的hash()方法,通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均; 在保证数组长度为2的幂次方的时候,使用hash()运算之后的值与运算(&)(数组长度 - 1)来获取数组下标的方式进行存储,这样一来是比取余操作更加有效率,二来也是因为只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,三来解决了“哈希值与数组大小范围不匹配”的问题; HashMap 的长度为什么是2的幂次方 为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法。 这个算法应该如何设计呢? 我们首先可能会想到采用%取余的操作来实现。但是,重点来了:“取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是2的 n 次方;)。” 并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是2的幂次方。 那为什么是两次扰动呢? 答:这样就是加大哈希值低位的随机性,使得分布更均匀,从而提高对应数组存储下标位置的随机性&均匀性,最终减少Hash冲突,两次就够了,已经达到了高位低位同时参与运算的目的; HashMap 与 HashTable 有什么区别? 线程安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!); 效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它; 对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛NullPointerException。 **初始容量大小和每次扩充容量大小的不同 **: ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。 推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。 如何决定使用 HashMap 还是 TreeMap? 对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。 HashMap 和 ConcurrentHashMap 的区别 ConcurrentHashMap对整个桶数组进行了分割分段(Segment),然后在每一个分段上都用lock锁进行保护,相对于HashTable的synchronized锁的粒度更精细了一些,并发性能更好,而HashMap没有锁机制,不是线程安全的。(JDK1.8之后ConcurrentHashMap启用了一种全新的方式实现,利用CAS算法。) HashMap的键值对允许有null,但是ConCurrentHashMap都不允许。 ConcurrentHashMap 和 Hashtable 的区别? ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。 底层数据结构: JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的; 实现线程安全的方式(重要): ① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16个Segment,比Hashtable效率提高16倍。) 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。 两者的对比图: HashTable: JDK1.7的ConcurrentHashMap: JDK1.8的ConcurrentHashMap(TreeBin: 红黑二叉树节点 Node: 链表节点): 答:ConcurrentHashMap 结合了 HashMap 和 HashTable 二者的优势。HashMap 没有考虑同步,HashTable 考虑了同步的问题。但是 HashTable 在每次同步执行时都要锁住整个结构。 ConcurrentHashMap 锁的方式是稍微细粒度的。 ConcurrentHashMap 底层具体实现知道吗?实现原理是什么? JDK1.7 首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。 在JDK1.7中,ConcurrentHashMap采用Segment + HashEntry的方式进行实现,结构如下: 一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护着一个HashEntry数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment的锁。 该类包含两个静态内部类 HashEntry 和 Segment ;前者用来封装映射表的键值对,后者用来充当锁的角色;Segment 是一种可重入的锁 ReentrantLock,每个 Segment 守护一个HashEntry 数组里得元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment 锁。 JDK1.8 在JDK1.8中,放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现,synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。 结构如下: 如果该节点是TreeBin类型的节点,说明是红黑树结构,则通过putTreeVal方法往红黑树中插入节点;如果binCount不为0,说明put操作对数据产生了影响,如果当前链表的个数达到8个,则通过treeifyBin方法转化为红黑树,如果oldVal不为空,说明是一次更新操作,没有对元素个数产生影响,则直接返回旧值;如果插入的是一个新节点,则执行addCount()方法尝试更新元素个数baseCount; 辅助工具类 Array 和 ArrayList 有何区别? Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。Array 内置方法没有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。 对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。 如何实现 Array 和 List 之间的转换? Array 转 List: Arrays. asList(array) ;List 转 Array:List 的 toArray() 方法。 comparable 和 comparator的区别? comparable接口实际上是出自java.lang包,它有一个 compareTo(Object obj)方法用来排序comparator接口实际上是出自 java.util 包,它有一个compare(Object obj1, Object obj2)方法用来排序 一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo方法或compare方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort(). 方法如何比较元素? TreeSet 要求存放的对象所属的类必须实现 Comparable 接口,该接口提供了比较元素的 compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap 要求存放的键值对映射的键必须实现 Comparable 接口从而根据键对元素进 行排 序。 Collections 工具类的 sort 方法有两种重载的形式, 第一种要求传入的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较; 第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java 中对函数式编程的支持)。
剑曼红尘 2020-03-24 14:41:57 0 浏览量 回答数 0

回答

134题 其实就是水平扩容了,Zookeeper在这方面不太好。两种方式:全部重启:关闭所有Zookeeper服务,修改配置之后启动。不影响之前客户端的会话。逐个重启:这是比较常用的方式。 133题 集群最低3(2N+1)台,保证奇数,主要是为了选举算法。一个由 3 台机器构成的 ZooKeeper 集群,能够在挂掉 1 台机器后依然正常工作,而对于一个由 5 台服务器构成的 ZooKeeper 集群,能够对 2 台机器挂掉的情况进行容灾。注意,如果是一个由6台服务器构成的 ZooKeeper 集群,同样只能够挂掉 2 台机器,因为如果挂掉 3 台,剩下的机器就无法实现过半了。 132题 基于“过半”设计原则,ZooKeeper 在运行期间,集群中至少有过半的机器保存了最新的数据。因此,只要集群中超过半数的机器还能够正常工作,整个集群就能够对外提供服务。 131题 不是。官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。为什么不是永久的,举个例子,如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,这太消耗性能了。一般是客户端执行getData(“/节点A”,true),如果节点A发生了变更或删除,客户端会得到它的watch事件,但是在之后节点A又发生了变更,而客户端又没有设置watch事件,就不再给客户端发送。在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数据即可。 130题 数据发布/订阅,负载均衡,命名服务,分布式协调/通知,集群管理,Master 选举,分布式锁,分布式队列 129题 客户端 SendThread 线程接收事件通知, 交由 EventThread 线程回调 Watcher。客户端的 Watcher 机制同样是一次性的, 一旦被触发后, 该 Watcher 就失效了。 128题 1、服务端接收 Watcher 并存储; 2、Watcher 触发; 2.1 封装 WatchedEvent; 2.2 查询 Watcher; 2.3 没找到;说明没有客户端在该数据节点上注册过 Watcher; 2.4 找到;提取并从 WatchTable 和 Watch2Paths 中删除对应 Watcher; 3、调用 process 方法来触发 Watcher。 127题 1.调用 getData()/getChildren()/exist()三个 API,传入 Watcher 对象 2.标记请求 request,封装 Watcher 到 WatchRegistration 3.封装成 Packet 对象,发服务端发送 request 4.收到服务端响应后,将 Watcher 注册到 ZKWatcherManager 中进行管理 5.请求返回,完成注册。 126题 Zookeeper 允许客户端向服务端的某个 Znode 注册一个 Watcher 监听,当服务端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,然后客户端根据 Watcher 通知状态和事件类型做出业务上的改变。工作机制:(1)客户端注册 watcher(2)服务端处理 watcher(3)客户端回调 watcher 125题 服务器具有四种状态,分别是 LOOKING、FOLLOWING、LEADING、OBSERVING。 LOOKING:寻 找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有 Leader,因此需要进入 Leader 选举状态。 FOLLOWING:跟随者状态。表明当前服务器角色是 Follower。 LEADING:领导者状态。表明当前服务器角色是 Leader。 OBSERVING:观察者状态。表明当前服务器角色是 Observer。 124题 Zookeeper 有三种部署模式:单机部署:一台集群上运行;集群部署:多台集群运行;伪集群部署:一台集群启动多个 Zookeeper 实例运行。 123题 Paxos算法是分布式选举算法,Zookeeper使用的 ZAB协议(Zookeeper原子广播),二者有相同的地方,比如都有一个Leader,用来协调N个Follower的运行;Leader要等待超半数的Follower做出正确反馈之后才进行提案;二者都有一个值来代表Leader的周期。不同的地方在于:ZAB用来构建高可用的分布式数据主备系统(Zookeeper),Paxos是用来构建分布式一致性状态机系统。Paxos算法、ZAB协议要想讲清楚可不是一时半会的事儿,自1990年莱斯利·兰伯特提出Paxos算法以来,因为晦涩难懂并没有受到重视。后续几年,兰伯特通过好几篇论文对其进行更进一步地解释,也直到06年谷歌发表了三篇论文,选择Paxos作为chubby cell的一致性算法,Paxos才真正流行起来。对于普通开发者来说,尤其是学习使用Zookeeper的开发者明确一点就好:分布式Zookeeper选举Leader服务器的算法与Paxos有很深的关系。 122题 ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议(paxos算法的一种实现)。ZAB协议包括两种基本的模式:崩溃恢复和消息广播。当整个zookeeper集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式,首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行数据同步,当集群中超过半数机器与该Leader服务器完成数据同步之后,退出恢复模式进入消息广播模式,Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。 121题 Zookeeper本身也是集群,推荐配置不少于3个服务器。Zookeeper自身也要保证当一个节点宕机时,其他节点会继续提供服务。如果是一个Follower宕机,还有2台服务器提供访问,因为Zookeeper上的数据是有多个副本的,数据并不会丢失;如果是一个Leader宕机,Zookeeper会选举出新的Leader。ZK集群的机制是只要超过半数的节点正常,集群就能正常提供服务。只有在ZK节点挂得太多,只剩一半或不到一半节点能工作,集群才失效。所以,3个节点的cluster可以挂掉1个节点(leader可以得到2票>1.5),2个节点的cluster就不能挂掉任何1个节点了(leader可以得到1票<=1)。 120题 选完Leader以后,zk就进入状态同步过程。1、Leader等待server连接;2、Follower连接leader,将最大的zxid发送给leader;3、Leader根据follower的zxid确定同步点;4、完成同步后通知follower 已经成为uptodate状态;5、Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。 119题 在zookeeper集群中也是一样,每个节点都会投票,如果某个节点获得超过半数以上的节点的投票,则该节点就是leader节点了。zookeeper中有三种选举算法,分别是LeaderElection,FastLeaderElection,AuthLeaderElection, FastLeaderElection此算法和LeaderElection不同的是它不会像后者那样在每轮投票中要搜集到所有结果后才统计投票结果,而是不断的统计结果,一旦没有新的影响leader结果的notification出现就返回投票结果。这样的效率更高。 118题 zk的负载均衡是可以调控,nginx只是能调权重,其他需要可控的都需要自己写插件;但是nginx的吞吐量比zk大很多,应该说按业务选择用哪种方式。 117题 Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。 116题 有临时节点和永久节点,分再细一点有临时有序/无序节点,有永久有序/无序节点。当创建临时节点的程序结束后,临时节点会自动消失,临时节点上的数据也会一起消失。 115题 在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,这就是主节点存在的意义。 114题 ZooKeeper 实现分布式事务,类似于两阶段提交,总共分为以下 4 步:客户端先给 ZooKeeper 节点发送写请求;ZooKeeper 节点将写请求转发给 Leader 节点,Leader 广播给集群要求投票,等待确认;Leader 收到确认,统计投票,票数过半则提交事务;事务提交成功后,ZooKeeper 节点告知客户端。 113题 ZooKeeper 实现分布式锁的步骤如下:客户端连接 ZooKeeper,并在 /lock 下创建临时的且有序的子节点,第一个客户端对应的子节点为 /lock/lock-10000000001,第二个为 /lock/lock-10000000002,以此类推。客户端获取 /lock 下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听刚好在自己之前一位的子节点删除消息,获得子节点变更通知后重复此步骤直至获得锁;执行业务代码;完成业务流程后,删除对应的子节点释放锁。 112题 ZooKeeper 特性如下:顺序一致性(Sequential Consistency):来自相同客户端提交的事务,ZooKeeper 将严格按照其提交顺序依次执行;原子性(Atomicity):于 ZooKeeper 集群中提交事务,事务将“全部完成”或“全部未完成”,不存在“部分完成”;单一系统镜像(Single System Image):客户端连接到 ZooKeeper 集群的任意节点,其获得的数据视图都是相同的;可靠性(Reliability):事务一旦完成,其产生的状态变化将永久保留,直到其他事务进行覆盖;实时性(Timeliness):事务一旦完成,客户端将于限定的时间段内,获得最新的数据。 111题 ZooKeeper 通常有三种搭建模式:单机模式:zoo.cfg 中只配置一个 server.id 就是单机模式了,此模式一般用在测试环境,如果当前主机宕机,那么所有依赖于当前 ZooKeeper 服务工作的其他服务器都不能进行正常工作;伪分布式模式:在一台机器启动不同端口的 ZooKeeper,配置到 zoo.cfg 中,和单机模式相同,此模式一般用在测试环境;分布式模式:多台机器各自配置 zoo.cfg 文件,将各自互相加入服务器列表,上面搭建的集群就是这种完全分布式。 110题 ZooKeeper 主要提供以下功能:分布式服务注册与订阅:在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,达到对等服务。而消费者就须要在这些对等的服务器中选择一个来执行相关的业务逻辑,比较典型的服务注册与订阅,如 Dubbo。分布式配置中心:发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 节点上,供订阅者获取数据,实现配置信息的集中式管理和动态更新。命名服务:在分布式系统中,通过命名服务客户端应用能够根据指定名字来获取资源、服务地址和提供者等信息。分布式锁:这个主要得益于 ZooKeeper 为我们保证了数据的强一致性。 109题 Dubbo是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而 Spring Cloud诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了 Spirng、Spirng Boot的优势之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、Spirng Cloud 是一个生态。 108题 Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。 107题 Dubbo超时时间设置有两种方式: 服务提供者端设置超时时间,在Dubbo的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。 服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,会产生警告。 106题 Random LoadBalance: 随机选取提供者策略,有利于动态调整提供者权重。截面碰撞率高,调用次数越多,分布越均匀; RoundRobin LoadBalance: 轮循选取提供者策略,平均分布,但是存在请求累积的问题; LeastActive LoadBalance: 最少活跃调用策略,解决慢提供者接收更少的请求; ConstantHash LoadBalance: 一致性Hash策略,使相同参数请求总是发到同一提供者,一台机器宕机,可以基于虚拟节点,分摊至其他提供者,避免引起提供者的剧烈变动; 缺省时为Random随机调用。 105题 Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心。 注册中心根据 消费 者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存。 Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。 Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer。 104题 Provider:暴露服务的服务提供方。 Consumer:调用远程服务的服务消费方。 Registry:服务注册与发现的注册中心。 Monitor:统计服务的调用次调和调用时间的监控中心。 Container:服务运行容器。 103题 主要就是如下3个核心功能: Remoting:网络通信框架,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。 Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。 Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。 102题 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。 101题 垂直分表定义:将一个表按照字段分成多表,每个表存储其中一部分字段。水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。 100题 垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。 99题 QPS:每秒查询数。TPS:每秒处理事务数。Uptime:服务器已经运行的时间,单位秒。Questions:已经发送给数据库查询数。Com_select:查询次数,实际操作数据库的。Com_insert:插入次数。Com_delete:删除次数。Com_update:更新次数。Com_commit:事务次数。Com_rollback:回滚次数。 98题 如果需要跨主机进行JOIN,跨应用进行JOIN,或者数据库不能获得较好的执行计划,都可以自己通过程序来实现JOIN。 例如:SELECT a.,b. FROM a,b WHERE a.col1=b.col1 AND a.col2> 10 ORDER BY a.col2; 可以利用程序实现,先SELECT * FROM a WHERE a.col2>10 ORDER BY a.col2;–(1) 利用(1)的结果集,做循环,SELECT * FROM b WHERE b.col1=a.col1; 这样可以避免排序,可以在程序里控制执行的速度,有效降低数据库压力,也可以实现跨主机的JOIN。 97题 搭建复制的必备条件:复制的机器之间网络通畅,Master打开了binlog。 搭建复制步骤:建立用户并设置权限,修改配置文件,查看master状态,配置slave,启动从服务,查看slave状态,主从测试。 96题 Heartbeat方案:利用Heartbeat管理VIP,利用crm管理MySQL,MySQL进行双M复制。(Linux系统下没有分库的标准方案)。 LVS+Keepalived方案:利用Keepalived管理LVS和VIP,LVS分发请求到MySQL,MySQL进行双M复制。(Linux系统下无分库无事务的方案)。 Cobar方案:利用Cobar进行HA和分库,应用程序请求Cobar,Cobar转发请求道数据库。(有分库的标准方案,Unix下唯一方案)。 95题 聚集(clustered)索引,也叫聚簇索引,数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。但是,覆盖索引可以模拟多个聚集索引。存储引擎负责实现索引,因此不是所有的存储索引都支持聚集索引。当前,SolidDB和InnoDB是唯一支持聚集索引的存储引擎。 优点:可以把相关数据保存在一起。数据访问快。 缺点:聚集能最大限度地提升I/O密集负载的性能。聚集能最大限度地提升I/O密集负载的性能。建立在聚集索引上的表在插入新行,或者在行的主键被更新,该行必须被移动的时候会进行分页。聚集表可会比全表扫描慢,尤其在表存储得比较稀疏或因为分页而没有顺序存储的时候。第二(非聚集)索引可能会比预想的大,因为它们的叶子节点包含了被引用行的主键列。 94题 以下原因是导致mysql 表毁坏的常见原因: 服务器突然断电导致数据文件损坏; 强制关机,没有先关闭mysql 服务; mysqld 进程在写表时被杀掉; 使用myisamchk 的同时,mysqld 也在操作表; 磁盘故障;服务器死机;mysql 本身的bug 。 93题 1.定位慢查询 首先先打开慢查询日志设置慢查询时间; 2.分析慢查询(使用explain工具分析sql语句); 3.优化慢查询 。
游客ih62co2qqq5ww 2020-06-15 13:55:41 0 浏览量 回答数 0

问题

DRDS 错误代码如何解决?

本文档列出了 DRDS 返回的常见错误码及解决方法。 TDDL-4006 ERR_TABLE_NOT_EXIST TDDL-4007 ERR_CANNOT_FETCH_TABLE_META TDDL-4100 ERR_ATOM_NOT...
猫饭先生 2019-12-01 21:21:21 7993 浏览量 回答数 0

回答

重试作用: 对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法、写操作等(要考虑写是否幂等)都不适合重试。 远程调用超时、网络突然中断可以重试。在微服务治理框架中,通常都有自己的重试与超时配置,比如dubbo可以设置retries=1,timeout=500调用失败只重试1次,超过500ms调用仍未返回则调用失败。 比如外部 RPC 调用,或者数据入库等操作,如果一次操作失败,可以进行多次重试,提高调用成功的可能性。 优雅的重试机制要具备几点: 无侵入:这个好理解,不改动当前的业务逻辑,对于需要重试的地方,可以很简单的实现 可配置:包括重试次数,重试的间隔时间,是否使用异步方式等 通用性:最好是无改动(或者很小改动)的支持绝大部分的场景,拿过来直接可用 优雅重试共性和原理: 正常和重试优雅解耦,重试断言条件实例或逻辑异常实例是两者沟通的媒介。 约定重试间隔,差异性重试策略,设置重试超时时间,进一步保证重试有效性以及重试流程稳定性。 都使用了命令设计模式,通过委托重试对象完成相应的逻辑操作,同时内部封装实现重试逻辑。 Spring-tryer和guava-tryer工具都是线程安全的重试,能够支持并发业务场景的重试逻辑正确性。 优雅重试适用场景: 功能逻辑中存在不稳定依赖场景,需要使用重试获取预期结果或者尝试重新执行逻辑不立即结束。比如远程接口访问,数据加载访问,数据上传校验等等。 对于异常场景存在需要重试场景,同时希望把正常逻辑和重试逻辑解耦。 对于需要基于数据媒介交互,希望通过重试轮询检测执行逻辑场景也可以考虑重试方案。 优雅重试解决思路: 切面方式 这个思路比较清晰,在需要添加重试的方法上添加一个用于重试的自定义注解,然后在切面中实现重试的逻辑,主要的配置参数则根据注解中的选项来初始化 优点: 真正的无侵入 缺点: 某些方法无法被切面拦截的场景无法覆盖(如spring-aop无法切私有方法,final方法) 直接使用aspecj则有些小复杂;如果用spring-aop,则只能切被spring容器管理的bean 消息总线方式 这个也比较容易理解,在需要重试的方法中,发送一个消息,并将业务逻辑作为回调方法传入;由一个订阅了重试消息的consumer来执行重试的业务逻辑 优点: 重试机制不受任何限制,即在任何地方你都可以使用 利用EventBus框架,可以非常容易把框架搭起来 缺点: 业务侵入,需要在重试的业务处,主动发起一条重试消息 调试理解复杂(消息总线方式的最大优点和缺点,就是过于灵活了,你可能都不知道什么地方处理这个消息,特别是新的童鞋来维护这段代码时) 如果要获取返回结果,不太好处理, 上下文参数不好处理 模板方式 优点: 简单(依赖简单:引入一个类就可以了; 使用简单:实现抽象类,讲业务逻辑填充即可;) 灵活(这个是真正的灵活了,你想怎么干都可以,完全由你控制) 缺点: 强侵入 代码臃肿 把这个单独捞出来,主要是某些时候我就一两个地方要用到重试,简单的实现下就好了,也没有必用用到上面这么重的方式;而且我希望可以针对代码快进行重试 这个的设计还是非常简单的,基本上代码都可以直接贴出来,一目了然: 复制代码 public abstract class RetryTemplate { private static final int DEFAULT_RETRY_TIME = 1; private int retryTime = DEFAULT_RETRY_TIME; private int sleepTime = 0;// 重试的睡眠时间 public int getSleepTime() { return sleepTime; } public RetryTemplate setSleepTime(int sleepTime) { if(sleepTime < 0) { throw new IllegalArgumentException("sleepTime should equal or bigger than 0"); } this.sleepTime = sleepTime; return this; } public int getRetryTime() { return retryTime; } public RetryTemplate setRetryTime(int retryTime) { if (retryTime <= 0) { throw new IllegalArgumentException("retryTime should bigger than 0"); } this.retryTime = retryTime; return this; } /** * 重试的业务执行代码 * 失败时请抛出一个异常 * * todo 确定返回的封装类,根据返回结果的状态来判定是否需要重试 * * @return */ protected abstract Object doBiz() throws Exception; //预留一个doBiz方法由业务方来实现,在其中书写需要重试的业务代码,然后执行即可 public Object execute() throws InterruptedException { for (int i = 0; i < retryTime; i++) { try { return doBiz(); } catch (Exception e) { log.error("业务执行出现异常,e: {}", e); Thread.sleep(sleepTime); } } return null; } public Object submit(ExecutorService executorService) { if (executorService == null) { throw new IllegalArgumentException("please choose executorService!"); } return executorService.submit((Callable) () -> execute()); } } 复制代码 使用示例: 复制代码 public void retryDemo() throws InterruptedException { Object ans = new RetryTemplate() { @Override protected Object doBiz() throws Exception { int temp = (int) (Math.random() * 10); System.out.println(temp); if (temp > 3) { throw new Exception("generate value bigger then 3! need retry"); } return temp; } }.setRetryTime(10).setSleepTime(10).execute(); System.out.println(ans); } 复制代码 spring-retry Spring Retry 为 Spring 应用程序提供了声明性重试支持。 它用于Spring批处理、Spring集成、Apache Hadoop(等等)的Spring。 在分布式系统中,为了保证数据分布式事务的强一致性,在调用RPC接口或者发送MQ时,针对可能会出现网络抖动请求超时情况采取一下重试操作。 用的最多的重试方式就是MQ了,但是如果你的项目中没有引入MQ,就不方便了。 还有一种方式,是开发者自己编写重试机制,但是大多不够优雅。 缺陷 spring-retry 工具虽能优雅实现重试,但是存在两个不友好设计: 一个是重试实体限定为 Throwable 子类,说明重试针对的是可捕捉的功能异常为设计前提的,但是我们希望依赖某个数据对象实体作为重试实体, 但 sping-retry框架必须强制转换为Throwable子类。 另一个是重试根源的断言对象使用的是 doWithRetry 的 Exception 异常实例,不符合正常内部断言的返回设计。 Spring Retry 提倡以注解的方式对方法进行重试,重试逻辑是同步执行的,当抛出相关异常后执行重试, 如果你要以返回值的某个状态来判定是否需要重试,可能只能通过自己判断返回值然后显式抛出异常了。只读操作可以重试,幂等写操作可以重试,但是非幂等写操作不能重试,重试可能导致脏写,或产生重复数据。 @Recover 注解在使用时无法指定方法,如果一个类中多个重试方法,就会很麻烦。 spring-retry 结构 BackOff:补偿值,一般指失败后多久进行重试的延迟值。 Sleeper:暂停应用的工具,通常用来应用补偿值。 RetryState:重试状态,通常包含一个重试的键值。 RetryCallback:封装你需要重试的业务逻辑(上文中的doSth) RecoverCallback:封装了多次重试都失败后你需要执行的业务逻辑(上文中的doSthWhenStillFail) RetryContext:重试语境下的上下文,代表了能被重试动作使用的资源。可用于在多次Retry或者Retry 和Recover之间传递参数或状态(在多次doSth或者doSth与doSthWhenStillFail之间传递参数) RetryOperations: 定义了“重试”的模板(重试的API),要求传入RetryCallback,可选传入RecoveryCallback; RetryTemplate :RetryOperations的具体实现,组合了RetryListener[],BackOffPolicy,RetryPolicy。 RetryListener:用来监控Retry的执行情况,并生成统计信息。 RetryPolicy:重试的策略或条件,可以简单的进行多次重试,可以是指定超时时间进行重试(上文中的someCondition),决定失败能否重试。 BackOffPolicy: 重试的回退策略,在业务逻辑执行发生异常时。如果需要重试,我们可能需要等一段时间(可能服务器过于繁忙,如果一直不间隔重试可能拖垮服务器),当然这段时间可以是0,也可以是固定的,可以是随机的(参见tcp的拥塞控制算法中的回退策略)。回退策略在上文中体现为wait(); RetryPolicy提供了如下策略实现: NeverRetryPolicy:只允许调用RetryCallback一次,不允许重试; AlwaysRetryPolicy:允许无限重试,直到成功,此方式逻辑不当会导致死循环; SimpleRetryPolicy:固定次数重试策略,默认重试最大次数为3次,RetryTemplate默认使用的策略; TimeoutRetryPolicy:超时时间重试策略,默认超时时间为1秒,在指定的超时时间内允许重试; CircuitBreakerRetryPolicy:有熔断功能的重试策略,需设置3个参数openTimeout、resetTimeout和delegate delegate:是真正判断是否重试的策略,当重试失败时,则执行熔断策略;应该配置基于次数的SimpleRetryPolicy或者基于超时的TimeoutRetryPolicy策略,且策略都是全局模式,而非局部模式,所以要注意次数或超时的配置合理性。 openTimeout:openWindow,配置熔断器电路打开的超时时间,当超过openTimeout之后熔断器电路变成半打开状态(主要有一次重试成功,则闭合电路); resetTimeout:timeout,配置重置熔断器重新闭合的超时时间 CompositeRetryPolicy:组合重试策略,有两种组合方式,乐观组合重试策略是指只要有一个策略允许重试即可以,悲观组合重试策略是指只要有一个策略不允许重试即可以,但不管哪种组合方式,组合中的每一个策略都会执行。 BackOffPolicy 提供了如下策略实现: NoBackOffPolicy:无退避算法策略,即当重试时是立即重试; FixedBackOffPolicy:固定时间的退避策略,需设置参数sleeper(指定等待策略,默认是Thread.sleep,即线程休眠)、backOffPeriod(休眠时间,默认1秒); UniformRandomBackOffPolicy:随机时间退避策略,需设置sleeper、minBackOffPeriod、maxBackOffPeriod,该策略在[minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒; ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier。initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier; ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数,固定乘数可能会引起很多服务同时重试导致DDos,使用随机休眠时间来避免这种情况。 RetryTemplate主要流程实现: 复制代码 //示例一 public void upload(final Map<String, Object> map) throws Exception { // 构建重试模板实例 RetryTemplate retryTemplate = new RetryTemplate(); // 设置重试策略,主要设置重试次数 SimpleRetryPolicy policy =         new SimpleRetryPolicy(3, Collections.<Class<? extends Throwable>, Boolean> singletonMap(Exception.class, true)); // 设置重试回退操作策略,主要设置重试间隔时间 FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy(); fixedBackOffPolicy.setBackOffPeriod(100); retryTemplate.setRetryPolicy(policy); retryTemplate.setBackOffPolicy(fixedBackOffPolicy); // 通过RetryCallback 重试回调实例包装正常逻辑逻辑,第一次执行和重试执行执行的都是这段逻辑 final RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() { //RetryContext 重试操作上下文约定,统一spring-try包装 public Object doWithRetry(RetryContext context) throws Exception { System.out.println("do some thing"); Exception e = uploadToOdps(map); System.out.println(context.getRetryCount()); throw e;//这个点特别注意,重试的根源通过Exception返回 } }; // 通过RecoveryCallback 重试流程正常结束或者达到重试上限后的退出恢复操作实例 final RecoveryCallback recoveryCallback = new RecoveryCallback() { public Object recover(RetryContext context) throws Exception { System.out.println("do recory operation"); return null; } }; try { // 由retryTemplate 执行execute方法开始逻辑执行 retryTemplate.execute(retryCallback, recoveryCallback); } catch (Exception e) { e.printStackTrace(); } } //示例二 protected <T, E extends Throwable> T doExecute(RetryCallback<T, E> retryCallback,RecoveryCallback recoveryCallback,   RetryState state) throws E, ExhaustedRetryException { //重试策略 RetryPolicy retryPolicy = this.retryPolicy; //退避策略 BackOffPolicy backOffPolicy = this.backOffPolicy; //重试上下文,当前重试次数等都记录在上下文中 RetryContext context = open(retryPolicy, state); try { //拦截器模式,执行RetryListener#open boolean running = doOpenInterceptors(retryCallback, context); //判断是否可以重试执行 while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) { try {//执行RetryCallback回调 return retryCallback.doWithRetry(context); } catch (Throwable e) {//异常时,要进行下一次重试准备 //遇到异常后,注册该异常的失败次数 registerThrowable(retryPolicy, state, context, e); //执行RetryListener#onError doOnErrorInterceptors(retryCallback, context, e); //如果可以重试,执行退避算法,比如休眠一小段时间后再重试 if (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) { backOffPolicy.backOff(backOffContext); } //state != null && state.rollbackFor(context.getLastThrowable()) //在有状态重试时,如果是需要执行回滚操作的异常,则立即抛出异常 if (shouldRethrow(retryPolicy, context, state)) { throw RetryTemplate. wrapIfNecessary(e); } } //如果是有状态重试,且有GLOBAL_STATE属性,则立即跳出重试终止;       //当抛出的异常是非需要执行回滚操作的异常时,才会执行到此处,CircuitBreakerRetryPolicy会在此跳出循环; if (state != null && context.hasAttribute(GLOBAL_STATE)) { break; } } //重试失败后,如果有RecoveryCallback,则执行此回调,否则抛出异常 return handleRetryExhausted(recoveryCallback, context, state); } catch (Throwable e) { throw RetryTemplate. wrapIfNecessary(e); } finally { //清理环境 close(retryPolicy, context, state, lastException == null || exhausted); //执行RetryListener#close,比如统计重试信息 doCloseInterceptors(retryCallback, context, lastException); } } 复制代码 有状态or无状态 无状态重试,是在一个循环中执行完重试策略,即重试上下文保持在一个线程上下文中,在一次调用中进行完整的重试策略判断。如远程调用某个查询方法时是最常见的无状态重试: 复制代码 RetryTemplate template = new RetryTemplate(); //重试策略:次数重试策略 RetryPolicy retryPolicy = new SimpleRetryPolicy(3); template.setRetryPolicy(retryPolicy); //退避策略:指数退避策略 ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); backOffPolicy.setInitialInterval(100); backOffPolicy.setMaxInterval(3000); backOffPolicy.setMultiplier(2); backOffPolicy.setSleeper(new ThreadWaitSleeper()); template.setBackOffPolicy(backOffPolicy); //当重试失败后,抛出异常 String result = template.execute(new RetryCallback<String, RuntimeException>() { @Override public String doWithRetry(RetryContext context) throws RuntimeException { throw new RuntimeException("timeout"); } }); //当重试失败后,执行RecoveryCallback String result = template.execute(new RetryCallback<String, RuntimeException>() { @Override public String doWithRetry(RetryContext context) throws RuntimeException { System.out.println("retry count:" + context.getRetryCount()); throw new RuntimeException("timeout"); } }, new RecoveryCallback () { @Override public String recover(RetryContext context) throws Exception { return "default"; } }); 复制代码 有状态重试,有两种情况需要使用有状态重试,事务操作需要回滚、熔断器模式。 事务操作需要回滚场景时,当整个操作中抛出的是数据库异常DataAccessException,则不能进行重试需要回滚,而抛出其他异常则可以进行重试,可以通过RetryState实现: 复制代码 //当前状态的名称,当把状态放入缓存时,通过该key查询获取 Object key = "mykey"; //是否每次都重新生成上下文还是从缓存中查询,即全局模式(如熔断器策略时从缓存中查询) boolean isForceRefresh = true; //对DataAccessException进行回滚 BinaryExceptionClassifier rollbackClassifier = new BinaryExceptionClassifier(Collections.<Class<? extends Throwable>>singleton(DataAccessException.class)); RetryState state = new DefaultRetryState(key, isForceRefresh, rollbackClassifier); String result = template.execute(new RetryCallback<String, RuntimeException>() { @Override public String doWithRetry(RetryContext context) throws RuntimeException { System.out.println("retry count:" + context.getRetryCount()); throw new TypeMismatchDataAccessException(""); } }, new RecoveryCallback () { @Override public String recover(RetryContext context) throws Exception { return "default"; } }, state); 复制代码 RetryTemplate中在有状态重试时,回滚场景时直接抛出异常处理代码: //state != null && state.rollbackFor(context.getLastThrowable()) //在有状态重试时,如果是需要执行回滚操作的异常,则立即抛出异常 if (shouldRethrow(retryPolicy,context, state)) { throw RetryTemplate. wrapIfNecessary(e); } 熔断器场景。在有状态重试时,且是全局模式,不在当前循环中处理重试,而是全局重试模式(不是线程上下文),如熔断器策略时测试代码如下所示。 复制代码 RetryTemplate template = new RetryTemplate(); CircuitBreakerRetryPolicy retryPolicy = new CircuitBreakerRetryPolicy(new SimpleRetryPolicy(3)); retryPolicy.setOpenTimeout(5000); retryPolicy.setResetTimeout(20000); template.setRetryPolicy(retryPolicy); for (int i = 0; i < 10; i++) { try { Object key = "circuit"; boolean isForceRefresh = false; RetryState state = new DefaultRetryState(key, isForceRefresh); String result = template.execute(new RetryCallback<String, RuntimeException>() { @Override public String doWithRetry(RetryContext context) throws RuntimeException { System.out.println("retry count:" + context.getRetryCount()); throw new RuntimeException("timeout"); } }, new RecoveryCallback () { @Override public String recover(RetryContext context) throws Exception { return "default"; } }, state); System.out.println(result); } catch (Exception e) { System.out.println(e); } } 复制代码 为什么说是全局模式呢?我们配置了isForceRefresh为false,则在获取上下文时是根据key “circuit”从缓存中获取,从而拿到同一个上下文。 Object key = "circuit"; boolean isForceRefresh = false; RetryState state = new DefaultRetryState(key,isForceRefresh); 如下RetryTemplate代码说明在有状态模式下,不会在循环中进行重试。 if (state != null && context.hasAttribute(GLOBAL_STATE)) { break; } 判断熔断器电路是否打开的代码: 复制代码 public boolean isOpen() { long time = System.currentTimeMillis() - this.start; boolean retryable = this.policy.canRetry(this.context); if (!retryable) {//重试失败 //在重置熔断器超时后,熔断器器电路闭合,重置上下文 if (time > this.timeout) { this.context = createDelegateContext(policy, getParent()); this.start = System.currentTimeMillis(); retryable = this.policy.canRetry(this.context); } else if (time < this.openWindow) { //当在熔断器打开状态时,熔断器电路打开,立即熔断 if ((Boolean) getAttribute(CIRCUIT_OPEN) == false) { setAttribute(CIRCUIT_OPEN, true); } this.start = System.currentTimeMillis(); return true; } } else {//重试成功 //在熔断器电路半打开状态时,断路器电路闭合,重置上下文 if (time > this.openWindow) { this.start = System.currentTimeMillis(); this.context = createDelegateContext(policy, getParent()); } } setAttribute(CIRCUIT_OPEN, !retryable); return !retryable; } 复制代码 从如上代码可看出spring-retry的熔断策略相对简单: 当重试失败,且在熔断器打开时间窗口[0,openWindow) 内,立即熔断; 当重试失败,且在指定超时时间后(>timeout),熔断器电路重新闭合; 在熔断器半打开状态[openWindow, timeout] 时,只要重试成功则重置上下文,断路器闭合。 注解介绍 @EnableRetry 表示是否开始重试。 序号 属性 类型 默认值 说明 1 proxyTargetClass boolean false 指示是否要创建基于子类的(CGLIB)代理,而不是创建标准的基于Java接口的代理。当proxyTargetClass属性为true时,使用CGLIB代理。默认使用标准JAVA注解 @Retryable 标注此注解的方法在发生异常时会进行重试 序号 属性 类型 默认值 说明 1 interceptor String ”” 将 interceptor 的 bean 名称应用到 retryable() 2 value class[] {} 可重试的异常类型 3 include class[] {} 和value一样,默认空,当exclude也为空时,所有异常都重试 4 exclude class[] {} 指定异常不重试,默认空,当include也为空时,所有异常都重试 5 label String ”” 统计报告的唯一标签。如果没有提供,调用者可以选择忽略它,或者提供默认值。 6 maxAttempts int 3 尝试的最大次数(包括第一次失败),默认为3次。 7 backoff @Backoff @Backoff() 重试补偿机制,指定用于重试此操作的backoff属性。默认为空 @Backoff 不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms 序号 属性 类型 默认值 说明 1 delay long 0 指定延迟后重试 ,如果不设置则默认使用 1000 milliseconds 2 maxDelay long 0 最大重试等待时间 3 multiplier long 0 指定延迟的倍数,比如delay=5000l,multiplier=2时,第一次重试为5秒后,第二次为10秒,第三次为20秒(大于0生效) 4 random boolean false 随机重试等待时间 @Recover 用于恢复处理程序的方法调用的注释。返回类型必须与@retryable方法匹配。 可抛出的第一个参数是可选的(但是没有它的方法只会被调用)。 从失败方法的参数列表按顺序填充后续的参数。 用于@Retryable重试失败后处理方法,此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。 说明: 使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效。也就是要标记为@Service,然后在其它类使用@Autowired注入或者@Bean去实例才能生效。 要触发@Recover方法,那么在@Retryable方法上不能有返回值,只能是void才能生效。 使用了@Retryable的方法里面不能使用try...catch包裹,要在发放上抛出异常,不然不会触发。 在重试期间这个方法是同步的,如果使用类似Spring Cloud这种框架的熔断机制时,可以结合重试机制来重试后返回结果。 Spring Retry不只能注入方式去实现,还可以通过API的方式实现,类似熔断处理的机制就基于API方式实现会比较宽松。 转载于:https://www.cnblogs.com/whatarewords/p/10656514.html
养狐狸的猫 2019-12-02 02:11:54 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板