SpringBoot与SpringCloud
1.什么是微服务?
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事.
2.什么是Spring Boot和 Spring Cloud?
●spring boot 是一个快速整合第三方框架 关注的是微观具体快速方便的开发单个个体的服务,它是对Spring应用的简化,使用特定的方式进行配置(properties或yml)配置,无须war包在tomcat下运行,直接jar包.
●spring cloud 关注的是 宏观 具体关注全局的微服务协调整理治理框架 将spring boot 开发的一个个单体服务整合并管理起来它为各个微服务之间提供 配置管理 服务发现 断路器路由 微代理 全局锁 分布式会话 等集成服务.
3.Eurake
为什么要使用注册中心:
1、微服务数量众多,要进行远程调用就需要知道服务端的ip地址和端口,注册中心帮助我们管理这些服务的IP和端口。
2、微服务会实时上报自己的状态,注册中心统一管理这些微服务的状态和信息,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用。
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言编写。下图显示了Eureka Server与Eureka Client的关系:
1> Eureka Server是服务端,负责管理各各微服务结点的信息和状态。
2> 在微服务上部署Eureka Client程序,远程访问Eureka Server将自己注册在Eureka Server。
3> 微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用(Feign)
3.1添加依赖,在父工程添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
3.2在Eureka Server工程添加:
<dependencies>
<!‐‐ 导入Eureka服务的依赖 ‐‐>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐eureka‐server</artifactId>
</dependency>
</dependencies>
3.3、启动类添加注解:@EnableEurekaServer
@EnableEurekaServer //标识这是一个Eureka服务,将注册到注册中心
@SpringBootApplication
@EnableDiscoveryClient //表示它是一个Eureka的客户端
public class GovernCenterApplication {
public static void main(String[] args) {
SpringApplication.run(GovernCenterApplication.class, args);
}
}
3.4需要在启动类上用@EnableEurekaServer标识此服务为Eureka服务
3.5 application.yml的配置内容如下:
server:
port: 50101 #服务端口
spring:
application:
name: xc‐govern‐center #指定服务名
eureka:
client:
registerWithEureka: false #服务注册,是否将自己注册到Eureka服务中
fetchRegistry: false #服务发现,是否从Eureka中获取注册信息
serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
defaultZone: http://localhost:50101/eureka/
server:
enable‐self‐preservation: false #是否开启自我保护模式
eviction‐interval‐timer‐in‐ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
3.6在启动类上添加注解 @EnableDiscoveryClient ,表示它是一个Eureka的客户端.
4.Eurake高可用环境:
1、在实际使用时Eureka Server至少部署两台服务器,实现高可用。
2、两台Eureka Server互相注册。
3、微服务需要连接两台Eureka Server注册,当其中一台Eureka死掉也不会影响服务的注册与发现。
4、微服务会定时向Eureka server发送心跳,报告自己的状态。
5、微服务从注册中心获取服务地址以RESTful方式发起远程调用。
5.微服务之远程调用:
5.1Ribbon介绍
Ribbon是Netflix公司开源的一个负载均衡的项目(https://github.com/Netflix/ribbon),它是一个基于HTTP、CP的客户端负载均衡器。
●什么是负载均衡?
负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等.
用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。
Spring Cloud引入Ribbon配合 restTemplate 实现客户端负载均衡。Java中远程调用的技术有很多,如:webservice、socket、rmi、Apache HttpClient、OkHttp等,互联网项目使用基于http的客户端较多,
5.2Feign介绍
Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
5.2.1、在客户端添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign‐okhttp</artifactId>
</dependency>
5.2.2定义FeignClient接口
@FeignClient(value = XcServiceList.XC_SERVICE_MANAGE_CMS)
public interface CmsPageClient {
@GetMapping("/cms/page/get/{id}")
public CmsPage findById(@PathVariable("id") String id);
}
5.2.33、启动类添加@EnableFeignClients注解
5.3Feign工作原理如下:
1、启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象
2、@FeignClient(value = XcServiceList.XC_SERVICE_MANAGE_CMS)即指定了cms的服务名称,Feign会从注册中心获取cms服务列表, 并通过负载均衡算法进行服务调用。
3、在接口方法 中使用注解@GetMapping("/cms/page/get/{id}"),指定调用的url,Feign将根据url进行远程调用。
5.4Feign注意点:
SpringCloud对Feign进行了增强兼容了SpringMVC的注解 ,我们在使用SpringMVC的注解时需要注意:
1、feignClient接口 有参数在参数必须加@PathVariable("XXX")和@RequestParam("XXX")
2、feignClient返回值为复杂对象时其类型必须有无参构造函数。
6.Ribbon和Feign的区别:
1、启动类使用的注解不同,Ribbon使用的时@RibbonClient,Feign用的时@EnableFeignClients.
2、服务的指定位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口使用@FeignClient声明。
3、调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐. Feign则是Ribbon 的 基础进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建http请求。不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。
7.spring Cloud和 Dubbo有哪些区別 ?
1、本质区别: dubbo 是 基于 RPC 远程 过程调用 ,cloud 是基于 http rest 方式,rest相比RPC更加灵活,不存在代码级别的依赖 .
2、cloud 是Spring家族的,与其他框架整合是契合会更加的完美.
3、spring cloud就像整机,dubbo需要自己组装的机子;整机的性能有保证,组装的机子更自由。
8.eureka和 zookeeper,两个的区別?
著名的CAP理论指出, 一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。
● zookeeper 遵守 CP
当向注册中心查询服务列表时, 我们可以容忍注册中心返回的是几分钟以前的注册信息, 但不能接受服务直接down掉不可用。
也就是说,服务注册功能对一致性的要求要高于可用性。
但是zookeeper 会出现这样一种情况, 当 master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行 leader选举。
问题在于,选举 leader的时间太长,30~120s,目选举期间整个zookeeper 集群都是不可用的,这就导致在选举期间注册服务瘫痪。
在云部署的环境下,因网络问题使得zookeeper 集群失去 master节点是较大概率会发生的事 .
● eureka 遵守 AP
Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。
而 Eureka的客户端在向某个 Eureka注册时如果发现连接失败,则会自动切换至其它节点
只要有一台 Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的不保证强一致性)。
除此之外, Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么 Eurekas就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1.Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2.Eureka仍然能够接受新服务的注册和査询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
3.当网络稳定时,当前实例新的注册信息会被同步到其它节点中
9.服务熔断:hystrix 断路器
hystrix 是一个处理分布式事务的系统延迟和容错的开源库,在分布式系统中,许多服务之间不可避免的需要调用,要调用就会存在由于超时,自身问题调用失败,hystrix 能够保证在在一个依赖出现问题 情况下,不会导致服务整体崩掉,避免级联错误,一提高分布式系统的弹性;
熔断器本身是一个开关装置,当某个服务单元发生故障时,通过熔断器的故障监控,向调用方法返回一个符合预期的/可处理的备选方案(FallBack) ,而不是长时间的等待或者方法调用的异常,这样就保证了服务调用方的线程不会被长时间、不必要 的占用,从而避免故障在分布式系统中方蔓延乃至雪崩;
熔断机制是应对雪崩效应的一种微服务治理机制
服务熔断 是指由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,当检测到该节点微服务调用响应正常服务恢复调用链路,springcloud中采用hystix实现,当失败的调用达到一定阈值时,缺省是在5到20秒的后启动熔断;熔断机制的注解@HystixCommand,在会出现异常的方法上增加注解@HystixCommand(fallbackMethod=异常时调用的方法),再在启动类上增加注解@EnableCircuitBreaker;
服务降级
从系统资源整体负荷考虑,当系统资源不够用时,当某个服务熔断之后,服务器不在调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值;
10.zuul网关:路由与guolv
为什么要使用zuul?
在实际分开发中,1.当我们通过ip+端口号去访问一个服务时,我们只能这样输入,但是我们的服务器就会被暴露,容易被攻击,2.很多服务我们要求调用,假如当我们做了个认证权限,不同的客户可能跑在不同的服务器上,那就是每一个都需要去认证,太麻烦了,so需要解决!
故当客户端访问时,我们可以通过做一个代理,像Nginx反向代理一样,当调用某个服务时,通过zuu api映射成某个路径,输入路径,匹配到了就可以去访问了,它不会直接去访问,而是通过Eureka注册中心拿到服务的id,再使用客户端负载均衡ribbon访问其中一台服务器;
11.SpringCloud的Config配置中心