首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微服务架构学习(一)之架构概览

微服务架构学习(一)之架构概览

作者头像
软件测试君
发布2021-05-06 15:16:48
5950
发布2021-05-06 15:16:48
举报
文章被收录于专栏:测试人生测试人生
一、微服务优点:
  • 微服务是继SOA后,最流行的服务架构风格之一。
  • 按照微服务对系统进行拆分后,每个服务的业务逻辑都更加简单、清晰。服务之间是松耦合的,模块之间的边界也更加清晰。
  • 微服务有效降低了软件项目的业务复杂程度,为小团队独立开发、持续交付和部署打下了良好的基础。

二、微服务缺点

  • 与传统的单一架构相比,微服务架构对团队的组织架构、技术水平、运维能力等方面,都提出了更高的要求。如果没有掌握得当的方法而生搬硬套,微服务架构只会会适得其反
  • 在国内外的技术社区中,比较推崇现有开源方案,如"Spring Cloud全家桶"或者阿里开源的"Dubbo"。使用开源框架省却了造轮子的过程,但也降低了我们学习、思考的欲望。
  • 已有的微服务资料过于重视微服务的开发,忽略了微服务赖以生存的生态系统:工具链、自动化运维。可以说,离开了这两点的支持,微服务架构将难以落地。

三、需要掌握技术

  • Git
  • Maven & Gradle
  • Docker & k8s
  • Java
  • Spring / Spring Boot
  • 数据库: 如MySQL
  • 消息队列: 如RabbitMQ
  • 缓存系统: 如Memcached
  • 内存数据库: 如Redis

四、运维工具链概览

1、单块架构的缺点

  • 耦合严重:单块服务内的各个逻辑之间,往往缺乏清晰的边界。导致内部耦合严重,正所谓“牵一发而动全身”。
  • 维护困难:单快服务包含了过多的业务,代码量严重膨胀。开发人员难免”失焦“,不知道如何下手。
  • 团队协作困难:如果多人同时开发同一个单块应用,势必导致代码冲突成为常态,团队协作成本急剧上升。
  • 测试困难:单块服务是作为一个整体进行开发、上线的。尽管你只对A功能进行了修改,但难免会影响B功能。随着单块应用的愈发膨胀,测试工作量会提升数倍。

2、微服务架构的优点

  • 低耦合:在单块服务中,不同业务的逻辑耦合在一起。做微服务拆分后,微服务内只包含有限的业务逻辑,耦合也随之大大降低。
  • 易维护:微服务内部只包含单一业务逻辑,功能更为集中,更容易开发人员聚焦问题和修改。
  • 适合团队协作:拆分为微服务后,每个服务中涉及的代码和功能更少,可以将不同微服务划分给不同团队甚至个人负责。各司其职后,有效降低了开发和代码冲突,使得其适合团队协作。
  • 测试成本低:在单块服务中,哪怕只改动了一点点代码,也需要对整个巨无霸服务进行测试。微服务拆分后,功能的修改,只需要涉及改动的个别微服务进行测试,有效降低了测试工作量。
  • 易横向拓展:在单块服务时代,巨无霸服务已经占用了大量资源,机器的配置已经很高,若要再单独部署一个结点做负载均衡,成本会非常很高,所以多数情况下,都是通过纵向拓展的方式提升系统性能(如加内存,换个更好的cpu)。采用微服务拆分后,各个微服务占用的资源更少,可以轻松的通过增加节点的横向拓展方式,提升系统性能。更进一步的说,根据阿姆达尔定律,微服务拆分后,各个微服务对性能的要求并不一致,可以优先拓展那些具有性能短板的微服务,有效降低了拓展成本。
  • 技术选择更多样:由于微服务是各自独立的进程。各个团队可以根据自己的需要选择不同的技术方案。然而在实践中,我并不推荐这么搞,这会在后面技术选型时展开。
  • 加快迭代速度:上面已经提到,微服务低耦合、易维护、适合团队协作、测试起来成本更低,也更易于横向拓展。采用微服务架构后,可以显著的提升迭代速度。

3、微服务整体架构

基础设施层
  • 微服务是后端服务,最终一定要部署在基础设施的某台机器上。基础设施层可以是自运维的服务器或机架,也可以选用云计算的虚拟机。
  • 在这一层,我们重点关注底层“物理资源”1的可用性及调整:计算资源(CPU 和 GPU)、存储资源(内存、硬盘)、网络资源(交换机、路由)。对这些基础设施的维护,或者是直接在机房维护,或者是操作云平台的API。
  • 举几个例子:大促前预估系统容量不足,我们要加半个机架的机器;直播平台今晚要来大V,预计带宽不足,要增加带宽。这些都是在基础设施层要关注的内容。
运维平台层
  • 对于后端服务的运维工作,持续交付是最重要的能力。由于微服务数量众多,一般需要构建一个持续交付系统,来完成微服务的自动运维,如微服务的初始化、发布、回滚、扩容。
  • 采用微服务架构后,上线的次数、频率都会显著提升,这就需要一个上线的镜像版本管理系统,记录上线的镜像版本。在微服务架构中,一般采用容器技术来实现微服务的自动运维。
  • 容器是轻量级资源,隔离能力相对较弱,我们需要对容器资源进行监控,调度和管理。举个例子:我们有三台物理机,现在物理机A和C各运行了20个容器,物理机B运行了22个容器,假设每个容器的资源占用完全一致,那么资源调度系统会自动地,将B的两个的容器调整到物理机A和C上。
微服务设施层
  • 假设服务A需要调用服务B,那么A服务如何获取服务B的地址(例如IP和端口)呢?在传统的单块架构中,服务数量很少,尚可采用同在配置中写死IP、端口的方法来解决这个问题。但在微服务时代,面对动辄成百上千的微服务,这种做法将不再可行。因此,如何自动注册、发现微服务的多个实例,是架构必须解决的核心问题。
  • 微服务拆分后,我们的系统从单机演化为分布式系统,为了防止分布式系统的雪崩效应2、微服务设施需要有的熔断和限流的能力。
  • 面对众多的微服务,逐一修改配置的方式显得更加笨拙,我们需要有一个中央配置平台,快速完成微服务的配置修改。
  • 前面已经提到,微服务的分布式架构,会加大调试难度,所以日志的收集和预警显得更加重要,同时,我们可以根据业务日志来进行一些监控预警,这和平台层的容器监控预警是不一样的。
  • 微服务需要集成一些后端组件,如数据库、消息队列、缓存等。
业务服务层:

在提供了微服务的基础设施后,我们可以放手开发各个微服务了。业务服务层是一些“基础微服务”或“业务微服务”,他们“各司其职”,服务之间的耦合应当做到最低。

接入网关层:

微服务面向的“用户”,一般是Web、移动端、PC端等。出于用户体验的考量,服务端提供给客户端的的接口应当尽量实现结果聚合,减少请求次数。因此,一般要设置一层接入网关,他负责调用业务微服务A B C等,完成结果聚合后,一并返回给客户端。

五、运维工具链概览

1、基础设施层:

对于绝大多数的中小公司,且无强烈的数据保密需求,我强烈建议使用云主机。

  • 运维成本更低。想对机器加64GB的内存,如果自运维的话跑去机房、断电、拆机器、插内存,半天过去了。如果采用云主机,就是点点鼠标,重启一下的事情。
  • 弹性更大。老板一拍脑袋,明天要上线大促,预估要扩容10倍。只有一天时间,是不可能完成100台机器的采购、上架、配置的。大促结束后,流量回归到平常情况,这100台机器还要继续空转烧钱么?如果采用云主机,这些就是点点鼠标,甚至是几个API调用就可以搞定的事情。
  • 平均稳定性更高。内存ECC故障、硬盘坏道、RAID卡故障,这些都是自运维服务器时代的家常便饭。若采用云主机,就可以很好的避免这些烦恼。常见的大厂云主机,都提供了至少3个9的在线时间保障,与运维服务器相比,平均稳定性更高。

2、运维平台层之容器管理:

前面已经提到,微服务需要借助容器技术才能“顺利启航”。目前主流的方案有:docker加脚本、swarm集群、Kubernetes集群、Marathon集群。选用Kubernetes集群,它内置的功能完全可以满足”容器的监控、调度、管理“。在这里我们采用排除法,说说为什么不选用其他几个方案。

  • docker加脚本:2014年Docker刚刚兴起时,还没有集群管理的解决方案,多数公司采用了这类架构,在不同物理机器上,通过自动化脚本来启动不同的容器。这种方式简单直接,但是当集群规模扩大后,运维非常困难。此外,这种方式很难解决自动网络配置、自动调度、容器数据迁移等很现实的问题。
  • swarm集群:swarm集群方案是Docker公司于2014年末推出的容器集群技术方案。尽管swarm是Docker公司的“亲儿子”又是市场的先发产品,但swarm很快被后起之秀Kubernetes超越。时至今日,从的新功能跟进、社区活跃、文档完善程度等方面,都弱于Kubernetes。更重要的是,借助CNCF基金会的影响力,Kubernetes已经成为了事实上的容器集群解决方案,GCE、AWS等云平台,都原生支持Kubernetes集群。在2017年,Docker公司在自己的商业化产品中直接集成了Kubernetes,标志着swarm项目的全面落败。所以我们也不会选用swarm集群。
  • Marathon集群:Marathon是构建在Mesos集群上的一套容器集群管理软件。想使用Marathon,先要部署一套底层的Mesos。对于大型公司,特别是已经部署了Mesos的Hadoop集群的公司来说,这种搞法可以提升机器复用程度。但对于中小规模的企业而言,Mesos + Marathon多少有一些“”高射炮打蚊子“的感觉。此外,虽然Marathon在大规模机器管理上有比较多的经验,但并未在容器编排上投入太多新功能,更像是借助容器的概念为自己"造势"。综上所述,我们也不会选用Marathon集群。
  • 运维平台之持续部署系统:部署前需要先构建,微服务开发选用Spring Boot框架,在构建方面,我们使用Gradle(之后会阐述原因)。在持续部署方面,我们选用老牌工具Jenkins,通过一些插件和配置完成全套的持续部署。
  • 运维平台之部署版本管理系统:前面已经提到,我们将采用容器技术。采用自建私有Docker仓库的方式,完成容器的镜像工作,并使用它作为部署版本的管理系统。

六、微服务技术栈概览

1、服务开发框架:

我们选用Java作为开发语言,并使用Spring Boot作为开发框架。Spring Boot作为Spring框架的一次"革命",可以说是为了微服务而生的。

2、服务注册与发现:

为了简化实现难度,我们将借助Kubernetes内置的服务和虚拟端口功能,来实现服务的注册与发现。换句话说,我们将服务注册与发现的能力,下推一层到运维平台层。对于微服务这一层,服务的注册与发现是完全透明的。熔断与限流:微服务之间的调用链更加复杂,为了降低&隔离服务故障造成的影响,一般选用和熔断或限流策略。我们选用Hystrix作为熔断功能的基础库并进行了封装,Guava的RateLimit作为限流功能的基础库并进行了封装。

3、配置中心:

这里主要关注配置的自动下发、自动更新和易维护性。我们采用git + cfg4j的模式实现配置中心。

4、后端组件

  • RPC: 目前主流的开源RPC框架是gRPC和Thrift。gRPC在设计理念上更为先进,且原生支持HTTP2,可以直接集成到客户端上。Thrift作为老牌RPC框架,历经多家公司的考验,已经非常成熟和稳定,且性能比gRPC更为出色。因此,我们选用Thrift作为RPC框架。
  • 关系型数据库:我们选用市场占有率最高的开源数据库MySQL。Spring Boot内置了多种数据库接入方式,我们会采用JPA和“裸写”DAO两种接入方法,以满足不同应用场景。
  • 内存数据库:让系统更快“是我们不断追求的目标。当基于磁盘的MySQL数据库不能满足性能需求时,我们选用Redis内存数据库。Redis是一款高性能的内存数据库,在官方的性能评测中,其QPS可达到十万级别1。在接入组件方面,我们选用Redisson。与老牌的jedis等开源库相比相比,Redisson的优势在于将Redis操作与数据结构进行了有机的结合,可以用类似Java内置数据类型的操作方式轻松地使用Redis。
  • 缓存:构建高性能的分布式系统,缓存是必不可少的。Memcached是经典的高性能分布式内存缓存系统,我们选用它作为后端缓存组件。只有后端组件是不够的,还需要与Spring Boot集成。常见的Java客户端有Spymemcached和xMemcached。由于xMemcached采用了NIO模型,我们选用它作为接入库。
  • 消息队列:当系统的同步阻塞处理频繁出现性能瓶颈,甚至拖垮整个系统时,我们可以引入消息队列,将同步处理转为异步处理。消息队列就是为这种场景而设计的。目前比较主流的开源消息队列有Kafka、RabbitMQ等。从设计理念来看,Kafka是一个成熟的分布式流处理平台,更专注于海量消息和分布式拓展性。RabbitMQ则更加专注于消息队列,且兼容AMQP协议。结合我们的需求,选用RabbitMQ更为合适。虽然Spring内置了AMQP的集成方案,但使用起来略为繁琐。我们会以官方客户端为基础,自行构建一套工具类库。
  • 日志:我们选用Spring Boot默认的logback作为日志记录系统;使用"EBLK"组合作为日志收集、分析系统。

5、监控:

  • 微服务监控:在微服务部署之后,我们需要对微服务和其所在的容器进行的健康状况进行监控。包括容器的内存、CPU、网络状况,以及微服务的GC等信息。我们选用Prometheus作为数据的收集和查询系统,Grafana作为监控可视化平台。我们会探讨如何向Prometheus发送自定义的监控数据。
  • 业务异常报警:微服务监控可以帮助我们了解服务的健康情况,定位性能瓶颈。但对于系统的业务异常却无能为力。Sentry是一款错误追踪系统,可以帮助我们发现并定位逻辑异常。类似的,我们也会探讨如何集成Spring Boot与Sentry。

七、研发工具链概览

  • 内部帐号管理:我们选用了经典的OpenLDAP 作为帐号管理服务器。OA、代码服务器、Jenkins等系统,都很方便地接入LDAP,实现“一套帐号,各系统共享”。
  • 代码版本管理:从架构和团队协作模式考虑,在微服务架构下,git比svn更合适作为版本管理系统。GitLab和Gerrit都是经典的Git代码托管系统。GitLab类似于GitHub适合GitFlow的分支独立开发,Gerrit侧重于代码评审。考虑到代码评审的需求较为强烈,我们选用Gerrit。
  • 依赖管理:无论什么开发语言,只要引入了开源库,就需要面对依赖管理的的问题。正如Python的Pip、Ruby的Gem、Node的npm,Java中使用Maven来管理库依赖。对于企业级开发,一般采用自搭建Maven私有仓库的方式,方便内部包的部署和依赖。我们选用Nexus搭建私有仓库,它被官方Maven仓库所采用,是Maven仓库的事实标准。
  • 自动构建工具:既然使用了Maven的依赖管理,那么配套工具按理也应但选用Maven。然而在微服务的开发中,版本依赖比传统系统更为复杂,Maven的xml文件会变得非常难以维护。Gradle在兼容Maven依赖管理的基础上,使用了更为简洁的DSL描述语言,且构建速度更快,插件更为丰富。因此,我们选用Gradle 4.X作为微服务的构建工具。
  • 效率脚本与工具:微服务架构下,经常需要新增微服务。为了降低新增成本,我们一套代码层面的脚本或工具来提升效率。我们会介绍“微服务初始化模板”、“更新Thrift RPC接口”等工具,以提升微服务的开发效率
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、微服务缺点
  • 三、需要掌握技术
  • 四、运维工具链概览
    • 1、单块架构的缺点
      • 2、微服务架构的优点
        • 3、微服务整体架构
          • 基础设施层
          • 运维平台层
          • 微服务设施层
          • 业务服务层:
          • 接入网关层:
      • 五、运维工具链概览
        • 1、基础设施层:
          • 2、运维平台层之容器管理:
          • 六、微服务技术栈概览
            • 1、服务开发框架:
              • 2、服务注册与发现:
                • 3、配置中心:
                  • 4、后端组件
                    • 5、监控:
                    • 七、研发工具链概览
                    相关产品与服务
                    容器服务
                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档