Spring Cloud 学习 Demo
微服务构建 Spring Boot
micai-springcloud-helloworld
服务治理 Spring Cloud Eureka
micai-springcloud-eureka-server 服务注册与发现中心
访问注册中心url:http://localhost:8081/,如下图
服务注册中心,服务提供者,服务消费者,如下图
构建服务注册中心
服务注册与发现
Eureka的基础架构
Eureka的服务治理机制
Eureka的配置
Netflix Eureka
Spring Cloud Eureka,使用Netflix Eureka来实现服务注册与发现,它既包含了服务端组件,也包含了客户端组件,
并且服务端与客户端均采用Java编写,所以Eureka主要适用于通过Java实现的分布式系统,或者与JVM兼容语音构建的系统.
Eureka服务端,我们也称为服务注册中心,它同其他服务注册中心一样,支持高可用配置。它依托于强一致性提供良好的服务
实例可用性,可以应对多种不同的故障场景.如果Eureka以集群模式部署,当集群中有分片出现故障时,那么Eureka就转入自
我保护模式.它允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复运行时,集群中的其他分片会把它们的状态再
次同步回来.
Eureka客户端,主要处理服务的注册与发现.客户端服务通过注解和参数配置的方式,嵌入在客户端应用程序代码中,在应用
程序运行时,Eureka客户端向注册中心注册自身提供的服务并周期性地发送心跳来更新它的服务租约.同时,它也能从服务端
查询当前注册的服务信息并把它们缓存到本地并周期性地刷新服务状态.
服务注册与发现
micai-springcloud-eureka-provider 服务提供者
访问服务提供者url:http://localhost:9001/hello,如下图:
micai-springcloud-eureka-consumer 服务消费者
访问服务消费者url:http://localhost:8001/ribbon-consumer/hello,如下图:
这样基于Spring Cloud的分布式服务就调用成功了!
(1).Spring Cloud GET POST PUT DELETE 方法实践
(2).加入服务重试机制
(3).micai-springcloud-eureka-consumer服务加入Spring Cloud Hystrix 断路器依赖
3.1:引入maven依赖:
org.springframework.cloud
spring-cloud-starter-hystrix
3.2:在服务消费者的主类使用注解:@EnableCircuitBreaker开启断路器功能
3.3:改造服务消费方式,新增HelloService类,注入RestTemplate实例。然后,将在ConsumerController中对RestTemplate的使用迁移到helloService函数中,
最后,在helloService函数上增加@HystrixCommand注解来指定回调方法
@Service
public class HelloService {
/**
* 服务提供者URL
*/
private static final String MICAI_SPRINGCLOUD_EUREKA_PROVIDER_URL = "http://MICAI-SPRINGCLOUD-EUREKA-PROVIDER";
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallback")
public String helloService() {
return restTemplate.getForEntity(MICAI_SPRINGCLOUD_EUREKA_PROVIDER_URL + "/hello", String.class).getBody();
}
public String helloFallback() {
return "error";
}
}
1.搭建声明式服务调用服务
2.参数绑定 支持@RequestParam,@RequestHeader,@RequestBody形式的参数绑定
3.继承特性
新建 micai-springcloud-service-api 基础工程,定义可同时复用于服务端和客户端的接口
使用Spring Cloud Fegin的优点与缺点
3.1.优点:可以将接口的定义从Controller中剥离,同时配合Maven私有仓库就可以轻易地实现接口定义的共享,实现在构建期的接口绑定,从而有效减少服务客户端的绑定配置。
3.2.缺点:这么做虽然很方便地实现接口定义和依赖的共享,不用再复制粘贴接口进行绑定,但是这样的做法使用不当的话,会带来副作用。由于接口在构建期间就建立起了依赖,
那么接口变动就会对项目构建造成影响,可能服务提供方修改了一个接口定义,那么会直接客户端工程的构建失败。所以,如果开发团队通过此方法来实现接口共享的话,建议在开
发评审期间严格遵守面向对象的开闭原则,尽可能地做好前后版本的兼容,防止牵一发而动全身的后果,增加团队不必要的维护工作量。
4.Ribbon配置
4.1.全局配置
# Ribbon配置
# 全局配置
ribbon.ConnectTimeout=500
ribbon.ReadTimeout=5000
4.2.指定服务配置 <br/>
# 指定服务配置 <br/>
MICAI-SPRINGCLOUD-EUREKA-PROVIDER.ribbon.ConnectTimeout=500 <br/>
MICAI-SPRINGCLOUD-EUREKA-PROVIDER.ribbon.ReadTimeout=2000 <br/>
MICAI-SPRINGCLOUD-EUREKA-PROVIDER.ribbon.OkToRetryOnAllOperations=true <br/>
MICAI-SPRINGCLOUD-EUREKA-PROVIDER.ribbon.MaxAutoRetriesNextServer=2 <br/>
MICAI-SPRINGCLOUD-EUREKA-PROVIDER.ribbon.MaxAutoRetries=1 <br/>
1.重试机制
这里需要注意一点,Ribbon的超时与Hystrix的超时是两个概念。为了实现重试机制,我们需要让Hystrix的超时时间
大于Ribbon的超时时间,否则Hystrix命令超时后,该命令就直接熔断,重试机制就没有意义了。
1.Hystrix配置
2.全局配置
# 设置全局的超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
# 关闭熔断功能
#hystrix.command.default.execution.timeout.enabled=false
3.禁用Hystrix
4.指定命令配置
5.服务降级配置
注意:服务降级的时候,遇到了问题,死活服务降级不起作用,原来是spring cloud版本的问题,这里记录下解决办法
5.1.修改spring cloud的版本依赖为如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
5.2.开启Hystrix功能
feign.hystrix.enabled=true
5.3.通过上面两步操作,基于Spring Cloud Feign的服务降级就实现了
6.其他配置
6.1.请求压缩
请求压缩 Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗
feign.compression.request.enabled=true
feign.compression.response.enabled=true
同时,我们还能对请求压缩做一些更细致的设置,比如下面的配置内容指定了压缩的请求数据类型,并设置了请求压缩的大小下限,只有超过这个大小的请求才会对气进行压缩
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
上述设置的feign.compression.request.mime-types和feign.compression.request.min-request-size均为默认值
6.2.日志配置
1.API网关服务:Spring Cloud Zuul
1.1.构建网关服务
1.2.请求路由
1.2.1.传统路由方式
使用Spring Cloud Zuul实现路由功能非常简单,只需要对micai-springcloud-api-gateway服务增加一些关于路由规则的配置,就能实现传统的路由转发功能
比如:
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:8080/
该配置定义了发往API网关服务的请求中,所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8080/地址上,也就是说,当我们访问
http://localhost:5555/api-a-url/hello的时候,API网关服务会将该请求路由到http://localhost:8080/hello提供的微服务接口上。其中,配置属性
zuul.routes.api-a-url.path中的api-a-url部分为路由的名字,可以任意定义,但是一组path和url映射关系的路由名要相同,下面将要介绍的面向服务的
映射方式也是如此。
1.2.2.面向服务的路由
很显然,传统路由的配置方式对于我们来说并不友好,它同样需要运维人员花费大量的时间来维护各个路由path和url的关系。为了解决这个问题,Spring Cloud Zuul
实现了与Spring Cloud Eureka的无缝整合,我们可以让路由的path不是映射具体的url,而是让它映射到某个具体的服务,而具体的url则交给Eureka的服务发现机制
去自动维护,我们称这类路由为面向服务的路由。在Zuul中使用服务路由也同样简单,只需做下面这些配置。
1.3.请求过滤
Zuul允许开发者在API网关上通过定义过滤器来实现对请求的拦截和过滤,实现的方法非常简单,我们只需要继承ZuulFilter抽象类并实现它定义的4个抽象函数就可以完成对请求的
拦截和过滤了。
1.3.1.创建zuul过滤器
1.3.2.在服务网关的启动类创建具体的zuul过滤器Bean
1.4.增加Zuul网关前的请求地址:localhost:8011/feign-consumer/getBook
1.5.增加了Zuul网关后的请求地址:localhost:8022/api-b/feign-consumer/getBook?accessToken=token
1.路由详解
1.1.传统路由配置
1.1.1.单实例配置
zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.url=http://localhost:8080/
该实例实现了符合/user-service/规则的请求路径转发到http://localhost:8080/地址的路由规则。比如:当有一个请求http://localhost:8022/user-service/hello 被转发到API网关上,由于/user-servcie/hello能够被上述配置的path规则匹配,所以API网关会转发请求到http://localhost:8080/hello地址。
1.1.2.多实例配置
zuul.routes.user-service.path=/user-service/
zuul.routes.user-service.serviceId=user-service
ribbon.enreka.enabled=false
user-service.ribbon.listOfServers=http://localhost:8080/,http://localhost:8081/
该配置实现了对符合/user-service/**规则的请求路径的转发到http://localhost:8080/和http://localhost:8081/两个实例地址的路由规则。它的配置方式与服务路由的配置方式一样,都采用了zuul.routes..path与zuul.routes..serviceId参数对的映射方式,只是这里的serviceId是由用户手工命名的服务名称,配合ribbon.listOfServers参数实现服务与实例的维护。由于存在多个实例,API网关在进行路由转发时需要实现负载均衡策略,于是这里还需要Spring Cloud Ribbon配合。由于在Spring Cloud Zuul中自带了对Ribbon的依赖,所以我们只需做一些配置即可,比如上面示例中关于Ribbon的各个配置,它们的具体作用如下所示。
ribbon.enreka.enabled:由于zuul.routes..serviceId指定的服务名称,默认情况下Ribbon会根据服务发现机制来获取配置服务名对应的实例清单。但是,该示例并没有整合类似Eureka之类的服务治理框架,所以需要将该参数设置为false,否则配置的serviceId获取不到对应实例的清单。
user-service.ribbon.listOfServers:该参数内容与zuul.routes..serviceId的配置相对应,开头的user-service对应了serviceId的值,这两个参数的配置相当于在该应用内部手工维护了服务与实例的对应关系。
1.2.服务路由配置 <br/>
zuul.routes.user-service.path=/user-service/** <br/>
zuul.routes.user-service.serviceId=user-service <br/>
等价于下面的配置 <br/>
zuul.routes.user-service=/user-service/** <br/>
1.服务路由的默认规则
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。