初體驗springcloud微服務不同模塊之間的服務調用
在order模塊,創建一個controller,用於調用video模塊的api
@RestController
@RequestMapping("api/v1/video_order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/save")
public Object save(int videoId){
Video video = restTemplate.getForObject("http://localhost:9000/api/v1/video/find_by_id?videoId="+videoId, Video.class);
VideoOrder videoOrder = new VideoOrder();
videoOrder.setVideoId(video.getId());
videoOrder.setVideoTitle(video.getTitle());
videoOrder.setCreateTime(new Date());
return videoOrder;
}
}
在啓動函數中添加@Bean註解方法,RestTemplate就是可以獲得別的模塊Api的類
@SpringBootApplication
public class OrderApplication {
public static void main(String [] args){
SpringApplication.run(OrderApplication.class,args);
}
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在video模塊中,controller
@RestController
@RequestMapping("api/v1/video")
public class VideoController {
@Autowired
private VideoService videoService;
@RequestMapping("find_by_id")
public Object findById(int videoId){
return videoService.findById(videoId);
}
}
兩個模塊都運行之後,訪問 localhost:8000/api/v1/video_order/save?videoId=40發現成功
缺點
- 服務之間的IP信息寫死
- 服務之間⽆法提供負載均衡
- 多個服務直接關係調⽤維護複雜
通過Nacos來管理微服務
- 服務註冊:服務提供者provider,啓動的時候向註冊中
⼼上報⾃⼰的⽹絡信息 - 服務發現:服務消費者consumer,啓動的時候向註冊中⼼上報⾃⼰的⽹絡信息,拉取provider的相關⽹絡信息
- 核⼼:服務管理,是有個服務註冊表,⼼跳機制動態維護,服務實例在啓動時註冊到服務註冊表,並在關閉時註銷。
- 微服務應⽤和機器越來越多,調⽤⽅需要知道接⼝的⽹絡地址,如果靠配置⽂件的⽅式去控制⽹絡地址,對於動態新增機器,維護帶來很⼤問題
使用方法
下載nacos安裝包之後,解壓,在bin目錄啓動
sh startup.sh -m standalone
然後瀏覽器訪問 localhost:8848/nacos,默認賬號密碼都是nacos
然後再在每個服務模塊添加依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
每個application.yml文件添加配置
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
然後再在每個啓動類上添加註解
@EnableDiscoveryClient
然後再在Order的controller中更改
@RestController
@RequestMapping("api/v1/video_order")
public class OrderController {
@Autowired
private DiscoveryClient discoveryClient; //通過它可以獲得請求的url和端口號
@Autowired
private RestTemplate restTemplate;
@RequestMapping("save")
public VideoOrder save(int videoId){
VideoOrder videoOrder = new VideoOrder();
videoOrder.setVideoId(videoId);
//獲取到對應的服務的相關信息
List<ServiceInstance> list = discoveryClient.getInstances("wpb-video-service");
ServiceInstance si = list.get(0);
//通過ServiceInstance獲取到他的url和端口號,這些信息都在nacos中註冊過了
Video video = restTemplate.getForObject("http://"+si.getHost()+":"+si.getPort()+
"/api/v1/video/find_by_id?videoId="+videoId,Video.class);
videoOrder.setVideoTitle(video.getTitle());
videoOrder.setVideoId(video.getId());
return videoOrder;
}
}
然後重啓項目可以看到
通過postman測試成功
不過這個時候並沒有考慮到負載均衡的問題,對於一個服務來說依然只是一臺服務器,常見的負載均衡策略有
- 節點輪詢
-- 簡介:每個請求按順序分配到不同的後端服務器 - weight 權重配置
-- 簡介:weight和訪問比率成正比,數字越大,分配得到的流量越高 - 固定分發
-- 簡介:根據請求按訪問ip的hash結果分配,這樣每個用戶就可以固定訪問一個後端服務器
Ribbon的使用
Ribbon是一個客戶端負載均衡工具,通過Spring Cloud封裝,可以輕鬆和AlibabaCloud整合
使用也比較簡單,在order的啓動類
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
其他的不變,這樣就開啓了負載均衡
Ribbon支持的負載均衡策略介紹
然後使用的話有一個注意點,在order模塊調用的時候
@RestController
@RequestMapping("api/v1/video_order")
public class OrderController {
@Autowired
private DiscoveryClient discoveryClient; //通過它可以獲得請求的url和端口號
@Autowired
private RestTemplate restTemplate;
@RequestMapping("save")
public VideoOrder save(int videoId){
VideoOrder videoOrder = new VideoOrder();
videoOrder.setVideoId(videoId);
//獲取到對應的服務的相關信息
List<ServiceInstance> list = discoveryClient.getInstances("wpb-video-service");
ServiceInstance si = list.get(0);
//通過ServiceInstance獲取到他的url和端口號,這些信息都在nacos中註冊過了
//如果使用了ribbon,這個就只能使用服務的名字了
// String url = "http://"+si.getHost()+":"+si.getPort()+
// "/api/v1/video/find_by_id?videoId="+videoId;
// System.out.println(url);
Video video = restTemplate.getForObject("http://wpb-video-service/api/v1/video/find_by_id?videoId="+videoId,Video.class);
videoOrder.setVideoTitle(video.getTitle());
videoOrder.setVideoId(video.getId());
videoOrder.setServerInfo(video.getServeInfo());
return videoOrder;
}
}
Ribbon不規範,風格不統一,維護性比較差
新的負載均衡組件Feign
不用像Ribbon中通過封裝HTTP請求報文的方式調用 Feign默認集成了Ribbon
Nacos支持Feign,可以直接集成實現負載均衡的效果
- 加入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 在每個啓動類上加上註解
@EnableFeignClients
- 在Order模塊裏service裏添加
@FeignClient(value = "wpb-video-service")
public interface VideoService {
@GetMapping("/api/v1/video/find_by_id")
Video findById(@RequestParam("videoId") int videoId);
@PostMapping("/api/v1/video/save")
int save(@RequestBody Video video);
}
然後就可以在Order模塊中的controlle裏直接調用了,就像調用自己的service方法一樣