如何向 Docker 容器传递参数

我们在运行 docker 镜像时希望能用下面的命令向容器传递命令行参数

docker run <image-name> <command> arg1 arg2
docker run <image-name> arg1 arg2

其实只有第一种形式,紧随镜像名后那个总是一个命令,其后才是参数。如果要向 docker 容器传递参数时,Dockerfile 该如何写,这就有必要稍稍了解一下 Dockerfile 中  CMD 和 ENTRYPOINT 这两个指令,并且它们有 exec 和 shell 两种格式的写法。详情请见上篇 Dockerfile 中命令的两种书写方式的区别

对于一个 docker 镜像,我们可以这么来理解  ENTRYPOINT 与 CMD 的关系

  1. 如果没有定义 ENTRYPOINT, CMD 将作为它的 ENTRYPOINT
  2. 定义了 ENTRYPOINT 的话,CMD 只为 ENTRYPOINT 提供参数
  3. CMD 可由 docker run <image> 后的命令覆盖,同时覆盖参数

对于 #1 和  #2 更精致的理解是容器运行的最终入口由 ENTRYPOINT 和实际的 CMD 拼接而成。ENTRYPOINT 和 CMD 需转换为实际镜像中的 exec 格式来拼接,合并后的第一个元素是命令,其余是它的参数。 阅读全文 >>

Dockerfile 中命令的两种书写方式的区别

最早的初衷是要研究一下运行 Docker 容器时如何向其传递参数,却冷不防掉入了另一个深渊,不得不关心起 Dockerfile 中命令(包括 RUN, CMD 和 ENTRYPOINT) 的两种不同写法上的区别。

所以呢,先要稍稍了解一下 Dockerfile 中 RUN, CMD, ENTRYPOINT 这三个指令

  1. RUN 执行命令并创建新的镜像层,常用于安装软件包。可以多个,为避免创建过多的镜像层,我们尽量把命令合在一起,用分号或 &&。它与容器运行期无关。
  2. CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够在启动容器时被覆盖。多个 CMD 只有最后一个是有效的
  3. ENTRYPOINT 配置容器启动时运行的命令。多个  ENTRYPOINT 也是只有最后一个有效

关于以上三个命令的区别,这儿有篇文章讲得很清楚 RUN vs CMD vs ENTRYPOINT - 每天5分钟玩转 Docker 容器技术(17),此处也照搬了些文字。

RUN, CMD 和  ENTRYPOINT 都支持两种写法,即 exec 和 shell 格式,见 Dockerfile reference #ENTRYPOINT 对这两种方式的解释。RUN 只影响如何构建镜像,所以镜像中不保留 RUN 命令。CMD 和 ENTRYPOINT 都可以在运行容器时执行命令,这里不讲述它们间的区别,而要说的是它们所支持的 exec 和  shell 两种格式的写法。此篇以 ENTRYPOINT 为例说明两种格式的区别,CMD 类似。 阅读全文 >>

AWS SQS 队列的 DLQ 设置与行为

和 Lambda 类似,AWS 的  SQS 队列也提供了 DLQ(Dead Letter Queue) 来支持重试功能,可以设定某一个消息在接收多次重新变得可见后进入到另一个 SQS 队列中。比如说队列 user-id-queue,设定了它的 Redrive Policy 为三次接收后转入到另一个 SQS 队列 user-id-dlq, 就会显示为

Maximum Receives 3
Dead Letter Queue arn:aws:sqs:us-east-1:<account_id>:user-id-dlq

在运用 SQS 的 DLQ 之前首先要理解 SQS 中消息的几个概念
  1. Message Available:  SQS 客户端可以获取到的消息, 即 Visible Messages
  2. Messages in Flight: 消息被 SQS 收取了之后,由 Available 转为 In Flight, 该状态的消息不能被客户端接收到
  3. Visibility Timeout:  消息停留在 In Flight 状态的时间, 如果在 Timeout 之前未删除这个消息,该消息重新变为 Available 状态

我们可以设置 SQS 队列的默认 Visibility Timeout 大小,也可以在代码中收取消息时指定这个值。

所以我们能够在集群环境中应用 SQS 的这个特性让多个节点同时监听单个 SQS 队列,基本上保证每个节点处理各自不同的消息。有一种例外就是:假设我们设置了 Visibility Timeout 是 30 秒,客户端 1 获取到消息后,消息变为 In Flight 状态,但 30 秒后仍然在处理过程中,此时消息回到Available 状态,客户端 2 也能获取到该消息,这也会造成单条消息的重复处理。解决的办法之一是适当延长 Visibility Timeout 的时间,给予第一个客户端更充分的处理时间。 阅读全文 >>

unmi.cc 博客大事记

写下此篇流水纯粹是为了重拾那些零星的记忆,只能建立起一个模糊的脉络,找不回具体的时间点了,现在也是试着能否从某些日志里寻回些线索来。本篇日志最早创建于 2014 年 2 月份,中间偶有修改,却一直在草稿箱里静静的躺着。终于又时隔多年首次放出一篇非技术文出来。

1. 开始的开始,2001 年工作起,进入一个几乎完全陌生的程序世界。为了奋力从大海洋中汲取营养,大跃进的方式学习,并坚持在笔记本上面现在看来像是抄写一样的记笔记,不觉几年功夫,工工整整,满满的记载了四五本笔记本。还有看到那些好的东西也爱打印下来,其实打印出来的东西与它在网络上是一回事,没完整看的还是没看完,写下来了可不一样。这样记笔记的习惯其实也是工作之后的事情,上学期间最爱在课本上记东西。

2. 到后来是网络的盛行,也是信息量的爆炸的时代,再系统再全的书籍也无法与 Google 相比了。所以大概是 2005 年想到了在 QQ 空间里记了三五篇,一块娱乐之地上记录这些东西格调十分不搭。

3. 找到了第一个真正意义上的 BSP,那就是 blogcn.com,它现在完全变样了。QQ 上的几篇只需要复制到编辑框保存就行,那应该是  2006 年的事情。blogcn 是个综合性的 BSP,不好玩,代码高亮用工具保存成的带样式的 HTML 代码,好像也只在这里折腾了一年多时光,到  2007 吧,继续寻租。 阅读全文 >>

Groovy 的多重赋值和方法的多返回值

追溯到刚开始学习 Groovy 还是在  2008 年,距今 2018 年有九年半余,曾记下几篇 Groovy 的日志。那时学习 Groovy 并无明确的目的,只因它是脚本语言, 可用来快速验证 Java API。曾经 BeanShell 芸花一现,JRuby 和 Jython 总是别人家的语言照搬而来的。而 Scala,Nashorn(jjs), JShell 更是后来的事,唯有 Groovy 写起来很亲切,完全不懂 Groovy 都没关系,直接上 Java。

现如今之所以重新勾搭上了 Groovy 是因为它仍然坚挺着,在 SoupUI(ReadyAPI) 和 Jenkins 中获得了重视,倒不是因为 Gradle。先前 Groovy 在 Spring 框架中的地位估计要被如今的 Kotlin 取而代之。

好了,回顾完后进入正题,关于 Groovy 如何进行多重赋值,以及延伸到方法返回多个值的情形。这里所说的多重赋值不是指用连等号来同时赋为一个值,

def a = b = c = 100   //不是说的这个

而是指同时对多个变量一步到位的赋成不同的值,要实现这个必须用到 List 类型。看下面一个基本例子(GroovyConsole) 阅读全文 >>