阅读更多
1 Overview
Spring-Cloud-Overview
本篇博客以Eureka
作为注册中心搭建一个Spirng-Cloud集群(据最新消息,Eureka已于2018-07-12
闭源)
Spring-Cloud对注册中心这一模块做了抽象,其实现不局限于Eureka
,还包括Zookeeper
等。以Zookeeper
为注册中心的Demo可以参考Spring-Cloud-Zookeeper-Based-Demo
2 Demo概览
本Demo工程(spring-cloud-cluster-eureka-based
)包含了如下几个子模块
eureka-server
:服务注册/发现的配置中心
eureka-provider
:服务提供方
ribbon-consumer
:服务消费方-以ribbon方式
feign-consumer
:服务消费方-以feign方式
config-server
:应用配置服务方
config-client
:应用配置消费方
spring-cloud-cluster-eureka-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 35 <?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-eureka-based</artifactId > <version > 1.0-SNAPSHOT</version > <modelVersion > 4.0.0</modelVersion > <packaging > pom</packaging > <modules > <module > eureka-server</module > <module > eureka-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 Eureka-Server
eureka-server
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 . ├── pom.xml └── src ├── main │ ├── java │ │ └── org │ │ └── liuyehcf │ │ └── spring │ │ └── cloud │ │ └── eureka │ │ └── server │ │ └── EurekaServerApplication.java │ └── resources │ └── application.yml
pom.xml
EurekaServerApplication.java
application.yml
3.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-netflix-eureka-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 <?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-eureka-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > eureka-server</artifactId > <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.cloud</groupId > <artifactId > spring-cloud-starter-netflix-eureka-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 >
3.2 EurekaServerApplication.java
@EnableEurekaServer
注解表示当前应用作为Eureka的服务端,即注册中心(RegisterCenter)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package org.liuyehcf.spring.cloud.eureka.server;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main (String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
3.3 application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 server: port: 1100 eureka: client: fetch-registry: false register-with-eureka: false serviceUrl: defaultZone: http://127.0.0.1:${server.port}/eureka/
3.4 Test
启动后,访问http://localhost:1100/ 就可以看到注册中心的控制台页面
4 Eureka-Provider
eureka-provider
模块的目录结构如下
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 │ │ └── eureka │ │ └── provider │ │ ├── EurekaProviderApplication.java │ │ └── ProviderGreetController.java │ └── resources │ └── application.yml
pom.xml
EurekaProviderApplication.java
ProviderGreetController.java
application.yml
4.1 pom.xml
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-netflix-eureka-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 <?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-eureka-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > eureka-provider</artifactId > <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.cloud</groupId > <artifactId > spring-cloud-starter-netflix-eureka-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 >
4.2 EurekaProviderApplication.java
@EnableEurekaClient
注解表示当前应用作为Eureka的客户端,即服务注册方(服务提供方,service-provider)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package org.liuyehcf.spring.cloud.eureka.provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient @SpringBootApplication public class EurekaProviderApplication { public static void main (String[] args) { SpringApplication.run(EurekaProviderApplication.class, args); } }
4.3 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.eureka.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.4 application.yml
Spring Cloud
默认将spring.application.name
作为serviceId
必须知道注册中心的地址
1 2 3 4 5 6 7 8 9 10 11 server: port: 1110 spring: application: name: GreetService eureka: client: serviceUrl: defaultZone: http://127.0.0.1:1100/eureka/
4.5 Test
启动后,访问http://localhost:1100/ 就可以在注册中心的控制台页面找到当前节点的信息
5 Ribbon-Consumer
Spring Cloud
有两种服务调用方式
一种是Ribbon
+RestTemplate
另一种是Feign
,其中Feign
集成了Ribbon
本小节先介绍Ribbon
+RestTemplate
方式的服务调用
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-netflix-eureka-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 <?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-eureka-based</artifactId > <groupId > org.liuyehcf.spring.cloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > ribbon-consumer</artifactId > <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.cloud</groupId > <artifactId > spring-cloud-starter-netflix-eureka-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 >
5.2 ConsumerGreetController.java
该模块对外提供的http服务,可以看到该服务仅仅对eureka-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.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
中用服务名(GreetService)代替服务方的ip:port信息,将地址映射交给Eureka Server
来完成。可以看出来,这种方式比较繁琐,且不太友好,好比用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 class ConsumerGreetService { @Resource private RestTemplate restTemplate; String sayHi (String name) { String reqURL = "http://GreetService/hi?name=" + name; return restTemplate.getForEntity(reqURL, String.class).getBody(); } }
5.4 RibbonConsumerApplication.java
@EnableDiscoveryClient
注解表示当前应用作为消费方(也可以使用@EnableEurekaClient
注解)
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 11 12 13 14 15 16 17 18 server: port: 1120 spring: application: name: client-consumer-ribbon eureka: instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 15 client: healthcheck: enabled: true serviceUrl: defaultZone: http://127.0.0.1:1100/eureka/
5.6 Test
启动后,访问http://localhost:1100/ 就可以在注册中心的控制台页面找到当前节点的信息
同时,访问http://localhost:1120/demo/ribbon/sayHi?name=strange 可以看到提示信息
6 Feign-Consumer
Feign
是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign
,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign
注解和JAX-RS注解。Feign
支持可插拔的编码器和解码器。Feign
默认集成了Ribbon
,并和Eureka
结合,默认实现了负载均衡的效果
Feign
采用的是基于接口的注解
Feign
整合了Ribbon
feign-consumer
模块的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 . ├── 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-netflix-eureka-server
org.springframework.cloud:spring-cloud-starter-openfeign
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 <?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-eureka-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-netflix-eureka-server</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-openfeign</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服务,可以看到该服务仅仅对eureka-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 = "GreetService") interface ConsumerGreetService { @RequestMapping(value = "/hi", method = RequestMethod.GET) String sayHi (@RequestParam("name") String name) ; }
6.4 FeignConsumerApplication.java
@EnableFeignClients
注解表明以Feign
方式进行服务消费
@EnableDiscoveryClient
注解表示当前应用作为消费方(也可以使用@EnableEurekaClient
注解)
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 11 12 13 14 15 16 17 18 server: port: 1130 spring: application: name: client-consumer-feign eureka: instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 15 client: healthcheck: enabled: true serviceUrl: defaultZone: http://127.0.0.1:1100/eureka/
6.6 Test
启动后,访问http://localhost:1100/ 就可以在注册中心的控制台页面找到当前节点的信息
同时,访问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
由于配置服务提供方(config-server)既可以直接暴露ip提供服务,也可以通过Eureka来提供服务,这里选择使用Eureka的方式
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-netflix-eureka-server
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 <?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-eureka-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-netflix-eureka-server</artifactId > </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 > </project >
7.2 ConfigServerApplication.java
@EnableConfigServer
注解表示当前应用作为Config的服务端
@EnableEurekaClient
注解表示当前应用将自身地址信息注册到Eureka服务器,供其他应用接入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package org.liuyehcf.spring.cloud.config.server;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.config.server.EnableConfigServer;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableConfigServer @EnableEurekaClient @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 18 19 20 21 22 23 24 25 26 server: port: 1140 spring: application: name: ConfigServer cloud: config: server: git: uri: https://github.com/liuyehcf/spring-cloud-config-demo searchPaths: config-repo eureka: instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 15 client: healthcheck: enabled: true serviceUrl: defaultZone: http://127.0.0.1:1100/eureka/
7.4 Test
启动后,访问http://localhost:1100/ 就可以在注册中心的控制台页面找到当前节点的信息
同时,访问以下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
由于配置服务消费方(config-client)可以强关联服务提供方的ip来使用服务,也可以通过Eureka来使用服务,这里选择使用Eureka的方式
在<dependencyManagement>
中引入Spring-Boot和Spring-Cloud相关依赖
在<dependencies>
中引入如下依赖
org.springframework.cloud:spring-cloud-starter-netflix-eureka-server
org.springframework.cloud:spring-cloud-starter-config
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 <?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-eureka-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-netflix-eureka-server</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</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 > </project >
8.2 ConfigClientApplication.java
@EnableEurekaClient
注解表示当前应用将通过Eureka来发现服务,该注解可以替换为@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.netflix.eureka.EnableEurekaClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController @EnableEurekaClient @SpringBootApplication @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
1 2 3 4 5 6 7 8 9 10 11 12 server: port: 1150 eureka: instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 15 client: healthcheck: enabled: true
8.4 bootstrap.yml
应用读取配置中心参数时,会配置配置中心的地址等相关参数,而这部分配置需优先于application.yml
被应用读取。Spring Cloud
中的 bootstrap.yml
是会比application.yml
先加载的,所以这部分配置要定义在bootstrap.yml
里面,这就引申出两个需要注意的地方
spring.application.name
:它应该配置在bootstrap.yml
,它的名字应该等于配置中心的配置文件的{application}
。所以配置中心在给配置文件取名字时,最好让它等于对应的应用服务名
配置中心与注册中心联合使用:若应用通过serviceId
而非url
来指定配置中心 ,则eureka.client.serviceUrl.defaultZone
也要配置在bootstrap.yml
,要不启动的时候,应用会找不到注册中心,自然也就找不到配置中心了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 spring: application: name: cloud.config.demo cloud: config: profile: dev label: temp discovery: enabled: true serviceId: ConfigServer eureka: client: serviceUrl: defaultZone: http://127.0.0.1:1100/eureka/
8.5 Test
启动后,访问http://localhost:1100/ 就可以在注册中心的控制台页面找到当前节点的信息
同时,访问如下URL,可以看到成功从config-server
获取了配置信息
9 参考