IDEA基於Spring Cloud Netflix(2.1.0RC3)的Spring Cloud Eureka來實現服務治理的微服務架構搭建以及和SSM框架的整合——實戰教程
這裡開始spring cloud微服務架構搭建,用的maven還是之前自己的本地安裝的,repository倉庫也是本地的。
在搭建專案框架之前先簡單學習一下spring cloud。
Spring Cloud 簡介
Spring Cloud是一個基於Spring Boot實現的雲應用開發工具,是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring Cloud包含了多個子專案(針對分散式系統中涉及的多個不同開源產品),具體如下spring cloud元件介紹。
Spring Cloud 常用元件
1. Spring Cloud Config
服務配置中心,將所有的服務的配置檔案放到本地倉庫或者遠端倉庫,配置中心負責讀取倉庫的配置檔案,其他服務向配置中心讀取配置。Spring Cloud Config使得服務的配置統一管理,並可以在不人為重啟服務的情況下進行配置檔案的重新整理。
2. Spring Cloud Netflix
它是通過包裝了Netflix公司的微服務元件實現的,也是Spring Cloud核心元件,包括Eureka,Hystrix,Zuul,Archaius。
3. Eureka
服務註冊和發現元件
4. Hystrix
熔斷器元件。它通過控制服務的API介面的熔斷來轉移故障,防止微服務系統發生雪崩效應。另外Hystrix能夠起到服務限流和服務降級的作用。使用Hystrix Dashboard元件監控單個服務的熔斷狀態,使用Hystrix Turbine元件可以監控多個服務的熔斷器的狀態。
5. Zuul
智慧路由閘道器元件。能夠起到智慧路由和請求過濾的作用
6. Feign
宣告式遠端排程元件。
7. Ribbon
負載均衡元件
8. Archaius
配置管理API元件,一個基於Java的配置管理庫,主要用於多配置的動態獲取。
9. Spring Cloud Bus
訊息匯流排元件,常和Spring Cloud Config配合使用,用於動態重新整理服務的配置。
10. Spring Cloud Sleuth
服務鏈路追蹤元件,封裝了Dapper,Zipkin,Kibina等元件,可以實時監控服務鏈路呼叫狀況。
11. Spring Cloud Data Flow
大資料操作元件,它是Spring XD的替代品,也是一個混合計算模型,可以通過命令列的方式操作資料流
12. Spring Cloud Consul
該元件是Spring Cloud對Consul的封裝,和Eureka類似,它是一個服務註冊和發現元件。
13. Spring Cloud Zookeeper
該元件是Spring Cloud對Zookeeper的封裝,也是用於服務註冊和發現
14. Spring Cloud Stream
資料流操作元件,可以封裝 Redis,RabbitMQ,Kafka等元件,實現訊息的接受和傳送。
15. Spring Cloud CLI
該元件是對Spring Boot CLI的封裝,可以讓使用者以命令列方式快速搭建和執行容器。
16. Spring Cloud Task
該元件基於Spring Tsak,提供任務排程和任務管理的功能。
Spring Cloud 與 Dubbo 的對比(微服務方面)
微服務關注點 | Spring Cloud | Dubbo |
管理配置 | Config | — |
服務發現 | Eureka、Consul、Zookeeper | Zookeeper |
負載均衡 | Ribbon | 自帶 |
網管 | Zuul | — |
分散式追蹤 | Spring Cloud Sleuth | — |
容錯 | Hystrix | 不完善 |
通訊方式 | HTTP、Message | RPC |
安全模組 | Spring Cloud Security | — |
Spring Cloud擁有很多的專案模組,包含微服務的方方面面,Dubbo是個十分優秀的服務治理和服務呼叫框架,但缺少了很多的功能模組,例如閘道器,鏈路追蹤等。
開發風格上,Dubbo傾向於xml配置方式,而Spring Cloud基於Spring Boot,它採用基於註解和JavaBean配置方式的敏捷開發。
通訊方式上Spring Cloud大多數基於HTTP Restful風格,服務與服務間完全耦合,因此服務無關乎語言和平臺。Dubbo採用遠端呼叫方式,對介面平臺和程式語言有強依賴性。
Dubbo和Spring Cloud各有優缺點,Dubbo更易上手,也非常成熟和穩定,Spring Cloud服務框架嚴格遵守 Martin Fowler 提出的微服務規範。
微服務架構
微服務的概念源於2014年3月Martin Fowler所寫的章“Microservices”http://martinfowler.com/articles/microservices.html
微服務(Microservices Architecture)是一種架構風格,一個大型複雜軟體應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表著一個小的業務能力。
微服務架構的核心思想是,一個應用是由多個小的、相互獨立的、微服務組成,這些服務執行在自己的程序中,開發和釋出都沒有依賴。不同服務通過一些輕量級互動機制來通訊,例如 RPC、HTTP 等,服務可獨立擴充套件伸縮,每個服務定義了明確的邊界,不同的服務甚至可以採用不同的程式語言來實現,由獨立的團隊來維護。簡單的來說,一個系統的不同模組轉變成不同的服務!而且服務可以使用不同的技術加以實現!
那我們在微服務中應該怎樣設計呢。以下是微服務的設計指南:
- 職責單一原則(Single Responsibility Principle):把某一個微服務的功能聚焦在特定業務或者有限的範圍內會有助於敏捷開發和服務的釋出。
- 設計階段就需要把業務範圍進行界定。
- 需要關心微服務的業務範圍,而不是服務的數量和規模儘量小。數量和規模需要依照業務功能而定。
- 於SOA不同,某個微服務的功能、操作和訊息協議儘量簡單。
- 專案初期把服務的範圍制定相對寬泛,隨著深入,進一步重構服務,細分微服務是個很好的做法。
關於為服務的一些取捨:
- 在合適的專案,合適的團隊,採用微服務架構收益會大於成本。
- 微服務架構有很多吸引人的地方,但在擁抱微服務之前,也需要認清它所帶來的挑戰。
- 需要避免為了“微服務”而“微服務”。
- 微服務架構引入策略 – 對傳統企業而言,開始時可以考慮引入部分合適的微服務架構原則對已有系統進行改造或新建微服務應用,逐步探索及積累微服務架構經驗,而非全盤實施微服務架構。
Spring Cloud Eureka來實現服務治理
如下我們使用 euraka 體系的spring cloud.
以下工作都在project->springcloud-erueka-project
開啟idea建立project:
選擇maven建立普通的maven管理專案:
填寫工程的組命GroupId和專案名ArtifactId:
確認資訊後點擊finish即可:
選擇自動導包:
建立好的工程:
檢查idea的maven設定file---->settings---->maven:
1. 建立一個module 註冊中心eureka-server(包括監控中心)
1.1)新建一個module sc-eureka-server 提供服務註冊和發現
右鍵單擊工程名選擇Module建立模組:
選擇spring boot風格建立spring cloud:
填寫模組組名和模組名稱:
建立註冊中心(包含監控中心),選擇cloud discovery的eureka server,這裡也能看出spring boot的版本是2.1.1:
確認資訊後完成:
建立好的模組目錄以及有以下兩個檔案:
1.2)增加依賴(其實採用spring boot方式建立的spring cloud已經簡化了很多工作,這裡的依賴也已經完成了,只是我們要知道是什麼依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
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.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kgc1803</groupId>
<artifactId>sc-eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sc-eureka-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RC2</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
1.3)這裡我的所有配置檔案均採用application.yml格式(即將application.properties字尾更改成.yml),當然你可不用更改,根據自己的風格愛好就可以,並在註冊中心模組配置eureka server。在預設設定下,該服務註冊中心也會將自己作為客戶端來嘗試註冊它自己,所以我們需要禁用它的客戶端註冊行為,只需要在application.yml
配置檔案中增加如下資訊:
register-with-eureka: false
fetch-registry: false
application.yml配置檔案內容如下,只是要注意,application.yml風格的配置需要注意各個子級需要對應工整,不然後面啟動服務是不會有效果的,要求更加嚴格:
#服務埠
server:
port: 8761
#eureka server 的配置
#register-with-eureka: false表示該eureka 節點不能註冊服務
#fetch-registry: false 表示該eureka 節點不能釋出(訂閱)服務
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 這裡預設的路徑後面需要加上eureka/才會訪問到。
1.4)在主服務啟動類上增加eureka server 的註解標籤( @EnableEurekaServer )
package com.kgc1803.sceurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class ScEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(ScEurekaServerApplication.class, args);
}
}
1.5)啟動測試
訪問服務
啟動工程後,訪問:http://localhost:8761/
可以看到下面的頁面,其中還沒有發現任何服務。
2. 釋出一個服務
2.1)新建一個module sc-eureka-service-provider
建立方法跟上面一樣,只是有一點不一樣如下選項:
這裡的取別如下圖:
2.2)檢查依賴並增加相應的依賴,spring cloud 釋出服務多用 rest 風格,所以需要spring-boot web 包:
<!-- eureka-client 既能註冊服務又能訂閱服務-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring cloud 釋出服務多用 rest 風格,所以需要spring-boot web 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
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.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kgc1803</groupId>
<artifactId>sc-eureka-service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sc-eureka-service-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RC2</spring-cloud.version>
</properties>
<dependencies>
<!-- eureka-client 既能註冊服務又能訂閱服務-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring cloud 釋出服務多用 rest 風格,所以需要spring-boot web 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
2.3)在ScEurekaServiceProviderApplication.java服務啟動類同級建立service包並編寫一個服務類;這裡我們使用rest風格的控制器註解:@RestController
DemoService.java服務類:
package com.kgc1803.sceurekaserviceprovider.service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//rest 風格控制器註解
@RestController
public class DemoService {
@RequestMapping("/getInfo")
public String getDemoInfo(){
return "this is a provided service !";
}
}
2.4)在application.yml中完成eureka client 釋出服務的配置(客戶端(client)向server(伺服器端)註冊服務的配置)
新增配置
需要配置才能找到 Eureka 伺服器。例:
完整配置
server:
port: 8081
#instance.appname 指明註冊中的名字
#service-url.defultzone:配置註冊中心地址
eureka:
instance:
appname: demo_service_provider
client:
service-url:
defaultZone: http://localhost:8761/eureka/
#應用名字
spring:
application:
name: eureka-provider
其中defaultZone
是一個魔術字串後備值,為任何不表示首選項的客戶端提供服務URL(即它是有用的預設值)。 通過spring.application.name
屬性,我們可以指定微服務的名稱後續在呼叫的時候只需要使用該名稱就可以進行服務的訪問
2.5)在主啟動類中增加 釋出服務的註解配置
開啟服務註冊,在應用主類中通過加上 @EnableEurekaClient,但只有Eureka 可用,你也可以使用@EnableDiscoveryClient。需要配置才能找到Eureka註冊中心伺服器;實驗證明可以不用加。
package com.kgc1803.sceurekaserviceprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ScEurekaServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ScEurekaServiceProviderApplication.class, args);
}
}
訪問服務
啟動該工程後,再次訪問啟動工程後:http://localhost:8761/
可以如下圖內容,我們定義的服務被成功註冊了。
2.6)啟動與測試:http://localhost:8081/getInfo
出現如下圖所示表名取到了值:
3. 發現(訂閱)一個服務
3.1)新建一個module sc-eureka-service-consume(流程跟上面釋出服務模組一樣)
建好的模組目錄:
3.2)增加依賴
<!-- eureka-client 既能註冊服務又能訂閱服務-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring cloud 釋出服務多用 rest 風格,所以需要spring-boot web 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.3)在 ScEurekaServiceConsumeApplication.java 啟動類的同級目錄編寫一個控制器(主要用來呼叫已註冊的服務,即上面第二個模組註冊的服務);這裡需要注入一個RestTemplate工具類物件才可以呼叫到,但是直接在控制器使用物件是沒辦法得到值的,為了方便其他控制器(同模組)可以呼叫這個工具物件,最好的辦法就是直接在啟動類裡面寫一個方法產生物件,啟動的時候就可以注入了(這裡調值與上面的方法不一樣,也是唯一最大的區別處)。
//向spring裡注入一個RestTemplate物件
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
完整的啟動類示例:
package com.kgc1803.sceurekaserviceconsume;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//在啟動類注入@EnableEurekaClient註解
@SpringBootApplication
@EnableEurekaClient
public class ScEurekaServiceConsumeApplication {
public static void main(String[] args) {
SpringApplication.run(ScEurekaServiceConsumeApplication.class, args);
}
//向spring裡注入一個RestTemplate物件
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在編寫的控制器中引入RestTemplate物件
@Autowired
private RestTemplate restTemplate;
完整的控制器示例:
package com.kgc1803.sceurekaserviceconsume.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class DemoController {
//映入工具物件RestTemplate
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/test")
public String getEurekaServiceInfo(){
/**
* exchange(url,type,paras,resultType)
* url:請求地址
* type:請求型別 get post
* paras:引數
* resultType:返回值型別
*/
//取sc-eureka-service-provider模組服務類getInfo()中的值,這裡獲取url地址和方法名
String url = "http://localhost:8081/getInfo";
HttpMethod type = HttpMethod.GET; //請求方式
RequestEntity<String> paras = null;//請求引數,沒有請求引數,所以給null值
//物件呼叫exchange()帶四個引數的方法,並返回請求
ResponseEntity<String> responseEntity = restTemplate.exchange(url,type,paras,String.class);
//返回值,注意,這裡是返回String型別,所以getBody()就是字串,如果方法返回是物件或者list集合,getBody()也就對應返回型別。
return responseEntity.getBody();
}
}
3.4)在application.yml中完成eureka client 釋出服務的配置,方法同上一個模組:
server:
port: 8082
#客戶端(client)向server(伺服器端)註冊服務的配置
#instance.appname 指明註冊中的名字
#service-url.defultzone:配置註冊中心地址
eureka:
instance:
appname: demo_service_consume
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
#應用名字
spring:
application:
name: eureka-consume
模組結構圖:
3.5)啟動測試服務類,重新整理:http://localhost:8761/ 如下圖,兩個服務都發布成功。
輸入地址:http://localhost:8082/test 測試從控制器根據物件工具取值是否成功:
取到值,測試成功!
啟動的三個服務類。
拓展總結:
後端的註冊中和服務類啟動後,註冊中心Eureka大概90秒向服務類做一次通訊,而服務類大概30秒左右跟註冊中心的Erueka回一次通訊;即使後端通訊斷掉了,前端頁面顯示的依然是註冊的服務存在,註冊有效。另外,想要把註冊中報紅色的安全保護機制關掉,只需要在註冊中心模組的配置檔案中加一個配置即可,如下:
#安全保護機制(埠)關閉
instance:
secure-port-enabled: false
Spring Cloud 與 SSM框架的整合
1.建立公共模組 sc-eureka-service-common(使用普通maven建立即可)
建立好的公共模組如下圖,這個公共模組需要操作的是完成pojo實體類,但是這裡因為和spring cloud並用,所以不用寫service介面了,匯入相應的jar檔案,將公共模組打包釋出到倉庫:
2. 在pomxml檔案增加 json 的依賴:
<!-- json 外掛 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
打一個jar檔案包:
<packaging>jar</packaging>
3. 編寫User.java實體類:
package com.kgc1803.demo.pojo;
import org.codehaus.jackson.annotate.JsonProperty;
import java.io.Serializable;
//注意的是pojo實體類一定要實現序列化介面
public class User implements Serializable {
@JsonProperty
private Integer id;
@JsonProperty
private String userCode;
@JsonProperty
private String userName;
@JsonProperty
private String password;
public User(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4. 公共模組打成 jar 包釋出到倉庫:
5. 在sc-eureka-service-consume和sc-eureka-service-provider模組的pom.xml檔案增加公共的 jar 包:
<!--公共包-->
<dependency>
<groupId>com.kgc1803</groupId>
<artifactId>sc-eureka-service-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
更新:對上面的服務類和控制器進行升級改造和拓展,升級是上面用的是無引數的服務類,在控制器用的是 restTemplate 工具物件呼叫 exchange(url,type,paras,resultType)方法實現的,這裡有四個引數,換成以下 getForObject(url,resultType) 或者是 postForObject(url,引數物件,返回值型別)方法會更簡潔(內部做了進一步封裝),這裡直接把三種類型(基礎型別String有參和無參、集合List、物件)示例程式碼全部碼上:
DemoService.java 服務類:
package com.kgc1803.sceurekaserviceprovider.service;
import com.kgc1803.demo.pojo.User;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//rest 風格控制器註解
@RestController
public class DemoService {
/**
* 基本資料型別無引數
* @return
*/
@RequestMapping("/getInfo")
public String getDemoInfo(){
return "this is a provided service !";
}
/**
* 基本資料型別有引數
* @param userCode
* @return
*/
@RequestMapping("/getInfo_02")
public String getDemoInfo_02(String userCode){
return userCode + " , this is a provided cloud 程式 !";
}
/**
* 帶引數的List集合型別
* @param userCode
* @return
*/
@RequestMapping("/getlist")
public List getList(String userCode){
List<Map> list = new ArrayList<Map>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("userName","張三");
map.put("userCode",userCode);
list.add(map);
return list;
}
/**
* 帶物件引數的物件型別,注意,這裡需要繫結註解:@RequestBody
* @param user
* @return
*/
@RequestMapping(value = "/getuser",method = {RequestMethod.GET,RequestMethod.POST})
public User getUser(@RequestBody User user){
return user;
}
}
DemoController.java 控制器類:
package com.kgc1803.sceurekaserviceconsume.controller;
import com.kgc1803.demo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* 這裡測試,傳值都是從後端傳到前端
* 測試三種類型:基本資料型別的String、List集合、物件
*/
@RestController
public class DemoController {
//映入工具物件RestTemplate
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/test")
public String getEurekaServiceInfo(){
/**
* exchange(url,type,paras,resultType) 請求無引數的getDemoInfo()
* url:請求地址(遠端服務地址)
* type:請求型別 get post
* paras:引數
* resultType:返回值型別 String.class
*/
//取sc-eureka-service-provider模組服務類getInfo()中的值,這裡獲取url地址和方法名
String url = "http://localhost:8081/getInfo";
HttpMethod type = HttpMethod.GET; //請求方式
RequestEntity<String> paras = null;//請求引數,沒有請求引數,所以給null值
//物件呼叫exchange()帶四個引數的方法,並返回請求
ResponseEntity<String> responseEntity = restTemplate.exchange(url,type,paras,String.class);
//返回值,注意,這裡是返回String型別,所以getBody()就是字串,如果方法返回是物件或者list集合,getBody()也就對應返回型別。
return responseEntity.getBody();
}
@RequestMapping("/test1")
public String getEurekaServiceInfo_01(){
/**
* 對上面的方法進行升級改造,進一步封裝,並呼叫無引數的getDemoInfo()方法達到同樣的效果
* getForObject(url,resultType) ,可以看出,這個方法的提交方式是GET
* url:遠端服務地址
* resultType:返回值型別 String.class
*/
String url = "http://localhost:8081/getInfo";
String res = restTemplate.getForObject(url,String.class);
return res;
}
@RequestMapping("/test2")
public String getEurekaServiceInfo_02(){
/**
* 用getForObject(url,resultType)方法呼叫有引數的getDemoInfo_02()方法
* getForObject(url,resultType) ,可以看出,這個方法的提交方式是GET
* url:遠端服務地址;我這裡做測試,直接在url將引數固定,利用url傳引數:?userCode=zhangsan
* resultType:返回值型別 String.class
*/
String url = "http://localhost:8081/getInfo_02?userCode=zhangsan";
String res = restTemplate.getForObject(url,String.class);
return res;
}
@RequestMapping("/test3")
public List getListInfo(){
/**
* 用getForObject(url,resultType)方法呼叫有引數的getList()方法
* getForObject(url,resultType) ,可以看出,這個方法的提交方式是GET
* url:遠端服務地址;我這裡做測試,直接在url將引數固定,利用url傳引數:?userCode=zhangsan
* resultType:返回值型別 List.class
* List mapList = restTemplate.getForObject(url,List.class);
* 返回到前端所顯示的值:[{"userName":"張三","userCode":"zhangsan"}] 是json 格式的資料
*/
String url = "http://localhost:8081/getlist?userCode=zhangsan";
List mapList = restTemplate.getForObject(url,List.class);
return mapList;
}
@RequestMapping("/test4")
public User getUserInfo(){
/**
* 用postForObject(url,引數物件,返回值型別)方法呼叫有引數的getUser()方法
* postForObject(url,引數物件,返回值型別)可以看出採用的是POST提交方法
* url:遠端服務地址
* user:引數物件
* resultType:返回值型別 User.class
* User u = restTemplate.postForObject(url,user,User.class);
*/
User user = new User();
user.setId(17);
user.setUserCode("zhangsan");
user.setUserName("張三");
user.setPassword("1234");
String url = "http://localhost:8081/getuser"; //遠端服務地址
User u = restTemplate.postForObject(url,user,User.class);
return u;
}
}
挨個測試以上控制器的輸出結果:
http://localhost:8082/test String 型別的無引數 呼叫的exchange(url,type,paras,resultType)方法
http://localhost:8082/test1 String 型別的無引數 呼叫的getForObject(url,resultType)方法
http://localhost:8082/test2 String 型別的帶引數 呼叫的getForObject(url,resultType)方法
http://localhost:8082/test3 集合型別的 List 帶引數 呼叫的getForObject(url,resultType)方法
http://localhost:8082/test4 物件型別 呼叫的是 postForObject(url,引數物件,返回值型別)方法
至此,IDEA基於Spring Cloud Netflix(2.1.0RC3)等同於(SpringBoot2.1.1正式版)的SpringCloud 微服務架構搭建——實戰教程(一)的Spring Cloud Eureka來實現服務治理就基本結束了!