nacos快速入手
Nacos是Spring Cloud Alibaba的组件, Spring Cloud Alibaba遵循Spring Cloud中定义的服务注册, 服
务发现规范. 因此使⽤Nacos和使⽤Eureka对于微服务来说,并没有太⼤区别.
主要差异在于:
- Eureka需要⾃⼰搭建⼀个服务, Nacos不⽤⾃⼰搭建服务, 组件已经准备好了, 只需启动即可.
- 对应依赖和配置不同
1.引入spring-cloud-alibaba的依赖
在⽗⼯程的pom⽂件中的 <dependencyManagement> 中引⼊Spring Cloud Alibaba的依赖:
<properties><spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<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>
<aside> 💡
注意: Spring Boot 和Spring Cloud的版本是有⼀定对应关系的. Spring Cloud Alibaba也遵循Spring Cloud 的标准, 在引⼊依赖时, ⼀定要确认各个版本的对应关系.
Spring Cloud Alibaba 和Spring Cloud版本对应关系, 参考官⽅⽂档:
版本发布说明-阿里云Spring Cloud Alibaba官网
版本在⼀定范围内可以⾃由选择.
</aside>
2.引入Nacos相关的依赖
在order-service和product-service中引⼊nacos依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>//引⼊Load Balance依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency>
3.修改配置
配置项 | Key | 默认值 | 说明 |
---|---|---|---|
服务端地址 | spring.cloud.nacos.discovery.server-addr | ⽆ | Nacos Server 启动监听的ip地址和端⼝ |
spring:application:name: product-servicecloud:nacos:discovery:server-addr: 110.41.51.65:10020
4.远程调用
修改IP为项目名称
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);String url = "<http://product-service/product/>" + orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}
为restTemplate添加负载均衡注解 @LoadBalanced
@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
5.测试
启动order-service 和product-service服务, 观察Nacos的管理界⾯, 发现order-service 和product-service 都注册在Nacos上了。
测试接口:http://127.0.0.1:8080/order/1
启动多个服务,测试负载均衡
启动三个 product-service 实例
观察nacos:
多次访问,http://127.0.0.1:8080/order/1,观察日志
常见问题
-
java.net.UnknownHostException
2023-12-25T19:04:23.803+08:00 ERROR 25892 --- [nio-8080-exec-1] o.a.c.c.C.[.[. [/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "<http://product-service/product/1001>": product-service] with root cause java.net.UnknownHostException: product-serviceat java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:572) ~ [na:na]at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]at java.base/java.net.Socket.connect(Socket.java:583) ~[na:na]at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183) ~ [na:na]at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:534) ~[na:na] ......
检查是否添加 LoadBalance 依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId> </dependency>
-
服务注册失败
可能没有报错⽇志, 或者报错⽇志如下(与版本有关)
Parameter 0 of method inetIPv6Utils in com.alibaba.cloud.nacos.util.UtilIPv6AutoConfiguration required a bean of type 'org.springframework.cloud.commons.util.InetUtilsProperties' that could not be found. The injection point has the following annotations:- @org.springframework.beans.factory.annotation.Autowired(required=true) Action: Consider defining a bean of type 'org.springframework.cloud.commons.util.InetUtilsProperties' in your configuration.
检查Spring Cloud Alibaba版本是否正确 参考:版本发布说明-阿里云Spring Cloud Alibaba官网
Nacos负载均衡
Nacos⽀持多种负载均衡策略, 包括权重, 同机房, 同地域, 同环境等.
服务下线
当某一个节点上接口的性能较差时,我们可以第一时间对该节点进行下线,防止对服务造成一定的影响。(问ai再确认一下)
步骤:服务详情 → 下线
点击下线后,再次请求接⼝,会发现该服务没有请求进来了,再次单击上线, 该节点会继续收到请求。
权重配置
权重配置,配置的是这个节点流量权重,权重大就代表流量大,权重小就代表流量小。
1.修改权重配置
操作: 详情 → 对应节点 → 编辑 → 修改权重值
权重配置默认为1,这里测试改成 0.1
2.开启 Nacos 负载均衡策略
由于Spring Cloud LoadBalance组件⾃⾝有负载均衡配置⽅式, 所以不⽀持Nacos的权重属性配置。
我们需要开启Nacos的负载均衡策略, 让权重配置⽣效
参考:如何解决MSE Nacos上修改服务实例的权重不生效问题_微服务引擎(MSE)-阿里云帮助中心
#开启nacos的负载均衡策略
spring:cloud:loadbalancer:nacos:enabled: true
3.测试权重配置
启动服务,访问多次接⼝,观察结果, 会发现9091端⼝号的实例接收的请求明显⽐另外两个实例少。
整体流量⽣效, 局部流量不是严格按照设置的⽐例进⾏分配的
常见问题
修改权重时, 可能会报错:
原因:Nacos 采⽤ raft 算法来计算 Leader, 并且会记录前⼀次启动的集群地址, 当服务器 IP 改变时
导致 raft 记录的集群地址失效, 导致选 Leader 出现问题. (⽹络环境发⽣变化时, IP地址也会发⽣变化)
解决办法:删除 Nacos 根⽬录下 data ⽂件夹下的 protocol ⽂件夹即可。
Nacos 集群优先访问
Nacos把同⼀个机房内的实例, 划分为⼀个集群. 所以同集群优先访问, 在⼀定程度上也可以理解为同房优先访问.
微服务架构中, ⼀个服务通常有多个实例共同提供服务, 这些实例可以部署在不同的机器上, 这些机器
可以分布在不同的机房, ⽐如product-service:
实例1: 分布在上海机房 实例2: 分布在上海机房 实例3: 分布在北京机房 实例4: 分布在北京机房
微服务访问时, 应尽量访问同机房的实例. 当本机房内实例不可⽤时, 才访问其他机房的实例.
⽐如order-service 在上海机房, product-service 在北京和上海机房都有实例, 那我们希望可以优先访
问上海机房, 如果上海机房没有实例, 或者实例不可⽤, 再访问北京机房的实例. 通常情况下, 因为同一
个机房的机器属于⼀个局域⽹, 局域⽹访问速度更快⼀点.
为实例配置集群名称
1.为product-service配置集群名称
spring:cloud:nacos:discovery:cluster-name: SH #集群名称: 上海集群
重启服务, 观察Nacos控制台, SH集群下多了⼀个实例
复制product-service启动配置, 添加VM Option
设置9091端⼝号的实例, 机房为BJ
-Dserver.port=9091 -Dspring.cloud.nacos.discovery.cluster-name=BJ
设置9092端⼝号的实例, 机房为BJ
-Dserver.port=9092 -Dspring.cloud.nacos.discovery.cluster-name=BJ
观察Nacos, BJ集群下多了两个实例
2.为order-service配置集群名称
spring:cloud:nacos:discovery:cluster-name: SH #集群名称: 上海集群
开启Nacos负载均衡策略
spring:cloud:loadbalancer:nacos:enabled: true
测试
启动服务
-
对接⼝访问多次, 观察⽇志, 会发现只有9090端⼝的实例收到了请求(同集群)
-
把9090端⼝的实例进⾏下线(SH集群), 再次访问接⼝, 观察⽇志, 发现9091端⼝和9092端⼝的实例收到了请求