Spring Cloud Alibaba使用Nacos做注冊中心浇揩,Feign負載均衡遠程調用

對在Spring Cloud Alibaba使用nacos做注冊和動態(tài)配置中心,Feign遠程調用绽榛,并實現負載均衡的學習過程做一下總結湿酸,希望大家共同進步。


一. 安裝nacos服務

  1. 具體安裝步驟可參考這篇博客:
    https://blog.csdn.net/qq_32352777/article/details/86560333
    寫的很不錯灭美,感謝作者推溃。

  2. 安裝問題總結

    • 測試環(huán)境一般建議安裝單機版的,簡單快速届腐。集群安裝的話铁坎,為了符合高可用的要求蜂奸,MySQL也需要安裝成集群形式。如Master-Slave模式硬萍。

    • 如果是在虛擬機上安裝扩所,一般的虛擬機我們不會給分配太大內存。所以我們得根據自己的機子內存情況修改一下nacos啟動時默認分配的虛擬機內存朴乖,否則會啟動失敗祖屏,我們去查看nacos的安裝目錄下的log目錄的nacos.log日志,會發(fā)現報內存不足的異常买羞。

      (1)在nacos安裝目錄下袁勺,打開nacos啟動腳本。

      vim  bin/startup.sh
      

      (2)vim模式下ctrl+f向后翻頁畜普,找到如下部分


      在這里插入圖片描述

      (3)根據實際情況進行對nacos啟動jvm虛擬機內存設置進行修改期丰。

二. 代碼實現

  1. 創(chuàng)建父項目

    父pom,具體說明在注釋里面

        <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.test</groupId>
        <artifactId>cloud-test</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-test</name>
        <packaging>pom</packaging>
    
        <!--子模塊-->
        <modules>
            <module>cloud-service1</module>
            <module>cloud-service2</module>
            <module>cloud-consumer</module>
            <module>cloud-common</module>
        </modules>
    
        <!--依賴的組件的大版本號-->
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
            <spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>
            <spring-boot-starter-parent.version>2.2.2.RELEASE</spring-boot-starter-parent.version>
        </properties>
    
        <!--依賴jar包版本管理-->
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>${spring-cloud-alibaba.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-parent</artifactId>
                    <version>${spring-boot-starter-parent.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
            
        <dependencies>
            <!--服務發(fā)現(注冊中心)-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <!--配置中心-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>LATEST</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
    

    項目結構圖:

    在這里插入圖片描述
  2. 創(chuàng)建公共子模塊

    公共做模塊是放服務調用的接口和一些公共實體類和公共工具的漠嵌。結構如下:

    在這里插入圖片描述

    pom文件:

        <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <artifactId>cloud-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-consumer</name>
        <packaging>jar</packaging>
    
        <parent>
            <groupId>com.test</groupId>
            <artifactId>cloud-test</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>com.test</groupId>
                <artifactId>cloud-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    創(chuàng)建一個測試的實體類User

    package com.common.model;
    
    import lombok.Data;
    
    /**
     * Author: yhl
     * DateTime: 2019/12/8 23:13
     * Description: write some description
     */
    @Data
    public class User {
        private Long id;
        private String name;
        private String url;
    }
    

    創(chuàng)建微服務調用的接口IUserService

    package com.common.service;
    
    import com.common.model.User;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import java.util.Map;
    
    /**
     * Author: yhl
     * DateTime: 2019/12/8 23:13
     * Description: write some description
     */
    public interface IUserService {
    
        @RequestMapping("/testOut")
        Map<Object,Object> test(@RequestParam("name") String name);
    
        @RequestMapping("/testOutObj")
        User testObj(@RequestBody User user);
    
        @RequestMapping("/testNacosDynamicProp")
        String testNacosDynamicProp();
    }
    

    配置文件application.yml可以放置一些公共的參數配置咐汞,比如加解密私鑰等等

  3. 創(chuàng)建服務提供者

    此模塊為服務提供方,實現真正的業(yè)務邏輯儒鹿。結構如下:

    在這里插入圖片描述

    為了測試Feign的負載均衡化撕,創(chuàng)建兩個一樣結構和內容的服務提供者,分別命名為cloud-service1和cloud-service2约炎,在它們各自的application.yml中植阴,使用不同的端口號來模擬不同地址的相同的服務。

    pom:

        <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.test</groupId>
            <artifactId>cloud-test</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <artifactId>cloud-service1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-service1</name>
        <packaging>jar</packaging>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <!--引入公共模塊-->
            <dependency>
                <groupId>com.test</groupId>
                <artifactId>cloud-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
    

    創(chuàng)建配置文件bootstrap.yaml和application.yml

    bootstrap.yml如下:

    spring:
    application:
    # 服務提供者名稱
    name: cloud-service
    cloud:
    nacos:
      discovery:
        # 服務注冊于發(fā)現地址
        server-addr: 192.168.31.217:8848
      config:
        # 配置中心地址
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        # 配置中心配置文件的格式圾浅,如果不設置此項掠手,默認為.properties格式
        file-extension: yaml
    

    application.yml如下:

    #服務端口,這里我們設置cloud-service1為8001狸捕,cloud-service2為8002
    server:
      port: 8081
    

    有了application.yml喷鸽,為什么還要創(chuàng)建一個bootstrap.yml呢,它們倆的區(qū)別如下:

    https://blog.csdn.net/ThinkWon/article/details/100007093

    感謝這篇文章的作者灸拍,解開了我的迷惑做祝。

    創(chuàng)建啟動類ServiceApplication1

    package com.service;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    public class ServiceApplication1 {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceApplication1.class, args);
        }
    
    }
    

    創(chuàng)建服務提供類UserServiceProvider

    package com.service.controller;
    
    import com.common.model.User;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Author: yhl
     * DateTime: 2019/12/8 23:17
     * Description: write some description
     */
    @RestController
    public class UserServiceProvider {
    
        @RequestMapping("/testOut")
        public Map test(@RequestParam("name") String name, HttpServletRequest req) {
            Map<Object, Object> map = new HashMap<>();
            map.put("url", req.getRequestURL().toString());
            map.put("name", name);
            return map;
        }
    
        @RequestMapping("/testOutObj")
        public User testObj(@RequestBody() User user, HttpServletRequest req) {
            user.setUrl(req.getRequestURL().toString());
            return user;
        }
    }
    

    服務提供者創(chuàng)建完成。

  1. 創(chuàng)建服務消費者cloud-consumer

    pom文件:

        <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <artifactId>cloud-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-consumer</name>
        <packaging>jar</packaging>
    
        <parent>
            <groupId>com.test</groupId>
            <artifactId>cloud-test</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.test</groupId>
                <artifactId>cloud-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            
            <!-Feign--->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    因為遠程調用使用的是Feign組件,所以pom中加了Feign的依賴鸡岗。

    創(chuàng)建配置文件bootstrap.yaml和application.yml

    bootstrap.yml如下:

    spring:
    application:
    # 服務提供者名稱
    name: cloud-consumer
    cloud:
    nacos:
      discovery:
        # 服務注冊于發(fā)現地址
        server-addr: 192.168.31.217:8848
      config:
        # 配置中心地址
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        # 配置中心配置文件的格式混槐,如果不設置此項,默認為.properties格式
        file-extension: yaml
    

    application.yml如下:

    #服務端口轩性,這里我們設置cloud-service1為8001声登,cloud-service2為8002
    server:
      port: 8080
    

    創(chuàng)建服務消費者啟動類ConsumerApplication

    package com.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableFeignClients//開啟feign
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    

    在啟動類上加@EnableFeignClients,代表開啟了對feign組件的支持。

    繼承服務提供方接口UserService

    @FeignClient(name ="cloud-service")
    public interface UserService extends IUserService {
    }
    

    此接口方法繼承了我們在common模塊定義的微服務接口悯嗓,加上@FeignClient注解之后件舵,表示可使用Feign來調用此接口中方法中@RequestMapping映射路徑的服務提供者的http服務。
    此接口是我抽象出來的绅作,目的是不用在common模塊中也引入Feign的依賴芦圾,當然也可以不用這么寫。直接在IUserService接口加上@FeignClient注解俄认。

    @FeignClient中的name屬性配置的為bootstrap.yml中配置的服務提供者名稱。

    創(chuàng)建消費者接口UserConsumerController

    package com.consumer.controller;
    
    import com.common.model.User;
    import com.consumer.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    /**
     * Author: yhl
     * DateTime: 2019/12/8 23:12
     * Description: write some description
     */
    @RestController
    public class UserConsumerController {
    
        @Autowired
        private UserService userService;
    
        @RequestMapping("/test")
        public Map<Object,Object> test() {
            return userService.test("張三");
        }
    
        @RequestMapping("/testObj")
        public User testObj() {
            return userService.testObj(new User());
        }
    
        @RequestMapping("/testNacosDynamicProp")
        public String testNacosDynamicProp() {
            return userService.testNacosDynamicProp();
        }
    }
    

    創(chuàng)建負載均衡配置類ConfigBean

    package com.consumer.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * @author: yhl
     * @DateTime: 2019/12/9 13:37
     * @Description:
     */
    
    @Configuration
    public class ConfigBean {
        /**
         * 默認按順序輪詢
         * @return
         */
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }
    

    至此洪乍,我們的模塊都創(chuàng)建完畢了眯杏,接下來進行測試。

  2. 服務和負載均衡測試

    我們將三個模塊的服務都啟動壳澳,如下圖:


    在這里插入圖片描述

    利用http接口測試工具來測試我們的接口

    選擇一個接口進行測試岂贩,如 http://localhost:8080/test

    在這里插入圖片描述

    在這里插入圖片描述

    發(fā)送兩次請求,會發(fā)現打印的請求地址的端口號不同巷波,說明實現了負載均衡萎津。
    連續(xù)發(fā)送多次請求,端口號會交替變化抹镊,因為默認的負載均衡策略為輪訓法锉屈。

     由于本片內容過程長,關于feign的負載均衡垮耳,單獨再開一篇blog颈渊,感興趣的話可以接著看
    

    Blog傳送門

    本項目代碼傳送門

    有什么問題歡迎大家交流。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末终佛,一起剝皮案震驚了整個濱河市俊嗽,隨后出現的幾起案子,更是在濱河造成了極大的恐慌铃彰,老刑警劉巖绍豁,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異牙捉,居然都是意外死亡竹揍,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門鹃共,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鬼佣,“玉大人,你說我怎么就攤上這事霜浴【е裕” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晌纫。 經常有香客問我税迷,道長,這世上最難降的妖魔是什么锹漱? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任箭养,我火速辦了婚禮,結果婚禮上哥牍,老公的妹妹穿的比我還像新娘毕泌。我一直安慰自己,他們只是感情好嗅辣,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布撼泛。 她就那樣靜靜地躺著,像睡著了一般澡谭。 火紅的嫁衣襯著肌膚如雪愿题。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天蛙奖,我揣著相機與錄音潘酗,去河邊找鬼。 笑死雁仲,一個胖子當著我的面吹牛仔夺,可吹牛的內容都是我干的。 我是一名探鬼主播伯顶,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼囚灼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祭衩?” 一聲冷哼從身側響起灶体,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掐暮,沒想到半個月后蝎抽,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡路克,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年樟结,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片精算。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓢宦,死狀恐怖,靈堂內的尸體忽然破棺而出灰羽,到底是詐尸還是另有隱情驮履,我是刑警寧澤鱼辙,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站玫镐,受9級特大地震影響倒戏,放射性物質發(fā)生泄漏。R本人自食惡果不足惜恐似,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一杜跷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矫夷,春花似錦葛闷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蔓彩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驳概,已是汗流浹背赤嚼。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顺又,地道東北人更卒。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像稚照,于是被迫代替她去往敵國和親蹂空。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容