微服务的基本思想在于考虑围绕着业务领域组件来创建应用,这些应用可独立地进行开发、管理和加速。目前只针对springboot和springcloud两种进行介绍。
1、SpringBoot:是 Spring 的一套快速配置脚手架,可以基于spring boot 快速开发单个微服务.是Spring的引导,就是用于启动Spring的,使得Spring的学习和使用变得快速无痛。不仅适合替换原有的工程结构,更适合微服务开发.
2、SpringCloud:是一个基于Spring Boot实现的云应用开发工具,为微服务体系开发中的架构问题,提供了一整套的解决方案——服务注册与发现,服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。
Spring boot专注于快速、方便集成的单个个体,Spring Cloud是关注全局的服务治理框架.
微服务架构整个应用分散成多个服务,定位故障点非常困难而且如果一个服务故障可能会产生雪崩效用,导致整个系统故障。
一、为了降低故障的可能性,需要:监控、链路跟踪、日志分析、网关
-
监控----->发现故障的征兆
使用actuator这个组件对应用程序进行监控与管理,它不是SpringCloud之后才有的,而是SpringBoot的一个starter,Spring Boot Actuator。只需在pom.xml中引入spring-boot-starter-actuator。<!-- JVM监控 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
其中默认我们访问/actuator/health做健康检查,包括检查磁盘空间、DataSource的连接、Elasticsearch、Mongo、Rabbit、Redis等信息。
-
链路跟踪----->定位问题
当其中某一个服务出现了问题或者访问超时,很难直接确定是由哪个服务引起的,所以就有了 Spring Cloud Sleuth 链路跟踪。常见的链路追踪组件有 Google 的 Dapper、 Twitter 的 Zipkin , 以及阿里的 Eagleeye(鹰眼)等。
集成 Zipkin在pom.xml中引入spring-cloud-starter-zipkin -
日志分析---->分析问题
ELK日志分析组件:ELK是Elasticsearch、Logstash和Kibana三个组件的缩写。
Elasticsearch:搜索引擎,同时也是日志的存储。
Logstash:日志采集器,它接收日志输入,对日志进行一些预处理,然后输出
Kibana:UI组件,通过Elasticsearch的API查找数据并展示给用户。
常见架构:Spring Cloud ELK+kafka。其中kafka作为现在大数据消息队列的标准可以作为Spring Cloud与ELK之间的桥梁 。
日志xml示例如下:
<appender name="infoAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.dir}/logs/${HOSTNAME}-ss_micro_app_${projectname}_lt_info.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/logs/${HOSTNAME}-ss_micro_app_${projectname}_lt_info_%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d [%thread] %-5p [%c] [%F:%L] [trace=%X{X-B3-TraceId:-},span=%X{X-B3-SpanId:-},parent=%X{X-B3-ParentSpanId:-},begintime=%X{begintime:-},endtime=%X{endtime:-}] - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework">
<level value="INFO"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="com.abcd">
<level value="INFO"/>
<appender-ref ref="STDOUT"/>
</logger>
<root>
<level value="INFO"/>
<appender-ref ref="infoAppender"/>
<appender-ref ref="errorAppender"/>
</root>
traceId:traceId标识一个用户请求的调用链路。具有相同traceId的调用属于同一条链路。 spanId:标识一次服务调用的ID,即链路跟踪的节点ID。
parentId:父节点的spanId。
requestTime & responseTime:请求时间和响应时间。
- 网关----> 权限控制,服务治理
多个服务和接口的调用放出乱七八糟调用,需要一个把关的东西,就是网关。在调用者和被调用者中间加一层网关,每次调用时进行权限校验。另外,网关也可以作为一个提供服务接口文档的平台。
微服务外部通过网关访问微服务,微服务内部则直接调用;网关访问的参数进行加密保证数据安全性。
二、如何降低故障产生的影响:服务注册与发现、熔断、服务降级、限流
-
服务注册与发现---->动态扩容
最常用的故障处理策略就是冗余.一个服务都会部署多个实例,这样一来能够分担压力提高性能,二来即使一个实例挂了其他实例还能响应.
将新实例注册到负载均衡或DNS上,防止多个ip配置,就要用到服务自动注册与发现。部署一个服务发现服务(DNS),然后各个应用服务在启动时自动将自己注册到服务发现服务上,启动后会实时(定期)从服务发现服务同步各个应用服务的地址列表到本地,也会定期检查应用服务的健康状态,去掉不健康的实例地址 -
熔断
当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。所以当多次访问一个服务失败时,应熔断,标记该服务已停止工作,直接返回错误。直至该服务恢复正常后再重新建立连接 -
服务降级
当下游服务停止工作后,如果该服务并非核心业务,则上游服务应该降级,以保证核心业务不中断 -
限流
一个服务挂掉后,上游服务或者用户一般会习惯性地重试访问。这导致一旦服务恢复正常,很可能因为瞬间网络流量过大又立刻挂掉,在棺材里重复着仰卧起坐。因此服务需要能够自我保护——限流。限流策略有很多,最简单的比如当单位时间内请求数过多时,丢弃多余的请求。另外,也可以考虑分区限流,仅拒绝来自产生大量请求的服务的请求。具体可参考:链接:https://www.zhihu.com/question/65502802/answer/802678798