SpringCloud Feign+Eurake實現應用間通信

說明:該文章只是簡單描述瞭如何進行通信,並沒有關於feign的詳細註解和高級使用。(大佬看看我寫的有沒有問題也是可以的)。

流程簡述:一個程序作爲eureka服務端供其餘兩個應用註冊,另外兩個應用註冊後使用feign進行應用間通信。

使用環境:JDK 8、SpringBoot: 2.1.3、SpringCloud:Greenwich.SR1
版本不一致可能會導致莫名奇妙的錯誤。

1、eureka服務端的創建(eureka-server):
(1)打開idea創建springboot項目,在選模塊的時候記得選上下圖所示模塊:

 

(2)給出pom.xml和application.yml的配置文件(只要你按照(1)選了Eureka Server模塊,pom.xml應該是和我一樣的)
pom.xml:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.yml配置:

server:
  #服務端口
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    # 禁止自己註冊自己
    register-with-eureka: false
    # 服務開啓的url
    service-url:
          defaultZone: http://localhost:8761/eureka/

 

(3)在啓動類上加上註解:@EnableEurekaServer

 

2、兩個eureka客戶端的創建(feign-client、feign-server):

    首先創建feign-client應用
(1)創建springboot應用,在選擇模塊的時候選擇下圖所示的兩個模塊:

(2)給出pom.xml和application.yml的配置(只要你(1)中選的模塊是和我一樣的,那麼pom.xml應該也是和我一樣的)
pom.xml(feign-client)

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>feign-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>feign-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.yml(feign-client):

server:
  port: 8080
spring:
  application:
    name: feign-client
eureka:
  client:
    service-url:
      # 註冊到服務於該url的eurekaServer
      defaultZone: http://localhost:8761/eureka/

(3)在啓動類上加上註解:@EnableDiscoveryClient

然後我們以相同的方式創建feign-server應用:
給出feign-server的application.yml配置文件(pom.xml就不給了,因爲暫時不需要加東西)

server:
  port: 8081
spring:
  application:
    name: feign-server
eureka:
  client:
    service-url:
      # 註冊到服務於該url的eurekaServer
      defaultZone: http://localhost:8761/eureka/

另外一定要給feign-server啓動類加上註解:@EnableDiscoveryClient

至此,一個簡單eureka服務端和兩個客戶端就創建好了,我們將這三個應用啓動,然後在瀏覽器上輸入:localhost:8761
看到如下畫面就代表初步準備就已經弄好了:

 

接下來,我們配置並使用feign進行應用間的遠程通信:
首先我們先理清思路,是feign-server要調用feign-client的服務,所以我們需要在feign-server應用裏配置feign

在feign-server應用裏配置feign:
(1)添加jar依賴:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

(2)在啓動類上加上註解:@EnableFeignClients,可以配置basePackage屬性,指定feign客戶端的包。(本應用沒有指定)
 

 

接下來我們來編寫業務類:
1、先寫feign-client的接口:
目錄結構:

 

ClientController類:

@Controller
@RequestMapping("/client")
public class ClientController {

    //返回字符串
    @GetMapping("/msg")
    @ResponseBody
    public String msg(){
        return "你調用了Client端的服務!";
    }

    //返回list,在list末尾添加“client”
    //必須使用Post方法,參數要加上@RequestBody
    @PostMapping("/list")
    @ResponseBody
    public List<String> list(@RequestBody List<String> list){
        list.add("client");
        return list;
    }
    
    //返回對象(爲dog的name賦值)
    //必須使用Post方法,參數要加上@RequestBody
    @PostMapping("/dog")
    @ResponseBody
    public Dog setDogName(@RequestBody Dog dog){
        dog.setName("clientDog");
        return dog;
    }
}

 

Dog類:

public class Dog {
    private String name;
    
    //feign返回對象時,一定要添加無參構造方法,不然會報錯:反序列化失敗
    public Dog(){}

    public Dog(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

2、編寫feign-server的業務類:
目錄結構

 

AFeignClient接口(核心,通過該接口實現向客戶端訪問):

//@FeignClient裏的name填寫需要請求的客戶端的name(註冊在eureka上的name)
//即在application.yml裏配置的spring.application.name
@FeignClient(name = "feign-client")
public interface AFeignClient {

    //url必須一樣,方法名可以不同
    @GetMapping("/client/msg")
    String getMsgFromClient();

    @PostMapping("/client/list")
    List<String> getListFromClient(@RequestBody List<String> stringList);

    @PostMapping("/client/dog")
    Dog setDogName(@RequestBody Dog dog);
}

 

ServerController類:

@Controller
@RequestMapping("/server")
public class ServerController {

    //@Autowired 編譯器可能會報紅,但是依然能運行(大佬告訴我爲啥...)
    //有人可能會說@EnableFeignClients註解可以配置basePackages屬性指定feign-client
    //我這樣做了,但是依然會報紅
    //如果你的應用啓動會報錯,提示無法注入該bean,那麼你可以配置下basePackages
    //例如:@EnableFeignClients(basePackages = "com.example.feignserver.client")
    @Autowired
    private AFeignClient aFeignClient;

    //從client端獲取字符串
    @RequestMapping("/msg")
    public void msg(){
        String msg = aFeignClient.getMsgFromClient();
        System.out.println(msg);
    }

    //從client端獲取處理後的list
    @RequestMapping("/list")
    public void list(){
        ArrayList<String> strList = new ArrayList<>();
        strList.add("server");
        List<String> listFromClient = aFeignClient.getListFromClient(strList);
        System.out.println(listFromClient);
    }

    //從client端獲取處理的對象
    @RequestMapping("/dog")
    public void setDogName(){
        Dog dog = aFeignClient.setDogName(new Dog());
        System.out.println(dog.getName());
    }
}

Dog類和client端的是一樣的,就不再給出了。

 

那麼接下來該測試了:
(1)同時打開三個應用,在瀏覽器上訪問localhost:8761,確認兩個客戶端都已經註冊。

(2)測試server端的返回字符串接口,在瀏覽器上訪問:localhost:8081/server/msg,feign-server的控制檯打印出如下內容:   

(2)測試list接口,訪問:localhost:8081/server/list,feign-server的控制檯打印出如下內容:

(3)測試對象接口,訪問:localhost:8081/server/dog,feign-server的控制檯打印出如下內容:      

我們可以看見,feign-server應用通過feign向feign-client發送請求並接受了數據。

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