TOP

新一代的微服务架构 Service Mesh(一)
2020-06-24 18:08:49 】 浏览:70次 本网站的内容取自网络,仅供学习参考之用,绝无侵犯任何人知识产权之意。如有侵犯请您及时与本人取得联系,万分感谢。
Tags:新一代 服务 架构 Service Mesh

新一代的微服务架构 Service Mesh

博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服务架构 Service Mesh

由于最近在工作中在做 Service Mesh 的落地项目,有非常多的感触,所以想写一篇文章来分享这个「新一代的微服务架构 Service Mesh」。

笔者会从以下顺序开始分享:

  • Part 1 从「单体应用架构」到「微服务架构」开始说起
  • Part 2 从「Docker」到 「K8s」
  • Part 3 从「边车模式」到「服务网格」
  • Part 4 用「Istio Demo」来讲一个实际的应用场景

首先会从 「单体应用架构」 演进到 「微服务架构」 产生的问题开始说起,到自己作为开发人员感触最深的痛点。

然后简单介绍以下今天的主角 Istio 的服务编排环境 Kubernetes

最后从 Sidecar 这种设计,说到 Service Mesh,最后到我们的主角 Istio

到正式的主角之前的铺垫会比较多,这是为了让大多数开发者都能理解。

本文大部分内容都整理自笔者的学习资料加上自己的一些总结和体会,大家最后可以从文末找到他们。

Part 1「单体应用架构」到「微服务架构」开始说起

1.1 单体应用架构与微服务架构对比

「单体」「分布式」演进(也就是微服务化)的原因我相信大家都很了解了。

因为业务量越来越大,我们需要多台机器才能应对大规模的应用,所以需要垂直或者水平拆分业务系统,让其变成一个分布式的架构

从上面的表格我们可以看到,分布式系统虽然有一些优势,但也存在一些问题。

  • 架构设计变得复杂。
  • 部署单个服务会比较快,但是如果一次部署需要多个服务,流程会变得复杂。
  • 系统的吞吐量会变大,但是响应时间会变长。
  • 运维复杂度会因为服务变多而变得很复杂。
  • 架构复杂导致学习曲线变大。
  • 测试和查错的复杂度增大。
  • 技术多元化,公司中可能会有多个技术栈,这会带来维护和运维的复杂度。
  • 管理分布式系统中的服务和调度变得困难和复杂。

作为业务开发人员最直观的感受

  • 接口为什么这么慢,明明只依赖了一个服务。我需要更新我的服务,但是哪些服务依赖了我的服务,这次更新会对哪些服务造成影响。
  • 我需要在代码框架层编写客户端接入监控、日志、链路追踪、告警、健康检查等各种各样非业务相关的代码
  • 测试很不方便,测试一个服务需要所有依赖的服务,测试环境资源紧张。
  • ...

1.2 微服务架构的痛点和需要解决的问题

总结来说,微服务架构有这些痛点和需要解决的问题:

  • 服务多,服务之间的依赖难以管理。
  • 服务之间的版本管理,不同版本的服务可能会有兼容性的问题。
  • 需要对整体架构监控,快速发现问题。
  • 资源调度管理。
  • 需要做流量控制。负载均衡、服务路由、熔断、降级、限流、灰度发布等流量相关的控制。

图片引用自 《左耳听风 - 分布式系统技术栈》

针对这么多的需要去解决和处理的问题。

引出了我们今天的主角 Istio

在介绍我们今天的主角 Istio 之前,先简单介绍一下它的服务编排环境 Kubernetes。通过 Docker 以及其衍生出来的 Kubernetes 之类的软件或解决方案,大大地降低了做上面很多事情的门槛。

Part 2「Docker」到 「K8s」

2.1 Docker 容器的本质

Docker 相信大家都非常了解了,所以这里我就从 Docker 过度讲到 k8s

Docker 容器这个听起来玄而又玄的概念,实际上是在创建容器进程时,指定了这个进程所需要启用的一组 Namespace 参数。这样,容器就只能“看”到当前 Namespace 所限定的资源、文件、设备、状态,或者配置。而对于宿主机以及其他不相关的程序,它就完全看不到了。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

我们知道,在 Linux 系统中创建线程的系统调用是 clone(),就像这样。而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数。这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100

所以说,容器,其实是一种特殊的进程而已。

感兴趣的同学可以阅读 《自己动手写 Docker》 和尝试一下书中的代码。

2.2 K8s 最小调度单位 Pod

我花了很多精力去学习 Linux 容器的原理、理解了 Docker 容器的本质,终于, Namespace 做隔离, Cgroups 做限制, rootfs 做文件系统” 这样的“三句箴言”可以朗朗上口了。

为什么 Kubernetes 又突然搞出一个 Pod 来呢?

这里提一个概念: Pod, 是 Kubernetes 项目中最小的 API 对象。如果换一个更专业的说法,我们可以这样描述: PodKubernetes 项目的原子调度单位。

这里通过一个实际的例子来说明:

我们通过 pstree 查看操作系统中运行的进程,进程并不是“孤苦伶仃”地独自运行的,而是以进程组的方式,“有原则地”组织在一起。

比如,这里有一个叫作 rsyslogd 的程序,它负责的是 Linux 操作系统里的日志处理。可以看到, rsyslogd 的主程序 main, 和它要用到的内核日志模块 imklog 等,同属于 1632 进程组。这些进程相互协作,共同完成 rsyslogd 程序的职责。

如果说 「Docker 容器」的其实就是一个「特殊的进程」。

那么「K8s」就可以理解成操作系统。

Kubernetes 所做的,其实就是将 “进程组” 的概念映射到了容器技术中,并使其成为了这个云计算 “操作系统” 里的 “原子调度单位”

不过,相信此时你可能会有第二个疑问:

对于初学者来说,一般都是先学会了用 Docker 这种单容器的工具,才会开始接触 Pod。而如果 Pod 的设计只是出于调度上的考虑,那么 Kubernetes 项目似乎完全没有必要非得把 Pod 作为“原子调度单位”吧?

首先,关于 Pod 最重要的一个事实是:它只是一个逻辑概念

具体的说: Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume

那这么来看的话,一个有 AB 两个容器的 Pod,不就是等同于一个容器(容器 A)共享另外一个容器(容器 B)的网络和 Volume ?这好像通过 docker run --net --volumes-from 这样的命令就能实现,就像这样。

但是,你有没有考虑过,如果真这样做的话,容器 B 就必须比容器 A 先启动,这样一个 Pod 里的多个容器就不是对等关系,而是拓扑关系了。

所以,在 Kubernetes 项目里, Pod 的实现需要使用一个中间容器,在这个 Pod 中,中间容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 中间容器关联在一起。

图片引用自 《Service Mesh 实战:用 Istio 软负载实现服务网格 3.1.3 Pause 容器》

图片引用自 《深入剖析Kubernetes - 为什么我们需要 Pod》

如上图所示,这个 Pod 里有两个用户容器 AB,还有一个中间容器容器。很容易理解,在 Kubernetes 项目里,

请关注公众号获取更多资料


新一代的微服务架构 Service Mesh(一) https://www.cppentry.com/bencandy.php?fid=97&id=293263

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇java 在线网络考试系统源码 sprin.. 下一篇架构设计思想-微服务架构设计模式

评论

验 证 码:
表  情:
内  容: