<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          服務(wù)注冊(cè)、發(fā)現(xiàn)和遠(yuǎn)程調(diào)用

          共 5467字,需瀏覽 11分鐘

           ·

          2021-10-11 17:35

          早期文章


          ? ? ? ? 本篇文章介紹如何完成一個(gè)簡(jiǎn)單的服務(wù)注冊(cè)、發(fā)現(xiàn)和遠(yuǎn)程調(diào)用的 Demo,通過該 Demo 來(lái)學(xué)習(xí)和了解關(guān)于 Spring Cloud 相關(guān)的知識(shí)。


          項(xiàng)目結(jié)構(gòu)

          ? ? ? ? 創(chuàng)建一個(gè) Maven 的聚合項(xiàng)目,使用 SpringBoot 作為其父項(xiàng)目,然后通過在其下添加子模塊來(lái)構(gòu)建一個(gè)簡(jiǎn)單的微服務(wù)的項(xiàng)目。


          創(chuàng)建一個(gè) service_user 服務(wù)

          ? ? ? ? 在 Maven 項(xiàng)目下創(chuàng)建一個(gè) Module 作為子模塊,在項(xiàng)目的 POM 文件中加入 web 依賴,依賴如下:

          <dependency>    <groupId>org.springframework.bootgroupId>    <artifactId>spring-boot-starter-webartifactId>dependency>

          ? ? ? ? 引入依賴后,創(chuàng)建 controller、service、impl 三個(gè)包,然后分別創(chuàng)建 UserController、UserService 和 UserServiceImpl 三個(gè)類文件,以及一個(gè)啟動(dòng)類。項(xiàng)目結(jié)構(gòu)如下圖。

          ? ? ? ??該項(xiàng)目來(lái)模擬通過輸入用戶的 id 來(lái)返回用戶名。UserController 代碼如下:

          @RestController@RequestMapping("/admin/user")public class UserController{    @Autowired    private UserService userService;
          @GetMapping("getUser/{id}") public String getUser(@PathVariable Long id) { return userService.getUser(id); }}

          ? ? ? ? UserServiceImpl 的代碼如下:

          @Servicepublic class UserServiceImpl implements UserService{
          @Override public String getUser(Long id) {
          ????????String?name?=?null;????????????????if?(id?==?1)?{ name = "admin"; } else { name = "user"; }
          return name; }}

          ? ? ? ? application.yml 配置文件如下:

          server:  port: 8001spring:  application:    name: service-user

          ? ? ? ? 注意,這里的 spring.application.name 的名字不能使用 下劃線,否則后面使用 OpenFeign 進(jìn)行遠(yuǎn)程調(diào)用時(shí)會(huì)報(bào)錯(cuò)。

          ? ? ? ? 因?yàn)閯?chuàng)建的子模塊是 Maven 類型的項(xiàng)目,因此需要手動(dòng)添加啟動(dòng)類,代碼如下:

          @SpringBootApplicationpublic class ServiceUserApplication{    public static void main(String[] args)??? {        SpringApplication.run(ServiceUserApplication.class, args);    }}

          ? ? ? ? 啟動(dòng)項(xiàng)目,訪問 8001 端口來(lái)請(qǐng)求我們的接口,如下所示。


          創(chuàng)建 service_dict 項(xiàng)目

          ? ? ? ? 接著再創(chuàng)建一個(gè)子模塊,同樣引入 web 依賴,創(chuàng)建 controller、service 和 impl 的包,并創(chuàng)建 DictController、DictService 和 DictImpl 三個(gè)類,以及啟動(dòng)類和 application.yml 配置文件,項(xiàng)目結(jié)構(gòu)如下:

          ? ? ? ? 分別來(lái)寫 DictController 和 DictServiceImpl 兩個(gè)類的代碼,DictController 代碼如下:

          @RestController@RequestMapping("/admin/dict")public class DictController{    @Autowired    private DictService dictService;
          @GetMapping("getDict/{id}") public String getDict(@PathVariable Long id) { return dictService.getDict(id); }}

          ? ? ? ? DictServiceImpl 代碼如下:

          @Servicepublic class DictServiceImpl implements DictService{
          @Override public String getDict(Long id) {
          String name = null;
          if (id == 1) { name = "管理員"; } else { name = "普通用戶"; }
          return name; }}

          ? ? ? ? application.yml 配置文件如下:

          server:  port: 8002spring:  application:    name: service-dict

          ? ? ? ??該項(xiàng)目的端口號(hào)為 8002,在添加了該項(xiàng)目的啟動(dòng)類之后,啟動(dòng)該項(xiàng)目,訪問 8002 接口,如下圖所示。


          服務(wù)注冊(cè)

          ? ? ? ??可以看到,我們完成了兩個(gè)服務(wù),第一個(gè)服務(wù)通過 id 來(lái)獲取用戶名,第二個(gè)服務(wù)通過 id 來(lái)判斷用戶的類型。為了提高服務(wù)的可用性,可以將每個(gè)服務(wù)進(jìn)行水平擴(kuò)展,當(dāng)調(diào)用這些服務(wù)的時(shí)候,服務(wù)有不同的 IP 地址,或者有不同的端口號(hào)。想要調(diào)用服務(wù),就需要知道服務(wù)的 IP 地址和端口號(hào)。但是,這樣做有一定的問題,比如某個(gè)服務(wù)下線了,或者新增加了服務(wù),那么調(diào)用方需要?jiǎng)討B(tài)的了解服務(wù)的變化,而服務(wù)的地址直接在調(diào)用方里進(jìn)行管理,那么就不方便了。

          ? ? ? ? 在這種情況下,可以通過服務(wù)注冊(cè)中心來(lái)動(dòng)態(tài)的管理服務(wù),服務(wù)中心有 Zookeeper、Eureka、Nacos 等。這里我們使用 Nacos 來(lái)管理服務(wù)的注冊(cè)。這里,我們?cè)?Windows 下啟動(dòng) Nacos,啟動(dòng)畫面如下:

          ? ? ? ? 然后通過瀏覽器訪問 http://localhost:8848/nacos 來(lái)訪問 Nacos 的管理頁(yè)面,登錄后的管理頁(yè)面如下圖所示:

          ? ? ? ? 有了 Nacos 后我們修改上面的兩個(gè)子模塊,讓兩個(gè)子模塊將自己注冊(cè)到 Nacos 中。分別在 service_user 和 service_dict 的 POM 文件中增加如下的依賴。

          <dependency>    <groupId>com.alibaba.cloudgroupId>    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>    <version>2.2.6.RELEASEversion>dependency>

          ? ? ? ? 并在啟動(dòng)類上增加注解,注解如下:

          @EnableDiscoveryClient

          ? ? ? ??在 application.yml 中將注冊(cè)中心的地址配置一下,配置如下:

          server:  port: 8002spring:  application:    name: service-dict  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848

          ? ? ? ? 然后重新啟動(dòng)這兩個(gè)子模塊,這樣,兩個(gè)服務(wù)就被注冊(cè)到了 Nacos 中,可以在 Nacos 中查看服務(wù)列表,如下圖所示。

          ? ? ? ? 通過上圖可以看到,已經(jīng)將自己注冊(cè)到了 Nacos 中。


          服務(wù)發(fā)現(xiàn)與遠(yuǎn)程服務(wù)調(diào)用

          ? ? ? ??現(xiàn)在,我們讓 service_user 去調(diào)用 service_dict 來(lái)模擬一次遠(yuǎn)程調(diào)用的過程,也就是在調(diào)用 getUser 接口時(shí),在 getUser 接口的內(nèi)部去調(diào)用 getDict 接口。

          ? ? ? ? 創(chuàng)建一個(gè)子模塊,命名為 client,引入如下依賴:

          <dependency>    <groupId>org.springframework.cloudgroupId>    <artifactId>spring-cloud-starter-openfeignartifactId>    <version>2.2.9.RELEASEversion>dependency>

          ? ? ? ? 有了該依賴以后,在項(xiàng)目中添加一個(gè)接口,通過該接口調(diào)用 service_dict 下的 getDict 接口。項(xiàng)目結(jié)構(gòu)如下:

          ? ? ? ? 這里只有 DictFeignClient 接口文件,該文件的代碼如下:

          @FeignClient("service-dict")@Repositorypublic interface DictFeignClient{    @GetMapping("/admin/dict/getDict/{id}")    String getDict(@PathVariable Long id);}

          ? ? ? ? 在注解 @FeignClient 中定義服務(wù)的名稱,在 @GetMapping 注解中寫入接口地址的 uri將該子模塊引入 service_user 中,即可通過 OpenFeign 來(lái)完成遠(yuǎn)程調(diào)用。修改 service_user 中的 UserServiceImpl 文件,代碼如下:

          @Servicepublic class UserServiceImpl implements UserService{
          @Autowired private DictFeignClient dictFeignClient;
          @Override public String getUser(Long id) {
          String name = null;
          String dictName = dictFeignClient.getDict(id);
          if (id == 1) { name = "admin"; } else { name = "user"; }
          return name + " " + dictName; }}

          ? ? ? ? 使用 @Autowired 來(lái)注入 DictFeignClient,調(diào)用 DictFeignClient 接口中定義的 getDict 來(lái)調(diào)用 service_dict 中的 getDict 接口。這樣就完成了遠(yuǎn)程調(diào)用。在 service_user 的啟動(dòng)類上加如下注解:

          @EnableFeignClients(basePackages = "com.coderup2u")

          ? ? ? ? 重新啟動(dòng) service_user 項(xiàng)目,并在瀏覽器中進(jìn)行訪問 getUser 接口,如下圖所示。

          ? ? ? ??從上面的代碼中可以看出,進(jìn)行遠(yuǎn)程調(diào)用時(shí),只定義了服務(wù)的名稱,也就是 通過 @FeignClient("service-dict"),但是并沒有給出該服務(wù)實(shí)際的地址和端口號(hào)。由此,我們可以想到,服務(wù)的 IP 地址和端口號(hào)是由服務(wù)中心獲取到的,即服務(wù)發(fā)現(xiàn)。服務(wù)發(fā)現(xiàn)會(huì)動(dòng)態(tài)的根據(jù)注冊(cè)中心服務(wù)列表的變化而變化。當(dāng)服務(wù)增加、下線,注冊(cè)中心管理的地址列表都會(huì)發(fā)生變化,從而提供給服務(wù)調(diào)用方,這樣就避免了調(diào)用了已經(jīng)下線的服務(wù),從而導(dǎo)致服務(wù)調(diào)用的失敗。他們大致的關(guān)系如下圖所示。



          總結(jié)

          ? ? ? ? 本文通過簡(jiǎn)單的 Demo 介紹 Spring Cloud Alibaba 中 Nacos 的使用,服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn),及遠(yuǎn)程服務(wù)的調(diào)用。可以通過在簡(jiǎn)單的 Demo 上來(lái)完成 Nacos 集群的搭建,服務(wù)集群的搭建來(lái)進(jìn)行測(cè)試。



          公眾號(hào)內(nèi)回復(fù)?【mongo】 下載 SpringBoot 整合操作 MongoDB 的文檔。


          更多文章


          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕日韩美 | 成人网站视频在线观看 | 日本一区二三区 | 蜜乳一区二区三区有限公司 | 伊人青青在线播放 |