Skip to content

Commit

Permalink
fix: typo
Browse files Browse the repository at this point in the history
  • Loading branch information
mzlogin committed Jan 3, 2022
1 parent be8bf5a commit df3f660
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 6 deletions.
2 changes: 1 addition & 1 deletion exploration/projects/microservice_arch_springcloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Fenix's Bookstore 采用基于 Spring Cloud 微服务架构,微服务部分主
- **服务发现**:默认采用[Netflix Eureka](https://github.com/Netflix/eureka),亦可使用[Spring Cloud Consul](https://spring.io/projects/spring-cloud-consul)[Spring Cloud ZooKeeper](https://spring.io/projects/spring-cloud-zookeeper)[Etcd](https://github.com/etcd-io/etcd)等代替。
- **服务网关**:默认采用[Netflix Zuul](https://github.com/Netflix/zuul),亦可使用[Spring Cloud Gateway](https://spring.io/projects/spring-cloud-gateway)代替。
- **服务治理**:默认采用[Netflix Hystrix](https://github.com/Netflix/Hystrix),亦可使用[Sentinel](https://github.com/alibaba/Sentinel)[Resilience4j](https://github.com/resilience4j/resilience4j)代替。
- **进程内负载均衡**:默认采用[Netfilix Ribbon](https://github.com/Netflix/ribbon),亦可使用[Spring Cloud Loadbalancer](https://spring.io/guides/gs/spring-cloud-loadbalancer/)代替。
- **进程内负载均衡**:默认采用[Netflix Ribbon](https://github.com/Netflix/ribbon),亦可使用[Spring Cloud Loadbalancer](https://spring.io/guides/gs/spring-cloud-loadbalancer/)代替。
- **声明式 HTTP 客户端**:默认采用[Spring Cloud OpenFeign](https://spring.io/projects/spring-cloud-openfeign)。声明式的 HTTP 客户端其实没有找替代品的必要性,如果需要,可考虑[Retrofit](https://square.github.io/retrofit/),或者使用 RestTemplete 乃至于更底层的[OkHTTP](https://square.github.io/okhttp/)[HTTPClient](https://hc.apache.org/httpcomponents-client-ga/)以命令式编程来访问,多写一些代码而已了。

尽管 Netflix 套件的使用人数很多,但考虑到 Spring Cloud Netflix 已进入维护模式,笔者均列出了上述组件的代替品。这些组件几乎都是声明式的,这确保了它们的替代成本相当低廉,只需要更换注解,修改配置,无需改动代码。你在阅读源码时也会发现,三个“platform”开头的服务,基本上没有任何实际代码的存在。
Expand Down
4 changes: 2 additions & 2 deletions immutable-infrastructure/mesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ A service mesh is a dedicated infrastructure layer for handling service-to-servi

:::

容器编排系统管理的最细粒度只能到达容器层次,在此粒度之下的技术细节,仍然只能依赖程序员自己来管理,编排系统很难提供有效的支持。2016 年,原 Twitter 基础设施工程师 William Morgan 和 Oliver Gould 在 GitHub 上发布了第一代的服务网格产品 Linkerd,并在很短的时间内围绕着 Linkered 组建了 Buoyant 公司,担任 CEO 的 Willian Morgan 发表的文章《[What's A Service Mesh? And Why Do I Need One?](https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/)》中首次正式地定义了“服务网格”(Service Mesh)一词,此后,服务网格作为一种新兴通信理念开始迅速传播,越来越频繁地出现在各个公司以及技术社区的视野中。之所以服务网格能够获得企业与社区的重视,就是因为它很好地弥补了容器编排系统对分布式应用细粒度管控能力高不足的缺憾。
容器编排系统管理的最细粒度只能到达容器层次,在此粒度之下的技术细节,仍然只能依赖程序员自己来管理,编排系统很难提供有效的支持。2016 年,原 Twitter 基础设施工程师 William Morgan 和 Oliver Gould 在 GitHub 上发布了第一代的服务网格产品 Linkerd,并在很短的时间内围绕着 Linkerd 组建了 Buoyant 公司,担任 CEO 的 William Morgan 发表的文章《[What's A Service Mesh? And Why Do I Need One?](https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/)》中首次正式地定义了“服务网格”(Service Mesh)一词,此后,服务网格作为一种新兴通信理念开始迅速传播,越来越频繁地出现在各个公司以及技术社区的视野中。之所以服务网格能够获得企业与社区的重视,就是因为它很好地弥补了容器编排系统对分布式应用细粒度管控能力高不足的缺憾。

服务网格并不是什么神秘难以理解的黑科技,它只是一种处理程序间通信的基础设施,典型的存在形式是部署在应用旁边,一对一为应用提供服务的边车代理,及管理这些边车代理的控制程序。“[边车](https://en.wikipedia.org/wiki/Sidecar)”(Sidecar)本来就是一种常见的[容器设计模式](https://www.usenix.org/sites/default/files/conference/protected-files/hotcloud16_slides_burns.pdf),用来形容外挂在容器身上的辅助程序。早在容器盛行以前,边车代理就已有了成功的应用案例,譬如 2014 年开始的[Netflix Prana 项目](https://github.com/Netflix/Prana),由于 Netfilix OSS 套件是用 Java 语言开发的,为了让非 JVM 语言的微服务,譬如以 Python、Node.js 编写的程序也同样能接入 Netfilix OSS 生态,享受到 Eureka、Ribbon、Hystrix 等框架的支持,Netflix 建立了 Prana 项目,它的作用是为每个服务都提供一个专门的 HTTP Endpoint,使得非 JVM 语言的程序能通过访问该 Endpoint 来获取系统中所有服务的实例、相关路由节点、系统配置参数等在 Netfilix 组件中管理的信息。
服务网格并不是什么神秘难以理解的黑科技,它只是一种处理程序间通信的基础设施,典型的存在形式是部署在应用旁边,一对一为应用提供服务的边车代理,及管理这些边车代理的控制程序。“[边车](https://en.wikipedia.org/wiki/Sidecar)”(Sidecar)本来就是一种常见的[容器设计模式](https://www.usenix.org/sites/default/files/conference/protected-files/hotcloud16_slides_burns.pdf),用来形容外挂在容器身上的辅助程序。早在容器盛行以前,边车代理就已有了成功的应用案例,譬如 2014 年开始的[Netflix Prana 项目](https://github.com/Netflix/Prana),由于 Netflix OSS 套件是用 Java 语言开发的,为了让非 JVM 语言的微服务,譬如以 Python、Node.js 编写的程序也同样能接入 Netflix OSS 生态,享受到 Eureka、Ribbon、Hystrix 等框架的支持,Netflix 建立了 Prana 项目,它的作用是为每个服务都提供一个专门的 HTTP Endpoint,使得非 JVM 语言的程序能通过访问该 Endpoint 来获取系统中所有服务的实例、相关路由节点、系统配置参数等在 Netflix 组件中管理的信息。

Netflix Prana 的代理需要由应用程序主动去访问才能发挥作用,但在容器的刻意支持下,服务网格无需应用程序的任何配合,就能强制性地对应用通信进行管理。它使用了类似网络攻击里中间人流量劫持的手段,完全透明(既无需程序主动访问,也不会被程序感知到)地接管掉容器与外界的通信,将管理的粒度从容器级别细化到了每个单独的远程服务级别,使得基础设施干涉应用程序、介入程序行为的能力大为增强。如此一来,云原生希望用基础设施接管应用程序非功能性需求的目标就能更进一步,从容器粒度延伸到远程访问,分布式系统继容器和容器编排之后,又发掘到另一块更广袤的舞台空间。
2 changes: 1 addition & 1 deletion immutable-infrastructure/mesh/communication.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

Kubernetes 为它管理的工作负载提供了工业级的韧性与弹性,也为每个处于运行状态的 Pod 维护了相互连通的虚拟化网络。不过,程序之间的通信不同于简单地在网络上拷贝数据,具备可连通的网络环境仅仅是程序间能够可靠通信的必要但非充分的条件,作为一名经历过 SOA、微服务、云原生洗礼的分布式程序员,你必定已深谙路由、容错、限流、加密、认证、授权、跟踪、度量等问题在分布式系统中都是无可回避的。

在本书开篇的“[远程服务调用](/architect-perspective/general-architecture/api-style/rpc.html#通信的成本)”一节里,笔者曾以“通信的成本”为题,讲述了三十多年计算机科学家们对“远程服务调用有否可能实现为透明通信”的一场声势浩大的争论。今天,服务网格的诞生在某种意义上可以说便是当年透明通信的重生,服务网格试图以容器、虚拟化网络、边车代理等技术所构筑的新一代通信基础设施为武器,重新对已盖棺定论三十多年的程序间远程通信不是透明的原则发起冲击。今天,这场关于通信的变革仍然在酝酿发展当中,最后到底会是成功的逆袭,抑或是另一场失败,笔者不敢妄言定论,但是作为程序通信发展历史的一名见证者,笔者丝毫不吝对服务网格投去最高的期许与最深的祝愿。
在本书开篇的“[远程服务调用](/architect-perspective/general-architecture/api-style/rpc.html#通信的成本)”一节里,笔者曾以“通信的成本”为题,讲述了三十多年计算机科学家们对“远程服务调用是否可能实现为透明通信”的一场声势浩大的争论。今天,服务网格的诞生在某种意义上可以说便是当年透明通信的重生,服务网格试图以容器、虚拟化网络、边车代理等技术所构筑的新一代通信基础设施为武器,重新对已盖棺定论三十多年的程序间远程通信不是透明的原则发起冲击。今天,这场关于通信的变革仍然在酝酿发展当中,最后到底会是成功的逆袭,抑或是另一场失败,笔者不敢妄言定论,但是作为程序通信发展历史的一名见证者,笔者丝毫不吝对服务网格投去最高的期许与最深的祝愿。

## 通信的成本

Expand Down
4 changes: 2 additions & 2 deletions immutable-infrastructure/schedule/hardware-schedule.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Kubernetes 给处理器资源设定的默认计量单位是“逻辑处理器的

设定资源计量单位的目的是为了管理员能够限制某个 Pod 对资源的过度占用,避免影响到其他 Pod 的正常运行。Pod 是由一到多个容器所组成,资源最终是交由 Pod 的各个容器去使用,所以资源的需求是设定在容器上的,具体的配置是 Pod 的`spec.containers[].resource.limits/requests.cpu/memory`字段。但是对资源需求的配额则不是针对容器的,而是针对 Pod 整体,Pod 的资源配额无需手动设置,它就是它包含的每个容器资源需求的累加值。

为容器设定最大的资源配额的做法从 cgroups 诞生后已经屡见不鲜,但你是否注意到 Kubernetes 给出的配置中有`limits``requests`两个设置项?这两者的区别其实很简单:`request`是给调度器用的,Kubernetes 选择哪个节点运行 Pod,只会根据`requests`的值来进行决策;`limits`才是给 cgroups 用的,Kubernetes 在向 cgroups 的传递资源配额时,会按照`limits`的值来进行设置。
为容器设定最大的资源配额的做法从 cgroups 诞生后已经屡见不鲜,但你是否注意到 Kubernetes 给出的配置中有`limits``requests`两个设置项?这两者的区别其实很简单:`requests`是给调度器用的,Kubernetes 选择哪个节点运行 Pod,只会根据`requests`的值来进行决策;`limits`才是给 cgroups 用的,Kubernetes 在向 cgroups 的传递资源配额时,会按照`limits`的值来进行设置。

Kubernetes 采用这样的设计完全是基于“心理学”的原因,是因为 Google 根据 Borg 和 Omega 系统长期运行的实践经验,总结出了一条经验法则:用户提交工作负载时设置的资源配额,并不是容器调度一定必须严格遵守的值,因为根据实际经验,大多数的工作负载运行过程中真正使用到的资源,其实都远小于它所请求的资源配额。

Expand Down Expand Up @@ -110,7 +110,7 @@ Kubernetes 的驱逐与编程语言中垃圾收集器另一个不同之处是垃
1. **运行**:从集群所有节点中找出一批剩余资源可以满足该 Pod 运行的节点。为此,Kubernetes 调度器设计了一组名为 Predicate 的筛选算法。
2. **恰当**:从符合运行要求的节点中找出一个最适合的节点完成调度。为此,Kubernetes 调度器设计了一组名为 Priority 的评价算法。

这两个算法的具体内容稍后笔者会详细解释,这里要先说明白一点:在几个、十几个节点的集群里进行调度,调度器怎么实现都不会太困难,但是对于数千个乃至更多节点的大规模集群,要实现高效的调度就绝不简单。请你想象一下,若一个由数千节点组成的集群,每次 Pod 的创建都必须依据各节点的实时资源状态来确定调度的目标节点,然而各节点的资源是随着程序运行无时无刻都在变动的,资源状况只有它本身才清楚,如果每次调度都要发生数千次的远程访问来获取这些信息的话,那压力与耗时都难压降下来。结果不仅会令调度器成为集群管理的性能瓶颈,还会出现因耗时过长,某些节点上资源状况已发生变化,调度器的资源信息过时而导致调度结果不准确的等问题
这两个算法的具体内容稍后笔者会详细解释,这里要先说明白一点:在几个、十几个节点的集群里进行调度,调度器怎么实现都不会太困难,但是对于数千个乃至更多节点的大规模集群,要实现高效的调度就绝不简单。请你想象一下,若一个由数千节点组成的集群,每次 Pod 的创建都必须依据各节点的实时资源状态来确定调度的目标节点,然而各节点的资源是随着程序运行无时无刻都在变动的,资源状况只有它本身才清楚,如果每次调度都要发生数千次的远程访问来获取这些信息的话,那压力与耗时都难以降下来。结果不仅会令调度器成为集群管理的性能瓶颈,还会出现因耗时过长,某些节点上资源状况已发生变化,调度器的资源信息过时而导致调度结果不准确等问题

:::quote Scheduler

Expand Down

0 comments on commit df3f660

Please sign in to comment.