点击蓝字关注我们

AMP

背景简介

在最原始的系统设计中,我们通常使用单体架构。单体架构把所有的业务逻辑都写在一起,没有对业务场景进行划分。在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,它暴露出来的问题也越来越多,比如高耦合,代码量大,维护困难,使用公用数据库,存储方式单一为解决这些问题,微服务架构应运而生。

什么是微服务架构

微服务是一种用于构建应用的架构方案。微服务架构将应用拆分成多个核心功能。比如之前构建过一个基于SpringBoot的订餐系统,要实现用户和管理员的登陆注册,食单和订单的增删改查。

基于业务将应用拆分成3个微服务:

1、用户登陆注册微服务;

2、订单管理微服务;

3、食单管理微服务。

每个微服务单独构建和部署,并且各项服务在工作或者出现故障时不会相互影响。比如在订单管理微服务出现问题,它不会影响到用户和食单管理微服务。

微服务是低耦合,服务之间相互独立, 不同模块可使用不同数据库和存储方式,也可使用不同的开发技术。

微服务的优势与劣势

1、优势

1.1 易于开发和维护:

开发某个微服务我们就只需关心这个微服务的逻辑即可,代码量和逻辑复杂度都会降低,从而易于开发和维护。

1.2 局部修改容易部署:

在开发中发现了一个问题,如果是单体架构的话,我们就需要重新发布并启动整个项目,非常耗时间,但是微服务则不同,哪个模块出现了bug我们只需要解决那个模块的bug就可以了,解决完bug之后,我们只需要重启这个模块的服务即可,部署相对简单,不必重启整个项目从而大大节约时间。

1.3 按需伸缩:

单体架构在扩展某个模块的性能时不得不考虑到其它模块的性能会不会受影响,对于微服务来讲,某个模块通过什么方式来提升性能不必考虑其它模块的情况。

2、劣势

2.1 运维要求较高:

对于单体架构来讲,只需要维护好这一个项目就可以了,但是对于微服务架构来讲,由于项目是由多个微服务构成的,每个模块出现问题都会造成整个项目运行出现异常,这就对运维人员提出了很高的要求。

2.2 接口调整成本高:

比如,用户微服务是要被订单微服务和餐食微服务所调用的,一旦订单微服务的接口发生大的变动,那么所有依赖它的微服务,都要做相应的调整,由于微服务可能非常多,那么调整接口所造成的成本将会明显提高。

2.3 监控复杂度提升:

微服务的规模和动态性使得数据收集的成本大幅度提升,比如CPU,内存和网络传输的开销。大量的监控数据会对后台数据处理分析产生影响,这导致监控复杂度提升。

微服务的四个要素

1、小

微服务体积小。每个微服务只需要实现自己的业务逻辑,比如订单管理模块,它只需要处理订单的业务逻辑,其它的不必考虑。

2、独

能够独立的部署和运行。每个微服务从开发、测试、运维等都是独立的,包括存储的数据库也都是独立的,自己就有一套完整的流程,不依赖其他模块。

3、轻

使用轻量级的通信机制和架构。该通信方式需要是跨语言、跨平台的,可以让每个微服务都有足够的独立性,不受技术的钳制。例如REST API。

4、松

微服务之间是松耦合的。

微服务架构带来的挑战

1、应用高可用的问题

随着业务的发展,流量的增大,若这台服务器挂掉或者性能不够,会带来单点风险,高可用性差,通过集群化的方式来实现应用高可用和水平扩展。原来是请求直接到服务端,现在是请求先到反向代理层,再到服务端。反向代理层对外只暴露一个地址,可以让应用系统内部的组成不被外界看到,也可实现路由转发,负载均衡的能力。比如在个人项目中,我有三个微服务,分别把每个微服务部署在两个节点上,如图一所示。前端静态页面访问nginx的地址,nginx实现路由转发和负载均衡,保证若有一个节点挂掉了,应用也能正常运行。

图一:订餐系统项目Nginx部署示意图

1.1 怎么进行负载分配:

常见的负载策略有以下几种:

随机:把来自网络的请求随机分配给内部中的多个服务器。

轮询:  每一个来自网络中的请求,轮流分配给内部的服务器。

静态权重:根据服务器的不同处理能力,比如CPU和内存配置,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。

一致性哈希:通过哈希算法使这个请求一直在某个节点上。

动态权重:根据服务的性能表现,比如通过响应时间来分配。

在个人项目中,我没有设置负载策略的方式,使用的是轮询。

在反向代理的过程中,它需要能够探测到节点是否正常,若不正常,响应就不再往那个节点发了。在四层探测中,是探测服务器的ip端口,在探测过程中,若响应超时就判断节点不可用,可能因为网络波动,使得某次探测失败,所以会设置一个不健康阈值,比如在几次探测均失败,才判断节点不可用。同样也会设置一个健康阈值,在几次探测均成功,会将之前不可用的节点复用。若在探测服务器的ip端口是成功,但程序假死,需要七层探测,需要调用它的健康探测服务,检查域名或者路径。

在个人项目中,通过nginx实现负载均衡,路由转发,nginx配置如下:

upstream users{

server IP地址1:8080

server IP地址2:8080

}

server {

location /users/ {

proxy_pass http://users/

}

}

1.2 如何解决反向代理层成为单点:

增加资源,增加多个代理节点,引入Keepalived 使得两个节点之间相互通信,实现主备模式。两个节点提供一个Virtual IP。但是这时,每次只有一个节点提供服务,资源利用率只有50%,所以引入多级反向代理,在软负载层前增加硬负载层,比如F5。

2、运维部署复杂的问题

因为把应用拆分成了很多微服务,会对服务器的资源需求有高要求,也会有复杂的人工部署。所以容器作为自动化的流程可以帮助我们。容器是在同一个操作系统上共享和操作资源,操作系统将容器看成一个进程,空闲的时候,他是不占用资源的。所以会需要有个资源调度管理分配平台,比如我司的稻客云平台。当应用构建比较复杂时,引入Jenkins。Jenkins从git代码仓库拉取解耦代码,打包成docker镜像,推到镜像仓库,我们就可以从应用商店里选择相应的镜像,启动成容器并进行部署,完成CICD的过程,如图二所示。

图二:Jenkins打包至Docker部署的流程图

Docker的运作:将你的项目和基础镜像打成一个带有启动指令的项目镜像,然后在服务器创建一个容器,让镜像在容器内运行,从而实现项目的部署。它不仅仅可以部署项目,还可以用于nginx服务搭建,redis搭建。比如在个人项目中,我们就应用到了nginx和redis。

镜像(Image):docker镜像是使用Dockerfile脚本,将你的应用以及应用的依赖包构建而成的一个应用包。

容器(Container):容器的主要作用就在于给镜像提供运行空间和环境,并执行镜像指令。

仓库(Repository):仓库是用来存东西的,但不是存容器,而是存储docker镜像。

镜像是基础,容器是镜像使用者,仓库是镜像的管理员。容器和仓库都是围绕着镜像来运作的,是对镜像的管理和使用。

3、服务注册发现的问题

3.1 为什么需要服务注册发现?

因为实现了应用高可用,所以一般每一个服务都是有多个拷贝,来做负载均衡。比如在个人项目中,每个微服务都是有两个节点,若其中一个食单管理微服务挂掉了,整个应用也可以正常运行。

服务之间需要创建一种服务发现机制,用于帮助服务之间互相感知彼此的存在。每个微服务都会有自己的ip以及端口号,若在代码中直接写上依赖的服务的ip和port来调用服务,维护成本太高,而且通过Jenkins和Docker对服务进行容器化部署后,每次重新启动Docker都会发现服务的IP发生变化,无法对IP进行固定。

并且服务注册与发现可以实现对服务的管理,它可以将挂掉的服务去除,保留好的服务。

3.2 实现过程:

在个人项目中,通过zookeeper实现服务注册发现。当服务上线时,服务提供者将自己的服务信息注册到ZK,并通过心跳维持长链接,实时更新链接信息。服务调用者通过ZK寻址,根据可定制算法,找到一个服务,还可以将服务信息缓存在本地以提高性能。当服务下线时,ZK会发通知给服务客户端。简单来讲,zookeeper可以充当一个服务注册表,让多个服务提供者形成一个集群,让服务消费者通过服务注册表获取具体的服务访问地址(ip+端口)去访问具体的服务提供者。

具体来说,zookeeper就是个分布式文件系统,每当一个服务提供者部署后都要将自己的服务注册到zookeeper的某一路径上: /{service}/{version}/{ip:port}, 比如个人项目中订单管理微服务orderfood部署到两个容器中,那么zookeeper上就会创建两条目录,分别为:

/orderfood/1.0.0/IP地址1:8070

/orderfood/1.0.0/IP地址2:8070

zookeeper提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立的是一个 socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,并将其剔除,比如IP地址1这台机器如果宕机了,那么zookeeper上的路径就会只剩 /orderfood/1.0.0/IP地址2:8070。

服务消费者会去监听相应路径(/orderfood/1.0.0),一旦路径上的数据有任务变化(增加或减少),zookeeper都会通知服务消费方服务提供者地址列表已经发生改变,从而进行更新。

4、全链路监控的问题

随着项目的扩展,微服务数量逐渐增加,服务按照不同的维度进行拆分,服务间的调用也越来越复杂,一次请求往往需要涉及到多个服务。这些服务可能由不同编程语言开发,不同团队开发,可能部署了很多副本。因此,就需要一个可以监控各个服务的性能及对服务间的调用进行跟踪的工具,以便发生故障的时候,能够快速定位和解决问题。全链路监控就在这样的背景下产生了。在个人项目中我们利用Pinpoint解决监控问题,Pinpoint是一款全链路分析工具,提供了无侵入式的调用链监控、方法执行详情查看、应用状态信息监控等功能。

Pinpoint支持的功能:

ServerMap:通过可视化它们的组件是如何互连的,了解任何分布式系统的拓扑结构。单击一个节点将显示关于组件的详细信息,例如其当前状态和事务计数

Realtime Active Thread Chart(实时活动线程图):实时监控应用程序内部的活动线程

Request/Response Scatter Chart(请求/响应散点图):随时间可视化请求计数和响应模式以识别潜在问题。可以通过拖动图表来选择其他细节

CallStack(调用堆栈):对分布式环境中的每个事务增加代码级可见性,在单个视图中识别瓶颈和故障点

Inspector(检查工具):查看应用程序的其他细节,如CPU使用、内存/垃圾收集、TPS和JVM参数。

另外因为微服务数量的增加,日志比较分散,想要检查各个微服务是否有报错信息,需要挨个服务去排查,比较麻烦。所以希望对日志进行聚合,然后通过监控,能够快速的找到各个微服务的报错信息,快速的排查,还需要日志收集存储的组件。比如用ELK来采集,集中处理和展示数据。

总结与展望

通过集群化,容器化的演进和增加资源,解耦拆分的设计思路,在个人项目中,也是通过这样的方式,将应用拆分成三个微服务,通过增加节点的方式来实现集群化部署。微服务虽然有很多优点,但是有很多约束,比如对开发团队的技术要求门槛高,对老旧系统改造困难等缺点。服务网格(Service Mesh)作为下一代微服务技术的代名词应运而生,它是解决服务间通讯的基础设施,集中控制的网关将会分散在每个节点处以分布式的形态存在,不需要侵入。所以微服务未来发展趋势将是集Spring Boot等微服务框架,Docker容器管理,Service Mesh服务网格等技术协同配合的发展趋势。

记得关注我哦~
点击下方

代码重新发布后docker服务会不会受影响_分享点经验 | 浅谈微服务架构相关推荐

  1. 浅谈微服务体系中的分层设计和领域划分

    1.摘要 本文阐述了一种将分层设计和DDD领域设计应用于微服务体系架构的方案实践,也是个人的最佳实践.对于互联网公司来说,我们主张将其Web服务架构分为五层:基础设施层.领域服务层.应用服务层.网关层 ...

  2. 浅谈微服务的来龙去脉

    作者:王清培(Plen wang) 沪江 公共业务平台 应用架构师 转载至沪江技术学院微信公众号 背景介绍 最近一段时间公共业务平台在进行大面积的重构,对原来的技术栈进行迁移,逐渐往Java.Go.N ...

  3. (未完待续)浅谈微服务以及 常用中间件( zookeeper redis rabbitmq)

    传统的单体框架,已经不满足目前公司战略规划要求,近几年"微服务" 这个字眼,出现的越来越频繁,虽然有过一年多微服务项目经验,也很难把微服务解释清楚,到底何为微服务? Martin ...

  4. 浅谈微服务基建的逻辑

    2019独角兽企业重金招聘Python工程师标准>>> 起点 首先,我们得有一个"服务".根据定义,我们可以把每个服务实例都视作一个黑盒.这个盒子有着明确的输入点 ...

  5. 微服务怎么部署到服务器的_浅谈微服务部署方案

    在项目迭代的过程中,不可避免需要"上线".上线对应着部署,或者重新部署:部署对应着修改:修改则意味着风险. 微服务目前有很多用于部署的技术,有的简单,有的复杂:有的得停机,有的不需 ...

  6. cx_oracle写日志信息_浅谈微服务架构之构建日志收集系统

    任何复杂的应用程序偶尔都会出现错误.在微服务应用程序中,需要跟踪几十甚至几百个服务发生的情况.要获取系统的整体视图,日志记录和监控至关重要.在微服务架构中,一个业务请求会经历多个服务,收集端到端链路上 ...

  7. (一)浅谈微服务概念理解

    1.什么是微服务 让我们以一个餐厅为例来解释微服务的概念. 想象一家传统的餐厅,它有一个集中式的厨房,所有的菜品都在同一个厨房中准备和烹饪.这个厨房负责接收顾客的点餐请求,准备食材,烹饪菜品,并最终将 ...

  8. 阿里技术专家浅谈微服务架构

  9. 应对海量并发请求,首席布道师谈微服务的应用架构设计

    何李石 七牛云首席布道师 <Go语言程序设计>译者,Go语言/容器虚拟化技术布道师.实践者. 5年以上互联网创业经验和企业级产品研发.运营经验,同时也是互联网产品基础架构解决方案专家. 随 ...

最新文章

  1. [ASP.NET]状态管理[摘自C#入门经典]
  2. 结合Apache和Tomcat实现集群和负载均衡
  3. 搭建MyBatis操作数据库
  4. 词向量之Word2vector原理浅析
  5. Java bean 是个什么概念?
  6. JavaScript DOM扩展——“选择符API和元素遍历”的注意要点
  7. pymysql使用变化的变量,构造SQL语句
  8. 做系统ghost步骤图解_u盘装系统步骤
  9. python开发软件的实例-如何编写Python软件开发文档(7个技巧)
  10. 五寸照片尺寸是多少?如何自己制作证件照?
  11. 开关电源matlab仿真文件,基于PI控制方式的7A开关电源的MATLAB仿真.doc
  12. 网络历史之金融投资三剑客0
  13. 【优化调度】基于NSGAII算法的车辆充电调度策略研究含Matlab代码
  14. 图灵奖得主亲授!深度学习视频课程精选
  15. ceph-cache-tier
  16. JS 数据容量转换/换算
  17. HC32F460开发之硬件IIC驱动AT24C64
  18. js 内置对象
  19. 电子产品安规测试产品及检测设备
  20. Category (mathematics)

热门文章

  1. 文献阅读005【精读】
  2. 【洛谷P3410】拍照题解(最大权闭合子图总结)
  3. 前端实习日记——高新兴科技集团
  4. Python(set/list/dict/tuple)
  5. CSS 强制换行和禁止换行学习
  6. PHP:判断客户端是否使用代理服务器及其匿名级别
  7. Tomcat 添加为系统服务 开机自动启动
  8. GridView的操作:导出Excel[方案一]
  9. 删除一行下方单元格上移_Excel小技巧——局部单元格的添加与删除
  10. php框架加滑动条,IOS_iOS实现双向滑动条效果,最近做项目,碰到一种双向滑 - phpStudy...