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端?的實例收到了請求