SpringCloud微服务架构实战之微服务治理功能的实现
微服务治理
Spring Cloud 工具套件为微服务治理提供了全面的技术支持。这些治理工具主要包括服务的注册与发现、负载均衡管理、动态路由、服务降级和故障转移、链路跟踪、服务监控等。微服务治理的主要功能组件如下:
- 注册管理服务组件Eureka,提供服务注册和发现的功能。
- 负载均衡服务组件Ribbon,提供负载均衡调度管理的功能。
- 边缘代理服务组件Zuul,提供网关服务和动态路由的功能。
- 断路器组件Hystrix,提供容错机制、服务降级、故障转移等功能。
- 聚合服务事件流组件Turbine,可用来监控集群中服务的运行情况。
- 日志收集组件Sleuth,通过日志收集提供对服务间调用进行跟踪管理的功能。
- 配置管理服务组件Config,提供统一的配置管理服务功能。
有关这些组件的工作原理,我们可以通过一一个服务调用序列图进行说明,如图5-1 所示。
在这个序列图中,Eureka 管理每个注册的微服务实例,并为其建立元数据列表。当一个服务消费者需要调用微服务时,Ribbon将依据微服务的实例列表实行负载均衡调度。这种调度默认使用轮询算法,从实例列表中取出一一个可用的实例,然后Zuul依据实例的元数据,对服务进行路由。在路由的过程中,Hystrix会检查这个微服务实例的断路器状态。如果断路器处于闭合状态,则提供正常的服务;如果断路器处打开状态,则说明服务已经出现故障,Hystrix 将根据实例的配置情况进行故障转移、服务降级等。
此外,其他一些组件也对微服务的治理起到一定的辅助作用。例如,Turbine可以对微服务的断路器实现全面监控,Config可以构建-一个在线更新的配置管理中心,Sleuth和Zipkin结合使用可以组建一个跟踪服务器,等等。通过这些组件和服务的使用,可进一步加大微服务治理的力度。
鉴于在新版本的Spring Cloud中,Eureka 已经不再更新,所以这里使用一个功能更加强大的,由第三方提供的Consul来创建注册中心。当然,这个注册中心在Spring Cloud工具集中,同样提供了对相关组件的支持。
使用 Consul 创建注册中心
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
这些配置参数的意义如下。
- -server 表示以服务端身份启动。
- -bind 表示绑定到哪个 地址(有些服务器会绑定多块网卡,可以通过 bind 参数强制指定绑定的 地址)
- -client :指定客户端访问的 地址( Consul 有丰富的 AP 接口,这里的客户端指的是浏览器或调用方) ' 0.0 0.0 表示不限客户端 地址。
- -bootstrap expect=3 :表示 Serv 集群最低节点数为 ,低于这个值将无法正常工作(注:ZooKeeper 类似,通常集群数为奇数,以方便选举。 onsul 采用的是 Raft 算法)。如果不使用集群,则可以设置为1.
- -d ata-d 表示指定数据的存放目录(该目录必须存在)。
- -node 表示节点在 We 中显示的名称。
其中, 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>
其中, 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 会根据调用关系通过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,下载后即可使用。
因为这个工具包在执行一次计算之后就会自动关闭,所以读者需要根据实际情况,设定为固定时间间隔执行一次。
ELK日志分析平台
除可以对微服务的运行和相互调用进行监控和跟踪外,微服务的输出日志也是故障分析中最直接的入口和切实依据。但是到每个微服务的控制台上去查看日志是很不方便的,特别是微服务,不仅使用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 日志查询控制台:
在日志查询控制台中,可以查询每个应用的日志输出,如图5-14所示。
小结
本章首先讲述了注册中心的创建,以及微服务的注册与配置。然后,以注册中心为基础,通过健康监控、服务告警、断路器仪表盘和链路跟踪等功能的实施,说明如何对微服务进行有效监控。同时,结合日志分析平台的使用,对所有运行的微服务应用进行全面而有效的治理。
后续的微服务的开发和实施将在这个微服务治理环境的基础上进行,而涉及有关服务治理的引用和配置将不再做特别说明。
本文给大家讲解的内容是SpringCloud微服务架构实战:微服务治理 下篇文章给大家讲解的是SpringCloud微服务架构实战:类目管理微服务开发;觉得文章不错的朋友可以转发此文关注小编;感谢大家的支持!