0%

用 Docker for Mac 已经很久了,用它跑本地开发环境可以说是非常方便。

但是 Docker for Mac 自诞生以来就一直有一个问题,那就是在宿主机上看不到 docker0,无法访问容器所在的网络,也就是说不能 ping 通 Docker 给 Container 所分配的 IP 地址。关于这个问题,官方文档有描述:Known limitations, use cases, and workarounds

对于 docker run 启动的 Container 来说,通常会通过 -p 参数映射相应的服务端口,一般不会遇到要直接访问容器 IP 的情况。

但是当我们在 docker 中运行多个微服务并想进行本地调试的时候,在 Mac 上却没法实现。(--net=host 仅在 Linux 系统上有效,我在这个上边被坑了两三个小时 [捂脸] )

┌───────────────────────────────────────────────────────────────┐
│                                                               │
│                          ┌──────────────────────────────┐     │
│     macOS                │ docker                       │     │
│                          │                              │     │
│                          │         ┌───────────────┐    │     │
│                          │         │    Eureka     │    │     │
│    ┌───────────────┐     │ ┌──────▶│172.22.0.2:8761│    │     │
│    │     Order     │     │ │       └───────────────┘    │     │
│    │127.0.0.1:8989 │─────┼─┘               ▲            │     │
│    └───────────────┘     │                 │            │     │
│            │             │         ┌───────────────┐    │     │
│            │             │         │     User      │    │     │
│            └─────────────┼────────▶│172.22.0.3:8080│    │     │
│                          │         └───────────────┘    │     │
│                          │                              │     │
│                          └──────────────────────────────┘     │
│                                                               │
└───────────────────────────────────────────────────────────────┘  

例如上图中,Eureka Server 和 User 服务均存在于容器中,本地调试 Order 服务。Order 需要调用 User,但是我们在本机上是访问不到 172.22.0.3:8080 的。

阅读全文 »

前言

快与好,实际上是我一直比较矛盾的。虽我不是处女座,但是也有一些些强迫症,比较追求完美。至于速度,我是个急性子,快是没的说的,这点从我的网名“逐风”也可以感觉出来。

但一直不知道如何平衡。

前两天看到阮一峰《科技爱好者周刊》上的刊首语,使我陷入了思考。

一件事“做得好”比较好,还是“做得快”比较好?

鱼和熊掌不能得兼,你怎么选择:做得好,付出的代价可能是耗时长、成本高;做得快,意味着完成度低、不是精品。

他推荐了一篇文章,那篇文章观点简单来说就是

做得快不仅可以让你在单位时间内完成更多的工作,而且 因为你工作得很快,所以你会觉得成本低,从而倾向于做更多。

写一篇博客,你可能需要两天。这是很高的时间成本,你觉得太贵了,于是你很少写。但是,做好一件事的唯一方法,就是多做这件事。做得越快,这件事的时间成本就越低,你会愿意做得更多。

人们总是倾向于,多消费时间成本低的东西。网站很快,就会多访问;搜索很快,就会多搜索;文章很容易读懂,就会多读几篇。做得快的核心,就是要让时间成本降下来,从而多做。

文章的原文是英文的:Speed matters: Why working quickly is more important than it seems

就决定自己试着翻译一下。

一方面抱着为自己解惑吧,另一方面最近也一直在学习英语,当做练习了。(第一次翻译,轻拍~~)

阅读全文 »

Golang

前一段在关闭 IDEA 打开 GoLand 之后,深深感慨了一声

丝滑般享受

但没想到声音刚落,就发现又掉坑里了 /(ㄒoㄒ)/~~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"foo": "Hello, World!",
"bar": {
"b": {
"go": "1"
},
"a": {
"go": "2"
},
"c": {
"go": "3"
}
}
}

有如上一段 JSON,在程序中需要将其转为一个结构体以方便读取里边的数据,struct 的定义大概如下:

1
2
3
4
5
6
type Foobar struct {
Foo string `json:"foo"`
Bar map[string]struct {
Go string `json:"go"`
} `json:"bar"`
}

现在有这么两个需求:

  1. 按顺序输出 bar.abar.bbar.c
  2. 按顺序输出 bar.bbar.abar.c

如果是用 Java 的小伙伴,肯定已经想到 SortedMap(用的比较多是 TreeMap)和 LinkedHashMap 了,前者是可以按 key 进行排序的,后者则可以保持键值对的插入顺序,而这两者都是 JDK 自带的,任何一个 Javaer 应该都使用过。

但是在 Go 语言的“简约设计”面前,这些都是不存在的——Go 只提供了最基础的 hash map。

并且,在借助 range 关键字对 Go 的 map 进行遍历访问的时候,会对 map 的 key 的顺序做随机化处理,也就是说即使是同一个 map 在同一个程序里进行两次相同的遍历,前后两轮访问 key 的顺序也是随机化的。(可以在这里验证:https://play.golang.org/p/s3Mj4gNfi4g )

在 Go 的官方 blog 的文章 Go maps in action 也确定了该现象确实存在,并且是有意而为之,

When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Since the release of Go 1.0, the runtime has randomized map iteration order.

那么在 Go 里边实现以上需求就得绕些路了。

阅读全文 »

为什么需要动态路由?

之前说过 Gateway 的路由配置,常用的有两种方式:

  • Fluent API
  • 配置文件

这两者之间因为配置文件的方式修改起来比较灵活,然后通过 Stream+Bus 的方式刷新路由配置,所以大家使用的比较多。

但是如果我们在网关层需要类似于 Canary Release(金丝雀发布,也称灰度发布)这样的能力的话,那么以上两种配置路由的方式就都显得太笨拙了。

矿井中的金丝雀
17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为 “瓦斯检测指标”,以便在危险状况下紧急撤离。

阅读全文 »

Spring Cloud Gateway(以下简称 SCG)做为网关服务,是其他各服务对外中转站,通过 SCG 进行请求转发。
在请求到达真正的微服务之前,我们可以在这里做一些预处理,比如:来源合法性检测,权限校验,反爬虫之类…

因为业务需要,我们的服务的请求参数都是经过加密的。
之前是在各个微服务的拦截器里对来解密验证的,现在既然有了网关,自然而然想把这一步骤放到网关层来统一解决。

Arch

如果是使用普通的 Web 编程中(比如用 Zuul),这本就是一个 pre filter 的事儿,把之前 Interceptor 中代码搬过来稍微改改就 OK 了。
不过因为使用的 SCG,它基于 Spring 5 的 WebFlux,即 Reactor 编程,要读取 Request Body 中的请求参数就没那么容易了。

本篇内容涉及 WebFlux 的响应式编程及 SCG 自定义全局过滤器,如果对这两者不了解的话,可以先看看相关的内容。
Reactive > Spring Cloud(十四):Spring Cloud Gateway(过滤器)

阅读全文 »

上个月最后一天的凌晨,Spring Cloud Alibaba 正式入驻了 Spring Cloud 官方孵化器,并在 maven 中央库发布了第一个版本。

目前 Spring Cloud Alibaba 还只能算是预览版吧,里边的坑肯定不少,不过我还是决定试试,看看 Alibaba 到底靠谱不靠谱。

Nacos for Spring Cloud

阅读全文 »

有一段时间没有用 Go 了,今天去社区一看,发现了 Go Modules 已经面世了。

Go 的包管理是一直是为人诟病之处,从 Go 1.5 引入的 vendor 机制,到准官方工具 dep,目前为止还没一个简便的解决方案。

不过现在 go modules 随着 golang1.11 的发布而和我们见面了,这是官方提倡的新的包管理,乃至项目管理机制,可以不再需要 GOPATH 的存在。

Go Module

欣喜之余,赶紧上手来试一下吧~

阅读全文 »

作为一位开发人员,经常要编辑各种各样的文件。而在 Mac 系统中,文件名的后缀也是五花八门的,如果系统识别出这是一个文本文件,右键菜单的「Open with」可能还有点用,如果识别不出来,那么手动选择应用程序就比较麻烦了:

open with none

我经常使用 Sublime Text 来编辑,这时候就有点怀念 Windows 了,希望也能在右键菜单里增加一个「Open in Sublime Text」的选项,这样每次就不用总是去 Applications 一个个去选了。

其实 Mac 系统的 AutoMator 是可以实现这个功能的。

阅读全文 »