本次讲解的是如何实现eureka
自定义注册,本次模拟的场景是当客户端往注册服务端上注册时,注册服务端会判断当前的客户端是否可以通过注册(获取当前客户端的IP能否与注册服务端的IP池匹配)来进行注册通过或者拒绝。
背景:
springboot 项目
maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<version>18.0</version>
<artifactId>guava</artifactId>
</dependency>
<!-- fast json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
config配置
/**
* 配置注册需要的bean
*/
@Component
@Slf4j
public class FactoryConfig implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext ac;
@Value("${spring.profiles.active:#{null}}")
private String profiles;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ac = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("peerAwareInstanceRegistry".equals(beanName)) {
System.out.println(bean + "," + beanName);
log.info(bean + "," + beanName);
CustomInstanceRegistryDecorator decorator = new CustomInstanceRegistryDecorator(
ac.getBean(EurekaServerConfig.class),
ac.getBean(EurekaClientConfig.class),
ac.getBean(ServerCodecs.class),
ac.getBean(EurekaClient.class),
ac.getBean(WhiteListThird.class)
);
decorator.setWhiteListService(profiles);
decorator.setApplicationContext(ac);
return decorator;
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
/**
* 自定义注册
*/
@Slf4j
public class CustomInstanceRegistryDecorator extends InstanceRegistry {
private String profiles;
private WhiteListThird whiteListThird;
public CustomInstanceRegistryDecorator(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig,
ServerCodecs serverCodecs, EurekaClient eurekaClient,
WhiteListThird whiteListThird) {
super(serverConfig, clientConfig, serverCodecs, eurekaClient,
1, 1);
this.whiteListThird = whiteListThird;
}
public void setWhiteListService(String profiles) {
this.profiles = profiles;
}
@Override
public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
if (checkRegister(info)) {
super.register(info, isReplication);
}
}
@Override
public void register(final InstanceInfo info, final boolean isReplication) {
if (checkRegister(info)) {
super.register(info, isReplication);
}
}
public boolean checkRegister(InstanceInfo info) {
Boolean allow = false;
String registerIp = info.getIPAddr();
//拦截黑名单
if (BlackIpCache.isBlackIp(registerIp)) return allow;
log.info("=====================custom=====================");
List<String> ipLists = IpContextHandler.getInstance().getIpList();
if (CollectionUtils.isEmpty(ipLists)) {
// 通过第三方接口获取当前注册服务器的环境,并查出当前环境下的已分配到服务器
whiteListThird.getInstanceIpList(IpContextHandler.getInstance().getLocalIp());
return allow;
}
for (String ip : ipLists) {
if (ip.equals(registerIp)) {
allow = true;
}
}
if (!allow) {
BlackIpCache.add(registerIp);
StringBuffer sb = new StringBuffer().append("客户端[" + info.getAppName())
.append("," + info.getInstanceId()).append("," + info.getIPAddr())
.append("," + info.getPort() + "被拒绝注册!");
log.info(sb.toString());
}
return allow;
}
}