概述
- 前陣子項目中要用到Spring Cloud來作微服務(wù)框架轧膘,由于某些原因,需要結(jié)合Consul而非Zookeeper撼嗓,但網(wǎng)上關(guān)于Spring Cloud跟Consul的結(jié)合搭建資料較少眯杏,因此想將搭建過程記錄下來。
概念
Spring Cloud
根據(jù)百度百科上的定義:Spring Cloud是一系列框架的有序集合捞稿。它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊、配置中心娱局、消息總線彰亥、負載均衡、斷路器铃辖、數(shù)據(jù)監(jiān)控等剩愧,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動和部署。Spring Cloud并沒有重復(fù)制造輪子娇斩,它只是將目前各家公司開發(fā)的比較成熟仁卷、經(jīng)得起實際考驗的服務(wù)框架組合起來,通過Spring Boot風(fēng)格進行再封裝屏蔽掉了復(fù)雜的配置和實現(xiàn)原理犬第,最終給開發(fā)者留出了一套簡單易懂锦积、易部署和易維護的分布式系統(tǒng)開發(fā)工具包。
簡而言之歉嗓,Spring Cloud可以說是實現(xiàn)微服務(wù)架構(gòu)的全家桶丰介,擁有各種組件,這里主要使用Spring Cloud來當(dāng)作RPC框架鉴分。
至于為什么不用其他RPC框架哮幢,比如國內(nèi)比較流行的,阿里的Dubbo志珍,或者國外Facebook的Thrfit(目前屬于Apache)等橙垢,這里不再進行贅述。簡單說下:Thrift是支持跨語言的伦糯,如果所用的微服務(wù)有各種不同的語言實現(xiàn)柜某,那Thrift將是一個選擇,但當(dāng)時項目模塊全都采用Java開發(fā)敛纲,所以這個優(yōu)勢就不明顯喂击。之前有簡單試用了下Thrift,發(fā)現(xiàn)不是那么好用(當(dāng)然淤翔,可能也是不熟悉的關(guān)系)翰绊,而且Thrift自身未實現(xiàn)負載均衡。gPRC的話則了解不深旁壮,跟Thrift一樣支持跨語言辞做。Dubbo相對比較成熟穩(wěn)定,資料也多寡具,但是其對API層的jar依賴比較嚴(yán)重,且容易產(chǎn)生序列化問題稚补,而Spring Cloud是基于HTTP的童叠,相對而言在可維護性和可擴展性方面較好。
Consul
按Consul官網(wǎng)定義,Consul是一個分布式服務(wù)網(wǎng)格厦坛,用于連接五垮、保護跨運行平臺的公共或私有云配置服務(wù)。E文不太好杜秸,翻譯的可能不太準(zhǔn)確放仗,以下貼出Consul官網(wǎng)原文:Consul is a distributed service mesh to connect, secure, and configure services across any runtime platform and public or private cloud。
-
這里使用Consul來作為注冊發(fā)現(xiàn)服務(wù)撬碟,對分布式系統(tǒng)進行服務(wù)治理诞挨。Consul的架構(gòu)圖如下:Consul架構(gòu)
-
那又為什么要選擇Consul而不用Zookeeper、Eureka呢蛤、Etcd呢惶傻,這個當(dāng)時有很多原因,不一定是技術(shù)上的原因其障。當(dāng)然银室,Consul也確實有跨數(shù)據(jù)中心的優(yōu)點,這個對高可用要求較高的項目是個很大的吸引力励翼。另外蜈敢,Consul集群部署也比較簡單,還自帶Web UI管理界面汽抚。這里附上這幾種服務(wù)的比較圖(參考CSDN博客【Etcd抓狭、Eureka、Consul殊橙、Zookeeper 之間的比較】https://blog.csdn.net/qq_34395857/article/details/89212566)
Etcd辐宾、Eureka、Consul膨蛮、Zookeeper比較圖
實現(xiàn)
應(yīng)用劃分
- 這里有兩個項目sc_server和sc_client叠纹,sc_server作為服務(wù)端,即被調(diào)用方敞葛,sc_client作為客戶端誉察,即調(diào)用方。
實現(xiàn)步驟
1惹谐、部署好Consul并啟動
- 本地開發(fā)可用命令consul agent -dev簡單啟動Consul持偏,啟動后在瀏覽器訪問:http://localhost:8500/
-
如出現(xiàn)如下界面則表示啟動成功Consul管理界面
2、新建Maven Web服務(wù)端工程sc_server
- 2.1 pom.xml配置如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sc.server</groupId>
<artifactId>sc_server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>sc_server Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- SpringBoot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot系統(tǒng)健康情況監(jiān)控工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--SpringCloud Consul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
</dependency>
</dependencies>
<build>
<finalName>sc_server</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 2.2 在src/main/resources源碼目錄下新建application.yml文件氨肌,配置如下:
server:
port: 8081
spring:
application:
name: sc-server
cloud:
consul:
host: 127.0.0.1
port: 8500
enabled: true
discovery:
enabled: true
serviceName: sc-server
spring.cloud.consul.host需修改為實際的Consul服務(wù)地址鸿秆。
spring.cloud.consul.discovery.serviceName是服務(wù)名,在客戶端的調(diào)用中會用到怎囚。
- 2.3 新建啟動類ScServerApp.java卿叽,代碼如下:
package com.sc.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ScServerApp {
public static void main(String[] args) {
try {
SpringApplication.run(ScServerApp.class, args);
System.out.println("服務(wù)端啟動成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
PS:注意要加上@EnableDiscoveryClient注解。
- 2.4 新建服務(wù)提供類DemoService,其實是個Controller考婴,暴露HTTP接口:
package com.sc.server;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/demo")
public class DemoService {
@RequestMapping(value = "/hello")
public String hello(@RequestParam("name") String name) {
System.out.println("服務(wù)被調(diào)用了");
return "Hello " + name;
}
}
至此贩虾,服務(wù)端工程搭建完成。
- 2.5 啟動服務(wù)端沥阱,用瀏覽器訪問http://localhost:8081/demo/hello?name=world缎罢,如顯示"Hello world"則啟動服務(wù)成功。服務(wù)端響應(yīng)結(jié)果
3考杉、新建Maven Web客戶端工程sc_client
- 3.1 pom.xml配置如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sc.client</groupId>
<artifactId>sc_client</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>sc_client Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- SpringBoot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot系統(tǒng)健康情況監(jiān)控工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--SpringCloud Consul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringCloud Feign 聲明式服務(wù)調(diào)用框架 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<finalName>sc_client</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
其中集成了OpenFeign策精,即采用了微服務(wù)架構(gòu)下服務(wù)之間聲明式的調(diào)用方案。
- 3.2 在src/main/resources源碼目錄下新建application.yml文件奔则,配置如下:
server:
port: 8082
spring:
application:
name: sc-client
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
register: false
spring.cloud.consul.host需改為實際的Consul服務(wù)所在地址蛮寂。
spring.cloud.consul.discovery.register設(shè)置為false,即該服務(wù)是客戶端易茬,不需要向Consul服務(wù)發(fā)現(xiàn)中心注冊服務(wù)酬蹋。
- 3.3 新建啟動類ScClientApp.java,代碼如下:
package com.sc.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ScClientApp {
public static void main(String[] args) {
try {
SpringApplication.run(ScClientApp.class, args);
System.out.println("客戶端啟動成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
PS:需注意加上@EnableFeignClients注解抽莱。
- 3.4 新建DemoServiceClient類范抓,代碼如下:
package com.sc.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* FeignClient的value取自服務(wù)端的配置spring.cloud.consul.discovery.serviceName
*/
@FeignClient(value = "sc-server")
@RequestMapping("/demo")
public interface DemoServiceClient {
@RequestMapping(value = "/hello")
String hello(@RequestParam("name") String name);
}
@FeignClient注解完成對服務(wù)提供方的接口綁定,
其中sc-server是服務(wù)注冊名食铐,即sc_server工程中spring.cloud.consul.discovery.serviceName的配置匕垫。
- 3.5 新建客戶端調(diào)用服務(wù)端微服務(wù)接口示例ClientController,代碼如下:
package com.sc.client;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/client")
public class ClientController {
@Resource
private DemoServiceClient demoService;
@RequestMapping(value = "/hello")
@ResponseBody
public String hello() {
String name = "客戶端";
String res = demoService.hello(name);
System.out.println("客戶端成功調(diào)用了服務(wù)端并得到響應(yīng)結(jié)果:" + res);
return res;
}
}
至此虐呻,客戶端工程搭建完成象泵。
- 3.6 啟動客戶端,用瀏覽器訪問http://localhost:8082/client/hello斟叼,如顯示"Hello 客戶端"則調(diào)用服務(wù)端成功偶惠。客戶端調(diào)用服務(wù)端響應(yīng)結(jié)果