3.1 Nacos介绍
Nacos注册中心的主要功能:
- 存储注册上来的服务实例
- 返回服务实例给消费端
- 服务实例变更之后推送新的实例列表给消费端
3.2 服务注册获取实战
3.2.1 搭建Nacos
下载地址: github.com/alibaba/nac…
我们下载的是nacos-server-1.4.1.zip版本,然后解压缩。
# 解压缩
unzip nacos-server-1.4.1.zip
# 进入目录
cd nacos/bin
# 启动
bin/startup.sh -m standalone
看到success等表明启动成功。
然后我们访问nacos,http://192.168.56.200:8848/nacos
当然这个nacos是单机版,生产环境我们需要安装集群版,参考官网集群版安装,这里不再详述。
3.2.2 将设备服务注册到Nacos
- 添加nacos依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 启动类上添加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableDiscoveryClient
public class DeviceApplication {
public static void main(String[] args) {
SpringApplication.run(DeviceApplication.class, args);
}
}
- 配置文件添加nacos地址
spring:
application:
name: smart-device
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.56.200:3306/device?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: password
# nacos地址
cloud:
nacos:
discovery:
server-addr: 192.168.56.200:8848
启动device服务,我们在nacos控制台看到device服务已经注册到nacos了。
3.2.3 将业务服务注册到Nacos
同理将业务服务注册到nacos,流程跟device服务注册类似,不再详述。
我们使用discoveryClient来从nacos注册中心中获取device服务实例,然后来调用设备服务获取设备信息。
/**
* @description:
* @author:xg
* @date: 2024/12/8
* @Copyright:
*/
@RestController
@RequestMapping("/deviceData")
@Slf4j
public class DeviceDataController {
@Resource
private RestTemplate restTemplate;
@Resource
private DeviceDataService deviceDataService;
@Resource
private DiscoveryClient discoveryClient;
@PostMapping("/save")
public Boolean save(@RequestBody @Valid DeviceDataDTO deviceDataDTO) {
// 通过discoveryClient从nacos中获取device服务实例
ServiceInstance serviceInstance = discoveryClient.getInstances("smart-device").get(0);
String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();
// 通过RestTemplate调用device服务获取设备绑定的userId
DeviceVO deviceVO = restTemplate.getForObject(
"http://"+url+"/device/get/" + deviceDataDTO.getPhysicalAdd(),
DeviceVO.class);
log.info("设备信息:{}", JSON.toJSONString(deviceVO));
if(Objects.isNull(deviceVO)) {
log.error("设备信息为null");
return false;
}
// 存储设备数据到DB
deviceDataDTO.setUserId(deviceVO.getUserId());
deviceDataService.save(deviceDataDTO);
return true;
}
}
3.3 Feign的使用
Feign支持以接口service的形式便于更方便的调用服务,同时也集成了Ribbon负载均衡的。Ribbon负载均衡机制,是客户端负载均衡,当从nacos注册中心中获取到服务实例列表之后,基于算法(默认是轮询)获取一个服务实例进行调用,以此来达到均衡调用服务实例的目的,同时使得服务具有可扩展性。
我们在idea中再启动一个device服务,设置端口为8081
3.3.1 添加Feign依赖
在smart-business业务服务工程中添加Feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3.3.2 启动类上加上Feign注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //开启Feign
public class BusinessApplication {
public static void main(String[] args) {
SpringApplication.run(BusinessApplication.class, args);
}
}
3.3.3 定义Feign接口来调用device服务
/**
* @description: 定义一个Feign接口,用于调用device服务
* @author:xg
* @date: 2024/12/13
* @Copyright:
*/
@FeignClient("smart-device")
public interface FeignDeviceService {
/**
* 定义接口url、参数
* @param physicalAdd
* @return
*/
@GetMapping("/device/get/{physicalAdd}")
DeviceVO get(@PathVariable("physicalAdd") String physicalAdd);
}
3.3.4 修改controller使用Feign调用服务
/**
* @description:
* @author:xg
* @date: 2024/12/8
* @Copyright:
*/
@RestController
@RequestMapping("/deviceData")
@Slf4j
public class DeviceDataController {
@Resource
private DeviceDataService deviceDataService;
@Resource
private FeignDeviceService feignDeviceService;
@PostMapping("/save")
public Boolean save(@RequestBody @Valid DeviceDataDTO deviceDataDTO) {
DeviceVO deviceVO = feignDeviceService.get(deviceDataDTO.getPhysicalAdd());
log.info("设备信息:{}", JSON.toJSONString(deviceVO));
if(Objects.isNull(deviceVO)) {
log.error("设备信息为null");
return false;
}
// 存储设备数据到DB
deviceDataDTO.setUserId(deviceVO.getUserId());
deviceDataService.save(deviceDataDTO);
return true;
}