springcloud第二天

初體驗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,可以直接集成實現負載均衡的效果

  1. 加入依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 在每個啓動類上加上註解
    @EnableFeignClients
  2. 在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方法一樣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章