springcloud分布式项目使用nacos集成到common项目中

实际工作中我们开发架构大多数使用spring cloud的分布式架构,会有很多服务比如订单服务order-server, 基础服务base-server, 库存服务stock-server等,这些服务可能公用一个nacos,那么每个服务就都会初始化nacos信息增加配置,这个时候我们就可以把nacos以及redis,mq等一些公用的信息抽出来放到一个如common-framework的服务里面,每个项目只需要引用这个common-framework服务就可以实现初始化,各个服务只需要在配置文件properties里面添加对应的
服务器地址即可。

新建一个common-framework项目,pom.xml增加nacos配置


    com.alibaba.nacos
    nacos-client
    2.0.4
    compile




    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-discovery



    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-config


增加一个nacos配置类

@Slf4j
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.cloud.nacos.discovery")
public class NacosPropertiesConfig {

    private String serverAddr;

    private String namespace;

    /**
     * 初始化nacos
     * @throws NacosException
     */
    @Bean
    public void nacosBaseProperties() throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        NacosUtil.init(properties);
        log.info("nacos properties init success!");
    }
}

Nacos初始化工具类 NacosUtil

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.cdws.common.utils.network.NetworkUtil;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * nacos初始化工具类
 */
public class NacosUtil {

    private static NamingService namingService;

    public static Properties nacosProperty = new Properties();

    /**
     * 初始化nacos
     * @param nacosProperties
     * @throws NacosException
     */
    public static void init(Properties nacosProperties) throws NacosException {
        nacosProperty = nacosProperties;
        namingService = NamingFactory.createNamingService(nacosProperties);
    }

    /**
     * 验证服务是否存在
     * @param serviceName
     * @throws RuntimeException
     */
    private static void valiNacos(String serviceName) throws RuntimeException {
        Assert.isTrue(!StringUtils.isEmpty(serviceName), "Please input service name");
        Assert.isTrue(null != namingService, "Nacos properties is not init, plase init nacos properties");
    }
}

实际工作中我们会分dev,test和prod环境,在使用openFeign调用时经常出现开发把自己的服务注册到Nacos上面去了,导致在服务调用的时候路由到同事本地电脑上去了,如果同事没有更新代码那么就会调的返回结果不是我们想要的,因此我们需要把开发本地环境启动的服务禁止注册到dev,test的nacos服务列表上去。

新建一个不注册到Nacos的配置类

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 排除非开发环境注册到Nacos的服务
 * 创建日期: 2022/5/5
 */
@Slf4j
@Order
@Component
public class NacosNeverRegister implements CommandLineRunner {

    @Value("${spring.profiles.active}")
    private String active;

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${spring.cloud.nacos.server-addr}")
    private String serverAddr;

    @Value("${spring.cloud.nacos.discovery.namespace}")
    private String namespace;

    /**
     * 开发环境ip地址
     **/
    private static final List ips = Arrays.asList("192.168.1.101", "192.168.1.102", "192.168.1.103");

    @Override
    public void run(String... args) {
        new Thread(() -> {
            try {
                if ("dev".equals(active)) {
                    Properties properties = new Properties();
                    properties.put("serverAddr", serverAddr);
                    properties.put("namespace", namespace);
                    int row = 0;
                    // 这里查询3次每次睡眠2秒防止项目启动的时候第一次查询没有查到
                    while (row < 3) {
                        List allInstances = NacosFactory.createNamingService(properties).getAllInstances(applicationName);
                        for (Instance i : allInstances) {
                            if (ips.contains(i.getIp())) {
                                i.setEnabled(true);
                            } else {
                                log.info("检测到IP为:" + i.getIp() + " 非开发环境部署,Nacos服务状态设置不可用,避免其他服务访问到本机.");
                                i.setEnabled(false);
                            }
                            NacosFactory.createMaintainService(properties).updateInstance(i.getServiceName(), i);
                        }
                        row++;
                        Thread.sleep(2000);
                    }
                }
            } catch (Exception e) {
                log.error("NacosNeverRegister 异常", e);
            }
        }).start();
    }
}

order-server使用nacos,pom.xml增加nacos配置jar包


    com.alibaba.nacos
    nacos-client
    2.0.4
    compile




    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-discovery



    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-config



    com.lockie
    common-framework

配置文件properties增加nacos地址配置

### server-address
spring.cloud.nacos.server-addr=127.0.0.1:8080
### spring cloud discovery
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.nacos.discovery.namespace=xxxxxxxxxxxxx
### spring cloud config
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.nacos.config.namespace=xxxxxxxxxxxxx

启动order-server服务,我们到nacos控制台找到order-server服务中心,发现有2个服务,一个是dev环境的,另一个是我们本地环境的,我们本地环境的没有上线处于下线状态,这样被人的请求就不会路由到我们的电脑上来。

springcloud分布式项目使用nacos集成到common项目中_第1张图片

 我们order-server引用了common-framework里面初始化了nacos配置,这样在order-server服务里面就不需要再创建nacosConfig配置类了

你可能感兴趣的:(nacos,spring,cloud,分布式,java)