前言
本文约定:
- SpringBootAdmin - SBA
- SpringSecurity - SSE
以当前我在搜索引擎检索的情况来看,大家对于SBA的应用都比较局限,发散性使用很少,基本都是基于官网给的例子(eureka-SBA-SSE),
而且网上的各文章,出现了一些很容易让人迷惑的问题,就比如引入依赖的部分SpringCloudAlibaba在引入依赖的时候竟然出现了两种GroupId...,
为此我也被绕晕了,故基于最新的版本以及SpringCloudAlibaba推荐的方式,对SBA-SSE-Nacos进行了一下集成,并写了这篇文章,希望后面看到的人避免再淌这个坑
Ps.不得不说微服务各界的版本是真的很混乱。
开始
安装Nacos
具体安装教程,可以参考官网,这里不再赘述,安装很简单。 版本:1.4+(其实1.1以上应该都可以)
创建项目
一个maven项目即可,按一般的教程会创建两个项目,一个作为Admin Server,一个作为Admin Client, 这里为了减少大家的学习成本,本示例会直接将本项目在作为AdminServer的同时,同时配置以客户端的身份注册到AdminServer.
引入依赖
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.6</spring-boot-admin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--安全模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Admin Server-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<!--nacos 配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<!--nacos 注册中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<!--作为AdminServer的客户端时必须引入的依赖 start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<!--用于开放JMX操作-->
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
<!--作为AdminServer的客户端时必须引入的依赖 end-->
</dependencies>
配置
创建AdminServerApp类
这么多代码,不慌,直接把这里面内容全丢进去即可,不需要改
/**
* @author vate
* @date 2019/12/18 23:03
*/
@SpringBootApplication
@EnableAdminServer // 作为AdminServer启动
@EnableDiscoveryClient // 开启服务发现
public class AdminServerApp {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(AdminServerApp.class);
springApplication.run(args);
}
@Profile("dev")
@Configuration()
public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecurityPermitAllConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminContextPath + "/instances", HttpMethod.POST.toString()),
new AntPathRequestMatcher(this.adminContextPath + "/instances/*",
HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(this.adminContextPath + "/actuator/**"));
}
}
@Profile("pro")
@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");
successHandler.setDefaultTargetUrl(this.adminContextPath + "/");
http.authorizeRequests()
.antMatchers(this.adminContextPath + "/assets/**").permitAll()
.antMatchers(this.adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(this.adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(this.adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminContextPath + "/instances", HttpMethod.POST.toString()),
new AntPathRequestMatcher(this.adminContextPath + "/instances/*", HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(this.adminContextPath + "/actuator/**")
);
// @formatter:on
}
}
}
创建bootstrap.yaml文件
填入以下内容,配置nacos服务中心
spring:
application:
name: admin-server
cloud:
# nacos配置
nacos:
discovery:
server-addr: xxx:8848
创建application.yaml文件
spring:
profiles:
active: pro,admin
server:
port: 3333
---
spring:
profiles: dev
---
spring:
profiles: pro
security:
user:
name: "user"
password: "password"
cloud:
nacos:
discovery:
# 将本服务实例注册到服务中心时,在元信息中携带访问本服务使用的用户名和密码
metadata:
user.name: "user"
user.password: "password"
# 如果采用eureka做注册中心时,将采用该配置
eureka:
instance:
# 将本服务实例注册到服务中心时,在元信息中携带访问本服务使用的用户名和密码
metadata-map:
user.name: "user" #These two are needed so that the server
user.password: "password" #can access the protected client endpoints
在上面的配置文件中,不管是作为Nacos的客户端还是Eureka的客户端,我们都有一个metadata的配置:
nacos:
metadata:
user.name: "user"
user.password: "password"
eureka:
metadata-map:
user.name: "user"
user.password: "password"
这个配置极其重要, 对于集成了Security的项目来讲,我们的所有接口都是被保护起来的,试问当我将本实例注册到注册中心, 却不提供访问的帐号和密码,Admin Server如何去访问本实例的接口获取状态信息呢,所以该配置的含义就是将本实例定义的Security框架的用户名和密码作为元信息一并上传到注册中心, 以让AdminServer在从注册中心拉取注册服务列表的同时,能获取到访问每个服务的密钥,因此才可以让Admin Server的监控功能起作用。
创建application-admin.yaml文件
填入以下内容
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
这些配置我就不解释了,读者后续可以自行去搜索引擎检索SpringBoot Actuator配置详解。
启动应用
查看Nacos界面:
Nacos的默认用户名/密码为:nacos/nacos
登录:
首页:
Wallboard:
点击方块进去看看:
successfully.
后记
看到这里读者可能会有个疑惑,被监控的客户端呢?AdminServer不是服务端吗,Admin客户端的配置呢?
解答:当我们集成了Nacos的服务发现依赖starter后,当应用启动时Nacos客户端就会自动将我们的服务实例注册到Nacos注册中心。
而AdminServer和注册中心集成的原理,
其实就是把原来Client直接获取到AdminServer的地址并且手动将自身注册进AdminServer的方式,变成了AdminClient服务注册至注册中心,
而AdminServer直接去注册中心动态获取所有注册服务的方式来监控所有服务(当然前提是该客户端集成了Actuator,且正确配置了相关访问的元信息)。
到这里也不得不再提一遍如果AdminClient集成了Security则一定要在元信息中携带用户访问信息:
nacos:
metadata:
user.name: "user"
user.password: "password"
eureka:
metadata-map:
user.name: "user"
user.password: "password"
来源:oschina
链接:https://my.oschina.net/u/3387406/blog/3197717