【课程22】spirng c...简介.xmind54KB
【课程22】spirng cl...架构.xmind0.5MB
【课程22】负载均...eign.xmind46.2KB
【课程22】基于rest...服务.xmind25.2KB
【课程22】微服务.xmind63.6KB
【课程22】注册中...reka.xmind0.7MB
微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务。这些小的Web服务可以独立地编译及部署,并通过各自暴露的API接口相互通讯。它们彼此相互协作,作为一个整体为用户提供功能,却可以独立运行扩展。
1:我们把整个系统根据业务拆分成几个子系统。
2:每个子系统可以部署多个应用,多个应用之间使用负载均衡。
3:需要一个服务注册中心,所有的服务都在注册中心注册,负载均衡也是通过在注册中心注册的服务来使用一定策略来实现。
4:所有的客户端都通过同一个网关地址访问后台的服务,通过路由配置,网关来判断一个URL请求由哪个服务处理。请求转发到服务上的时候也使用负载均衡。
5:服务之间有时候也需要相互访问。例如有一个用户模块,其他服务在处理一些业务的时候,要获取用户服务的用户数据。
6:需要一个断路器,及时处理服务调用时的超时和错误,防止由于其中一个服务的问题而导致整体系统的瘫痪。
7:还需要一个监控功能,监控每个服务调用花费的时间等。
- 单一职责原则
- 服务自治原则
- 轻量级通信机制
- 跨语言、平台
- 通信体量轻,如REST
- 微服务粒度
可以试用spring的restTemplate做rest远程调用。
- 主要使用RestTemplate完成rest调用
(服务提供者)
(服务调用者)
- 适用场景有局限,服务提供者对我接口不能发生变化,会直接影响到消费者。
- 服务容灾不法保证,容易造成服务雪崩
- 适合较为简单微服务系统
spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring cloud是基于springboot的,所以需要开发中对springboot有一定的了解。
开发工具集合,含有多个项目。
简化了分布式开发。
- 利用Spring boot的开发便利
- 主要是基于对Netfix开源组件的进一步封装
- 分布式/版本化配置
- 服务注册和发现
- 路由
- 服务和服务之间的调用
- 负载均衡
- 断路器
- 分布式消息传递
这些特性都是由不同的组件来完成,在架构的演进过程中扮演着重要的角色
1:约定优于配置
2:开箱即用、快速启动
3:与springboot紧密结合
4:轻量级的组件
5:组件支持丰富,功能齐全
从上图可以看出Spring Cloud各个组件相互配合,合作支持了一套完整的微服务架构。
- 其中Eureka负责服务的注册与发现,很好将各服务连接起来
- Hystrix 负责监控服务之间的调用情况,连续多次失败进行熔断保护。
- Hystrix dashboard,Turbine 负责监控 Hystrix的熔断情况,并给予图形化的展示
- Spring Cloud Config 提供了统一的配置中心服务
- 当配置文件发生变化的时候,Spring Cloud Bus 负责通知各服务去获取最新的配置信息
- 所有对外的请求和服务,我们都通过Zuul来进行转发,起到API网关的作用
- 监控我们使用Sleuth+Zipkin+springAdmin将所有的请求数据记录下来,方便我们进行后续分析
Spring Cloud Config:配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储、Git以及Subversion。
Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。
Spring Cloud Netflix:针对多种Netflix组件提供的开发工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。
Netflix Eureka:云端负载均衡,一个基于 REST 的服务,用于定位服务,以实现云端的负载均衡和中间层服务器的故障转移。
Netflix Hystrix:容错管理工具,旨在通过控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
Netflix Zuul:边缘服务工具,是提供动态路由,监控,弹性,安全等的边缘服务。
Netflix Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
Spring Cloud for Cloud Foundry:通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台。
Spring Cloud Sleuth:日志收集工具包,封装了Dapper,Zipkin和HTrace操作。
Spring Cloud Data Flow:大数据操作工具,通过命令行方式操作数据流。
Spring Cloud Security:安全工具包,为你的应用程序添加安全控制,主要是指OAuth2。
Spring Cloud Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。
Spring Cloud Zookeeper:操作Zookeeper的工具包,用于使用zookeeper方式的服务注册和发现。
Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。
Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。
(心跳检测、健康检查、负载均衡等)
Spring Cloud解决的第一个问题就是:服务与服务之间的解耦。很多公司在业务高速发展的时候,服务组件也会相应的不断增加。服务和服务之间有着复杂的相互调用关系,经常有服务A调用服务B,服务B调用服务C和服务D ...,随着服务化组件的不断增多,服务之间的调用关系成指数级别的增长。
这样最容易导致的情况就是牵一发而动全身。经常出现由于某个服务更新而没有通知到其它服务,导致上线后*频发。这时候就应该进行服务治理,将服务之间的直接依赖转化为服务对服务中心的依赖。
两个组件组成
- Eureka Server注册中心
- Eureka Client服务注册
当然服务中心这么重要的组件一但挂掉将会影响全部服务,因此需要搭建Eureka集群来保持高可用性,生产中建议最少两台。随着系统的流量不断增加,需要根据情况来扩展某个服务,Eureka内部已经提供均衡负载的功能,只需要增加相应的服务端实例既可。那么在系统的运行期间某个实例挂了怎么办?Eureka内容有一个心跳检测机制,如果某个实例在规定的时间内没有进行通讯则会自动被剔除掉,避免了某个实例挂掉而影响服务。
因此使用了Eureka就自动具有了注册中心、负载均衡、故障转移的功能。
第一步、导入Eurka坐标
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--actuator用于应用监控管理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
第二步、Applcation上添加注解
#开启Eurka注册中心服务
@EnableEurekaServer
第三步、在aplication.yml上配置Eureka注册信息
server:
port: 8761
eureka:
client:
# 表示是否将自己注册到Eureka Servcer。
register-with-eureka: false
# 表示是否从Eureka Server获取注册信息
fetchRegistry: false
serviceUrl:
# 设置Eureka Server交互的地址
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-server-1
第四步、启动项目,访问http://localhost:8761 可以访问到Eureka服务界面
# 开启注册服务发现功能
@EnableDiscoveryClient
# 开启Eureka注册中心服务功能
@EnableEurekaServer
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。
默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。
Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
自我保护的条件:
一般情况下,微服务在Eureka上注册后,会30秒定期发送心跳,Eureka 通过心跳来判断微服务是否健康,同时会定期删除超过90秒没有发送心跳的服务。
有2种情况会导致Eureka Server收不到微服务的心跳,
1. 是微服务自身原因所致,比如故障或关闭;
2. 是微服务与eureka之间的网络出现故障。
通常(微服务自身的故障关闭)只会导致个别服务出现故障,一般不会出现大面积的故障,而(网络故障)通常会导致Eureka Server在短时间内无法收到大批心跳。
考虑到这个区别,Eureka设定了一个阀值,当判断挂掉的服务的数量超过阀值时,Eureka Server认为很大程度上出现了网络故障,将不再删除心跳过期的服务。
那这个阀值是多少呢?
1. 15分钟之内是否低于85%;
2. Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%
3. 这种算法叫着Eureka Server的自我保护模式。
关闭自我保护模式(生产上不建议)
(关闭了自我保护之后,然后需要几分钟才能把失效的客户端节点删掉)
作为一个注册中心,为了确保微服务能够正常的注册和发现,单机的eureka server肯定不能满足这样的需求,如果注册中心挂掉,那么线上的所有服务都会有影响,那么需要有一个高可用的eureka server来支撑。
在eureka的服务治理设计中,所有的节点既是服务提供方,也是服务消费方,服务注册中心也是,那么eureka server的高可用实际上是将自己作为服务注册到其他的注册中心,这样可以形成一组相互注册的服务注册中心,可以实现服务清单的同步,达到高可用的目的。
注册中心节点之间相互注册即可实现高可用部署。
(相互注册)
假如3个以上也一样,把其他的都注册到自己的server上面,用逗号隔开。客户端需要配置所有的Eureka server地址。
(客户端)
如此可以保证注册节点的高可用。
原理
在euerka 集群中如果某台服务器宕机,euerka没有zookeeper的选举leader规则过程,客户端请求会自动切换到新的euerka的节点上,当宕机的服务器从恢复后,euerka会从新将其纳入到euerka服务器集群中(实现高可用)
注册中心地位
客户端发现
- eureka
服务端发现
- nginx
- zookeeper
eureka启动之后,可以通过链接直接访问到eureka。所以需要添加security。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
添加security的账号密码。
spring:
security:
user:
name: admin
password: admin
可以通过spring-boot-starter-sercurity对Eureka Server添加安全认证。默认情况下,将其添加到classpath后,会对每个请求进行CSRF检查。Eureka并不会生成CSRF token,所以需要关掉对/eureka/*路径下的检查:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
客户端连接eureka的时候,defaultZone需要改动。
eureka:
client:
# 设置Eureka Server交互的地址
service-url:
defaultZone: http://admin:admin@localhost:8761/eureka/
Spring Cloud Ribbon是基于HTTP和TCP的客户端负载工具,它是基于Netflix Ribbon实现的。通过Spring Cloud的封装,可以轻松地将面向服务的REST模板请求,自动转换成客户端负载均衡服务调用。
步骤一:导入Ribbon坐标(其实可以不用加,client直接有)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
步骤二:为RestTemplate添加@@LoadBalanced注解,表示使用负载均衡算法
@Bean
//为RestTemplate整合Ribbon的负载均衡能力
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
步骤三:eureka-client-2是被调用者的应用名称。名称为eureka-client-2应用的有多个。此时就会根据负载算法调用生产者。
步骤四:改变负载均衡策略,配置形式,或者注解形式都可以(IRule)
ORDER:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
被调用方(生产者)可以通过注入loadBalancerClient查看当前端口。
@Autowired
private LoadBalancerClient loadBalancerClient;
在Eureka server看到的效果:
客户端负载均衡的使用
LoadBalancerInterceptor
service.ribbon.listOfServers
Feign可以创建声明式、模板化的HTTP客户端,进行微服务调用。使用简单,创建一个接口,然后在接口上添加一些注解,代码就完成了。
代码如下:
第一步、导入Feign坐标,并在Application上添加注解@EnableFeignClients表示开启Feign模块
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步 :创建一个Feign接口,并添加@FeignClient注解
import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@GetMapping(value = "/{id}")
User findById(@PathVariable("id") Long id);
}
第三步、controller上地方
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
}
feign常见问题汇总: