zoukankan      html  css  js  c++  java
  • 微服务实践:什么是微服务

    微服务实践:什么是微服务

    微服务

       微服务是一种软件架构风格,该词来源于Martin Fowler 的一篇博客。他在自己博客中阐述了微服务六个特点

    • 一组小的服务。微服务主张把单体应用拆开成一个个小的服务单元
    • 基于业务能力。比如购物网站,可以有订单服务、商品服务、推荐服务等等。
    • 微服务运行在独立的进程。比如现在的容器技术,容器可以部署在物理机上,以进程的方式进行横向扩展。
    • 轻量级通信机制。比如HTTP通讯协议&JSON消息格式。
    • 独立部署。每个团队在应用交付过程中,独立地开发、测试和部署自己的微服务,团队之间不需要特别多的协调,提高系统迭代能力和业务支持能力。
    • 无集中式管理。原先的架构需要有统一的技术栈、存储方式,微服务主张每个服务根据自己的实际情况,选择合适的技术栈及存储方式。

    历史的车轮

    创业初期

      我们开始了一个网上超市的创业项目,处于安全考虑,将购物网站与管理后台分开,其结构如下:

      

      代码很快完成后,找了家云服务部署上线,开始了创业之路。

    规模扩大

      规模扩大后,为了扩展客户渠道,除了网站外,还开发了移动端APP、微信小程序等,此外,还增加了一些新颖的营销手段,如促销活动、精准营销等等。升级后的架构如下:

      

      这一阶段存在着很多不合理的地方:

    • 网站和移动端应用有很多相同业务逻辑的重复代码。
    • 数据有时候通过数据库共享,有时候通过接口调用传输。接口调用关系杂乱。
    • 单个应用为了给其他应用提供接口,渐渐地越改越大,包含了很多本来就不属于它的逻辑。应用边界模糊,功能归属混乱。
    • 管理后台在一开始的设计中保障级别较低。加入数据分析和促销管理相关功能后出现性能瓶颈,影响了其他应用。
    • 数据库表结构被多个应用依赖,无法重构和优化。
    • 所有应用都在一个数据库上操作,数据库出现性能瓶颈。特别是数据分析跑起来的时候,数据库性能急剧下降。
    • 开发、测试、部署、维护愈发困难。即使只改动一个小功能,也需要整个应用一起发布。有时候发布会不小心带上了一些未经测试的代码,或者修改了一个功能后,另一个意想不到的地方出错了。为了减轻发布可能产生的问题的影响和线上业务停顿的影响,所有应用都要在凌晨三四点执行发布。发布后为了验证应用正常运行,还得盯到第二天白天的用户高峰期……
    • 团队出现推诿扯皮现象。关于一些公用的功能应该建设在哪个应用上的问题常常要争论很久,最后要么干脆各做各的,或者随便放个地方但是都不维护。

    做出改变

      在编程的世界里,最重要的是抽象能力,通过整理业务逻辑,抽象初公共的业务能力,做成了几个公共的服务。各个应用只需要从这些服务获取所需的数据,从而删掉了大量冗余的代码,就生了轻薄的控制层和前端,这一阶段的架构如下:

      

      

      这一阶段依然存在着很多缺点:

    • 数据库成为性能瓶颈,并且有单点故障的风险。
    • 数据管理趋向混乱,可能存在一个服务直接从数据库调用另一个服务的数据的现象。
    • 数据库表结构可能被多个服务依赖,牵一发而动全身,很难调整。

      后来,一鼓作气,把数据库拆分了,所有持久化层相互隔离,由各个服务负责,此外,为了提高实时性,加入了消息队列机制。

      

      完全拆分后各个服务可以采用异构的技术。比如数据分析服务可以使用数据仓库作为持久化层,以便于高效地做一些统计计算;商品服务和促销服务访问频率比较大,因此加入了缓存机制等。

    趋于成熟

    API网关

      随着业务的发展,服务越来越多,前端用户如何调用微服务就成了一个难题,因为他需要知道所有提供信息的微服务。这个时候API网关的作用就体现出来了,通过API聚合内部服务,提供统一对外的API接口给前端系统,屏蔽内部实现细节。除此之外,API网关还可以进行安全认证、流量限制、日志监控、防止爬虫等等。

      

    服务注册与发现

      一个服务经常需要调用另一个服务,在单一架构应用中,service通过语言层面或者程序层面去调用,在传统的分布式系统部署中,服务运行在一个固定的已知的地址(host和ports),从而可以简单的被别的service通过HTTP/REST或者某种RPC机制来调用。

      在微服务架构中,一个服务都会部署多个实例,这样一来能够分担压力提高性能,二来即使一个实例挂了其他实例还能响应。并且服务实例的数量和网络地址都是动态变化的,这对系统运维提出了巨大挑战,因此,动态的服务注册与发现就显得尤为重要。

    • 服务注册:服务实例将自身服务信息注册到注册中心。这部分服务信息包括服务所在主机IP和提供服务的Port,以及暴露服务自身状态以及访问协议等信息。
    • 服务发现:服务实例请求注册中心获取所依赖服务信息。服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。

      

    熔断

      当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。所以当多次访问一个服务失败时,应熔断,标记该服务已停止工作,直接返回错误。直至该服务恢复正常后再重新建立连接。

    服务降级

      当下游服务停止工作后,如果该服务并非核心业务,则上游服务应该降级,以保证核心业务不中断。比如网上超市下单界面有一个推荐商品凑单的功能,当推荐模块挂了后,下单功能不能一起挂掉,只需要暂时关闭推荐功能即可

    限流

      一个服务挂掉后,上游服务或者用户一般会习惯性地重试访问。这导致一旦服务恢复正常,很可能因为瞬间网络流量过大又立刻挂掉,在棺材里重复着仰卧起坐。因此服务需要能够自我保护——限流。限流策略有很多,最简单的比如当单位时间内请求数过多时,丢弃多余的请求。另外,也可以考虑分区限流。仅拒绝来自产生大量请求的服务的请求。例如商品服务和订单服务都需要访问促销服务,商品服务由于代码问题发起了大量请求,促销服务则只限制来自商品服务的请求,来自订单服务的请求则正常响应。
      

    参考链接

    原文链接:https://www.cnblogs.com/skabyy/p/11396571.html

  • 相关阅读:
    未能加载文件或程序集“file:///C:Program Files (x86)SAP BusinessObjectsCrystal Reports for .NET Framework 4.0
    iwms后台出现从客户端(ctl00$cphMain$logo="<img src="pic/logo.g...")中检测到有潜在危险的 Request.Form 值。错误解决方法
    Socket层实现系列 — accept()的实现(二)
    Socket层实现系列 — accept()的实现(一)
    Socket层实现系列 — getsockname()和getpeername()的实现
    洛谷1279 字串距离
    poj 2411
    poj 2411
    noip提高组 2010 关押罪犯 (洛谷1525)
    二分图匹配 (匈牙利算法) 洛谷3386
  • 原文地址:https://www.cnblogs.com/MrSaver/p/11441984.html
Copyright © 2011-2022 走看看