spring boot启动找不到log4j 系统找不到指定的文件_dubbo实战技巧:启动服务但是根据环境决定是否注册...

本文介绍了如何在dubbo微服务中根据开发环境决定是否注册到注册中心。通过实现Spring的ApplicationContextInitializer并在启动时判断操作系统环境,避免影响其他开发者。在开发环境下,服务不注册,而在测试或生产环境中正常注册。
摘要由CSDN通过智能技术生成

今天给大家分享一个实用技能,dubbo随心注册,让你的微服务根据实际需要来决定是否发布到注册中心。

我是一个热衷于编程和解决问题的'资深'码农,目前正在开发一个venus的商城项目,在这个过程中我会把各种有趣有料的技术技能记录下来(vue前端/dubbo微服务/可能还有大数据哦),感兴趣的朋友欢迎关注和交流。

d2bd520c59952714e06efd54b4f0b0cc.png

本文使用的技术和版本如下:

dubbo 2.7.8spring-boot  2.2.10

问题的由来

为什么会有启动服务却不想注册到注册中心去的需求?如果你正在做微服务的项目,只要不是只有你一个人做开发,那么你就会碰到这种情况:我正在开发或者修改的服务还未完成,我本地启动服务是为了自己验证,自己启动一个本地的消费者,直接调用自己的服务提供者,因为服务没有完成,如果我把它注册到注册中心,那就会有别的消费者的请求发到我这里,我正在做的修改就会对其他人产生影响。

为了保证我在做的事情不影响其他人,我难道就不能启动本地的服务了?这肯定不行,所以就有了这么一个问题,我想启动服务的时候,自己能够根据情况决定要不要注册到nacos或者zookeeper等注册中心上去,这个问题有两个方法:

1、我本地启动的时候,将dubbo的组修改成一个单独的组,这样我就算注册上去,别人和我不在一个组里,他的请求也不会到我这里来。

这种方法可行,但是麻烦,需要在本地修改配置文件,而且要提交的时候,不能把你本地的配置提交上去,但是谁能保证你每次提交前都会记得把配置还原呢??

2、本地启动的时候,我服务就不注册过去了,自己要测试的话,在消费者项目中,指定调用本地localhost的服务(dubbo是可以绕过注册中心的,消费者和服务提供者直联)

这种方式就是本文介绍的内容。

在dubbo中该如何设置?

dubbo服务启动的时候如果不需要注册,那么在配置文件中添加下面一行是最简单的方法:

dubbo.registry.register=false

但是真正的需求并非这么简单,配置文件中这么改了,就像上面第一种方法,又不能推送到远程,不是一劳永逸的解决之道。

这就要另想办法了,我的思路是,我们要根据本地操作系统环境来决定是否注册,windows和mac一般是开发用的,那就不注册,如果是linux,一般是部署测试环境的,这种就正常注册,有两种方式可以尝试:

1、要么介入修改dubbo的初始化过程,在dubbo启动时,判断环境并修改Registry相关的类。

2、要么就介入spring-boot的初始化过程,在dubbo初始化之前,我往环境中设置dubbo.registry.register的值。

第一种方式我翻了官方文档没有找到可行的方法(也可能是我技艺不精,手动狗头:) )。最终只能锁定第二种方法了,我首先想到的就是分布式项目可能会使用的配置中心,类似于apollo和nacos这种,这种框架也是在spring启动时,从远程获取一些配置,然后项目根据这些配置初始化,项目运行过程中,再监听远程的配置变化,实现灰度发布等等功能,跟我第二中方法的思路一致。

配置中心的切入点,就是spring的ApplicationContextInitializer了。

spring的ApplicationContextInitializer的作用

这个接口其实定义了一种行为,可以让我们在spring项目初始化的过程中,插入我们自己希望执行的代码,我们只需要定义一个类实现这个接口,就像下面这样:

import org.springframework.context.ApplicationContextInitializer;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.core.annotation.Order;import org.springframework.core.env.ConfigurableEnvironment;import org.springframework.core.env.PropertiesPropertySource;import org.springframework.core.env.StandardEnvironment;import java.util.Properties;@Order(1)  //这个顺序决定spring初始化的顺序,越小越优先执行@Log4j2public class DubboConfiguration implements ApplicationContextInitializer {    @Override    public void initialize(ConfigurableApplicationContext applicationContext) {        if(VenusEnvironmentUtils.isDevelopEnv()) {            ConfigurableEnvironment environment = new StandardEnvironment();            Properties properties = new Properties();            properties.put("dubbo.registry.register", false);            PropertiesPropertySource propertySource = new PropertiesPropertySource("dubbo.debug", properties);            environment.getPropertySources().addFirst(propertySource);            applicationContext.setEnvironment(environment);            log.info("develop environment, set dubbo.registry.register=false");        }    }}

将自己实现的ApplicationContextInitializer添加到spring的启动序列中

但是上面我们定义的类,并不会被spring自动发现(使用@Component注解也不行),我们就需要手动将其加入到spring的初始化中了,那我们要从SpringApplication中找答案了。

spring-boot的启动方法可以改成下面这样:

public static void main( String[] args) {        //ConfigurableApplicationContext application = SpringApplication.run(UserApplication.class, args);        SpringApplication application = new SpringApplication(UserApplication.class);        application.addInitializers(new DubboConfiguration());        application.run(args);}

我们的自定义的ApplicationContextInitializer就完美加入其中了。

根据环境来决定是否向注册中心注册

最后看一下我们的判断方法,isDevelopEnv()

public class VenusEnvironmentUtils {    private static String system = System.getProperty("os.name").toLowerCase();    public static boolean isWindows(){        return system.contains("windows");    }    public static boolean isMac(){        return system.contains("mac") && system.indexOf("os")>0 && system.indexOf("x")>0;    }    /**     * 本地开发环境,识别windows操作系统和mac操作系统     * @return     */    public static boolean isDevelopEnv(){        return isMac() || isWindows();    }}

这样就完美实现了目标,这个服务在部署到测试环境或者生产环境中时,服务正常注册,在我们本地启动的时候,就不向注册中心注册了,只用于我们本地直接调用,对别人和测试环境都不会有影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值