1.在IDEA中運行Nacos(001拓展)
1.1編輯配置資訊


選擇shell script(shell腳本)
script path(腳本路徑)--- nacos目錄下bin目錄下的startup.cmd命令檔案
CMD檔案的專業名稱叫聯結器組態檔,是存放聯結器的配置資訊的,我們簡稱為命令檔案

script options(腳本選項)需要執行的命令

點擊運行啟動nacos

服務注冊中心 nacos啟動成功

測驗nacos http://localhost:8848/nacos
關閉nacos ctrl+c 需要等一會才能關閉

2.服務之間的呼叫

2.1提供方服務(sca-provider)注冊
2.1.1.添加nacos服務的注冊和發現依賴

根據官網提供:Nacos Spring 快速開始
https://nacos.io/zh-cn/docs/quick-start-spring.html
<dependencies>
<!-- web服務依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos服務的注冊和發現依賴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2.1.2.創建并修改組態檔application.yml(或者application.properties),實作服務注冊

server:
port: 8082 #服務埠
spring:
application:
name: sca-provider #服務名 不能重復 map集合k-value(value可以是一個集合)中的k 錯誤代碼503服務不可用 檢查nacos
cloud:
nacos: #服務
discovery: #服務的注冊和發現
server-addr: localhost:8848 #nacos server
2.1.3創建啟動類,并定義處理請求的控制層物件和方法:
package com.cy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@RestController
public class providerController{
//動態賦值xml檔案里的資訊,配置默認值8080以防null時報錯
@Value("${server.port:8080}")
private String server;
/* echo:回顯的意思
rest:一種軟體架構編碼風格
訪問:http://localhost:8081/provider/echo/nacos */
@GetMapping("/provider/echo/{msg}")
//兼容java8以下的版本 必須注明@PathVariable("msg")與請求路徑的msg相同 變數則可以自定義
public String doRestEcho1(@PathVariable("msg") String msg1){
return server +"hello"+msg1;
}
}
}
控制層代碼可以寫在控制層里,但這里這是簡單的一個入門案例我就直接寫在啟動類里了,
2.1.4測驗提供方服務
注意:先啟動Nacos在啟動啟動類,要不會報錯

測驗 http://localhost:8082/provider/echo/msa

證明我們的提供方服務創建成功
2.2消費方(sca-consumer)服務注冊
2.2.1.添加依賴和提供方一樣
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2.2.2.創建并修改組態檔application.yml(或者application.properties),實作服務注冊

server:
port: 8090 #默認8090
spring:
application:
name: sca-consumer #假如做服務注冊,必須寫
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos
2.2.3.創建消費方啟動類并寫入

package com.cy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.security.Provider;
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@RestController
public class providerController{
//動態賦值xml檔案里的資訊,配置默認值8080以防null時報錯
@Value("${server.port:8080}")
private String server;
/*
echo:回顯的意思
rest:一種軟體架構編碼風格
訪問:http://localhost:8081/provider/echo/nacos
*/
@GetMapping("/provider/echo/{msg}")
//兼容java8以下的版本 必須注明@PathVariable("msg")與請求路徑的msg相同 變數則可以自定義
public String doRestEcho1(@PathVariable("msg") String msg1){
return server +"hello"+msg1;
}
}
}
注意:先啟動Nacos在啟動啟動類,要不會報錯,可以看到現在消費方服務和提供方服務均已經啟動,

測驗消費方呼叫提供方

2.3負載均衡方法
如果一個提供方只能抗住10w的并發量,而消費方有100w的并發請求來呼叫提供方,這時則需要用到負載均衡的方法,所以至少得運行十個提供方
2.3.1 編輯ConsumerApplication啟動類
思路 1.從注冊中心獲取服務實體 2.基于restTemplate進行服務實體呼叫
package com.cy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
//服務消費方啟動類
//當客戶端向服務方發起請求時,服務消費方呼叫服務提供方的API進而獲取服務提供方的資料
//例如我們訪問一個訂單模塊資料;例如我的訂單
//訂單模塊中還要呈現商品資訊(成為提供方) 我呼叫consumer呼叫provider
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
/*
構建RestTemplate物件,并將此物件交給spring管理,
* 后續我們會通過此物件進行遠程服務呼叫
*/
@Bean//也是交給spring容器去管理 跨行程使用該物件
//第三方整合用@Bean
//spring中有快取 加了bean只需呼叫一次,不加就呼叫一次new一次物件
public RestTemplate restTemplate(){
return new RestTemplate();
}
@RestController
public class ConsumerController{
@Autowired//負載均衡客戶端物件 呼叫
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String appName;
@GetMapping("/consumer/doRestEcho1")
public String doRestEcho1(){
//呼叫服務提供方API(不只是類和介面也包含請求路徑)
//
String url="http://localhost:8081/provider/echo/"+appName;
return restTemplate.getForObject(url,String.class);
}
//負載均衡方式呼叫
@GetMapping("/consumer/doRestEcho2")
public String doRestEcho2(){
//1.從注冊中心獲取服務實體
//2.基于restTemplate進行服務實體呼叫
//服務實體instance
ServiceInstance instance = loadBalancerClient.choose("sca-provider");
String ip = instance.getHost();
int port = instance.getPort();
// String url = "http://"+ip+":"+port+"/provider/echo/"+appName;
//格式化
String url = String.format("http://%s:%s/provider/echo/%s", ip,port,appName);
//服務呼叫 基于服務名去查找實體
return restTemplate.getForObject(url,String.class);
}
}
}
2.3.2 啟動兩個服務器


然后修改組態檔里的埠號,


此時已經開啟了兩個提供方服務器
測驗:如果可以像我這樣說明服務器已經在負載均衡了(默認為負載均衡中的輪詢策略)



注意:
服務啟動時會向nacos發送心跳包 五秒一次 ,十五秒沒收到就標識你為 非健康狀態
三十秒左右收不到心跳包 就確認你已經下線 就把你刪掉服務,所以當我們關閉啟動類時服務還暫存在Nacos中,


2.4代碼優化
package com.cy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* 服務消費方物件的啟動類
* 業務描述:
* 當客戶端(瀏覽器,手機app)向服務消費方發起請求時,
* 服務消費方呼叫服務提供方的api,進而獲取服務提供方
* 的資料,
* 例如:
* 我們訪問一個訂單模塊資料(例如我的訂單),訂單模塊中
* 還要呈現商品資訊,
*/
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
/**
* 構建RestTemplate物件,并將此物件交給spring管理,
* 后續我們會通過此物件進行遠程服務呼叫
* @return
*/
@Bean
//@Bean("rt")
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
@LoadBalanced
public RestTemplate loadBalancerRestTemplate(){
return new RestTemplate();
}
@RestController
public class ConsumerController{
/**
* 負載均衡客戶端物件
*/
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Autowired
private RestTemplate loadBalancerRestTemplate;
@Value("${spring.application.name}")
private String appName;
//http://ip:port/consumer/doRestEcho1
@GetMapping("/consumer/doRestEcho1")
public String doRestEcho1(){
System.out.println("==doRestEcho1()==");
//呼叫服務提供方API(http://ip:port/path)
//1.定義要呼叫的API
String url=
"http://localhost:8081/provider/echo/"+appName;
//2.誰去訪問這個API? restTemplate;
return restTemplate
.getForObject(url,
String.class);
}
/**
* 負載均衡方式呼叫
* @return
*/
@GetMapping("/consumer/doRestEcho2")
public String doRestEcho2 (){
//1.從注冊中心獲取服務實體
ServiceInstance instance =
loadBalancerClient
.choose("sca-provider");
//2.基于RestTemplate進行服務實體呼叫
String ip=instance.getHost();//ip
int port=instance.getPort();//port
//String url= "http://"+ip+":"+port+"/provider/echo/"+appName;
String url=String.format(
"http://%s:%s/provider/echo/%s",
ip,port,appName);
return restTemplate.getForObject(
url, String.class);
}
@GetMapping("/consumer/doRestEcho3")
public String doRestEcho3(){
//定義url
String url=
String.format("http://sca-provider/provider/echo/%s", appName);
//服務呼叫
return loadBalancerRestTemplate.getForObject(
url, String.class);
}
}
}
//browser->provider
//browser->consumer
//browser-(url)->consumer-(url)->provider

2.5 代碼優化部分


3.面試分析
為什么要將服務注冊到nacos?(為了更好的查找這些服務)
在Nacos中服務提供者是如何向Nacos注冊中心(Registry)續約的?(5秒心跳)
對于Nacos服務來講它是如何判定服務實體的狀態?(檢測心跳包,15,30)
服務啟動時如何找到服務啟動注冊配置類?(NacosNamingService)
服務消費方是如何呼叫服務提供方的服務的?(RestTemplate)

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/300449.html
標籤:其他
上一篇:SpringCloud系列(二)、微服務與分布式核心知識
下一篇:輾轉相除法證明
