1 Spring Cloud簡述及簡單入門實例
1.1 概述
Spring Cloud基於Spring Boot,提供了多個組件來幫助企業進行微服務系統建設;它提供的主要功能有:服務注冊中心/服務注冊/服務調用/負載均衡/斷路器等;一般情況下它都是使用已有的開源軟件,在其基礎上按Spring Boot的理念來進行封裝,簡化各種個組件的調用以及各個組件之間的交互。
1.2 常用組件
Spring Cloud主要包含以下常用組件:Eureka或nacos、Ribbon、Feign
1.2.1 Eureka
分成兩類:
(1)一是注冊中心及EurekaServer,用於提供服務注冊/服務申請等功能;
(2)一是被注冊者及服務提供者EurekaClient,用於向EurekaServer注冊服務並可從EurekaServer獲取需要調用的服務地址信息;
需要向外提供服務的應用,需要使用EurekaClient來向Server注冊服務。
1.2.2 Ribbon
負責進行客戶端負載均衡的組件;一般與RestTemplate結合,在訪問EurekaClient提供的服務時進行負載均衡處理。
也就是說,Ribbon用於服務調用者向被調用者進行服務調用,並且如果服務者有多個節點時,會進行客戶端的負載均衡處理;
1.2.3 Feign
與Ribbon功能類型,用於調用方與被調用方的服務調用,同時進行客戶端負載均衡的處理;不過它能提供類似本地調用的方式調用遠程的EurekaClient提供的服務;它實際上是在Ribbon基礎上進行了進一步的封裝來提高調用服務的簡便性。
1.3 使用示例
假設現在有springcloud-eurekaClient和springcloud-eurekaClient2向外提供服務,該服務同時部署兩個節點;Client通過Feign或者是Ribbon調用其提供的服務,其部署關系及數據流向圖如下所示:

第一步:啟動注冊中心(啟動springCloud-EurekaServer項目);服務提供者及調用者向服務中心注冊;
第二步:服務調用者向服務中心申請服務,根據服務中心返回的地址信息調用服務提供者提供的服務;
第三步:注冊中心通過心跳檢測方式檢測服務提供者的狀態,當某個提供者連接不上時,發送消息通知所有注冊者;
下面詳細說明每個節點的實現; 具體代碼見
1.4 Eureka服務端(springCloud-EurekaServer)
新建springCloud-EurekaServer Maven工程,具體目錄結構如下圖

1.4.1 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>
<groupId>org.example</groupId> <artifactId>springCloud</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath /> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencies> <!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies>
<!-- Spring Cloud --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
</project> |
1.4.2 Application.yml配置
server: port: 8888
#應用的名字 spring: application: name: springCloud-EurekaServer eureka: instance: hostname: localhost client: registerWithEureka: false # 由於該應用為注冊中心,所以設置為false,代表不向注冊中心注冊自己 fetchRegistry: false # 由於注冊中心的職責就是維護服務實例,他並不需要去檢索服務,所以也設置為false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ |
1.4.3 Application.cs文件
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
// 通過@EnableEurekaServer注解啟動一個服務注冊中心提供給其他應用進行對話。 @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); System.out.println("啟動成功!"); } } |
1.4.4 啟動結果
啟動完后通過http://localhost:8888/可以看到EurekaServer的監控頁面; 此時還沒有節點注冊,如下圖;

1.5 Eureka服務提供方(springcloud-eurekaClient)
新建springcloud-eurekaClient Maven工程,具體目錄結構如下圖

1.5.1 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>
<groupId>org.example</groupId> <artifactId>springcloud-eurekaserver</artifactId> <version>1.0-SNAPSHOT</version>
<!-- Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath /> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
<!-- Spring Cloud --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project> |
1.5.2 Application.yml配置
server: port: 8901 #應用的名字 spring: application: name: springcloud-eurekaClient eureka: client: serviceUrl: defaultZone: http://localhost:8888/eureka/ |
1.5.3 Application.cs文件
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); System.out.println("啟用成功!"); } } |
1.5.4 ComputeController.cs文件
package com.lijun.controller;
import org.apache.log4j.Logger; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass());
@RequestMapping(value = "/add" ,method = RequestMethod.GET) public Integer add(@RequestParam Integer a, @RequestParam Integer b) { Integer r = a + b; logger.info("/add, result:" + r); return r; } @GetMapping("/hello") public String sayHi(@RequestParam String name){ return " Welcome-: "+name; } } |
1.5.5 啟動結果
啟動main函數后,通過http://localhost:8888可以看到已經有節點注冊;
如果要啟動多個節點做負載均衡,可以修改application.yml中的端口信息后再次啟動main函數就可以了。

1.6 調用方(springCloud-feignClient)
新建springCloud-feignClient Maven工程,具體目錄結構如下圖

1.6.1 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>
<groupId>org.example</groupId> <artifactId>springCloud-feignClient</artifactId> <version>1.0-SNAPSHOT</version>
<!-- Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath /> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
<!-- Spring Cloud --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
</project> |
1.6.2 Application.yml配置
server: port: 8999 #應用的名字 spring: application: name: springCloud-feignClient eureka: client: serviceUrl: defaultZone: http://localhost:8888/eureka/ |
1.6.3 FeignApplication.cs文件
package com.lijun.feign;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.feign.EnableFeignClients;
/** * 在啟動類上加@EnableFeignClients注解, * 如果你的Feign接口定義跟你的啟動類不在一個包名下,還需要制定掃描的包 * 名@EnableFeignClients(basePackages = "com.lijun.api.client") * @author ljl * */ @SpringBootApplication @EnableEurekaClient @EnableFeignClients public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args); System.out.println("啟動成功"); } } |
1.6.4 FeignConfiguration.cs文件
package com.lijun.feign.config;
import feign.Retryer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/** * 自定義配置類 * @author ljl * */ @Configuration public class FeignConfiguration { /** * 覆蓋默認的Retryer的Bean,重試間隔為100毫秒,最大重試時間為1秒,重試次數5次 * @return */ @Bean public Retryer feignRetryer(){ return new Retryer.Default(100, TimeUnit.SECONDS.toMillis(1), 5); }
} |
1.6.5 EurekaClientFeign.cs文件
package com.lijun.feign.interfaces;
import com.lijun.feign.config.FeignConfiguration; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam;
/** * Feign客戶端調用接口 * @author ljl * */ @FeignClient(value = "springcloud-eurekaClient",configuration = FeignConfiguration.class) public interface EurekaClientFeign {
/** * 調用遠程服務器的方法 * 服務器即為上述注解@FeignClient的value = "ppl-server" * @param name * @return */ @GetMapping("/hello") String sayHiFromRemote(@RequestParam(value = "name") String name); } |
1.6.6 Hiservice.cs文件
package com.lijun.feign.service;
import com.lijun.feign.interfaces.EurekaClientFeign; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
@Service public class Hiservice {
@Autowired EurekaClientFeign eureClientFeign; public String sayHi(String name){ return eureClientFeign.sayHiFromRemote(name); } } |
1.6.7 HiController.cs文件
package com.lijun.feign.controller;
import com.lijun.feign.service.Hiservice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RestController public class HiController {
@Autowired Hiservice hiService; /** * 在該接口調用了Hiservice的sayHi()方法,Hiservice通過接口EurekaClientFeign遠程 * 調用 springcloud-eurekaClient 項目 ComputeController.cs中的 "/hello" * @param name * @return */ @GetMapping("/hi") public String sayHi(@RequestParam(defaultValue="Feifn-client-test",required=false)String name){ return hiService.sayHi(name); } } |
1.6.8 啟動結果
啟動main方法后,通過EurekaServer的監控頁面可以看到又多了一個名稱為SPRINGCLOUD-FEIGNCLIENT的節點; 此時可以通過http://localhost:8999/hi來查看執行結果。

1.7 結束
這就是spring cloud 的簡單示例,在此感謝 https://blog.csdn.net/icarusliu/article/details/79461012 博主,如果需要代碼,請關注公眾號,發送“springcloud”,獲取下載地址
