目录
一、SpringCloud简介
二、SpringCoud组件介绍
2.1 服务注册与发现:eureka
eureka简介
如何使用Eureka进行服务注册和发现
实际开发过程
eureka配置项解读
测试环境参考配置
2.2 配置服务器:config Server
configServer简介
服务器配置
2.3 网关:zuul
zuul简介
路由配置
Spring Cloud 是一个基于Spring Boot实现的云应用开发工具,它为基于jvm的云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话、集群状态管理等操作提供了一种简单的开发方式。
Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Sping Cloud Netflix、Spring Cloud Config、Spring Cloud CloudFounry、Spring Cloud Security等项目。
那么该如何使用Spring Cloud搭建服务注册与发现模块呢?这里我们会用到Sping Cloud Netflix,你会注意到它是Spring Cloud的子项目之一,主要内容是对NetFlix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix OSS(Netflix Open Source Software)整合。通过一些简单的注解,开发者可以快速的在应用中配置一个常用模块并构建庞大的分布式系统。它主要提供的模块有:服务发现(eureka)、断路器(Hystrix)、智能路由(zuul)、客户端负载均衡(ribbon)等。
eureka就是将其他微服务信息(ip、port等)记住,作为一个统一的注册中心。
调用关系说明:
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址给消费者。
4.服务消费者从提供者地址中调用消费者。
注意! 下面的服务端指:注册中心,客户端指:提供者和消费者
1、最左边的client(即服务提供者)发起eureka注册请求;
2、图下放的client(即服务消费者)向eureka server获取注册信息及Get Registry。
1、服务端添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
2、服务端添加配置
# server (eureka 默认端口为:8761)
server.port=8761
# 服务名
spring.application.name=spring-cloud-server
# 是否注册到eureka(eureka本身是不需要再注册到自己的)
eureka.client.register-with-eureka=false
# 是否从eureka获取注册信息
eureka.client.fetch-registry=false
# eureka服务器的地址(注意:地址最后面的 /eureka/ 这个是固定值)
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
eureka.instance.leaseExpirationDurationInSeconds=15
#eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
eureka.server.evictionIntervalTimerInMs=20000
3、服务端添加注解
@EnableEurekaServer
4、客户端添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
5、客户端添加配置
服务提供者:
# server
server.port=7777
# 客户端在注册时就会使用自己的ip地址而不是主机名(客户端自身加)
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
#renew频率,向Eureka服务发送renew信息,默认30秒
eureka.instance.leaseRenewalIntervalInSeconds=10
# 提供者服务名
spring.application.name=spring-cloud-provider
# eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
消费者(一般需要连接其他微服务的服务或者gateway/zuul)
# server
server.port=8888
# 消费者服务名
spring.application.name=spring-cloud-consumer
#client隔多久去拉取服务注册信息,默认为30秒,zuul需要将该时间缩短以便迅速获取其他服务信息
eureka.client.registry-fetch-interval-seconds=5
# eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
6、客户端添加注解
@EnableEurekaClient
当在eureka注册中心界面查看已注册服务清单时,会出现以下状态:
注意:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
分析:是由于Eureka进入了保护模式。
在保护模式下,Eureka Server将会尝试保护其服务注册表中的信息,暂时不会注销服务注册表中的服务。
eureka server【eureka服务器】
# 关闭自我保护模式(缺省为打开)
eureka.server.enable-self-preservation: false
# 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
eureka.server.eviction-interval-timer-in-ms: 5000
eureka client【一般微服务】
# 心跳时间,即服务续约间隔时间(缺省为30s)
eureka.instance.lease-renewal-interval-in-seconds: 5
# 发呆时间,即服务续约到期时间(缺省为90s)
eureka.instance.lease-expiration-duration-in-seconds: 10
# 开启健康检查(依赖spring-boot-starter-actuator)
eureka.client.healthcheck.enabled: true
zuul服务器
# 默认为30秒
eureka.client.registry-fetch-interval-seconds: 5
Spring Cloud Config项目提供了一个解决分布式系统的配置管理方案。它包含了server和client两部分。
Sping Cloud Config Server管理Git或svn的外部配置,集中配置到所有客户端。
Sping Cloud Config Client根据Spring框架的Environment和PropertySource从Spring Cloud Server获取配置。
1.添加依赖
<!-- config服务器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- kafka消息总线 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
当配置文件有刷新时,需要能够刷新到最新值,这时服务间刷新(即刷新消息的发送与接收)需要依赖kafka,故而引入kafka依赖。
2.配置参数
# git管理配置
spring.cloud.config.server.git.uri=http://git服务器ip/...../**.git
spring.cloud.config.server.git.searchPaths=configserver
spring.cloud.config.server.git.username=******
spring.cloud.config.server.git.password=******
# kafka,服务器上搭建的kafka(依赖kafka服务器)
spring.cloud.stream.kafka.binder.zk-nodes=[kafkaIp]:2181
spring.cloud.stream.kafka.binder.brokers=[kafkaIp]:9092
● 客户端配置
1.添加依赖
<!-- 需要配置服务器,依赖此项可以读到配置服务器中相应配置文件 -->
<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>
<!-- kafka消息总线 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
2.配置参数
# 能否发现配置
spring.cloud.config.discovery.enabled=true
# 配置中心服务id
spring.cloud.config.discovery.serviceId=f1-configserver
# 场景
spring.cloud.config.profile=dev
# 分支
spring.cloud.config.label=master
# 配置中心地址
spring.cloud.config.uri=http://localhost:7001/
# 是否使用本地配置文件(当此配置项为native时,将使用本地配置文件)
# spring.profiles.active=native
# kafka,服务器上搭建的kafka(依赖kafka服务器)
spring.cloud.stream.kafka.binder.zk-nodes=[kafkaIp]:2181
spring.cloud.stream.kafka.binder.brokers=[kafkaIp]:9092
至此,我们的微服务已经使用了配置服务器提供的配置文件,当我们将git上的配置文件修改了该如何通知所有服务刷新呢?通过发送post请求:http://ip:配置服务器端口/bus/refresh进行配置信息的刷新。
服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供rest api的过程中,除了具备服务路由、均衡负载功能之外,他还具备了权限控制等功能。Spring Cloud Netflix中的zuul就担任了这样一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使的服务集群主体能够具备更高的可复用性和可测试性。
大家可以想一下,zuul之所以能进行路由转发,还需要依赖于谁?凭什么去定位服务呢?是不是需要一个统一的微服务集散中心来进行服务的路由?对,那就是eureka了,因此还需要将zuul作为一个eureka client,可以拉取注册的服务信息。
zuul服务器我们已经提供好了,接下来看看如何配置路由转发吧!
通过服务路由的功能,我们在对外提供服务的时候,只需要通过暴露Zuul中配置的调用地址就可以让调用方统一的来访问我们的服务,而不需要了解具体提供服务的主机信息了。
在Zuul中提供了两种映射方式:
● 通过url直接映射,我们可以如下配置:
# routes to url
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
该配置,定义了,所有到Zuul的中规则为:/api-a-url/**的访问都映射到http://localhost:2222/上,也就是说当我们访问http://localhost:5555/api-a-url/add?a=1&b=2的时候,Zuul会将该请求路由到:http://localhost:2222/add?a=1&b=2上。
其中,配置属性zuul.routes.api-a-url.path中的api-a-url部分为路由的名字,可以任意定义,但是一组映射关系的path和url要相同,下面讲serviceId时候也是如此。
● 通过url映射的方式对于Zuul来说,并不是特别友好,Zuul需要知道我们所有为服务的地址,才能完成所有的映射配置。而实际上,我们在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,我们就可以实现对serviceId的映射。例如,我们可以如下配置:
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=service-A
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=service-B
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
针对我们在准备工作中实现的两个微服务service-A和service-B,定义了两个路由api-a和api-b来分别映射。另外为了让Zuul能发现service-A和service-B,也加入了eureka的配置。