随着微服务的流行,相比较以前一个大型应用程序搞定所有需求,我们现在更倾向于把大型应用程序切分成多个微服务。而SpringBoot是微服务的基础,一个一个的微服务构成了一个错综复杂的系统,spring-boot-starter-actuator 是SpringBoot下的一个包它提供了监控接口,例如:/health、/info等等,实际上除了之前提到的信息,还有其他信息业需要监控:当前处于活跃状态的会话数量、当前应用的并发数、服务资源、延迟以及其他度量信息,精简配置。而SpringBootAdmin正是基于这些接口开发了一套功能强大的监控系统。
创建SpringBootAdmin的Server端
1.加入以下依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
2.在application中加入注解如下
@Configuration
@EnableAutoConfiguration
@EnableAdminServer
public class SpringBootAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminApplication.class, args);
}
}
创建SpringBootAdmin的Client端
1.加入以下依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
client中引入很多其他包,目前用到的是 jolokia
(用来添加JMX功能) 和 actuator
(SpringBoot提供的监控端点所依赖的包)。
2.配置文件中添加
spring.boot.admin.url: http://localhost:8080 //要注册的服务端
management.security.enabled: false //SpringBoot 1.5以后的版本都默认开启端点保护
SpringBootAdmin的Server端也可以注册在eureka这样的管理中心上,好处是可以监控所有注册在eureka上的服务,SpringBootAdmin客户端无需再配置服务端,注册到Eureka上后,SpringBootAdmin可以定时拉取服务注册列表,无需再为服务节点配置监控中心的地址。
为监控系统添加权限保护
为server端设置登陆页面和权限
1.在server端中需要引入如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-login</artifactId>
</dependency>
2.修改配置文件
security.user.name=aa
security.user.password=aa //登陆用户名密码
security.basic.enabled=false //关掉security框架自带的登陆弹出框
3.配置config类
@Bean
public HttpHeadersProvider httpHeadersProvider() {
return new ServerAuthHttpHeaderProvider();
}
@Override
public void configure(WebSecurity web) throws Exception {
//忽略css.jq.img等文件
web.ignoring().antMatchers("/**.html", "/**.css", "/img/**", "/**.js", "/third-party/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll().defaultSuccessUrl("/")
.and()//Logout Form configuration
.logout()
.deleteCookies("remove")
.logoutSuccessUrl("/login.html").permitAll()
.and().authorizeRequests().antMatchers(HttpMethod.POST, "/apiapplications/").permitAll()
.antMatchers("/health").permitAll()
.anyRequest().authenticated()//
.and().csrf().ignoringAntMatchers("/api/**", "/**")
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
为client端设置端点保护
1.加入如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.修改配置文件
#可在线查看日志
endpoints.logfile.enabled=true
logging.file=fileDir
#客户端开启停止服务端点
endpoints.shutdown.enabled=true
#保护客户端端点数据
security.user.name=aa
security.user.password=aa
security.basic.path=/aa
eureka.instance.metadata-map.user.name=${security.user.name}
eureka.instance.metadata-map.user.password=${security.user.password}
Eureka中的metadataMap是专门用来存放一些自定义的数据,当注册中心或者其他服务需要此服务的某些配置时可以在metadataMap里取。实际上,每个instance都有各自的metadataMap,map中存放着需要用到的属性。例如,上面配置中的eureka.instance.metadata-map.user.name
,当这个服务成功注册到Eureka上,SpringBootAdmin就会取拿到这个instance,进而拿到metadataMap里的属性,然后放入请求头,向此服务发送请求,访问此服务的actuator开放的端点。
为了避免Zuul请求路由到别的系统泄露一些重要信息,在请求头中默认没有这三个属性。而SpringSecurity是通过请求中的请求头Authentiction来取账号密码,所以每次提交账号密码验证的时候都获取不到,解决办法是修改zuul配置 zuul.sensitive-headers=
覆盖zuul的默认配置即可。
网友评论