Home | 简体中文 | 繁体中文 | 杂文 | 打赏(Donations) | OSChina 博客 | Facebook | Linkedin | 知乎专栏 | Search | About

第 11 章 Spring Cloud

目录

11.1. Spring Cloud Config
11.1.1. Git 仓库
11.1.1.1. 分支
11.1.1.2. HTTP Auth
11.1.1.3. basedir
11.1.1.4. 本地git仓库
11.1.2. Server
11.1.2.1. Maven
11.1.2.2. Application
11.1.2.3. application.properties
11.1.2.4. 测试服务器
11.1.3. Client
11.1.3.1. Maven pom.xml
11.1.3.2. Application
11.1.3.3. bootstrap.properties
11.1.3.4. 测试 client
11.1.4. Config server 用户认证
11.1.4.1. Server 配置
11.1.4.1.1. application.properties
11.1.4.1.2. Maven
11.1.4.1.3. 测试是否生效
11.1.4.2. Client 配置
11.1.5. 加密敏感数据
11.1.6. Old
11.1.6.1. Server (Camden.SR5)
11.1.6.2. Client (Camden.SR5)
11.2. Spring Cloud Netflix
11.2.1. Eureka Server
11.2.1.1. Maven
11.2.1.2. Application
11.2.1.3. application.properties
11.2.1.4. 检查注册服务器
11.2.1.5. 为 Eureka Server 增加用户认证
11.2.1.5.1. Maven
11.2.1.5.2. application.properties
11.2.1.5.3. Eureka Client
11.2.1.5.4. Feign Client
11.2.2. Eureka Client
11.2.2.1. Maven
11.2.2.2. Application
11.2.2.3. RestController
11.2.2.4. application.properties
11.2.2.5. 测试
11.2.3. Feign client
11.2.3.1. Maven
11.2.3.2. Application
11.2.3.3. interface
11.2.3.4. application.properties
11.2.3.5. 测试
11.2.3.6. fallback
11.2.4. Zuul
11.2.4.1. Maven
11.2.4.2. EnableZuulProxy
11.2.4.3. application.yml
11.2.4.4. 负载均衡配置
11.3. Spring Cloud 相关的 application.properties 配置
11.3.1. 启用或禁用 bootstrap
11.4. FAQ
11.4.1. Feign请求超时
11.4.2. 已停止的微服务节点注销慢或不注销
11.4.3. Eureka Client (Dalston.SR1)
11.4.3.1. Maven
11.4.3.2. Application
11.4.3.3. RestController
11.4.3.4. application.properties
11.4.3.5. 测试
11.4.4. Feign 启动出错 PathVariable annotation was empty on param 0.
11.4.5. Feign 提示 Consider defining a bean of type 'common.feign.Cms' in your configuration.

11.1. Spring Cloud Config

11.1.1. Git 仓库

克隆仓库

git clone https://github.com/netkiller/config.git
		

创建配置文件 server-development.properties

vim server-development.properties

test.a=KKOOKK
message=Hello world
		

提交配置文件

git commit -a
git push
		

配置文件格式

		
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties		
		
		

label 是指 git 的分支

11.1.1.1. 分支
spring.cloud.config.label=mybranch
			
11.1.1.2. HTTP Auth
spring.application.name=config-server
spring.cloud.config.server.git.uri=https://netkiller:xxxxxx@github.com/xyz/microservices-configs.git			
			

spring.application.name=config-server
spring.cloud.config.server.git.uri=https://github.com/xyz/microservices-configs.git
spring.cloud.config.server.git.username=netkiller
spring.cloud.config.server.git.password=password
			
11.1.1.3. basedir
spring.cloud.config.server.git.basedir=api/configs		
			
11.1.1.4. 本地git仓库

创建本地仓库

			
mkdir ~/config
cd config
git init
git config --global user.email "neo.chen@live.com"
git config --global user.name "Neo Chen"
			
			

创建测试配置文件

			
# cat app-test.properties 
name=neo
age=10
			
			

提交配置文件

			
git add app-test.properties 
git commit -a
			
			

检查文件是否提交成功

			
[root@netkiller config]# git log
commit aee6c35bacf1740004e02f8ecdcf2fd322422405
Author: Neo Chen <neo.chen@live.com>
Date:   Thu Nov 2 14:18:48 2017 +0800

        new file:   app-test.properties
			
			

配置 Spring cloud config 服务器,修改 application.properties 文件

			
server.port=8888
#spring.cloud.config.server.git.uri=/opt/config
spring.cloud.config.server.git.uri= file://${user.home}/config
security.user.name=cfg
security.user.password=s3cr3t

## Spring cloud GIT Repository file
${user.home}/config/root-server.properties		
			
			

检验配置中心

			
[root@netkiller config]# curl http://cfg:test@localhost:8888/app-test.properties
age: 10
name: neo
			
			

11.1.2. Server

11.1.2.1. Maven
			
<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>cn.netkiller</groupId>
	<artifactId>config</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>config</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.6.RELEASE</version>
		<relativePath />
	</parent>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-config</artifactId>
				<version>1.3.1.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>


	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

			
			
11.1.2.2. Application

Application

			
package cn.netkiller.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}
			
			
11.1.2.3. application.properties
server.port=8888
spring.cloud.config.server.git.uri=https://github.com/netkiller/config.git
			
11.1.2.4. 测试服务器
neo@netkiller $ curl http://localhost:8888/server-development.json
{"message":"Hello world","test":{"a":"KKOOKK"}}
			

11.1.3. Client

11.1.3.1. Maven 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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>netkiller.cn</groupId>
	<artifactId>cloud</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath />
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencyManagement>
	    <dependencies>
	        <dependency>
	            <groupId>org.springframework.cloud</groupId>
	            <artifactId>spring-cloud-config</artifactId>
	            <version>1.3.1.RELEASE</version>
	            <type>pom</type>
	            <scope>import</scope>
	        </dependency>
	    </dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<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>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>			
			
			
11.1.3.2. Application
			
package cn.netkiller.cloud.client;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

@RefreshScope
@RestController
class MessageRestController {

	@Value("${message:Hello default}")
	private String message;

	@RequestMapping("/message")
	String getMessage() {
		return this.message;
	}
}			
			
			

注意 @RefreshScope 注解

11.1.3.3. bootstrap.properties
			
spring.application.name=server-development
spring.cloud.config.uri=http://localhost:8888
management.security.enabled=false			
			
			
11.1.3.4. 测试 client
neo@netkiller $ curl http://localhost:8080/message.json             
Hello world
			

11.1.4. Config server 用户认证

11.1.4.1. Server 配置
11.1.4.1.1. application.properties
server.port=8888
spring.cloud.config.server.git.uri=ssh://localhost/config-repo
spring.cloud.config.server.git.clone-on-start=true
security.user.name=cfg
security.user.password=s3cr3t
				
11.1.4.1.2. Maven
				
<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>cn.netkiller</groupId>
	<artifactId>config</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>config</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.7.RELEASE</version>
		<relativePath />
	</parent>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-config</artifactId>
				<version>1.3.1.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
				
				
				
11.1.4.1.3. 测试是否生效
				
neo@MacBook-Pro ~/deployment % curl http://cfg:s3cr3t@localhost:8888/neo-development.json
{"message":"Hello world","test":{"name":"neo"}}		
				
				
11.1.4.2. Client 配置

bootstrap.properties:

spring.application.name=project
spring.profiles.active=development
spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.username=cfg
spring.cloud.config.password=s3cr3t
			

11.1.5. 加密敏感数据

Config server 创建证书

		
keytool -genkeypair -alias config-server-key \
       -keyalg RSA -keysize 4096 -sigalg SHA512withRSA \
       -dname 'CN=Config Server,OU=Spring Cloud,O=Netkiller' \
       -keypass s3cr3t -keystore config-server.jks \
       -storepass passw0rd		
		
		

application.properties 中配置证书

		
# spring.cloud.config.server.encrypt.enabled=true
encrypt.key-store.location=classpath:/config-server.jks
encrypt.key-store.alias=config-server-key
encrypt.key-store.secret=s3cr3t
encrypt.key-store.password=passw0rd
		
		

测试加密

		
curl -X POST --data-urlencode mypassword http://localhost:8888/encrypt
		
		
		
$ PASSWORD=$(curl -X POST --data-urlencode passw0rd http://cfg:s3cr3t@localhost:8888/encrypt)
$ echo "user.password=$PASSWORD" >> api-interface-development.properties
$ git commit -am 'Added encrypted password'

# 刷新配置
$ curl -X POST http://cfg:s3cr3t@localhost:8888/refresh		
		
		

11.1.6. Old

11.1.6.1. Server (Camden.SR5)

Maven pom.xml 请使用最新版本 1.3.1, 下面的 maven 是早期 Camden.SR5 版本的配置

			
<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>netkiller.cn</groupId>
	<artifactId>cloud</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Neo</name>
	<description>http://www.netkiller.cn</description>
	<packaging>jar</packaging>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.3.RELEASE</version>
		<relativePath />
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-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>Camden.SR5</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>
			
			
11.1.6.2. Client (Camden.SR5)

Maven pom.xml Camden.SR5 为早期版本,尽可以使用新版

			
<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>netkiller.cn</groupId>
	<artifactId>cloud</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath />
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<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>Camden.SR5</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>