SpringCloud官方文档 https://www.springcloud.cc/spring-cloud-dalston.html
SpringCloud为开发人员白提供了快速构建分布式系统中一些常见的模式工具集(配置管理,服务发现,智能路由,微代理,控制总线)。
SpingCloud开发的应用非常适合在docker和Paas上部署。所以叫云原生应用。
SpringCloud的特点:
- 约定大于配置
- 适用于各种环境
- 隐藏了组件的复杂性,提供声明式,无XML式的配置方式
- 开箱即用,快速启动
- 组件丰富,功能齐全
Spring的核心子项目
- Spring Cloud Netfix :核心组件,可以对多个Netfix OSS开源套件进行整合,包括以下组件
- Eureka:服务治理组件包含服务注册发现
- Hystrix:容错服务组件,实现熔断器
- Ribbon:负载均衡的服务调用组件
- Feign:基于Ribbon和Hystrix的声明式服务调用组件
- Zuul:网关组件提供智能路由、访问过滤等功能
- Archaius:外部化配置组件
- Spring Cloud Config :配置管理工具,实现应用配置的外部化存储,支持客户端配置刷新、加密/解密配置内容等。
- Spring Cloud Bus :事件、消息总线,用于传播集群中的状态变化或事件,以及触发后续处理
- Spring Cloud Security :基于Spring security安全工具包,为我们应用添加安全控制
- Spring Cloud Consul : 封装Consul操作,Consul是服务发现的配置工具(与Eureka类似),与Docker容器可以无缝集成
服务注册(Eureka)– 如docker需要服务注册中心,接口提供者,接口消费者两个都注册到服务中心。通过@FeignClient调用接口提供都的接口HTTP的方式。可以部署多个注册中心,注册中心相互注册,就能保证一个死了,服务照样运行。
熔断器(Hystrix) 在微服务架构中,如果某个节点提供者出现错误,会让调用都出现联级错误,导致整个服务不可用。熔断器可以让其快速失败,不再远程访问。从而防止程序不断的尝试执行可能会失败的操作。
hystrix的maven包
spring-cloud-starter-hystrix
spring-cloud-starter-feign
启动类注解
@EnableCircuitBreaker
执行失败后的处理
@FeignClient(name = "eureka-provider",fallback = HelloFeignFallback.class)
public interface HelloFeign {
@RequestMapping("hello")
String hello(@RequestParam(value = "name",defaultValue = "Andy") String name);
}
HelloFeignFallback.java
@Component
public class HelloFeignFallback implements HelloFeign {
@Override
public String hello(String name) {
return "hello interface is erro!";
}
}
修改feign的hystrix的默认配置
feign:
hystrix:
enabled: true
负载均衡(Ribbon): 和服务注册中心一样,是一个单独的服务。
maven引用包
spring-cloud-starter-netfix-ribbon
添加RestTemplate和IRule两个bean
/**
* RestTemplate 提供了多种便捷访问远程http服务方法,能够提高编码效率
* LoadBalanced 提供了大量的与服务治理相关的抽象接口
*/
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* RandomRule 随机选择服务器
*/
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
指定服务和访问的接口(http)
public String port(){
loadBalancerClient.choose("eureka-provider");
String info = restTemplate.getForObject("http://eureka-provider/hello",String.class);
return info;
}
Zuul提供智能路由,请求过滤等功能
你想调用某个服务,它会给你映射,把你的服务ip映射成某个地址。你输入某个路径,它匹配到了,就代替你去访问这个服务。它会有个请求转发的过程,就像nginx一样,服务器的具体实例,它不会直接去访问ip,它会去Eureka服务注册中心拿到这个实例id。我再次使用客户端的负载均衡ribbon访问实例的其中一台。
maven包
spring-cloud-starter-netflix-zuul
启动类注解
@EnableZuulProxy
application.yml
zuul:
routes:
eureka-provider:
path: /eureka-provider/hello/**
serviceId: eureka-provider
# url: http://localhost:8082/
# service-Id: eureka-provider
host:
socket-timeout-millis: 12000
connect-timeout-millis: 12000
hystrix:
command:
default:
execution:
isolation:
thread:
timeout-in-milliseconds: 12000
ribbon:
eureka:
enabled: true
ReadTimeout: 12000
ConnectTimeout: 12000
zuul的过滤器
hystrix:
command:
default:
execution:
isolation:
thread:
timeout-in-milliseconds: 12000
ribbon:
eureka:
enabled: true
ReadTimeout: 12000
ConnectTimeout: 12000
Archaius是一个功能强大的配置管理库。 它是一个用于从许多不同来源收集配置属性框架,提供对配置信息快速及线程安全的访问。
Archaius允许属性在运行时动态更改,使系统无需重启应用程序即可获得这些变化。
Archaius功能:
- 动态和类型属性(
在修改配置文件不用重启项目
) - 在属性改变时调用回调属性
- 动态配置源(如URL,JDBC,Amazon DynamoDB)的实现(
可以配置多个properties文件
) - Spring Boot Actuator或JConsole可以访问的JMX MBean,用于检查和操作属性
- 动态属性验证
Consul用于实现分布式系统的服务发现与配置。 与其它分布式服务注册与发现的方案,Consul更是一站式,内置了服务注册与发现的框架、分布一致性协议发现、健康检查、Key/Value存储、多数据方案,不需要依赖其它工具。使用起来简单,方便部署,与docker无缝配合。
Consul优势:
- 使用Raft保持一致性,比Paxos算法理简洁。(zookeeper使用Paxos,etcd用的Raft算法)
- 支持多数据中心,内外网采用不同的端口进行监听。多数据中心可以避免单数据中心的单点故障,而其它部署则要考虑网络延时,分片情况。zookeeper和etct不支持多数据中心功能支持。
- 支持健康检查。etct不支持此功能。
- 支持http和dns协议接口。zookeeper集成较复杂,etcd不支持http协议。
- 官方提供web管理图面,etct无此功能。
Consul 和 Eureka对比
Eureka是服务发现工具。该体系结构主要是客户端/服务端,每个数据中心有一组Eureka服务器,通常每个可用区域一个。通常Eureka的客户使用嵌入式SDK来注册和发现服务。对于非本地集成的客户,官方提供Eureka一些REST操作API,其它语言可以使用这些API来实现对Eureka Server的操作实现。
Eureka提供了一个弱一致的服务视图,尽可能提供服务的可用性。当客户端向服务器注册时,该服务尝试复制到其它服务器,但不提供保证服务完成。服务注册的生存时间较短,要求客户端对服务器进行心跳检测。有健康服务或节点停止心跳,导致他们超时并从注册表中删除。服务发现可路由到注册到任何服务,由于心跳机制有时间间隔,可能会导致部分服务不能用。这个简单的模型允许简单的集群管理和高可用扩展。
Consul提供了一些特性,包括丰富的健康检查,键值对储存以及多数据中心。Consul需要每个数据中心都有一套服务,以及每个客户端agent,类似于Ribbon这样的服务。Consul agent允许大多数应用程序成为Consul的不知情者,通过配置文件执行服务注册并通过DNS或负载平衡器 sidecars等。
Consul强大的一致性保证,因为服务器使用Raft协议复制状态。Consul支持丰富的健康检查,包括HTTP、TCP、Nagios、sensu兼容脚本或基于Eureka的TTL。客户端节点参与基于Grossip协议的健康检查,该检查分发健康检查工作,而不像集中式心跳检测那样成为可扩展性挑战。发现请求被路由到选举出来的leader,这使们们默认情况下强一致性。允许客户端过时读取服务器处理他们的请求,从而实现像像Eureka那样的线性伸缩。
maven包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
application.yml
server:
port: 8086
spring:
profiles:
active: dev
application:
name: consul-service
bootstrap.yml 这个文件一定要分开
spring:
profiles:
active: dev
application:
name: consul-service
cloud:
consul:
discovery:
serviceName: consul-service
port: 8500 # 不能用discovery里面的host,port属性
hostname: localhost
config:
enabled: true
format: yaml
prefix: config
profile-separator: ':'
data-key: data
defaultContext: application
配置注解
@EnableDiscoveryClient
以上就可以注册到Consul中
Project读取Consul的Key/Velue值
@Value("${myName}")
private String myName;
//对象
@ConfigurationProperties(prefix = "student")
public class StudentEntity {
private String name;
private Integer age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
sping项目docker部署
maven插件
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<dockerfile>${project.basedir}/src/main/docker/Dockerfile</dockerfile>
<buildArgs>
<JAR_FILE>target/${project.artifactId}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
<mainClass>com.guanheng.HelloApplication</mainClass>
</configuration>
</plugin>
dockerfile配置
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} hello.jar
ENTRYPOINT ["java","-jar","/hello.jar"]
启动命令
mvn clean install dockerfile:build