第三步:将微服务注册到nacos,通过openfeign实现微服务间调用
什么是nacos
Nacos是阿里巴巴开源的服务发现、配置管理和服务管理平台。它主要提供两大核心功能:
服务注册与发现:微服务启动时注册到Nacos,服务间通过服务名而非IP地址相互发现和调用。
配置中心:集中管理应用配置,支持动态更新,无需重启服务即可生效。
Nacos替代了Eureka和Config,简化了微服务架构,支持健康检查、动态DNS和流量管理,是云原生应用的关键组件。
我们先学习一下如何通过配置来实现服务注册与发现。
在centos上安装nacos
通过git clone获取最新版nacos-docker
git clone https://github.com/nacos-group/nacos-docker.git
完成后进入到nacos-docker/example目录下,使用以下命令进行nacos服务管理
启动服务
docker compose -f standalone-derby.yaml up -d
查看服务状态
docker compose -f standalone-derby.yaml ps
停止并移除服务
docker compose -f standalone-derby.yaml down
查看实时日志
docker compose -f standalone-derby.yaml logs -f
重启服务
docker compose -f standalone-derby.yaml restart
暂停/恢复服务
docker compose -f standalone-derby.yaml pause/unpause
如果未安装docker compose可以通过下面这个命令安装
sudo yum install -y docker-compose-plugin
nacos启动后可以通过docker ps查看容器启动情况,可以看到除了nacos-server还有grafana和prometheus这两个监控服务。这里先关注nacos-server的状态是UP即可。
还需留意nacos比较耗费系统资源,建议将虚拟机内存调整到4G以上。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ddd3ddc2a9dc prom/prometheus:latest "/bin/prometheus --c…" 11 hours ago Up 2 hours 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp prometheus
fdf54d32ef1f grafana/grafana:latest "/run.sh" 11 hours ago Up 2 hours 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp grafana
53d370c5430b nacos/nacos-server:v3.1.1 "sh bin/docker-start…" 11 hours ago Up 2 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:8848->8848/tcp, :::8848->8848/tcp, 0.0.0.0:9848->9848/tcp, :::9848->9848/tcp nacos-standalone
服务启动后,可以在浏览器上登录nacos控制台,默认端口是8080
什么是openfeign
OpenFeign是Java的声明式HTTP客户端,常用于微服务架构。开发者只需编写接口并用注解(如@RequestMapping)声明远程服务的API契约,OpenFeign便会自动生成实现类,简化了服务间的HTTP调用。它整合了Ribbon实现负载均衡,并能与Eureka等服务发现组件协作,让微服务调用像调用本地方法一样简单,提升了代码的可读性与可维护性。
有了openfeign,我们只需要新增一个接口类(interface),按要求写一下格式,就可以很方便的实现调用了。如下图:
//UserClient.java
package com.decotest.orderservice;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name ="user-service")
public interface UserClient {
@GetMapping("/user/{id}")
String getUserById(@PathVariable("id") String id);
}
服务注册及调用实例
新建两个服务,一个是user-service,一个是order-service。order-service调用user-service模拟用户验证。
user-service相关代码如下:
//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.decotest</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1</version>
<name>user-service</name>
<description>user-service</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud 依赖管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba 依赖管理 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#application.properties
spring.application.name=user-service
server.port=8080
# Nacos server--此处需要修改为部署nacos的服务器地址
spring.cloud.nacos.discovery.server-addr=192.168.31.172:8848
spring.cloud.nacos.discovery.namespace=public
spring.cloud.nacos.discovery.group=DEFAULT_GROUP
# nacos client
spring.cloud.nacos.discovery.ip=127.0.0.1
spring.cloud.nacos.discovery.port=${server.port}
spring.cloud.nacos.discovery.service=${spring.application.name}
//UserServiceApplication.java
package com.decotest.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//此处要增加nacos的注解EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
//userservice.java
package com.decotest.userservice;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class userservice {
@RequestMapping("/user/{id}")
public String getUserById(@PathVariable String id) {
try {
int iId = Integer.parseInt(id);
if (iId < 10000) {
return "user id(" + id + ") is alive";
} else {
return "user id(" + id + ") is not alive";
}
} catch (Exception e) {
return "user id(" + id + ") is invalid";
}
}
}
order-service相关代码
//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.decotest</groupId>
<artifactId>order-service</artifactId>
<version>0.0.1</version>
<name>order-service</name>
<description>order-service</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud 依赖管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba 依赖管理 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#application.properties
spring.application.name=order-service
server.port=8081
# Nacos server--此处需要修改为部署nacos的服务器地址
spring.cloud.nacos.discovery.server-addr=192.168.31.172:8848
spring.cloud.nacos.discovery.namespace=public
spring.cloud.nacos.discovery.group=DEFAULT_GROUP
# nacos client
spring.cloud.nacos.discovery.ip=127.0.0.1
spring.cloud.nacos.discovery.port=${server.port}
spring.cloud.nacos.discovery.service=${spring.application.name}
logging.level.com.decotest.feign.UserClient=DEBUG
//OrderServiceApplication.java
package com.decotest.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
//此处要增加nacos的注解@EnableDiscoveryClient,以及OpenFeign的注解@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
//UserClient.java
//声明OpenFeign调用接口
package com.decotest.orderservice;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name ="user-service")
public interface UserClient {
@GetMapping("/user/{id}")
String getUserById(@PathVariable("id") String id);
}
//orderservice.java
package com.decotest.orderservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequestMapping("/order")
public class orderservice {
@Autowired
private UserClient uc;
@RequestMapping("/place/{id}")
public String placeOrder(@PathVariable String id){
String userinfo;
try {
userinfo = uc.getUserById(id); //通过openfeign接口进行服务调用
} catch (Exception e) {
return "call user-service error!";
}
if (userinfo.contains("is alive")) {
return "order id " + UUID.randomUUID().toString() + " is placed by user " + id + "!";
} else {
return userinfo;
}
}
}
服务启动后,通过nacos控制台可以看到服务注册上来了

访问oder-service,可观察到服务调用

将user-service服务停掉后,再访问order-service,可观察调用失败的异常返回

大功告成!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)