华为云用户手册

  • 一句话识别 支持“华北-北京四”、“华东-上海一”区域。 当前服务仅支持北京和上海区域,后续会陆续上线其他区域。 华北-北京四,推荐的区域,支持一句话识别、录音文件识别、 实时语音识别 语音合成 和热词等接口。 华东-上海一,推荐的区域,支持一句话识别、录音文件识别、实时 语音识别 、语音合成和热词等接口。 支持pcm16k16bit、pcm8k16bit、ulaw16k8bit、ulaw8k8bit、alaw16k8bit、wav、amr、amrwb等多种格式,详见API参考文档中的“audio_format取值范围”。 音频时长不超过1分钟。 支持中文普通话、方言和英语的语音识别,其中方言包括:四川话、粤语和上海话。 方言仅支持“华北-北京四”区域,英语仅支持“华东-上海一”区域。 父主题: 约束与限制
  • 语音合成 支持“华北-北京四”、“华东-上海一”区域。 当前服务仅支持北京和上海区域,后续会陆续上线其他区域。 华北-北京四,推荐的区域,支持一句话识别、录音文件识别、实时语音识别和语音合成和热词等接口。 华东-上海一,推荐的区域,支持一句话识别、录音文件识别、实时语音识别、语音合成和热词等接口。 支持中文、英文、中英文,文本不长于500个字符。 支持合成采样率8kHz、16kHz。 父主题: 约束与限制
  • 应用场景 语音客服质检 识别客服、客户的语音,转换为文本。进一步通过文本检索,检查有没有违规、敏感词、电话号码等信息。 会议记录 对会议记录的音频文件,进行快速的识别,转化成文字,方便进行会议记录。 语音短消息 通过语音发送或者接收短消息时,将音频短消息转文字,提升阅读效率和交互体验。 游戏娱乐 将游戏娱乐中的语音聊天转成文字消息,提升用户阅读效率,提升用户体验。 有声读物 将书籍、杂志、新闻的文本内容转换成逼真的人声发音,充分解放人们的眼睛,在搭乘地铁、开车、健身等场景下获取信息、享受乐趣。 电话回访 在客服系统场景中,通过将回访内容转换成人声,直接使用语音和客户交流,提升用户体验。 智能教育 集成语音合成的教育系统可以实现中文标准朗读及带读,应用于课堂和学生自学,提升教学效率。 直播实时字幕 将 视频直播 或现场直播中的音频实时转为字幕,为观众提供更高效的观会体验,方便对直播内容进行监控。 会议实时记录 将视频或电话会议中的音频实时转为文字,可实时校核、修改及检索转写会议内容,提高会议效率。 即时文本录入 手机App上实时录音并即时提供转写的文本,例如语音输入法等。 人机交互 通过语音合成,实现高品质的机器人发声,使得人机交互更加自然。 智能客服 借助语音合成,联络中心可以用自然的声音与客户互动。
  • 不同消费者消费不同Tag 在实际使用场景中,可能会遇到不同的消费者消费同一Topic的不同Tag消息。对于同一个Topic的不同Tag,如果RocketMQ消费者设置了相同的消费组,会导致消息消费混乱。 例如Topic A下有Tag A和Tag B,消费者A订阅了Tag A的消息,消费者B订阅了Tag B的消息。 如果消费者A和消费者B设置了相同的消费组,当生产者发送Tag A的消息时,Tag A的消息会均匀发送给消费者A和消费者B。由于消费者B没有订阅Tag A的消息,会把Tag A消息过滤掉,从而导致部分Tag A消息未被消费。 图1 错误的消费组设置 这种情况下,把消费者A和消费者B设置不同的消费组,即可解决消费混乱的问题。 图2 正确的消费者组设置
  • 方案概述 Topic是消息关联的基础逻辑单元,消息的生产与消费围绕着Topic进行。每个Topic包含若干条消息,每条消息只能属于一个Topic。 Tag是消息的标签,用于在同一Topic下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一Topic下设置不同的标签。标签能够有效保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同Topic的不同消费逻辑,实现更好的扩展性。 Topic是消息的一级分类,Tag是消息的二级分类,关系如下图。 应用场景 在实际业务中,通过合理使用Topic和Tag,可以使业务结构更清晰,提高效率。可以根据如下几方面判断Topic和Tag的具体使用场景: 根据消息类型判断:RocketMQ的消息可分为普通消息、顺序消息、定时/延迟消息、事务消息,不同类型的消息需要用不同的Topic来区分,无法通过Tag区分。 根据消息优先级判断:在业务中紧急程度高和紧急程度一般的消息用不同的Topic来区分,方便后续业务处理。 根据业务关联性判断:业务逻辑上不相关的消息用不同Topic来区分,业务逻辑上强关联的消息发送到同一Topic下,并用Tag进行子类型或流程先后关系的区分。
  • 实施方法 以物流运输场景为例,普通货物订单消息和生鲜货物订单消息属于不同类型的消息,分别创建Topic_Common和Topic_Fresh。在不同消息类型中,以不同的Tag划分不同的订单目的省份。 Topic:Topic_Common Tag = Province_A Tag = Province_B Topic: Topic_Fresh Tag = Province_A Tag = Province_B 以生产发往Province A的普通货物订单消息为例,代码示例如下: Message msg = new Message("Topic_Common", "Province_A" /* Tag */, ("Order_id " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)); 以订阅发往Province A和Province B的生鲜货物订单消息为例,代码示例如下: consumer.subscribe("Topic_Fresh", "Province_A || Province_B");
  • 实施方法 订阅一个Topic且订阅一个Tag 同一消费组Group1中的消费者Consumer1、Consumer2和Consumer3都订阅了Topic_A,且都订阅了Topic_A的Tag_A,符合订阅关系一致原则。Consumer1、Consumer2、Consumer3的订阅关系一致,即Consumer1、Consumer2、Consumer3订阅消息的代码必须完全一致,代码示例如下: DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("Group1");consumer.subscribe("Topic_A", "Tag_A"); 订阅一个Topic且订阅多个Tag 同一消费组Group1中的消费者Consumer1、Consumer2和Consumer3都订阅了Topic_A,且都订阅了Topic_A的Tag_A和Tag_B(即订阅Topic_A中所有Tag为Tag_A或Tag_B的消息),顺序都是Tag_A||Tag_B,符合订阅关系一致性原则。Consumer1、Consumer2、Consumer3的订阅关系一致,即Consumer1、Consumer2、Consumer3订阅消息的代码必须完全一致,代码示例如下: DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("Group1");consumer.subscribe("Topic_A", "Tag_A||Tag_B"); 订阅多个Topic且订阅多个Tag 同一消费组Group1中的消费者Consumer1、Consumer2和Consumer3都订阅了Topic_A和Topic_B,且订阅Topic_A都未指定Tag(即订阅Topic_A中的所有消息),订阅Topic_B的Tag都是Tag_A和Tag_B(即订阅Topic_B中所有Tag为Tag_A或Tag_B的消息),顺序都是Tag_A||Tag_B,符合订阅关系一致性原则。Consumer1、Consumer2、Consumer3的订阅关系一致,即Consumer1、Consumer2、Consumer3订阅消息的代码必须完全一致,代码示例如下: DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("Group1");consumer.subscribe("Topic_A", "*");consumer.subscribe("Topic_B", "Tag_A||Tag_B");
  • RocketMQ最佳实践汇总 本文汇总了基于RocketMQ常见应用场景的操作实践,为每个实践提供详细的方案描述和操作指导,帮助用户轻松构建基于RocketMQ的业务。 表1 RocketMQ最佳实践一览表 最佳实践 说明 通过消息幂等实现消息去重 为了防止消息重复消费导致业务处理异常,RocketMQ的消费者在接收到消息后,有必要根据业务上的唯一Key对消息做幂等处理。本章节介绍消息幂等的概念、适用场景以及实施方法。 通过Topic和Tag实现消息分类 在RocketMQ中,Topic与Tag都是业务上用来归类的标识,区分在于Topic是一级分类,而Tag可以理解为是二级分类。本章节介绍如何搭配使用Topic和Tag来实现消息过滤。 实现订阅关系一致 订阅关系不一致,可能导致消息消费逻辑混乱,消息被重复消费或遗漏。本章节介绍订阅关系一致的概念、原理以及实施方法。 消息堆积处理建议 本章节介绍出现消息堆积的主要原因和实施方法。 配置消息堆积数监控 本章节介绍RocketMQ通过 云监控 配置告警规则的具体操作,以便您可以实时监控实例的运行状态和关键的业务指标,并能够及时收到异常的告警通知,实现生产环境的风险预警。 DMS for RocketMQ安全使用建议 本章节提供了RocketMQ使用过程中的安全最佳实践,旨在为提高整体安全能力提供可操作的规范性指导。
  • 方案概述 订阅关系一致指的是同一个消费组下所有消费者所订阅的Topic、Tag必须完全一致。如果订阅关系不一致,消息消费的逻辑就会混乱,甚至导致消息丢失。 消费原理 RocketMQ为每个Topic划分了消息队列(Queue),队列数越大消费的并发度越大。一个消费组表示一个消费者群组,在分布式应用场景下,同一个消费组中的多个消费者共同完成Topic所有Queue的消费。Queue的分配以消费组为单位,会均匀分配给消费组下的消费者,而不会在意该消费者是否订阅了当前Topic。一个消费者只会分配到Topic中的某几个Queue,而一个Queue只会分配给一个消费者。 正确的订阅关系 在分布式应用场景下,一个消费组中所有的消费者拥有一个相同的消费组ID,他们需订阅相同的Topic和Tag,保持订阅关系一致,才能保证消息消费逻辑正确,消息不丢失。 同一个消费组的消费者必须订阅同一个Topic。例如,消费组Group1中有消费者A和消费者B,消费者A订阅了Topic A和Topic B,则消费者B也必须订阅Topic A和Topic B,不能只订阅Topic A或只订阅Topic B,或者额外订阅Topic C。 同一个消费组的消费者订阅同一个Topic下的Tag必须一致,包括Tag的数量和顺序。例如,消费组Group2中有消费者A和消费者B,消费者A订阅Topic A且Tag为Tag A||Tag B,则消费者B订阅Topic A时Tag也必须为Tag A||Tag B,不能只订阅Tag A或只订阅Tag B或订阅Tag B||Tag A。 图1 正确的订阅关系一致设置 订阅关系一致性保证了同一个消费组中消费消息的正常运行,避免消息逻辑混乱和消息丢失。在实际使用中,生产者端要做好消息的分类,便于消费者可以使用Tag进行消息的准确订阅。而在消费者端,则要保证订阅关系的一致性。 错误的订阅关系 同一消费组下的消费者订阅了不同的Topic 例如,消费组Group1下有消费者A和消费者B,消费者A订阅了Topic A,消费者B订阅了Topic B。当生产者向Topic A发送消息时,消息会按Queue均匀发送给消费者A和消费者B。由于消费者B没有订阅Topic A的消息,会把Topic A消息过滤掉(即图2中Topic A的Queue2中的消息会被消费者B过滤),从而导致部分Topic A消息未被消费。 图2 错误的Topic订阅 同一消费组下的消费者订阅了相同Topic下不同的Tag 例如,消费组Group1下有消费者A和消费者B,消费者A订阅了Topic A的Tag A,消费者B订阅了Topic A的Tag B。当生产者A向Topic A发送Tag A的消息时,Tag A消息会按Queue均匀发送给消费者A和消费者B。由于消费者B没有订阅Tag A的消息,会把Tag A消息过滤掉(即图3中Queue2中的Tag A消息会被消费者B过滤),从而导致部分Tag A消息未被消费。 图3 错误的Tag订阅
  • 实施方法 从上面的消费重复场景可以看到,不同Message ID的消息可能有相同的消息内容,因此Message ID无法作为消息的唯一标识符。RocketMQ可以为消息设置Key,把业务的唯一标识作为消息的唯一标识,从而实现消息的幂等。为消息设置Key的示例代码如下: Message message = new Message();message.setKey("Order_id"); // 设置消息的Key,可以使用业务的唯一标识作为Key,例如订单号等。SentResult sendResult = mqProducer.send(message); 生产者发送消息时,消息已经设置了唯一的Key,在消费者消费消息时,可以根据消息的Key进行幂等处理。消费者通过getKeys()能够读取到消息的唯一标识(如订单号等),业务逻辑围绕该唯一标识进行幂等处理即可。
  • 通过访问控制,保护数据安全性 建议对不同角色的 IAM 用户仅设置最小权限,避免权限过大导致数据泄露或被误操作。 为了更好的进行权限隔离和管理,建议您配置独立的IAM管理员,授予IAM管理员IAM策略的管理权限。IAM管理员可以根据您业务的实际诉求创建不同的用户组,用户组对应不同的数据访问场景,通过将用户添加到用户组并将IAM策略绑定到对应用户组,IAM管理员可以为不同职能部门的员工按照最小权限原则授予不同的数据访问权限,详情请参见权限管理。 建议配置安全组访问控制,保护您的数据不被异常读取和操作。 参照表1配置安全组的入方向规则限制,控制连接实例的网络范围,避免DMS for RocketMQ暴露给不可信的第三方。 表1 安全组规则 实例版本 方向 协议 端口 源地址 说明 4.8.0 5.x 入方向 TCP 8100 访问DMS for RocketMQ实例的客户端地址,应避免设置为0.0.0.0/0。 使用TCP协议,通过内网访问实例的端口。 4.8.0 5.x 入方向 TCP 8200 使用TCP协议,通过公网访问实例的端口。 4.8.0 5.x 入方向 TCP 10100-10199 使用TCP协议,访问业务节点的端口。 5.x 入方向 TCP 8080 使用gRPC协议,通过内网访问实例的端口。 5.x 入方向 TCP 8081 使用gRPC协议,通过公网访问实例的端口。 建议将访问DMS for RocketMQ实例方式设置为密码访问(即开启ACL访问控制),防止未经认证的客户端误操作实例。 您可以选择如下任意一种方法开启ACL访问控制。 在“购买实例”页面开启ACL访问控制,具体可参考购买RocketMQ实例。 购买实例后,在实例的“基本信息”页面中开启ACL访问控制,具体可参考查看和修改RocketMQ实例基本信息。 开启敏感操作多因子认证保护您的数据不被误删。 DMS for RocketMQ支持敏感操作保护,开启后执行删除实例等敏感操作时,系统会进行身份验证,进一步对数据的高危操作进行控制,保证DMS for RocketMQ数据的安全性。详情请参见敏感操作。
  • 方案概述 在RocketMQ的业务处理过程中,如果消息重发了多次,消费者端对该重复消息消费多次与消费一次的结果是相同的,多次消费并没有对业务产生负面影响,那么这个消息处理过程是幂等的。消息幂等保证了无论消息被重复投递多少次,最终的处理结果都是一致的,避免了因消息重复而对业务产生影响。 例如在支付场景下,用户购买商品后进行支付,由于网络不稳定导致用户收到多次扣款请求,导致重复扣款。但实际上扣款业务只应进行一次,商家也只应产生一条订单流水。这时候使用消息幂等就可以避免这个问题。 在实际应用中,导致消息重复的原因有网络闪断、客户端故障等,且可能发生在消息生产阶段,也可能发生在消息消费阶段。因此,可以将消息重复的场景分为以下两类: 生产者发送消息时发生消息重复: 生产者发送消息时,消息成功发送至服务端。如果此时发生网络闪断,导致生产者未收到服务端的响应,此时生产者会认为消息发送失败,因此尝试重新发送消息至服务端。当消息重新发送成功后,在服务端中就会存在两条内容相同的消息,最终消费者会消费到两条内容一样的重复消息。 消费者消费消息时发生消息重复: 消费者消费消息时,服务端将消息投递至消费者并完成业务处理。如果此时发生网络闪断,导致服务端未收到消费者的响应,此时服务端会认为消息投递失败。为了保证消息至少被消费一次,服务端会尝试投递之前已被处理过的消息,最终消费者会消费到两条内容一样的重复消息。
  • 审计是否存在异常数据访问 开启 云审计 服务,记录DMS for RocketMQ的所有访问操作,便于后期审查。 云审计服务(Cloud Trace Service, CTS ),是华为 云安全 解决方案中专业的日志审计服务,提供对各种云资源操作记录的收集、存储和查询功能,可用于支撑安全分析、合规审计、资源跟踪和问题定位等常见应用场景。 您开通云审计服务并创建和配置追踪器后,CTS可记录DMS for RocketMQ的管理事件和数据事件用于审计。相关文档请参见查看RocketMQ审计日志。 使用 云监控服务 对安全事件进行实时监控和告警。 为使您更好地掌握DMS for RocketMQ实例状态,华为云提供了云监控服务(Cloud Eye)。您可使用该服务监控自己的DMS for RocketMQ实例,执行自动实时监控、告警和通知操作,帮助您实时掌握DMS for RocketMQ实例中所产生的请求、流量等信息。 云监控服务不需要开通,会在用户创建DMS for RocketMQ实例后自动启动。相关文档请参见RocketMQ支持的监控指标、配置RocketMQ监控告警。
  • 方案概述 在RocketMQ的实际业务中,消息堆积是比较常见的问题。在消息处理过程中,如果客户端的消费速度跟不上服务端的发送速度,未处理的消息会越来越多,这部分消息就被称为堆积消息。消息没有被及时消费而产生消息堆积,从而会造成消息消费延迟。对于消息消费实时性要求较高的业务系统,即使是消息堆积造成的短暂消息延迟也无法接受。造成消息堆积的原因有以下两个: 消息没有及时被消费,生产者生产消息的速度快于消费者消费消息的速度,从而产生消息积压且无法自行恢复。 业务系统本身逻辑耗费时间较长,导致消息消费效率较低。 消息消费过程 图1 消息消费的过程 一个完整的消息消费过程主要分为2个阶段: 消息拉取 客户端通过批量拉取的方式从服务端获取消息,将拉取到的消息缓存到本地缓存队列中。对于拉取式消费,在内网环境下的吞吐量很高,因此消息拉取阶段一般不会引起消息堆积。 消息消费 客户端将本地缓存的消息提交到消费线程中,提供给业务消费逻辑进行消息处理,待消息处理完成后获取处理结果。此阶段的消费能力依赖于消息的消费耗时和消费并发度。如果由于业务处理逻辑复杂等原因,导致处理单条消息的耗时较长,就会影响整体的消息吞吐量。而消息吞吐量低会导致客户端本地缓存队列达到上限,从而停止从服务端拉取消息,引起消息堆积。 所以,消息堆积的主要瓶颈在于客户端的消费能力,而消费能力由消费耗时和消费并发度决定。消费耗时的优先级要高于消费并发度,应在保证消费耗时合理性的前提下,再考虑消费并发度问题。 消费耗时 影响消息处理时长的主要因素是业务处理的代码逻辑,而代码逻辑中会影响处理时长的主要有两种代码类型:CPU内部计算型代码和外部I/O操作型代码。如果代码中没有复杂的递归和循环处理,CPU内部计算耗时相对于外部I/O操作耗时来说几乎可以忽略,因此应关注外部I/O操作型代码的消息处理效率。 外部IO操作型代码主要有以下业务操作: 读写外部数据库,例如对远程MySQL数据库读写。 读写外部缓存系统,例如对远程Redis读写。 下游系统调用,例如Dubbo的RPC远程调用,Spring Cloud对下游系统的HTTP接口调用。 提前梳理下游系统的调用逻辑,掌握每个调用操作的预期耗时,有助于判断业务逻辑中I/O操作的耗时是否合理。通常消息堆积都是由于下游系统出现了服务异常或容量限制,从而导致消费耗时增加。而服务异常,并不仅仅是系统出现报错,也可能是更加隐蔽的问题,比如网络带宽问题。 消费并发度 客户端的消费并发度由单客户端线程数和客户端数量决定。单客户端线程数是指单个客户端所包含的线程数量,客户端数量是指消费组所包含的客户端(消费者)数量。对于普通消息、定时/延时消息、事务消息及顺序消息的消费并发度计算方法如下: 消息类型 消费并发度 普通消息 单客户端线程数 * 客户端数 定时/延时消息 事务消息 顺序消息 Min(单客户端线程数 * 客户端数,队列数) 单客户端线程数的调整需谨慎,不能盲目调大线程数,如果设置过大的线程数反而会带来大量的线程切换开销。 理想环境下单客户端的最优线程数计算模型为:C *(T1+T2)/T1。 其中,C为单机vCPU核数,T1为业务逻辑的CPU计算耗时,T2为外部I/O操作耗时,另外线程切换耗时忽略不计,I/O操作不消耗CPU,线程需有足够消息等待处理且内存充足。 此处最大线程数的计算模型是在理想环境下得到的,在实际应用中建议逐步调大线程数,在观察效果后再进行调整。
  • 实施方法 为了避免在实际业务中出现非预期的消息堆积问题,需要在业务系统的设计阶段梳理业务逻辑的消费耗时和设置消费并发度。 梳理消费耗时 通过压测获取消息的消费耗时,并对耗时较高的操作代码逻辑进行分析和优化。梳理消息的消费耗时需要注意以下几点: 消息消费逻辑的计算复杂度是否过高,代码是否存在复杂的递归和循环处理。 消息消费逻辑中的I/O操作是否是必须,是否可以使用本地缓存等方案规避。 消息消费逻辑中的复杂耗时操作是否可以做异步化处理。 设置消费并发度 对于消费并发度的计算,可以按如下方法进行处理: 根据公式计算出线程数的理想值,然后选取一个比理想值小的数据作为线程数起始值。逐步调大单个客户端的线程数,并观测客户端的系统指标,得到单个客户端的最优消费线程数和消息吞吐量。 根据上下游链路的流量峰值,计算出需要设置的客户端数量:客户端数=流量峰值/单客户端消息吞吐量。
  • 使用特定的标签 当镜像没有指定标签时,将默认使用latest标签。因此,FROM ubuntu指令等同于FROM ubuntu:latest。当镜像更新时,latest标签会指向不同的镜像,这时构建镜像有可能失败。 如下示例中使用16.04作为标签。 FROM ubuntu:16.04RUN apt-get update && apt-get install -y nodejs ADD . /app RUN cd /app && npm installCMD npm start
  • 删除多余文件 假设更新了apt-get源,下载解压并安装了一些软件包,它们都保存在“/var/lib/apt/lists/”目录中。 但是,运行应用时Docker镜像中并不需要这些文件。因此最好将它们删除,因为它会使Docker镜像变大。 示例Dockerfile中,删除“/var/lib/apt/lists/”目录中的文件。 FROM ubuntu:16.04RUN apt-get update \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/*ADD . /app RUN cd /app && npm installCMD npm start
  • 选择合适的基础镜像 在示例中,选择了ubuntu作为基础镜像。但是只需要运行node程序,没有必要使用一个通用的基础镜像,node镜像应该是更好的选择。 更好的选择是alpine版本的node镜像。alpine是一个极小化的Linux发行版,只有4MB,这让它非常适合作为基础镜像。 FROM node:7-alpineADD . /app RUN cd /app && npm installCMD npm start
  • 使用VOLUME管理数据库逻辑卷 VOLUME指令用于暴露任何数据库存储文件、配置文件或容器创建的文件和目录。强烈建议使用VOLUME来管理镜像中的可变部分和用户可以改变的部分。 下面示例中填写一个媒体目录。 FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV MEDIA_DIR=/media \ APP_PORT=3000VOLUME $MEDIA_DIR EXPOSE $APP_PORTENTRYPOINT ["./entrypoint.sh"] CMD ["start"]
  • 不要在构建中升级版本 为了降低复杂性、减少依赖、减小文件大小、节约构建时间,您应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。 如果基础镜像中的某个包过时了,但您不知道具体是哪一个包,您应该联系它的维护者。如果您确定某个特定的包,比如foo需要升级,使用apt-get install -y foo就行,该指令会自动升级foo包。 apt-get upgrade会使得镜像构建过程非常不稳定,在构建时不确定哪些包会被安装,此时可能会产生不一致的镜像。因此通常会删掉apt-get upgrade。 删掉apt-get upgrade后,Dockerfile如下: FROM ubuntuADD . /appRUN apt-get updateRUN apt-get install -y nodejsRUN cd /app && npm installCMD npm start
  • 设置默认的环境变量、映射端口和数据库逻辑卷 运行Docker容器时很可能需要一些环境变量。在Dockerfile设置默认的环境变量是一种很好的方式。另外,应该在Dockerfile中设置映射端口和数据库逻辑卷。示例如下: FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENTRYPOINT ["./entrypoint.sh"] CMD ["start"] ENV指令指定的环境变量在容器中可以使用。如果您只是需要指定构建镜像时的变量,您可以使用ARG指令。
  • 使用EXPOSE暴露端口 EXPOSE指令用于指定容器将要监听的端口。因此,您应该为您的应用程序使用常见的端口。例如,提供Apache web服务的镜像应该使用EXPOSE 80,而提供MongoDB服务的镜像使用EXPOSE 27017。 对于外部访问,用户可以在执行docker run时使用一个标志来指示如何将指定的端口映射到所选择的端口。 FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV APP_PORT=3000EXPOSE $APP_PORTENTRYPOINT ["./entrypoint.sh"] CMD ["start"]
  • 设置WORKDIR和CMD WORKDIR指令可以设置默认目录,也就是运行RUN / CMD / ENTRYPOINT指令的地方。 CMD指令可以设置容器创建时执行的默认命令。另外,您应该将命令写在一个数组中,数组中每个元素为命令的每个单词。 FROM node:7-alpineWORKDIR /app ADD . /app RUN npm installCMD ["npm", "start"]
  • 将变化频率一样的RUN指令合一 Docker镜像是分层的,类似于洋葱,它们都有很多层,为了修改内层,则需要将外面的层都删掉。Docker镜像有如下特性: Dockerfile中的每个指令都会创建一个新的镜像层。 镜像层将被缓存和复用。 Dockerfile修改后,复制的文件变化了或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效。 某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效。 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker容器中不可见。 将变化频率一样的指令合并在一起,目的是为了更好的将镜像分层,避免带来不必要的成本。如本例中将node.js安装与npm模块安装放在一起的话,则每次修改源代码,都需要重新安装node.js,这显然不合适。 FROM ubuntuADD . /appRUN apt-get update \ && apt-get install -y nodejs \ && cd /app \ && npm installCMD npm start 因此,正确的写法是这样的: FROM ubuntuRUN apt-get update && apt-get install -y nodejs ADD . /appRUN cd /app && npm installCMD npm start
  • 使用ENTRYPOINT(可选) ENTRYPOINT指令并不是必须的,因为它会增加复杂度。ENTRYPOINT是一个脚本,它会默认执行,并且将指定的命令作为其参数。它通常用于构建可执行的Docker镜像。 FROM node:7-alpineWORKDIR /app ADD . /app RUN npm installENTRYPOINT ["./entrypoint.sh"] CMD ["start"]
  • 一个容器只运行一个进程 从技术角度讲,Docker容器中可以运行多个进程,您可以将数据库、前端、后端、ssh等都运行在同一个Docker容器中。但是,这样跟未使用容器前没有太大区别,且这样容器的构建时间非常长(一处修改就要构建全部),镜像体积大,横向扩展时非常浪费资源(不同的应用需要运行的容器数并不相同)。 通常所说的容器化改造是对应用整体微服务进行架构改造,改造后,再容器化。这样做可以带来如下好处: 单独扩展:拆分为微服务后,可单独增加或缩减每个微服务的实例数量。 提升开发速度:各微服务之间解耦,某个微服务的代码开发不影响其他微服务。 通过隔离确保安全:整体应用中,若存在安全漏洞,一旦被攻击,所有功能的权限都可能会被窃取。微服务架构中,若攻击了某个服务,只可获得该服务的访问权限,无法入侵其他服务。 提升稳定性:如果其中一个微服务崩溃,其他微服务还可以持续正常运行。 因此,上述企业门户网站可以进行如下改造,Web应用和MySQL运行在不同容器中。 MySQL运行在独立的镜像中,这样的好处就是,可以对它们分别进行修改,且不会牵一发而动全身。如下面这个例子所示,可以删除MySQL,只安装node.js。 FROM ubuntuADD . /appRUN apt-get update RUN apt-get upgrade -yRUN apt-get install -y nodejs RUN cd /app && npm installCMD npm start
  • 合理调整COPY与RUN的顺序 将变化最少的部分放在Dockerfile的前面,这样可以充分利用镜像缓存。 示例中,源代码会经常变化,则每次构建镜像时都需要重新安装NPM模块,这显然不是希望看到的。因此可以先拷贝package.json,然后安装NPM模块,最后才拷贝其余的源代码。这样的话,即使源代码变化,也不需要重新安装NPM模块。 FROM node:7-alpineWORKDIR /appCOPY package.json /app RUN npm install COPY . /appENTRYPOINT ["./entrypoint.sh"] CMD ["start"]
  • 添加HEALTHCHECK 运行容器时,可以指定--restart always选项。这样的话,容器崩溃时,docker daemon会重启容器。对于需要长时间运行的容器,这个选项非常有用。但是,如果容器的确在运行,但是不可用怎么办?使用HEALTHCHECK指令可以让Docker周期性的检查容器的健康状况。只需要指定一个命令,如果一切正常的话返回0,否则返回1。当请求失败时,curl --fail命令返回非0状态。示例如下: FROM node:7-alpine LABEL com.example.version="0.0.1-beta"ENV PROJECT_DIR=/app WORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV MEDIA_DIR=/media \ APP_PORT=3000VOLUME $MEDIA_DIR EXPOSE $APP_PORT HEALTHCHECK CMD curl --fail http://localhost:$APP_PORT || exit 1ENTRYPOINT ["./entrypoint.sh"] CMD ["start"]
  • 镜像迁移操作步骤 准备镜像仓库访问权限文件:auth.json。 新建一个auth.json文件,并按照格式修改,如果是匿名访问仓库,则不需要填写用户名、密码等信息。将文件放置在image-migrator所在目录下。 示例: { "quay.io/coreos": { }, "swr.cn-north-4.myhuaweicloud.com": { "username": "cn-north-4@RVHVMX******", "password": "cab4ceab4a1545***************", "insecure": true }} 详细的参数说明请参见“auth.json”文件。 准备镜像列表文件:images.json。 通过kubectl连接源集群。具体方法可参考使用kubectl连接集群。 执行镜像迁移config子命令,生成images.json文件。 您可以参考image-migrator config使用方法中的方法和示例,不指定命名空间,或者指定一个、多个命名空间来获取源集群应用中使用的镜像。 根据需求调整images.json文件内容,但要遵循“images.json”文件中所讲的八项要求。 镜像迁移。 您可以执行默认的./image-migrator-linux-amd64命令进行镜像迁移,也可以根据需要设置image-migrator的参数。 例如以下命令: ./image-migrator-linux-amd64 --workers=5 --auth=./auth.json --images=./images.json --namespace=test --registry=swr.cn-north-4.myhuaweicloud.com --retries=2 示例: $ ./image-migrator-linux-amd64 Start to generate images tasks, please wait ...Start to handle images tasks, please wait ...Images(38) migration finished, 0 images tasks failed, 0 tasks generate failed 结果查看。 上述命令执行完毕后,回显如下类似信息: Images(38) migration finished, 0 images tasks failed, 0 tasks generate failed 表示按照配置,成功将38个镜像迁移到SWR仓库中。
  • image-migrator config使用方法 image-migrator工具的config子命令可用于获取集群应用中使用的镜像,在工具所在目录下生成images.json。执行./image-migrator-linux-amd64 config -h命令可以查看config子命令的使用方法。 -k, --kubeconfig:指定kubectl的kubeConfig位置,默认是$HOME/.kube/config。kubeConfig文件:用于配置对Kubernetes集群的访问,KubeConfig文件中包含访问注册kubernetes集群所需要的认证凭据以及Endpoint(访问地址),详细介绍可参见Kubernetes文档。 -n, --namespaces:指定获取镜像的命名空间,多个命名空间用逗号分隔(如:ns1,ns2,ns3),默认是"",表示获取所有命名空间的镜像。 -t, --repo:指定目标仓库的地址(registry/namespace)。 $ ./image-migrator-linux-amd64 config -hgenerate images.jsonUsage: image-migrator config [flags]Flags: -h, --help help for config -k, --kubeconfig string The kubeconfig of k8s cluster's. Default is the $HOME/.kube/config. (default "/root/.kube/config") -n, --namespaces string Specify a namespace for information collection. If multiple namespaces are specified, separate them with commas (,), such as ns1,ns2. default("") is all namespaces -t, --repo string target repo,such as swr.cn-north-4.myhuaweicloud.com/test 示例如下: 指定一个命名空间 ./image-migrator-linux-amd64 config -n default -t swr.cn-north-4.myhuaweicloud.com/test 指定多个命名空间 ./image-migrator-linux-amd64 config -n default,kube-system -t swr.cn-north-4.myhuaweicloud.com/test 不指定命名空间(表示获取所有命名空间的镜像) ./image-migrator-linux-amd64 config -t swr.cn-north-4.myhuaweicloud.com/test
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全