Spring Cloud 工具套件为微服务治理提供了全面的技术支持。这些治理工具主要包括服务的注册与发现、负载均衡管理、动态路由、服务降级和故障转移、链路跟踪、服务监控等。微服务治理的主要功能组件如下:
有关这些组件的工作原理,我们可以通过一一个服务调用序列图进行说明,如图5-1 所示。
在这个序列图中,Eureka 管理每个注册的微服务实例,并为其建立元数据列表。当一个服务消费者需要调用微服务时,Ribbon将依据微服务的实例列表实行负载均衡调度。这种调度默认使用轮询算法,从实例列表中取出一一个可用的实例,然后Zuul依据实例的元数据,对服务进行路由。在路由的过程中,Hystrix会检查这个微服务实例的断路器状态。如果断路器处于闭合状态,则提供正常的服务;如果断路器处打开状态,则说明服务已经出现故障,Hystrix 将根据实例的配置情况进行故障转移、服务降级等。
此外,其他一些组件也对微服务的治理起到一定的辅助作用。例如,Turbine可以对微服务的断路器实现全面监控,Config可以构建-一个在线更新的配置管理中心,Sleuth和Zipkin结合使用可以组建一个跟踪服务器,等等。通过这些组件和服务的使用,可进一步加大微服务治理的力度。
鉴于在新版本的Spring Cloud中,Eureka 已经不再更新,所以这里使用一个功能更加强大的,由第三方提供的Consul来创建注册中心。当然,这个注册中心在Spring Cloud工具集中,同样提供了对相关组件的支持。
Consul 是一个功能非常强大,性能相当稳定的注册中心,而且还包 了统 配置管理功能。另外,它在 Docker 中运行和搭建集群时,更加容易整合。
Consul 的安装并不复杂, 读者可从 Consul 官网中根据自己使用的操作系统,选择相关的版本进行下载。下载解压缩后 ,可以使用如下指令用开发模式启动
consul agent -dev
启动后即可通过浏览器打开其控制台,链接地址如下:
http:l/localhost:8500
如能看到如图 5-2 示的图 ,则说明注册中心已经启动就绪 Consul 默认的服务端口为8500 ,控制台管理和服务接入都使用这一端口。
为了能够将配置信息保存在磁盘文件中,这里使用了类似于生产环境中的启动参数,如下所示:
consul agent - server - bind=127 . 0 . 0.l - client=0.0.0 . 0 -bootstrap-expect=3-data-dir=/Users/apple/consul_data/application/data/- node=server
这些配置参数的意义如下。
其中, data-dir 可以设置配置信息保存的地址,可以根据所使用的机器设备输入一个已经存在的目录路径。
服务注册与发现
微服务在 Consul 中进行注册后,就能够被其他服务发现了。有关服务注册的过程,主要需要完成以下步骤。
1. 侬赖引用
引用与 Co ul 相关的服务发现和配置管理依赖包,代码如下所示:
<dependency>
<groupid>org . springframework . cloud</groupid>
<artifactid>spring-cloud-starter co sul discovery</artifactid>
</dependency>
<dependency>
<group d>org spri gframework cloud</groupid>
<artifactid>spri ng-cloud-starter- consul- config</artifactid>
</dependency>
其中, discovery 组件提供了服务注册与发现的功能, onfig 组件是 远程配置管理工具。
2. 连接设置
连接注册中 的配置,在配置文件 boot tr p. yml 中进行设定,这个配置文件将在系统加载Application.yml 之前被加载,代码如下所示:
spring :
cloud :
consul :
host : 127.0 . 0 . 1
port : 8500
discovery :
serviceName : ${spring . application . name}
healthCheckPath : /actuator/health
healthCheckinterval : 15s
tags :
urlprefix-/${spr ng application . name}
ins tance Id :
${spring . application . name} : ${vcap.application.instance id ♀{ spr ng applicati
on . instance id ♀{ random value}}}
在上面的配置中 host port 根据实际情况进行设定,其他参数无须更改。 serviceName是微服务的 名称,它所 用的变量需要在配置文件中 进行设定,代码如下所示:
s pri ng :
application :
name : catalogapi
即把微服务的名称定义为 logapi 。这样,当其 服务程序需要对这个微服务进行调用时,使用这个名称进行调用即可。因而在一个注册中心中,微服务的名称必须具有唯一性。
3.注册激活
在微服务应用的主程序中增加一个注解@EnableDiscoveryClien,即可激活服务注册与发现的功能,代码如下所示:
@SpringBootApplication
@EnableDiscoveryClient
public class SortsRestApiApplication {
public static void main(String[) args) {
SpringApplication.run(SortsRestApiApplication.class, args);
}
}
当完成上述步骤之后,启动微服务,即可在Consul的控制台上看到已经注册的微服务,如图5-3所示。
从图5-3中可以看出,除了consul服务本身,还有一一个catalogapi 服务,这就是成功注册的微服务。单击catalogapi右边的相关条款,还可以看到这个微服务健康状态相关的详细数据。
统一配置管理
在Consul上可以使用配置管理的功能,并且它还支持YAML的格式,配置的功能十分强大。另外,还可以将配置信息保存在磁盘文件中。
想要启用配置管理的功能,就需要在微服务的配置文件bootstrap.yml中增加如下所示的设置:
spring:
cloud:
consul :
config:
enabled: true #默认是true
format: YAML #表示Consul. 上面文件的格式
data-key: data #表示Consul上面的KEY值(或者说文件的名字),默认是data
defaultContext: ${ spring . application. name }
这样,在微服务启动时,就最先从Consul中读取配置。
我们可以为每个微服务配置一些独立的参数, 例如,数据源配置等。图5-4是针对微服务catalogapi的数据源配置。
最终, 一个连接 Consul 的完整配置如下所示:
spring:
appl ication:
name: catalogapi
cloud:
consul :
host: 127.0.0.1
port: 8500
discovery:
serviceName: ${spr ing. application. name}
heal thCheckPath: /actuator/health
healthCheckInterval: 15s
tags: urlprefix-/$ {spring . application. name }
instanceId:
$ { spring.application.name} :${vcap.application. instance id:$ {spring. application. instance_ id:$ {random. value}} }
#配置中心
config:
enabled: true #默认是true
format: YAML #表示Consul.上面文件的格式有四种: YAML、PROPERTIES、KEY-VALUE
#和FILES
data-key: data #表示Consul上面的KEY值(或者说文件的名字)默认是data
de faultContext: $ { spring . application. name }
在微服务的相互调用中,为了提高微服务的高可用性,有时我们会启用断路器功能。断路器就像电路的跳闸开关一样,当负载过载时切断电路,转为降级调用或执行故障转移操作。当负载释放时,再提供正常访问功能。
经过多次测试,我们对启用断路器功能的应用使用了下列配置,在高可用和高性能之间进行了一个折中设置:
#是否开启断路器(false)
feign.hystrix. enabled: true
#是否失败重试(true)
spring.cloud. loadbalancer. retry .enabled: true
#断路器超时配置(true)
hystrix. command. default. execution. timeout. enabled: true
#断路器的超时时间需要大于ribbon的超时时间,否则不会触发重试
(>ConnectT imeout+ReadTimeout)
hystrix. command . de fault. execution. isolation. thread. timeoutInMilliseconds:
19000
#并发执行的最大线程数(10)
hystrix. threadpool .default.coreSize: 500
#负载超时配置
ribbon. ConnectTimeout: 3000
r ibbon. ReadTimeout: 15000
#对所有操作请求都进行重试
r ibbon. OkToRetryOnAllOperations: true
#切换实例的重试次数
r ibbon. MaxAutoRetriesNextServer: 1
#对当前实例的重试次数
ribbon.MaxAutoRetries: 0
这个配置有两点需要注意:
(1)断路器的超时时间必须大于负载配置中的超时时间之和,例如,在上面的配置中,19000> 3000 + 15000。
(2)并发执行的最大线程数默认为10个,这远远不够,所以这里设置为500个。读者可以根据服务器的CPU频率和个数酌情设定。
当然,对于一个微服务来说,只有不启用断路器功能,其性能才是最优的。
通过使用Spring Cloud工具套件提供的功能,结合第三方提供的工具,我们可以对所有微服务的运行情况进行更加有效的监控,从而为微服务提供更加安全可靠的保障。
针对这些工具的使用,我们只需引用相关的工具组件,增加一-点简单的设计,并进行相关的配置,就可以使用其强大的功能。
服务健康状态监控
这里使用一个优秀的第三方管理工具Spring Boot Admin实现服务的健康状态监控和告警。
这一部分的内容在项目的base-admin模块中,首先引用其工具组件的依赖,代码如下所示:
<dependency>
<groupid>de . codecentric</groupid>
<artifactid>spring-boot- adrnin - starter-server</artifactid>
<versio口> 1.0</version>
</dependency>
该工具还提供了管理控制台访问控制功能及其WebUI设计,所以我们只需结合使用Spring的安全组件,增加一个安全管理配置,就可以启用这些功能。这个配置的核心代码如下所示:
@Override
protected void configure (HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new
SavedRequestAwareAuthent icationSuccessHandler() ;
successHandler . setTargetUrlParameter ("redi rectTo") ;
http. authorizeRequests ()
. antMatchers ("/assets/**") .permitAll ()
. antMatchers (" /actuator/**") .permitAll ()
. antMatchers ("/ login") .permitAll ()
. anyRequest () . authenticated()
.and()
. formLogin() .loginPage ("/login") . successHandler (successHandler) .and()
logout () . logoutUrl (" /logout") .and()
. httpBasic() .and()
.csrf() .disable() ;
}
在上面的代码中,主要是对一-些链接进行授权,同时在登录页面设置中使用loginPage页面。loginPage页面将使用由Spring Boot Admin提供的WebUI设计,运行效果如图5-5所示。
图5-5中的用户名和密码,使用了简单实现的策略设计,可以直接在配置文件中进行设置。
SpringBootAdmin是通过注册中心对微服务进行监控的,所以它本身也需要接入注册中心,而所有受监控的服务都无须进行设计。为了能够提供完整的状态数据,我们需在配置文件中增加如下所示的配置:
management :
e ndpoints :
web :
exposure :
include :”* ”
e ndpoi nt :
health:
show- details: ALWAYS
登录Sping Boot Admin控制台,就可以看到所有在注册中心中注册的微服务的运行情况,以及相关的一些健康数据,如线程数、内存使用情况等。Sping Boot Admin本身的运行状态及相关健康数据如图5-6所示。
重大故障告警
SpringBootAdmin还可以对其监控的服务提供告警功能,当出现重大故障,如服务宕机时,可以及时以邮件方式通知运维人员。
想要实现这个功能,就必须结合使用Spring Boot Mail组件。在配置文件中使用如下所示的配置,启动Spring Boot Admin的邮件通知功能:
spring :
boot:
admin:
notify:
mail:
to : devops@ai.com
from : usercenter@ai . com
上面设置的邮箱地址必须是有效的,同时还要配置SpingBootMail邮件的收发功能。这样,当微服务重启或宕机时,运维人员就可以收到来自Spring Boot Admin的告警通知邮件了。
断路器仪表盘
base- microservice项目工程的base-hystrix 模块是- - 个断路器仪表盘设计。
断路器仪表盘是Spring Cloud工具套件中的一一个组件,为了使用这个功能组件,我们需要引用如下所示的工具包:
<dependenc s>
<dependency>
<groupid>org .springframework.cloud</groupid>
<artifactid>spring- cloud- starter- netflix- hystrix-dashboard</artifactid>
</dependency>
</dependencies>
单独的断路器仪表盘应用程序,不用接入注册中心,只需在主程序中增加如下所示代码即可使用:
@SpringBootApplication
@Controller
@EnableHystrixDashboard
public class HystrixApplication {
@RequestMapping (” / ” )
public String home() {
return ” forward : /hystrix ” ;
}
...
}
启动断路器仪表盘应用程序之后,通过下面链接打开浏览器,即可看到如图 5-7 所示的控制台主页:
http://localhost : 7979
在控制台中,我们输入一个如下所示的需要监控的服务链接地址和端口号,并加上hytrix.stream字符串,单击Monitor Stream按钮,即可对相关微服务实行监控:
http:/ / localhost: 8091/hystrix. stream
如果所监控的服务有请求发生,就可以看到如图5-8所示的情况。
这只是针对单独一个微服务进行的监控,所以在实际中作用不是很大,只可以为进行性能测试提供一些参考数据。
如果使用Turbine组件,就可以实现对一-组服务进行监控。这种聚合服务的断路器仪表盘设计,在项目工程的base-turbine模块中。这里增加了对Turbine组件的引用,同时将这一-服务接入注册中心之中,这样,即可在配置文件中指定需要监控的服务了,如下所示:
turbine:
appConfig: catalogapi, catalogweb
aggregator:
clusterConfig: default
clusterNameExpression: new String ("default")
在这个配置中,我们只对catalogapi和catalogweb两个微服务实施了监控。这样,在启动应用之后,在首页控制台中输入这个应用的链接地址和端口号,同时在后面加上turbine.stream字符串,即可开启聚合服务的断路器仪表盘了。
http: / /localhost:8989/ turbine .stream
如图5-9所示,是聚合服务断路器仪表盘的一一个监控实例的情况。
使用Zipkin可以实现对微服务的链路跟踪功能。Zipkin 是一一个开放源代码的分布式链路跟踪系统,每个服务都向Zipkin发送实时数据, Zipkin 会根据调用关系通过Zipkin UI生成依赖关系图。
Zipkin提供的数据存储方式有In-Memory、MySQL Cassandra 和Elasticsearch等。
Zipkin用Trace结构表示对一次请求的追踪,同时又把每个Trace拆分为若干个有依赖关系的Span。在微服务应用中,一次用户请求可能由后台若干个微服务负责处理,而每个处理请求的微服务就可以理解为一个Span。
从网上下载一个可运行的zipkin-server的jar包,创建Zipkin服务。
下载成功后,在Java环境中使用下列指令运行(要求JDK的版本为1.7 及以上) :
java -jar zipkin-server-*.jar --logging.level. zipkin2=INFO
Zipkin默认使用的端口号为9411,在程序启动成功之后,通过浏览器使用如下链接可以打开其控制台:
http:// localhost:9411/
控制台的初次打开界面如图5-10所示。
在一个微服务应用中,可以通过以下步骤加入链路跟踪功能。
(1)引用Spring Cloud工具套件中支持Zipkin 的组件,代码如下所示:
<!--链路跟踪-->
<dependency>
<groupId>org. springframework.cloud</groupId>
<arti factId>spring-cloud-starter-zipkin</artifactId>
</dependency>
(2)在配置文件中增加如下所示的配置项:
#链路跟踪
| spring:
sleuth:
sampler :
probability: 1.0
zipkin:
sender :
type: web :
base-url: http://localhost:9411/
经上述配置之后,如果服务中有请求发生,那么就可以在Zipkin的控制台中看到相关服务的调用记录,如调用过程中涉及的方法、服务之间的依赖关系等,如图5-11、图5-12和图5-13所示。
这里我们没有保存Zipkin的跟踪数据,并且数据的传输也只是简单地使用了Web方式,因此只能在开发时测试使用。在实际应用中,可以将跟踪数据保存在Elasticsearch中,同时数据:
传输也可以使用异步消息通信实现。当数据保存在Elasticsearch 中时,默认以天为单位进行分割,这样将造成Zipkin 的依赖信息无法正常显示。这时,需要使用另一个开源工具包zipkin-dependencies进行计算。打开GitHub官网,搜索zipkin-dependencies,下载后即可使用。
因为这个工具包在执行一次计算之后就会自动关闭,所以读者需要根据实际情况,设定为固定时间间隔执行一次。
除可以对微服务的运行和相互调用进行监控和跟踪外,微服务的输出日志也是故障分析中最直接的入口和切实依据。但是到每个微服务的控制台上去查看日志是很不方便的,特别是微服务,不仅使用Docker发布,并且还分布在很多不同的服务器上,所以这里将使用一个日志分析平台,将所有微服务的日志收集起来,进行集中管理,并且提供统一的管理平台进行查询和分析。
创建日志分析平台
日志分析平台ELK 是由Elasticsearch、 Logstash 和Kibana 三个服务组成的。其中,Elasticsearch负责日志存储并提供搜索功能,Logstash 负责日志收集,Kibana 提供Web查询操作界面。这三个服务都是开源的,可以使用Docker进行安装。
使用日志分析平台
在微服务工程中增加如下所示的依赖引用,即可在应用中使用日志分析平台提供的日志收集功能:
<!--日志服务-->
<dependency>
<groupId>net. logstash. logback</groupId>
<artifactId> logstash- logback-encoder</artifactId>
<version>4. 10</version>
</ dependency>
在应用中增加一个“logback.xm1”配置文件,内容如下所示:
<?xm1 version="1.0" encoding="UTF-8"?>
| <configuration>
<property name="LOG_ HOME" value="/logs" />
<appender name=" STDOUT" class="ch. qos. logback. core. ConsoleAppender">
<encoder charset="UTF-8">
<pattern>ad{yyyy-MM-dd HH :mm:ss.Sss} [8thread] 8-5level glogger{50}
- 8msg&n</pattern>
</encoder>
</ appender>
<appender name="stash"
class="net. logstash. logback. appender . LogstashTcpSocketAppender">
<destination>192. 168.1.28: 5000</destination>
<encoder charset="UTF-8"
class= "net. logstash. logback. encoder . LogstashEncoder" />
</ appender>
<appender name="async" class="ch. qos. logback. classic.AsyncAppender">
<appender-ref ref="stash" />
</appender>
<!--设置日志级别-->
<root level="info">
<appender-ref ref="STDOUT" />
<!--输出到ELK-->
<!--<appender-ref ref="stash" />-->
</ root>
</ configuration>
在上面的配置中,“ stash”配置就是连接日志分析平台的设置。在这个配置中,假设日志收集服务器的IP地址为“192.168.1.28” ,读者可以根据实际情况进行设定。
在应用启动之后,即可通过下列链接打开Kibana 日志查询控制台:
http://192.168.1.28:5601
在日志查询控制台中,可以查询每个应用的日志输出,如图5-14所示。
本章首先讲述了注册中心的创建,以及微服务的注册与配置。然后,以注册中心为基础,通过健康监控、服务告警、断路器仪表盘和链路跟踪等功能的实施,说明如何对微服务进行有效监控。同时,结合日志分析平台的使用,对所有运行的微服务应用进行全面而有效的治理。
后续的微服务的开发和实施将在这个微服务治理环境的基础上进行,而涉及有关服务治理的引用和配置将不再做特别说明。
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。