实际工作中我们开发架构大多数使用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环境的,另一个是我们本地环境的,我们本地环境的没有上线处于下线状态,这样被人的请求就不会路由到我们的电脑上来。
我们order-server引用了common-framework里面初始化了nacos配置,这样在order-server服务里面就不需要再创建nacosConfig配置类了