目录
一、SpringCloud微服务技术简介
Spring Cloud 作为Java 语言的微服务框架,它依赖于Spring Boot,有快速开发、持续交付和容易部署等特点。Spring Cloud 的组件非常多,涉及微服务的方方面面,井在开源社区Spring 和Netflix 、Pivotal 两大公司的推动下越来越完善。
1.1 微服务的功能主要体现在以下儿个方面。
口服务的注册和发现。
口服务的负载均衡。
口服务的容错。
口服务网关。
口服务配置的统一管理。
口链路追踪。
口实时日志。
1.2 微服务具有以下的特点。
口按照业务来划分服务,单个服务代码量小,业务单一,易于维护。
口每个微服务都有自己独立的基础组件,例如数据库、缓存等,且运行在独立的进程中。
口微服务之间的通信是通过HTTP 协议或者消息组件,且具有容错能力。
口微服务有一套服务治理的解决方案,服务之间不相合,可以随时加入和剔除服务。
口单个微服务能够集群化部署,并且有负载均衡的能力。
口整个微服务系统应该有一个完整的安全机制,包括用户验证、权限验证、资源保护等。
口整个微服务系统有链路追踪的能力。
口有一套完整的实时日志系统。
二、开发框架SpringBoot
三、服务注册和发现Ereka
3.1 什么是Eureka
Eureka和Consul 、Zookeeper 类似, Eureka 是一个用于服务注册和发现的组件,最开始主要应用于亚马逊公司旗下的云计算服务平台AWS o Eureka 分为Eureka Server 和Eureka Client, EurekaServer 为Eureka 服务注册中心, Eureka Client 为Eureka 客户端。
3.2 Ereka优势
Eureka 和其他组件,比如负载均衡组件Ribbon 、熔断器组件Hystrix 、熔断器监控组件Hystrix Dashboard 组件、熔断器聚合监控Turbine 组件,以及网关Zuul 组件相互配合, 能够很容易实现服务注册、负载均衡、熔断和智能路由等功能。这些组件都是由Netflix 公司开源的,一起被称为Netflix OSS 组件。Netflix OSS 组件由Spring Cloud 整合为Spring Cloud Netflix 组件,
Eureka 的基本架构如图2-3 所示,其中主要包括以下3 种角色。
口Register Service :服务注册中心,它是一个Eureka Server ,提供服务注册和发现的功能。
口Provider Service :服务提供者,它是一个Eureka Client ,提供服务。
口Consumer Service :服务消费者,它是一个Eureka Cient ,消费服务。
服务消费的基本过程如下:首先前要一个服务注册中心Eureka Server ,服务提供者EurekaClient 向服务注册中心Eureka Server 注册,将自己的信息(比如服务名和服务的IP 地址等)通过阻ST A 凹的形式提交给服务注册中心Eureka Server 。同样,服务消费者Eureka Client 也向服务注册中心 Eureka Server 注册,同时服务消费者获取一份服务注册列表的信息, 该列表
包含了所有向服务注册中心Eureka Server 注册的服务信息。获取服务注册列表信息之后,服务消费者就知道服务提供者的IP 地址,可以通过Http 远程调度来消费服务提供者的服务。
( l ) Registe 「一一服务注册
当Eureka Client 向Eureka Server 注册时, Eureka Client 提供自身的元数据,比如IP 地址、端口、运行状况指标的Url 、主页地址等信息。
(2) Renew一一服务续约
Eureka Client 在默认的情况下会每隔30 秒发送一次心跳来进行服务续约。通过服务续约来告知Eureka Server 该Eureka Client 仍然可用,没有出现故障。正常情况下,如果Eureka Server在90 秒内没有收到Eureka Client 的心跳, Eureka Server 会将Eureka Client 实例从注册列表中删除。注意:官网建议不要更改服务续约的间隔时间。
(3) Fetch Registries一一获取服务注册列表信息
Eureka Client 从Eureka Server 获取服务注册表信息,井将其缓存在本地。Eureka Client会使用服务注册列表信息查找其他服务的信息,从而进行远程调用。该注册列表信息定时(每30 秒) 更新一次,每次返回注册列表信息可能与Eureka Client 的缓存信息不同, Eureka Client会自己处理这些信息。如果由于某种原因导致注册列表信息不能及时匹配,Eureka Client 会重
新获取整个注册表信息。Eureka Server 缓存了所有的服务注册列表信息,并将整个注册列表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka Client和Eureka Server 可以使用JSON 和XML数据格式进行通信。在默认的情况下, Eureka Client 使用JSON 格式的方式来获取服务注册列表的信息。
( 4) Cancel ——服务下线
Eureka Client 在程序关闭时可以向Eureka Server 发送下线请求。发送请求后,该客户端的实例信息将从Eureka Server 的服务注册列表中删除。该下线请求不会自动完成,需要在程序关闭时调用以下代码:
DiscoveryManager.getinstance().shutdownComponent();
( 5 ) Eviction一一服务剔除
在默认情况下,当Eureka Client 连续90 秒没有向Eureka Server 发送服务续约(即心跳)时, Eureka Server 会将该服务实例从服务注册列表删除,即服务剔除。
四、负载均衡
五、申明式调用
5.1 申明式Feign的简介
@Feign Client 注解用于创建声明式API 接口,该接口是RESTful 风格的。Feign 被设计成插拔式的,可以注入其他组件和Feign 一起使用。最典型的是如果Ribbon 可用, Feign 会和Ribbon 相结合进行负载均衡。
在代码中, value()和name()一样,是被调用的服务的Serviceld 。url ()直接填写硬编码的Url地址。decode404()即404 是被解码,还是抛异常。configuration ()指明FeignClient 的配置类,默认的配置类为FeignClientsConfiguration 类, 在缺省的情况下, 这个类注入了默认的Decoder 、Encoder 和Contract 等配置的Bean 。fallback()为配置熔断器的处理类。
配置如下:
spring:
application:
name: eureka-feign-client
server:
port: 8765
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
在程序的启动类EurekaFeignClientApplication 加上注解@E nableEurekaClient 开启EurekaClient 的功能,通过注解@EnableFeignClients 开启Feign Client 的功能。代码如下:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class EurekaFeignClientApplication {
public static void main (String [] args) {
SpririgApplication.run(EurekaFeignClientApplication.class , args);
}
}
5.2 Feign简单构建
通过以上3 个步骤,该程序就具备了Feign 的功能,现在来实现一个简单的Feign Client;新建一个EurekaClientFeign 的接口,在接口上加@FeignClient 注解来声明一个Feign Client,其中value 为远程调用其他服务的服务名, FeignConfig.class 为Feign Client 的配置类。在EurekaClientFeign 接口内部有一个sayHiFromClientEureka()方法,该方法通过Feign 来调用
eureka-client 服务的API 接口。
六、熔断器
6.1 什么是Hystrix
在分布式系统中,服务与服务之间的依赖错综复杂, 一种不可避免的情况就是某些服务会出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞。Hystrix 是Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性。
6.2 Hystrix的作用
在复杂的分布式系统中,可能有几十个服务相互依赖,这些服务由于某些原因,例如机房的不可靠性、网络服务商的不可靠性等,导致某个服务不可用。如果系统不隔离该不可用的服务,可能会导致整个系统不可用。例如,对于依赖30 个服务的应用程序,每个服务的正常运行时间为99.99% ,对于单个服务来说, 99.99% 的可用是非常完美的。有99.9930 = 99.7% 的可正常运行时间和0.3% 的不可用时间,那么10 亿次请求中有3000000次失败,实际的情况可能比这更糟糕。如果不设计整个系统的韧性,即使所有依赖关系表现良好,单个服务只有0.01% 的不可用,由于整个系统的服务相互依赖,最终对整个系统的影响是非常大的。在微服务系统中, 一个用户请求可能需要调用几个服务才能完成。如图8-1 所示,在所有的服务都处于可用状态时, 一个用户请求需要调用A 、H 、I 和P 服务。
6.3 Hystrix的场景
当某一个服务,例如服务I,出现网络延迟或者故障时,即使服务A 、H 和P 可用,由于服务I 的不可用,整个用户请求会处于阻塞状态,并等待服务I 的响应,如图8-2 所示。在高并发的情况下,单个服务的延迟会导致整个请求都处于延迟状态,可能在几秒钟就使整个服务处于线程负载饱和的状态。某个服务的单个点的请求故障会导致用户的请求处于阻塞状态,最终的结果就是整个服务的线程资源消耗殆尽。由于服务的依赖性,会导致依赖于该故障服务的其他服务也处于线程阻塞状态,最终导致这些服务的线程资源消耗殆尽, 直到不可用,从而导致整个问服务系统都不可用,即雪崩效应。为了防止雪崩效应,因而产生了熔断器模型。Hystrix 是在业界表现非常好的一个熔断器模型实现的开源组件,它是Spring Cloud 组件不可缺少的一部分。
6.4 Hystrix设计原则
Hystrix 的设计原则如下。
口防止单个服务的故障耗尽整个服务的Servlet 容器(例如Tomcat )的线程资源。
口快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等待。
口提供回退( fallback )方案,在请求发生故障时,提供设定好的回退方案。
口使用熔断机制,防止故障扩散到其他服务。
口提供熔断器的监控组件Hystrix Dashboard,可以实时监控熔断器的状态。
6.5 Hystrix 的工作机制
当服务的某个API 接口的失败次数在一定时间内小于设定的阀值时,熔断器处于关闭状态,该API 接口正常提供服务。当该API 接口处理请求的失败次数大于设定的阀值时, Hystrix 判定该API 接口出现了故障,打开熔断器,这时请求该API 接口会执行快速失败的逻辑(即fallback 回退的逻辑),不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器, 一段时间后会处于半打开状态,并将一定数量的请求执行正常逻辑。剩余的请求会执行快速失败,若执行正常逻辑的请求失败了,则熔断器继续打开: 若成功了,则将熔断器关闭。这样熔断器就具有了自我修复的能力。
6.6 Hystrix Dashboard 是监控Hystrix 的熔断器状态
在微服务架构中,为了保证服务实例的可用性,防止服务实例出现故障导致线程阻塞,而出现了熔断器模型。烙断器的状况反映了一个程序的可用性和健壮性,它是一个重要指标。Hystrix Dashboard 是监控Hystrix 的熔断器状况的一个组件,提供了数据监控和很友好的图形化展示界面。本节在上一节的基础上,以案例的形式讲述如何使用Hystrix Dashboard 监控熔断器的状态。
七、路由网关
智能路由网关组件Zuul:Zuul 作为微服务系统的网关组件,用于构建边界服务( EdgeService ),致力于动态路由、过滤、监控、弹性伸缩和安全。
7.1 Zuul的作用
Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用,主要体现在以下6 个方面。
口 Zuul 、Ribbon 以及Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例。
口 网关将所有服务的API 接口统一聚合,并统一对外暴露。外界系统调用API 接口时,都是由网关对外暴露的API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的API 接口, 防止其被外界直接调用,导致服务的敏感信息对外暴露。
口 网关服务可以做用户身份认证和权限认证,防止非法请求操作API 接口,对服务器起到保护作用。
口 网关可以实现监控功能,实时日志输出,对请求进行记录。
口 网关可以用来实现流量监控, 在高流量的情况下,对服务进行降级。
口 API 接口从内部服务分离出来, 方便做测试。
7.2 Zuul的工作原理
Zuul 是通过Servlet 来实现的, Zuul 通过自定义的ZuulServlet (类似于Spring MVC 的DispatchServlet〕来对请求进行控制。Zuul 的核心是一系列过滤器,可以在Http 请求的发起和响应返回期间执行一系列的过滤器。Zuul 包括以下4 种过滤器。
口PRE 过滤器: 它是在请求路由到具体的服务之前执行的,这种类型的过滤器可以做安全验证,例如身份验证、参数验证等。
口ROUTING 过滤器: 它用于将请求路由到具体的微服务实例。在默认情况下,它使用Http Client 进行网络请求。
口POST 过滤器:它是在请求己被路由到微服务后执行的。一般情况下,用作收集统计信息、指标,以及将响应传输到客户端。
口ERROR 过滤器:它是在其他过滤器发生错误时执行的。Zuul 采取了动态读取、编译和运行这些过滤器。过滤器之间不能直接相互通信,而是通过RequestContext 对象来共享数据, 每个请求都会创建一个RequestContext 对象。Zuul 过滤器具有以下关键特性。
口Type (类型) : Zuul 过滤器的类型,这个类型决定了过滤器在请求的哪个阶段起作用,例如Pre 、Post 阶段等。
口Execution Order (执行顺序) :规定了过滤器的执行顺序, Order 的值越小,越先执行。
口Criteria (标准) : Filter 执行所需的条件。
口Action (行动): 如果符合执行条件,则执行Action (即逻辑代码)。
Zuul 请求的生命周期如图9-1 所示,该图来自Zuul 的官方文档。当一个客户端Request 请求进入Zuul 网关服务时,网关先进入“pre filter飞进行一系列的验证、操作或者判断。然后交给“routing filter ”进行路由转发,转发到具体的服务实例进行逻辑处理、返回数据。当具体的服务处理完后,最后由“post filter 进行处理, 该类型的处理器处理完之后,将Response 信息返回给客户端。
7.3 在Zuul 上配置熔断器
Zuul 作为Netflix 组件,可以与Ribbon 、Eureka 和Hystrix 等组件相结合,实现负载均衡、熔断器的功能。在默认情况下, Zuul 和Ribbon 相结合, 实现了负载均衡的功能。下面来讲解如何在Zuul 上实现熔断功能。在Zuul 中实现熔断功能需要实现ZuulFallbackProvider 的接口。实现该接口有两个方法, 一个是getRouteO方法,用于指定熔断功能应用于哪些路由的服务; 另一个方法fallbackResponseO为进入熔断功能时执行的逻辑。
7.4 在Zuul 中使用过滤器
在前面的章节讲述了过滤器的作用和种类,下面来讲解如何实现一个自定义的过滤器。实现过滤器很简单, 只需要继承ZuulFilter ,井实现Zuu!Filter 中的抽象方法,包括filterType()和filterOrder(),以及ZuulFilter 的shouldFilter()和0bject run()的两个方法。其中, filterType()即过滤器的类型,在前文已经讲解过了,它有4 种类型,分别是“ pre '’“ post ”“ routing ”和“ error ” 。白lterOrder()是过滤顺序,它为一个Int 类型的值,值越小,越早执行该过滤器。shouldFilter()表示该过滤器是否过滤逻辑,如果为true ,则执行run()方法:如果为false ,则不执行run ()方法。run ()方法写具体的过滤的逻辑。
7.5 Zuul 的常见使用方式
Zuul 是采用了类似于Spring MVC 的DispatchServlet 来实现的,采用的是异步阻塞模型,所以性能比Ngnix 差。由于Zuul 和其他Netflix 组件可以相互配合、无缝集成, Zuul 很容易就能实现负载均衡、智能路由和熔断器等功能。在大多数情况下Zuul 都是以集群的形式存在的。由于Zuul的横向扩展能力非常好,所以当负载过高时,可以通过添加实例来解决性能瓶颈。一种常见的使用方式是对不同的渠道使用不同的Zuul 来进行路由,例如移动端共用一个Zuul 网关实例, Web 端用另一个Zuul 网关实例,其他的客户端用另外一个Zuul 实例进行路由。这种不同的渠边用不同Zuul 实例的架构如图9-3 所示。
另外一种常见的集群是通过Ngnix 和Zuul 相互结合来做负载均衡。暴露在最外面的是Ngnix 主从双热备进行Keepalive, Ngnix 经过某种路由策略,将请求路由转发到Zuul 集群上,Zuul 最终将请求分发到具体的服务上,架构图如图9-4 所示。
八、配置中心
8.1 分布式配置中心Spring Cloud Config
口Config Server 从本地读取配置文件。
Config Server 可以从本地仓库读取配置文件,也可以从远处Git 仓库读取。本地仓库是指将所有的配置文件统一写在Config Server 工程目录下。Config Sever 暴露HttpAPI 接口, ConfigClient 通过调用Config Sever 的H即API 接口来读取配置文件。
spring:
cloud:
config:
server:
native:
search-locations: classpath:/shared
profiles:
active: native
application:
name: config- server
server:
port: 8769
在工程的Resources 目录下建一个shared 文件夹,用于存放本地配置文件。在shared 目录下,新建一个config-client-dev. yml 文件,用作eureka-client 工程的dev (开发环境)的配置文件。在config-client-dev.yml 配置文件中,指定程序的端口号为8762 , 并定义一个变量 foo , 该变量的值为foo version l。
口Config Server 从远程Git 仓库读取配置文件。
Spring Cloud Config 支持从远程Git 仓库读取配置文件,即Config Server 可以不从本地的仓库读取,而是从远程Git 仓库读取。这样做的好处就是将配置统一管理,并且可以通过SpringCloud Bus 在不人工启动程序的情况下对Config Client 的配置进行刷新。
server:
port:8769
spring:
cloud:
config:
server:
git:
uri: https://github.com/forezp/SpringcloudConfig
searchPaths: respo
username: miles02@163.com
password:
label: master
application:
name: config-server
其中, uri 为远程Git 仓库的地址, serachPaths 为搜索远程仓库的文件夹地址, usemame和password 为Git 仓库的登录名和密码。如果是私人Git 仓库,登录名和密码是必须的;如果是公开的Git 仓库,可以不需要。label 为git 仓库的分支名。
口搭建高可用Co nfig Server 集群。当服务实例很多时,所有的服务实例需要同时从配置中心Config Server 读取配置文件,这时可以考虑将配置中心Config Server 做成一个微服务,并且将其集群化,从而达到高可用。
口使用Spring Cloud Bus 刷新配置。
Spring Cloud Bus 是用轻量的消息代理将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。个关键的思想就是,消息总线可以为微服务做监控,也可以实现应用程序之间相I T-L 通信。S pring Cloud Bus 可选的消息代理组建包括RabbitMQ 、AMQP 和Kafka 等。本节讲述的是用RabbitMQ 作为Spring Cloud 的消息组件去刷新更改微服务的配置文件。
九、服务链路追踪
Spring Cloud Sleuth 是Spring Cloud 的一个组件,它的主要功能是在分布式系统中提供服务链路追踪的解决方案。
使用分布式链路的意义
微服务架构是一个分布式架构,微服务系统按业务划分服务单元, 一个微服务系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性较高,如果出现了错误和异常,很难去定位。主要体现在一个请求可能需要调用很多个服务,而内部服务的调用复杂性决定了问题难以定位。所以在微服务架构中,必须实现分布式链路追踪, 去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题能够快速定位的目的。
常见链路追踪组件
常见的链路追踪组件有Google 的Dapper 、Twitter 的Zipkin , 以及阿里的Eag leeye(鹰眼)等,它们都是非常优秀的链路追踪开源组件。本章主要讲述如何在Spring Cloud Sleuth 中集成Zipkin o 在Spring Cloud Sleuth 中集成Zipkin 非常简单,只需要引入相应的依赖并做相关的配置即可。.
zipkin-server作为链路追踪服务中心,负责存储链路数据。gateway-service 作为服务网关工程,负责请求的转发,同时它也作为链路追踪客户端,负责产生链路数据,并上传给zipkin-service 。user-service是一个服务提供者,对外暴露API 接口,同时它也作为链路追踪客户端,负责产生链路数据。
Maven依赖
<parent>
<groupid>com.forezp</groupid>
<artifactid>sleuth</artifactid>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud starter eureka</artifactid>
</dependency>
<dependency>
<groupid>io.zipkin.java</groupid>
<artifactid>zipkin-server</artifactid>
</dependency>
<dependency>
<groupid>io.zipkin.java</groupid>
<artifactid>zipkin-autoconfigure-ui</artifactid>
</dependency>
</dependencies>
程序启动类
在程序的启动类ZipkinServiceApplication 加上@EnableZipkinSe凹er 注解,开启ZipkinServer 的功能,加上@EnableEurekaClient 注解, 启动Eureka Client,代码如下:
@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class zipkinServerApplication {
public statrt void main(String[] args) {
SpringApplication.run(ZipkinServerApplication.class , args) ;
}
}
在程序的配置文件application.yml 文件做程序的相关配置,指定程序名为zipkin-server,端口号为9411 , 服务注册地址为http://localhost:8761 /eureka/,代码如下:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 9411
spring:
application:
name: zipkin-server
操作界面
使用刷刷tMQ 传输链路数据
Spring Cloud Sleuth 中支持消息组件来传输链路数据, 本节使用RabbitMQ 来传输链路数据。首先改造zipkin咽rver 工程, 在其porn 文件中将zipkin 咽rver 的依赖去掉,加上spring-cloud-sleu出-zipkin-stream 和spring-cloud-starter-stream-rabbit 的依赖,代码如下:
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-sleuth-zipkin-stream</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-stream-rabbit</artifactid>
</dependency>
在工程的配置文件application.yml 加上RabbitMQ 的配置,包括host 、端口、用户名、密码,代码如下:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
在程序的启动类ZipkinServerApplication 中加上@EnableZipkinStreamServer 注解,开启ZipkinStreamServer,代码如下:
@SpringBootApplication
@EnableEurekaClient
@EnableZipkinStreamServer
public class ZipkinServerApplication {
public static void main (String [] args) {
SpringApplication.run(ZipkinServerApplication.class , args) ;
}
}
十、微服务监控
Spring Boot Admin 是一个管理和监控你的Spring Boot程序的应用程序。 这些应用程序通过 Spring Boot Admin Client(通过 HTTP)注册或者使用 Spring Cloud(例如 Eureka)发现。 UI只是 Spring Boot Actuator 端点上的一个 AngularJs 应用程序。
1、搭建Admin Server服务端
新建model:admin-server
pom.xml
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
2、应用主类添加注解并添加配置(这个配置来资源官方文档推荐):
@SpringBootApplication
@EnableAdminServer
@EnableEurekaClient
public class AdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(AdminServerApplication.class, args);
}
@Profile("insecure")
@Configuration
public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll()//
.and().csrf().disable();
}
}
@Profile("secure")
@Configuration
public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf().disable();
// @formatter:on
}
}
}
3、修改客户端
在原来service-feign,service-ribbon,eureka-client三个model的基础上修改其依赖和配置,新增依赖:
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.0.1</version>
</dependency>
配置文件新增配置:
spring:
boot:
admin:
client:
url: "http://localhost:9997"
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
Spring Boot 的 Actuator 只暴露了 /health、/info 两个端口(为了安全考虑),所以要配置 management.endpoints.web.exposure.include 的属性。
十一、SpringSecurity
1、简介
一个能够为基于Spring的企业应用系统提供声明式的安全訪问控制解决方式的安全框架(简单说是对访问权限进行控制嘛),应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。 spring security的主要核心功能为 认证和授权,所有的架构也是基于这两个核心功能去实现的。
2、框架原理
众所周知 想要对对Web资源进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。所以springSecurity在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全。
如下为其主要过滤器
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
UsernamePasswordAuthenticationFilter
BasicAuthenticationFilter
3、框架的核心组件
SecurityContextHolder:提供对SecurityContext的访问
SecurityContext,:持有Authentication对象和其他可能需要的信息
AuthenticationManager 其中可以包含多个AuthenticationProvider
ProviderManager对象为AuthenticationManager接口的实现类
AuthenticationProvider 主要用来进行认证操作的类 调用其中的authenticate()方法去进行认证操作
Authentication:Spring Security方式的认证主体
GrantedAuthority:对认证主题的应用层面的授权,含当前用户的权限信息,通常使用角色表示
UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
UserDetailsService:通过username构建UserDetails对象,通过loadUserByUsername根据userName获取UserDetail对象 (可以在这里基于自身业务进行自定义的实现 如通过数据库,xml,缓存获取等)