阅读更多
1 Overview
Spring-Cloud-Overview
本篇博客以Zookeeper
作为注册中心搭建一个Spirng-Cloud集群
Spring-Cloud对注册中心这一模块做了抽象,其实现不局限于Zookeeper
,还包括Eureka
等。以Eureka
为注册中心的Demo可以参考Spring-Cloud-Eureka-Based-Demo
2 Demo概览
本Demo工程(spring-cloud-cluster-zookeeper-based
)包含了如下几个子模块
zookeeper-provider
:服务提供方
ribbon-consumer
:服务消费方-以ribbon方式
feign-consumer
:服务消费方-以feign方式
config-server
:应用配置服务方
config-client
:应用配置消费方
此外,需要额外启动一个zookeeper进程,作为注册中心,这是与Eureka
有差异的地方(在Eureka
方式下,注册中心也是一个Java程序)
spring-cloud-cluster-zookeeper-based
Deom工程的的pom文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?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" > <groupId > org.liuyehcf.spring.cloud</groupId > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <version > 1.0-SNAPSHOT</version > <modelVersion > 4.0.0</modelVersion > <packaging > pom</packaging > <modules > <module > zookeeper-provider</module > <module > feign-consumer</module > <module > ribbon-consumer</module > <module > config-server</module > <module > config-client</module > </modules > <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.6.0</version > <configuration > <source > 1.8</source > <target > 1.8</target > </configuration > </plugin > </plugins > </build > </project >
3 Zookeeper进程
首先,需要在本机安装zookeeper,然后启动zookeeper作为本Demo的注册中心
zookeeper启动地址为http://localhost:2181
4 Zookeeper-Provider
zookeeper-provider
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── liuyehcf │ │ │ └── spring │ │ │ └── cloud │ │ │ └── zookeeper │ │ │ └── provider │ │ │ ├── ProviderGreetController.java │ │ │ └── ZookeeperProviderApplication.java │ │ └── resources │ │ └── application.yml
pom.xml
ProviderGreetController.java
ZookeeperProviderApplication.java
application.yml
4.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-zookeeper-all
org.apache.zookeeper:zookeeper
org.springframework.boot:spring-boot-starter-web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 <?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" > <parent > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > zookeeper-provider</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-zookeeper-all</artifactId > <exclusions > <exclusion > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.12</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Finchley.RELEASE</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 >
4.2 ProviderGreetController.java
提供了一个简单的http服务,打印名字、时间与当前服务器的端口号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package org.liuyehcf.spring.cloud.zookeeper.provider;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.Date;@RestController public class ProviderGreetController { @Value("${server.port}") private String port; @RequestMapping("/hi") public String hi (@RequestParam String name) { return "hi " + name + ", I'm from port " + port + ", current Time is " + new Date (); } }
4.3 ZookeeperProviderApplication.java
与SpringBoot应用完全一致的Application类,无需其他注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package org.liuyehcf.spring.cloud.zookeeper.provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication public class ZookeeperProviderApplication { public static void main (String[] args) { SpringApplication.run(ZookeeperProviderApplication.class, args); } }
4.4 application.yml
Spring Cloud
默认将spring.application.name
作为serviceId
必须知道注册中心的地址
1 2 3 4 5 6 7 8 9 10 server: port: 1110 spring: application: name: ZookeeperProvider cloud: zookeeper: connect-string: localhost:2181
4.5 Test
启动后,执行bin/zkCli.sh
运行Zookeeper客户端交互程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [zk: localhost:2181(CONNECTED) 34] ls /services [ZookeeperProvider] [zk: localhost:2181(CONNECTED) 36] get /services/ZookeeperProvider cZxid = 0x19 ctime = Sat Jul 14 14:58:20 CST 2018 mZxid = 0x19 mtime = Sat Jul 14 14:58:20 CST 2018 pZxid = 0x1e cversion = 3 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 1 [zk: localhost:2181(CONNECTED) 37] ls /services/ZookeeperProvider [b3735b44-3e69-4a1c-9de9-c7c813767bb6] [zk: localhost:2181(CONNECTED) 38] get /services/ZookeeperProvider/b3735b44-3e69-4a1c-9de9-c7c813767bb6 {"name" :"ZookeeperProvider" ,"id" :"b3735b44-3e69-4a1c-9de9-c7c813767bb6" ,"address" :"192.168.31.104" ,"port" :1110,"sslPort" :null,"payload" :{"@class" :"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance" ,"id" :"application-1" ,"name" :"ZookeeperProvider" ,"metadata" :{}},"registrationTimeUTC" :1531551844868,"serviceType" :"DYNAMIC" ,"uriSpec" :{"parts" :[{"value" :"scheme" ,"variable" :true },{"value" :"://" ,"variable" :false },{"value" :"address" ,"variable" :true },{"value" :":" ,"variable" :false },{"value" :"port" ,"variable" :true }]}} cZxid = 0x1e ctime = Sat Jul 14 15:04:05 CST 2018 mZxid = 0x1e mtime = Sat Jul 14 15:04:05 CST 2018 pZxid = 0x1e cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x1000013a8d70003 dataLength = 525 numChildren = 0
上述/services/ZookeeperProvider/b3735b44-3e69-4a1c-9de9-c7c813767bb6
节点的节点内容如下(后面那串字符串是随机生成的临时id,你电脑上极大概率是不同的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 { "name" : "ZookeeperProvider" , "id" : "b3735b44-3e69-4a1c-9de9-c7c813767bb6" , "address" : "192.168.31.104" , "port" : 1110 , "sslPort" : null , "payload" : { "@class" : "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance" , "id" : "application-1" , "name" : "ZookeeperProvider" , "metadata" : { } } , "registrationTimeUTC" : 1531551844868 , "serviceType" : "DYNAMIC" , "uriSpec" : { "parts" : [ { "value" : "scheme" , "variable" : true } , { "value" : "://" , "variable" : false } , { "value" : "address" , "variable" : true } , { "value" : ":" , "variable" : false } , { "value" : "port" , "variable" : true } ] } }
于是,我们可以得出结论:
Spring-Cloud-Zookeeper在注册服务时,会根据服务名创建一个节点(一个服务对应一个节点),其路径为/services/<service name>
一个服务可能会有多个实例存在,每个实例对应着一个子节点,子节点的名称是一个类似uuid的字符串,且子节点保存着对应实例的注册信息,包括ip,port等一系列元数据
5 Ribbon-Consumer
ribbon-consumer
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── liuyehcf │ │ │ └── spring │ │ │ └── cloud │ │ │ └── ribbon │ │ │ └── consumer │ │ │ ├── ConsumerGreetController.java │ │ │ ├── ConsumerGreetService.java │ │ │ └── RibbonConsumerApplication.java │ │ └── resources │ │ └── application.yml
pom.xml
ConsumerGreetController.java
ConsumerGreetService.java
RibbonConsumerApplication.java
application.yml
5.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-zookeeper-all
org.apache.zookeeper:zookeeper
org.springframework.boot:spring-boot-starter-web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 <?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" > <parent > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > ribbon-consumer</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-zookeeper-all</artifactId > <exclusions > <exclusion > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.12</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Finchley.RELEASE</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 >
5.2 ConsumerGreetController.java
该模块对外提供的http服务,可以看到该服务仅仅对zookeeper-provider
模块的http服务做了一层代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package org.liuyehcf.spring.cloud.ribbon.consumer;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController @RequestMapping("/demo/ribbon") public class ConsumerGreetController { @Resource private ConsumerGreetService consumerGreetService; @RequestMapping("/sayHi") String sayHi (@RequestParam String name) { return consumerGreetService.sayHi(name); } }
5.3 ConsumerGreetService.java
该类实现服务间的调用,在reqURL
中用服务名(ZookeeperProvider)代替服务方的ip:port信息,将地址映射交给Zookeeper
来完成。可以看出来,这种方式比较繁琐,且不太友好,好比用JDBC Connection
来进行数据库操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package org.liuyehcf.spring.cloud.ribbon.consumer;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@Service public class ConsumerGreetService { @Resource private RestTemplate restTemplate; String sayHi (String name) { String reqURL = "http://ZookeeperProvider/hi?name=" + name; return restTemplate.getForEntity(reqURL, String.class).getBody(); } }
5.4 RibbonConsumerApplication.java
@EnableDiscoveryClient
注解表示当前应用作为消费方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package org.liuyehcf.spring.cloud.ribbon.consumer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate;@EnableDiscoveryClient @SpringBootApplication public class RibbonConsumerApplication { public static void main (String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } @LoadBalanced @Bean RestTemplate restTemplate () { return new RestTemplate (); } }
5.5 application.yml
Spring Cloud
默认将spring.application.name
作为serviceId
必须知道注册中心的地址
1 2 3 4 5 6 7 8 9 10 server: port: 1120 spring: application: name: RibbonConsumer cloud: zookeeper: connect-string: localhost:2181
5.6 Test
启动后,执行bin/zkCli.sh
运行Zookeeper客户端交互程序
1 2 3 [zk: localhost:2181(CONNECTED) 39] ls /services [ZookeeperProvider, RibbonConsumer]
同时,访问http://localhost:1120/demo/ribbon/sayHi?name=strange 可以看到提示信息
6 Feign-Consumer
Feign
是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign
,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign
注解和JAX-RS注解。Feign
支持可插拔的编码器和解码器。Feign
默认集成了Ribbon
,并和Zookeeper
结合,默认实现了负载均衡的效果
Feign
采用的是基于接口的注解
Feign
整合了Ribbon
feign-consumer
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── liuyehcf │ │ │ └── spring │ │ │ └── cloud │ │ │ └── feign │ │ │ └── consumer │ │ │ ├── ConsumerGreetController.java │ │ │ ├── ConsumerGreetService.java │ │ │ └── FeignConsumerApplication.java │ │ └── resources │ │ └── application.yml
pom.xml
ConsumerGreetController.java
ConsumerGreetService.java
FeignConsumerApplication.java
application.yml
6.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-zookeeper-all
org.apache.zookeeper:zookeeper
org.springframework.cloud:spring-cloud-starter-openfeign
org.springframework.boot:spring-boot-starter-web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 <?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" > <parent > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > feign-consumer</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-zookeeper-all</artifactId > <exclusions > <exclusion > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.12</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-openfeign</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Finchley.RELEASE</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 >
6.2 ConsumerGreetController.java
该模块对外提供的http服务,可以看到该服务仅仅对zookeeper-provier
模块的http服务做了一层代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package org.liuyehcf.spring.cloud.feign.consumer;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController @RequestMapping("/demo/feign") public class ConsumerGreetController { @Resource private ConsumerGreetService consumerGreetService; @RequestMapping("/sayHi") String sayHi (@RequestParam String name) { return consumerGreetService.sayHi(name); } }
6.3 ConsumerGreetService.java
在Feign
方式下,我们仅仅利用注解来标记接口(声明式地编程),就能够确定服务消费方与服务提供方的绑定关系,十分简洁高效
其中,@FeignClient
注解的value属性指的是服务提供方的服务名称
@RequestMapping
注解的value属性表示的是服务提供方的方法路由路径
方法参数以及返回值可以利用http相关注解进行标记,例如@RequestParam
、@RequestBody
、@PathVariable
、@ResultBody
等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package org.liuyehcf.spring.cloud.feign.consumer;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;@FeignClient(value = "ZookeeperProvider") public interface ConsumerGreetService { @RequestMapping(value = "hi", method = RequestMethod.GET) String sayHi (@RequestParam("name") String name) ; }
6.4 FeignConsumerApplication.java
@EnableFeignClients
注解表明以Feign
方式进行服务消费
@EnableDiscoveryClient
注解表示当前应用作为消费方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package org.liuyehcf.spring.cloud.feign.consumer;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 FeignConsumerApplication { public static void main (String[] args) { SpringApplication.run(FeignConsumerApplication.class, args); } }
6.5 application.yml
Spring Cloud
默认将spring.application.name
作为serviceId
必须知道注册中心的地址
1 2 3 4 5 6 7 8 9 10 server: port: 1130 spring: application: name: FeignConsumer cloud: zookeeper: connect-string: localhost:2181
6.6 Test
启动后,执行bin/zkCli.sh
运行Zookeeper客户端交互程序
1 2 3 [zk: localhost:2181(CONNECTED) 40] ls /services [ZookeeperProvider, FeignConsumer, RibbonConsumer]
同时,访问http://localhost:1130/demo/feign/sayHi?name=strange 可以看到提示信息
7 Config-Server
config-server
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── liuyehcf │ │ │ └── spring │ │ │ └── cloud │ │ │ └── config │ │ │ └── server │ │ │ └── ConfigServerApplication.java │ │ └── resources │ │ └── application.yml
pom.xml
ConfigServerApplication.java
application.yml
7.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-zookeeper-all
org.apache.zookeeper:zookeeper
org.springframework.cloud:spring-cloud-config-server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 <?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" > <parent > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > config-server</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-zookeeper-all</artifactId > <exclusions > <exclusion > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.12</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-config-server</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Finchley.RELEASE</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 >
7.2 ConfigServerApplication.java
@EnableConfigServer
注解表示当前应用作为Config的服务端
@EnableDiscoveryClient
注解表示当前应用作为消费方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package org.liuyehcf.spring.cloud.config.server;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.config.server.EnableConfigServer;@EnableConfigServer @EnableDiscoveryClient @SpringBootApplication public class ConfigServerApplication { public static void main (String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
7.3 application.yml
Spring Cloud
默认将spring.application.name
作为serviceId
必须知道注册中心的地址
由于需要从远程git仓库获取配置信息,因此需要配置git仓库的相关元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 server: port: 1140 spring: application: name: ConfigServer cloud: config: server: git: uri: https://github.com/liuyehcf/spring-cloud-config-demo searchPaths: config-repo zookeeper: connect-string: localhost:2181
7.4 Test
启动后,执行bin/zkCli.sh
运行Zookeeper客户端交互程序
1 2 3 [zk: localhost:2181(CONNECTED) 42] ls /services [ZookeeperProvider, FeignConsumer, ConfigServer, RibbonConsumer]
同时,访问以下URL,可以获取配置信息
HTTP URL与Resource的对应关系如下,其中
{application}
:表示的是文件名,一般来说会以应用名作为配置的文件名,因此占位符的名字叫application
{profile}
:表示profile后缀
{label}
:表示git的分支
1 2 3 4 5 /{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
8 Config-Client
config-client
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── liuyehcf │ │ │ └── spring │ │ │ └── cloud │ │ │ └── config │ │ │ └── client │ │ │ └── ConfigClientApplication.java │ │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml
pom.xml
ConfigClientApplication.java
application.yml
bootstrap.yml
8.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-zookeeper-all
org.apache.zookeeper:zookeeper
org.springframework.cloud:spring-cloud-starter-config
org.springframework.boot:spring-boot-starter-web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 <?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" > <parent > <artifactId > spring-cloud-cluster-zookeeper-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > config-client</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-zookeeper-all</artifactId > <exclusions > <exclusion > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.12</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Finchley.RELEASE</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 >
8.2 ConfigClientApplication.java
@EnableDiscoveryClient
注解表示当前应用作为消费方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package org.liuyehcf.spring.cloud.config.client;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@EnableDiscoveryClient @SpringBootApplication @RestController @RequestMapping("/demo/config") public class ConfigClientApplication { public static void main (String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } @Value("${host}") private String host; @Value("${description}") private String description; @GetMapping("/getHost") public String getHost () { return this .host; } @GetMapping("/getDescription") public String getDescription () { return this .description; } }
8.3 application.yml
8.4 bootstrap.yml
应用读取配置中心参数时,会配置配置中心的地址等相关参数,而这部分配置需优先于application.yml
被应用读取。Spring Cloud
中的 bootstrap.yml
是会比application.yml
先加载的,所以这部分配置要定义在bootstrap.yml
里面,这就引申出两个需要注意的地方
spring.application.name
:它应该配置在bootstrap.yml
,它的名字应该等于配置中心的配置文件的{application}
。所以配置中心在给配置文件取名字时,最好让它等于对应的应用服务名
配置中心与注册中心联合使用:若应用通过serviceId
而非url
来指定配置中心 ,则spring.cloud.zookeeper.connect-string
也要配置在bootstrap.yml
,要不启动的时候,应用会找不到注册中心,自然也就找不到配置中心了
此外还必须配置spring.cloud.zookeeper.discovery.register
属性。按照Spring-Cloud的官方文档,该属性默认是true,但是配置了spring.cloud.config
相关配置项后,必须手动将spring.cloud.zookeeper.discovery.register
属性设置为true,否则将不会注册到Zookeeper中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 spring: application: name: cloud.config.demo cloud: config: profile: dev label: master discovery: enabled: true serviceId: ConfigServer zookeeper: discovery: register: true connect-string: localhost:2181
8.5 Test
启动后,执行bin/zkCli.sh
运行Zookeeper客户端交互程序
1 2 3 [zk: localhost:2181(CONNECTED) 126] ls /services [ZookeeperProvider, cloud.config.demo, FeignConsumer, ConfigServer, RibbonConsumer]
同时,访问如下URL,可以看到成功从config-server
获取了配置信息
9 参考