Nacos使用(上):Nacos安装
Nacos使用(中):Java项目和Spring项目使用Nacos
Nacos使用(下):SpringBoot和SpringCloud项目中使用Nacos
3.3 SpringBoot SDK
父工程指定springboot版本:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
导入jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--配置中心-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.12</version>
</dependency>
<!--服务治理-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.12</version>
</dependency>
配置文件application.properties
spring.application.name=boot-test
server.port=8080
#配置中心
nacos.config.server-addr=127.0.0.1:8848
nacos.config.username=nacos
nacos.config.password=nacos
nacos.config.namespace=dev
#注册中心
nacos.discovery.server-addr=127.0.0.1:8848
nacos.discovery.username=nacos
nacos.discovery.password=nacos
nacos.discovery.namespace=dev
启动类
package com.test.nacos;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
/**
* @author 专治八阿哥的孟老师
*/
@SpringBootApplication
// 读取配置中心配置文件
@NacosPropertySource(dataId = "example.properties", autoRefreshed = true)
// 启动服务治理
@EnableNacosDiscovery
public class BootTestStarter {
public static void main(String[] args) {
SpringApplication.run(BootTestStarter.class, args);
}
}
Nacos上创建一个配置文件
属性可以直接通过@NacosValue读取,也可以映射到一个配置类中
配置类:
package com.test.nacos;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author 专治八阿哥的孟老师
*/
@Component
@NacosConfigurationProperties(prefix = "test", dataId = "example.properties", autoRefreshed = true)
public class TestConfiguration {
private String config;
public String getConfig() {
return config;
}
public void setConfig(String config) {
this.config = config;
}
}
测试类
package com.test.nacos;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
/**
* @author 专治八阿哥的孟老师
*/
@Component
public class TestBean {
@NacosInjected
private ConfigService configService;
// 服务名称
@Value("${spring.application.name}")
private String applicationName;
// 服务的端口号
@Value("${server.port}")
private Integer port;
// 远程配置,直接读取属性
@NacosValue(value = "${test.config}", autoRefreshed = true)
private String config;
@Autowired
private TestConfiguration testConfiguration;
@NacosInjected
private NamingService namingService;
@PostConstruct
public void register() throws NacosException {
// 测试服务注册
namingService.registerInstance(applicationName, "127.0.0.1", port);
}
@PostConstruct
public void init() {
try {
System.out.println(configService.getConfig("example.properties", "DEFAULT_GROUP", 5000));
System.out.println(config);
System.out.println(testConfiguration.getConfig());
} catch (NacosException e) {
throw new RuntimeException(e);
}
}
}
3.4 SpringCloud
父工程指定:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.4.1 配置中心
在 Nacos Spring Cloud 中,
dataId
的完整格式如下,其中**${prefix}
**默认是spring.application.name,可以通过配置
${prefix}-${spring.profiles.active}.${file-extension}
Nacos Spring Cloud默认使用的是bootstrap.properties文件
spring.application.name=consumer
spring.profiles.active = dev
不同环境使用不同配置文件,bootstrap-dev.properties内容为如下
server.port=8080
spring.cloud.nacos.config.server-addr=http://localhost:8848
spring.cloud.nacos.config.namespace=${spring.profiles.active}
spring.cloud.nacos.config.file-extension=properties
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
在Nacos上添加配置文件,文件的dataId要与当前项目的application-name对应
spring.datasource.url = jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username =root
spring.datasource.password =
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
测试类
package com.test.consumer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 专治八阿哥的孟老师
*/
@RestController
@RefreshScope // 自动刷新
public class TestController {
//从nacos读取
@Value("${spring.datasource.url}")
private String url;
@RequestMapping("test")
public String test() { //访问接口可以看读取出的配置
return url;
}
}
启动类
package com.test.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 专治八阿哥的孟老师
*/
@SpringBootApplication
public class ConsumerStarter {
public static void main(String[] args) {
SpringApplication.run(ConsumerStarter.class, args);
}
}
3.4.2 服务治理-Feign
常用的服务有Feign和Dubbo两种,我们写两种类型的提供者,注意此处配置与版本有关,旧版本需要在启动类上加@EnableDiscoveryClient
http服务的提供者不需要特殊配置,写一个普通的controller接口
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
启动类
package com.test.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 专治八阿哥的孟老师
*/
@SpringBootApplication
public class HttpProviderStarter {
public static void main(String[] args) {
SpringApplication.run(HttpProviderStarter.class, args);
}
}
package com.test.nacos.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 专治八阿哥的孟老师
*/
@RestController
public class TestController {
@RequestMapping("/test")
public Map test() {
Map map = new HashMap();
map.put("name", "张三");
map.put("id", 123);
return map;
}
}
bootstrap.properties
spring.application.name=provider-http
spring.profiles.active = dev
server.port=8081
spring.cloud.nacos.discovery.server-addr=http://localhost:8848
spring.cloud.nacos.discovery.namespace=${spring.profiles.active}
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
消费者
<!--服务治理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--调用feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
bootstrap.properties
spring.cloud.nacos.discovery.server-addr=http://localhost:8848
spring.cloud.nacos.discovery.namespace=${spring.profiles.active}
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
#只做消费者,不被其他服务发现
spring.cloud.nacos.discovery.register-enabled=false
启动类上添加@EnableFeignClients注解
调用Feign服务,详见SpringCloud
package com.test.consumer.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
/**
* @author 专治八阿哥的孟老师
*/
@FeignClient(value = "provider-http")
public interface TestFeignService {
@RequestMapping(value = "/test", method = RequestMethod.GET)
Map test();
}
需要用到服务的地方注入service即可
@Autowired
private TestFeignService testFeignService;
@RequestMapping("feign")
public Map feign() {
return testFeignService.test();
}
3.4.3 服务治理-Dubbo
Dubbo服务通常需要把暴露的接口和实体单独提取出来,封装成jar,服务提供者实现jar里的接口,消费者通过jar调用远程服务
dubbo-service,注意实体类一定要实现Serializable接口,否则调用过程中会报通信失败
package com.test.nacos.entity;
import java.io.Serializable;
/**
* @author 专治八阿哥的孟老师
*/
public class User implements Serializable {
private Integer id;
private String name;
//getter/setter略
}
package com.test.nacos.service;
import com.test.nacos.entity.User;
public interface TestDubboService {
User getUser(Integer id);
}
dubbo-provider
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!--不同版本不一样-->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<!--定义接口的包-->
<dependency>
<groupId>com.test.nacos</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
bootstrap.properties
spring.application.name=provider-dubbo
spring.profiles.active = dev
server.port=8082
spring.cloud.nacos.discovery.server-addr=http://localhost:8848
spring.cloud.nacos.discovery.namespace=${spring.profiles.active}
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
dubbo.application.name=${spring.application.name}
# dubbo扫描包路径
dubbo.scan.base-packages=com.test.nacos.service
# dubbo协议
dubbo.protocol.name=dubbo
# 随机端口
dubbo.protocol.port=-1
# nacos地址
dubbo.registry.address=spring-cloud://localhost:8848
dubbo.registry.username=nacos
dubbo.registry.password=nacos
接口实现类
package com.test.nacos.service.impl;
import com.test.nacos.entity.User;
import com.test.nacos.service.TestDubboService;
import org.apache.dubbo.config.annotation.DubboService;
/**
* @author 专治八阿哥的孟老师
*/
@DubboService // dubbo注解
public class TestDubboServiceImpl implements TestDubboService {
@Override
public User getUser(Integer id) {
User user = new User();
user.setId(id);
user.setName("test");
return user;
}
}
启动类
package com.test.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 专治八阿哥的孟老师
*/
@SpringBootApplication
public class DubboTestStarter {
public static void main(String[] args) {
SpringApplication.run(DubboTestStarter.class, args);
}
}
消费者追加jar包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.test.nacos</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
dubbo.registry.protocol=dubbo
dubbo.registry.address=spring-cloud://localhost:8848
# dubbo 协议
dubbo.protocol.id=dubbo
dubbo.protocol.name=dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
dubbo.protocol.port=-1
# Dubbo 消费端订阅服务端的应用名,多个服务提供者用逗号分隔
dubbo.cloud.subscribed-services=provider-dubbo
需要引入的时候,通过 @DubboReference引入服务
@DubboReference
private TestDubboService testDubboService;
@RequestMapping("dubbo")
public User dubbo() {
return testDubboService.getUser(1);
}