本文内容为自己学习Spring cloud的学习笔记,对学习内容的一些思考。本篇为第一篇,包含如下内容:
Spring cloud作为一系列框架的有序集合,规范化同时也简单化了大型分布式系统的设计和开发。其设计目标是让用户快速的搭建弹性的、可靠的、协调的分布式系统。
Spring cloud基于 Spring boot构建,Spring boot遵循约定大于配置的理念,是进行了大量默认配置封装的快速开发脚手架。故而大多数场景使用默认值即可,在需要调整的时候再调整配置。
一个基于Spring cloud的微服务的分布式应用的逻辑图如下:
如上图,Spring cloud为通用分布式系统提供了全套的实施方案,包括网关,注册中心,数据流处理等等,调研的目标是Spring cloud的服务治理相关的内容,故以下内容则针对Spring cloud的Netflix组件进行。
Netflix子项目的部分子项目提供了服务治理框架,该框架包括的内容如下:
1. Eureka,提供消费者、生成者动态注册,提供服务发现、心跳监测、故障转移等功能。区分server端和client端。
2. Feign,提供支持JAX-RS或者Spring mvc注解、支持动态执行接口的rest风格的http客户端。
3. Ribbon,支持负载均衡的http客户端。
使用以上这三个组件即可搭建一个支持负载均衡的基于rest的服务调用。
1.引入依赖,仅需要引入eureka-server即可。如下pom
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
<version>1.4.1.BUILD-SNAPSHOTversion>
dependency>
dependencies>
2.编写启动类
@SpringBootApplication
@RestController
@EnableEurekaServer
public class HelloWordController {
@RequestMapping("/")
public String home() {
return "Hi,I'm Eureka";
}
public static void main(String[] args) {
SpringApplication.run(HelloWordController.class, args);
}
}
@SpringBootApplication
表示以启动Spring-boot,并检查该类所在包下的所有组件,自动更新配置,作用等同于Configuration,EnableAutoConfiguration ,ComponentScan 三个注解同时使用。
@EnableEurekaServer
表示启动EurekaServer服务器,可接受服务的注册,监控心跳等。
3.编写配置文件
文件路径为src\main\resources\application.properties
spring.application.name=spring-cloud-eureka
server.port=8000
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
Spring cloud的默认配置能力非常强,但此处的部分配置不可省略
spring.application.name
应用名称
server.port 端
口号,默认端口号8761
eureka.client.register-with-eureka
是否向服务注册发起注册请求,默认为true,生产者需要配置为true
eureka.client.fetch-registry
是否向注册中心发起检索请求,默认为true,服务消费者需要设置为true
eureka.client.serviceUrl.defaultZone
服务注册中心的配置内容,指定服务注册中心的地址
4.打包发布
mvn package
java –jar xxxEurekaServer.jar
建议打成jar,若打war包则需要修改pom的依赖,从设计初衷来看,我觉得jar更符合分布式微服务的场景。
启动成功后,访问defaultZone所配置的地址可见其管理页面如下图
1.引入pom,只需要引入eureka的启动器即可
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.1.BUILD-SNAPSHOTversion>
dependency>
dependencies>
2.编写启动器类
@SpringBootApplication
@EnableEurekaClient
public class SpringBootStarter{
public static void main( String[] args ) {
SpringApplication.run(SpringBootStarter.class, args);
}
}
@EnableEurekaClient
声明为Ereka客户端
3.编写配置文件
配置文件相对路径和名称相同,此处及后续均不再重复
server.port=8001
spring.application.name=spring-cloud-provider
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
spring.application.name
应用注册到Ereka时的唯一标识,相同name会被Ereka视为相同服务,若不配置name则Ereka会注册一个那么叫做UNKONWN到Ereka服务器上。
eureka.client.serviceUrl.defaultZone
注册中心的地址
4.打包运行
mvn package
java –jar xxxEurekaProvider.jar
1.引入pom
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.1.BUILD-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-feignartifactId>
<version>1.4.1.BUILD-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-ribbonartifactId>
<version>1.4.1.BUILD-SNAPSHOTversion>
dependency>
dependencies>
这里引入了两个rest客户端,Feign和Ribbon。消费者可以分别以这两种客户端请求生产者。实际使用时使用其中之一作为客户端,个人比较推荐Feign。
2.编写配置文件
server.port=8002
spring.application.name=spring-cloud-consumer
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
3.编写启动器
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Bootstrap {
public static void main( String[] args ) {
SpringApplication.run(Bootstrap.class, args);
}
/**
* 基于Ribbon的负载均衡
* @return
*/
@Bean
@LoadBalanced
public RestTemplate getRestTemplateNewInstance(){
return new RestTemplate();
}
}
@EnableFeignClients
当使用Feign客户端时,需要启用此注解。
@LoadBalanced
当使用Ribbon作为客户端,启用此注解标识使用负载均衡。
5.编写服务调用
@FeignClient(name = "spring-cloud-provider")
public interface RemoteApi {
@RequestMapping("/query")
public String getResult();
}
@FeignClient
标注客户端,name属性标识生产者的注册ID。
@RequestMapping
标注访问生产者的请求分发路径,由于Feign实现了SpringMvc的注解故而访问方式与访问SpringMvc的rest接口一致。
Feign亦是对Ribbon的封装,默认使用了随机算法做负载。
@RestController
public class HelloWordController {
@Autowired
private RemoteApi remoteApi;
@RequestMapping("/f/query")
public String queryByFeign(){
return "feign:"+remoteApi.getResult();
}
}
@RestController
public class HelloWordController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/r/query")
public String queryByRibbon(){
return "ribbon:"+restTemplate.getForObject("http://spring-cloud-provider/query",String.class).toString();
}
}
注入RestTemplate之后,在调用时使用rest风格的url作为参数,声明返回值的class,即可完成调用。
Eureka服务治理的逻辑方案同dubbo,当服务启动时发起向注册中心注册的请求,消费者会更新注册内容到本地。消费者进行服务调用时通过本地的服务列表和负载均衡算费进行调用,实现生产者、消费者与注册中心的解耦合。
消费者更新本地路由表是通过轮询的方式,默认间隔30s请求一次注册中心,这点与dubbo的发布/订阅方式不同。Eureka server通过客户端的注册和心跳监测来更新本地路由表,客户端通过轮询更新到本地。(暂时未发现有资料表明Eureka 也有发布订阅的方式)