SpringCloud-Netflix学习笔记
什么是微服务?
在了解SpringCloud之前,我们先来大致了解下微服务这个概念吧。
传统单体架构
单体架构在小微企业比较常见,典型代表就是一个应用、一个数据库、一个web容器就可以跑起来。
微服务架构
通俗来讲,就是把一个大的项目内部功能拆分出来,一个功能一个模块,比如用户模块,商品模块,支付模块,下单模块,购物车管理等等,各个模块单独开发,然后互相调用的方式为微服务架构模式
有什么?
Spring Cloud-Netflix是一系列框架的有序集合。它分为几大模块,分别是:服务发现注册Eureka、配置中心、消息总线、负载均衡、断路器、数据监控等;都可以用Spring Boot的开发风格做到一键启动和部署。
微服务技术栈有哪些?
服务开发:SpringBoot,Spring,SpringMVC
服务配置与管理:NetFix公司的Archaius,阿里的Diamond等
服务注册与发现:Eureka,Consul,Zookeeper等
服务调用:Rest,RPC,gRPC
服务熔断器:Hystrix,Nginx等
服务接口调用:Feign等
消息队列:Kafka,RabbitMQ,ActiveMQ等
服务配置中心管理:SpringCloudConfig,Chet等
服务路由:Zuul等
服务监控:Zabbix,Nagiox,Metrics,Specatator等
全链路追踪:Zipkin,Brave,Dapper等
服务部署:Docker,OpenStack,Kubernetes等
数据流操作开发包:SpringCloud Stream(封装与Redis,Rabbit,Kafka等发送接收消息)
微服务优缺点
优点
单一职责原则
每个服务足够内聚,足够小,代码易理解,这样能聚焦一个指定的业务功能或业务需求
开发简单,开发效率提高,一个服务可能就是专一的只干一件事情
微服务能被小团队单独开发,这个小团队是2-5人的开发人员组成
微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署都是独立的
微服务能使用不同的语言开发
易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如jenkins,Hudson,bamboo
微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值
微服务允许你利用融合最新技术
微服务只是业务逻辑的代码,不会和HTML,CSS或其他界面混合
每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一的数据库
缺点
开发人员要处理分布式系统的复杂性
多服务运维难度,随着服务的增加,运维的压力也在增大
系统部署依赖
服务间通信成本
数据一致性
系统集成测试
性能监控…
服务注册Eureka
CAP原则
C: 强一致性
A: 可用性
P: 分区容错性
CAP的三进二 : CA, AP, CP
CAP理论的核心:
一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求(通俗来讲,在一个分布式系统中,这三个要素最多只能实现两个,不可能三者兼顾)
根据CAP原理,将NoSql数据库分成了满足CA原则,满足CP原则和满足AP原则三大类:
CA:单点集群,满足一致性,可用性的系统,通常可扩展性差
CP:满足一致性,分区容错性的系统,通常性能不高
AP:满足可用性,分区容错性的系统,通常可能对一致性的要求较低
作为服务注册中心,Eurekar和Zookeper的区别
一个分布式系统中,P是必须要保证的,所以只能在A和C中选择
Zookeper保证的是CP
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟前的注册信息,但不能接受服务直接down掉,zk会出现这样之中情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选举leader,问题在于选举时间过长 30~120S,且选举期间整个集群不可用,会导致选举时服务瘫痪,虽然最后能够恢复,但是漫长的选举时间导致注册长期不可用是不能容忍的
EureKa 保证的是AP
Eureka各个节点都是平等的,几个节点挂掉都不会影响正常的工作,剩余的节点仍然会提供注册和查询服务。而Eureka客户端在向某个Eureka注册时,如果发现连接失败,则会自动切换至其他节点,只要有一台Eureka还在,就能保住注册服务的可用性,只不过查到的信息可能不是最新的,除此之外,Eureka还有一种保护机制,如果15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1,Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2,Eureka仍然能接收新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点依然可用)
3,当网络稳定时,当前实例的注册信息会被同步到其他节点中
eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪
Eureka配置:详细配置
Rest服务调用:详情参考
SpringCloud服务搭建
参考链接:项目搭建
Ribbon
是什么?
SpringCloudRibbon是基于Netfix Ribbon实现的一套客户端负载均衡的工具
能干嘛?
LB,即负载均衡
简单说就是将用户请求平均分摊到多个服务上,达到系统的HA(高可用)
常见负载均衡软件有Nginx,Lvs等
怎么用?
添加注解即可
也可以自定义负载均衡:详情请参考
@Bean
@LoadBalanced //负载均衡机制,如果多个服务,则轮询访问,不会一直请求同一个服务
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
Feign 负载均衡
服务调用使用 Ribbon + RestTemplete,形成一套模板化的调用方法;实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常对每个微服务自行封装一些客户端来包装这些依赖服务的调用
Feign组件的实现下,我们只需要创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定。
怎么用?
引入jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
Service添加同服务端注册相同服务的接口
//spring-cloud-production 为服务注册ID
@Component
@FeignClient(name="spring-cloud-production")
public interface FeignService {
//login方法为服务端注册的服务接口
@RequestMapping(value="/login", method = RequestMethod.POST)
public String login(@RequestParam("username") String username,@RequestParam("pwd") String pwd);
}
Hystrix 服务熔断
写于服务端,用于某个服务超时或者异常,引起熔断,相当于保险丝;
是什么?
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常等;Hytrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性;在SpringCloud中,Hystrix会监控微服务间调用的情况,当失败的调用到一定的阈值,缺省是5秒内20次调用失败就会启动熔断机制
怎么用?
引入jar:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
接口添加熔断器注解
@GetMapping("/testGet/{id}")
//添加Hystrix熔断器注解,fallbackMethod 为失败后调用的方法
@HystrixCommand(fallbackMethod = "testHystrixGet")
public String testGet(@PathVariable("id") String id) {
String test = hystrxservice.test(id);
if(test == null) {
//代码抛出异常,则熔断机制启动,调用熔断接口
throw new RuntimeException("调用信息失败");
}
return test;
}
//熔断接口
public String testHystrixGet(@PathVariable("id") String id) {
return "异常,没有对应的信息";
}
启动类添加注解
@SpringBootApplication(exclude=
{DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@EnableEurekaClient //在服务中启动后启动注册到Eurka中
@EnableCircuitBreaker //添加对熔断器的支持
public class ProductionApp
{
public static void main(String[] args) {
SpringApplication.run(ProductionApp.class, args);
}
}
服务降级
客户端,从整体网站请求负载考虑,当某个服务熔断或者关闭之后,服务不再被调用,此时在客户端,我们可以准备一个fallbackFactory,返回一个默认的值,整体的服务水平下降了,但是好歹能用
怎么用?
引入jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
Service添加服务端注册的接口
@Component
@FeignClient(name="spring-cloud-production",fallbackFactory = FeignServiceFailBackTwo.class)
public interface FeignService {
@RequestMapping(value="/login", method = RequestMethod.POST)
public String login(@RequestParam("username") String username,@RequestParam("pwd") String pwd);
}
配置服务降级接口,实现 FallbackFactory接口,new 需要实现的接口,eg:FeignService
@Component
public class FeignServiceFailBackTwo implements FallbackFactory<FeignService>{
@Override
public FeignService create(Throwable cause) {
return new FeignService() {
@Override
public String login(String username, String pwd) {
return "服务异常!";
}
}
}
};
启动类添加注解
@SpringBootApplication //spring-boot 启动注解
@EnableDiscoveryClient //开启发现服务功能
@EnableFeignClients(basePackages = {"com.Service"}) //调取别人 方法可写至Common公共类内
//随机算法调用接口注解 name 填写所调用服务instance-ID
@RibbonClient(name="spring-cloud-production",configuration = RodomTest.class)
//@EnableCircuitBreaker //添加对熔断器的支持
public class ConsumerApp
{
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
开启熔断器
#hystrix熔断器开启start
feign:
hystrix:
enabled: true
#hystrix熔断器开启end
监控
引入jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
启动类开启注解
@SpringBootApplication
@EnableHystrixDashboard //开启监控注解
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}
配置监控;详情
Zuul网关
是什么?
Zuul包含了对请求的路由和过滤的两个最主要的功能:
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,而过滤器功能则负责对请求处理过程进行干预,是实现请求校验,服务聚合等功能的基础。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Z跳转后获得;
注意:Zuul服务最终还是会注册进Eureka
提供:代理+路由+过滤 三大功能
能干吗?
路由+过滤
引入jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
配置启动类
@SpringBootApplication
@EnableZuulProxy
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}
配置文件
#Zuul
server:
port: 9527
spring:
application:
name: spring-cloud-zuul
#注册中心指向start
eureka:
instance:
prefer-ip-address: true
instance-id: spring-cloud-zuul
appname: ${spring.application.name}
client:
service-url:
defaultZone: http://admin:123456@shuang.com:8888/eureka/
#注册中心指向end
#Zuul配置
zuul:
routes:
myzuul.serviceId: spring-cloud-production #所要访问的路由的服务Id
myzuul.path: /myzuul/** #自己定义的路由网关名称
ignored-services: '*' #忽略所有myzuul.serviceId服务,只能通过自己定义的path访问
本文地址:https://blog.csdn.net/qq_36971119/article/details/107555220