草庐IT

《JAVA生态圈技术总结》之 微服务架构蓝图总览

掂掂三生有幸 2023-09-06 原文

目录导航

一、微服务定义

1.1 定义一

  • 微服务是一种架构风格,将单体应用划分成一组小的服务,尽量符合单一职责的原则,使得服务之间相互协作,实现业务功能;
  • 每个服务都运行在独立的进程、虚拟机、容器、服务器中,服务之间采用轻量级的通信机制(HTTP/JSON)进行协作;
  • 每个服务围绕各自的业务能力进行构建,并且能够通过自动化机制独立地部署,相互之间无部署依赖;
  • 每个服务可以使用不同的技术栈进行开发;

1.2 定义二

微服务是一种基于有界上下文的,松散耦合的面向服务的架构。

二、微服务利弊

2.1 优点

  • 划分了业务模块,具有更强的业务边界;
  • 每个微服务都是可以独立部署的,互不影响;
  • 允许技术多样性;

2.2 缺点

  • 带来了分布式系统的复杂性;
  • 带来了最终一致性的难题;
  • 带来了运维的复杂性;
  • 带来了测试复杂性;

三、微服务的适用性

什么场景下适用微服务?什么阶段时适用微服务?

3.1 康威法则

设计的微服务系统的组织,其产生的架构设计应等价于组织间的沟通结构。

这句话的意思是说,原始组织之间的结构最好能映射到设计的微服务系统架构上。比如一个系统包含订单、商品、用户等功能,现实中分别由A、B、C三个小组进行开发维护,那么如果要拆分为微服务的架构,最好就能拆分为订单服务、商品服务、用户服务三个微服务,对应A、B、C三个现实的小组结构。

3.2 生产力

微服务并不是适合任何阶段,最好的方式就是随着项目的扩大或者团队的扩大时,逐步演进到微服务。因为单体应用会随着规模的扩大而逐渐增加内耗,导致生产力降低。微服务的目标是在规模扩大时,使得生产力能维持在一个稳定的水准之上。

微服务与单体的生产力比较:

微服务生产力超过单体的拐点,一般来说是指当团队人数规模达到百人时。当然,这也不是绝对的,需要团队负责人自己视情况进行评估。

3.3 架构演进

如果在项目一开始就设计微服务的架构,一路上会遇到极大的困难与风险。比如业务模块边界的划分、无法预估的业务或者技术复杂性,这些都会耗费更多的人力和时间,甚至最终导致项目失败。

建议的方式就是由单体演进,我们可以在单体阶段不断摸索和沉淀业务和技术上的问题,随着越来越清晰的认知,再加上日渐增加的复杂度,可以考虑逐步拆分部分服务出来,朝着微服务架构的方向演进。

架构演进:

四、服务分层

微服务架构中服务与服务各有不同,相互之间也应该按照层级的方式进行编排。有的与业务无关的服务天然属于底层基础服务,有的与业务有关联的服务则属于聚合了基础服务的聚合服务。

服务分层:

在常见的公司微服务总体架构中,一般的架构表现就如下所示:

微服务总体架构:

有了各个层级的服务之后,中台的概念和战略就显得很自然。

中台战略:

五、服务注册发现

服务注册与发现是微服务架构得以运转的核心功能,它不提供任何业务功能,仅仅用来进行服务的发现和注册,并对服务的健康状态进行监控和管理。其核心的工作原理:

  • 注册中心负责维护所有服务的地址信息,包括服务名称、IP地址、端口等;
  • 提供服务方将自己的信息注册到注册中心上,并维持一个心跳以此来表明自己一直可用;
  • 调用服务方想要调用某个服务时,询问注册中心该服务的地址,然后以负载均衡的方式发起调用;

现在注册中心比较多,主流的有Eureka、Consul、Zookeeper、Nacos等。

六、微服务网关

网关是整个系统对外暴露的唯一入口,它封装了系统内的所有微服务,对外看来,别人只知道也只能通过网关才可以和系统进行交互。网关对所有请求进行非业务功能的处理,然后再将请求发送给内部指定的微服务进行业务上的处理。总的来说,网关最主要的功能如下:

  • 反向路由;
  • 安全认证;
  • 限流熔断;
  • 日志监控;

现在常见的网关有Kong、Zuul、Spring Cloud Gateway等;

微服务网关:

在实际应用中,一个微服务体系架构的系统可以有多个网关用来应对不同的使用场景,比如公司内网网关、外网网关、提供给第三方调用的网关等;

多网关的使用:

七、微服务配置中心

微服务在启动和运行的过程中,经常会需要读取一些配置信息,这些配置信息拥有如下的特点:

  • 独立于程序的只读内容;配置与程序应该分离,应用应该只会去读取配置,而不应该去修改配置;
  • 伴随应用的整个生命周期;配置会被程序读取用来控制自己的行为逻辑;因此配置是可以被更改的;
  • 拥有多种加载方式;可以通过硬编码、配置文件、环境变量、启动参数、数据库存储等方式被加载到应用内;
  • 配置内容需要治理;不同的环境下,配置具有不同的内容,因此需要配置内容的治理;

如上这些特点和需求,催生了配置中心的出现。现在主流的配置中心有Spring Cloud Config、Nacos、Apollo等;

配置中心:

八、微服务通信

RPC和REST:

九、服务监控

9.1 监控体系

监控体系:

9.2 监控架构

监控架构:

9.3 全链路监控

在微服务架构中,一次调用请求可能贯穿多个服务,这些服务可能是由不同的团队使用不同的技术开发而成的,如果出现调用失败需要排查问题时,如何能快速地复现调用现场,发现问题出在哪个服务哪个服务器上就成了全链路监控需要解决的问题。

全链路监控的基本原理都是:

  • 一次请求全过程中只有一个TraceID保持不变;
  • 每贯穿一个服务,SpanID都不同,同时标注上一个SpanID;
  • 按照时间序列将监控信息进行报错和展示;

全链路监控主流工具有CAT、Zipkin、Pinpoint、Skywalking等;

十、断路器与流量控制

在微服务架构体系中,服务之间的调用是很频繁的,一旦某些服务出现故障或者高延迟,会很可能造成级联故障,如果客户端还在不停重试,将会加剧问题的严重性,最终导致整个系统彻底崩溃。

断路器的设计与实现有助于防止多服务之间的级联故障,允许我们构建具有容错性和高弹性的微服务架构系统,当某些服务不可用时,提供服务熔断和服务降级功能,保证系统的其它部分仍能正常运行。

断路器的三个状态和含义如下:

  • 关闭;此时所有调用都能访问到当前的服务。当调用次数或者故障数超过设定的阈值后,断路器变为打开状态;
  • 打开;不再调用当前服务,而是返回预设的错误信息;
  • 半开;打开一定时间后,断路器切换为半开状态,放一个请求调用当前服务,测试服务是否正常。如果正常,则变为关闭状态;如果还是异常,再次变为打开状态。

主流常见的断路器有Hystrix、Sentinel等;

十一、DevOps(云原生架构系列)

DevOps:

蓝绿发布:

十二、容器云

如果使用了容器技术,那么容器编排、发布、治理就成了避不开的话题。主流的技术如下:

各大容器云厂商基本都是使用基于k8s的容器治理方案,k8s也已经成为该领域事实上的标准了。

有关《JAVA生态圈技术总结》之 微服务架构蓝图总览的更多相关文章

  1. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  2. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  3. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  6. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  7. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  8. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

随机推荐