SOA: 面向服务的架构,将服务拆分后注册到企业总线统一对外提供服务
微服务:业务系统彻底组件化,将应用拆分为多个小的应用,这些应用从web UI到服务api都是独立的完整的一个整体。
微服务特点:单一职责,自治。
微服务与SOA的区别:微服务不再强调传统SOA架构里面比较重的ESB企业服务总线,微服务将业务系统彻底的组件化。
微服务优点:
1、逻辑清晰,每个服务只负责自己的那部分业务
2、扩展方便,只需修改当前的微服务,且部署的时候也不会影响其他模块
3、高可用,分布式部署提高了整体应用的吞吐量,对某些访问量比较高的服务可以单独扩充节点 4、技术异构,不同的团队维护不同的服务时,可以根据自己熟悉的技术栈去实现并不会影响其他人。
微服务缺点:
1、相对于单体应用,复杂度相对较高
2、维护成本较高,应用拆分出大量的微服务一定程度上也会增加运维的成本
3、相对单体应用的本地调用,微服务之间相互调用需要使用Rest、RPC等方式,一定程度上影响了性能。
Spring Cloud Netflix Eureka 与服务治理:
服务发现与调用流程图
三个服务A,B,C都是多实例部署在集群环境中,都需要到注册中心注册,B,C作为A的服务提供者,A需要通过负载均衡器找到B,C完成服务调用,负载均衡器从注册中心获取服务的定义信息。
服务治理涉及的角色主要有三种:
注册中心:提供服务的注册和发现
服务提供者:服务提供者将自身服务注册到注册中心,从而使消费者能够找到
服务消费者:从注册中心获取注册服务列表,从而完成消费
服务治理的策略:
轮询机制:消费者定时去注册中心拉取最新的服务列表并更新本地缓存
监听和通知机制:注册中心注册服务列表发生变化时,触发回调通知消费者更新本地缓存。
服务治理实现工具:Zookeeper(Java)、Consul(Go)、Eureka(Java)
搭建一个Eureka服务非常简单,引入spring-cloud-starter-eureka-server依赖,在启动类上添加@EnableEurekaServer就完成了。Euraka可以通过相互注册(eureka.client.serviceUrl.defaultZone:多个eureka-url)的方式形成一个集群。
Eureka客户端的搭建也非常简单,引入依赖spring-cloud-starter-eureka,在启动类上添加注解@EnableEurekaClient,配置文件中添加配置eureka.client.serviceUrl.defaultZone:eureka-server-url
获取注册到Eureka服务器上的具体某一个服务实例的详细信息可以通过访问http:eureka-service-url/eureka/apps/appid(servername)
Eureka基本架构
Spring cloud Netflix Ribbon 负载均衡
所有的服务实例注册到注册中心后,Ribbon从注册中心获取服务列表实现负载均衡。
负载均衡的类型:
1、服务端负载均衡,在客户端与服务端之间加一个代理,访问代理,代理将请求转发到某个微服务节点上
2、客户端负载均衡,负载均衡器与客户端为一个整体,客户端在发起请求时首先根据负载均衡器定位到本次访问的目的节点,然后发起请求
Ribbon是一种客户端负载均衡方案
负载均衡的算法:
1、静态负载均衡算法:随机算法,使用JDK自带的随机算法或者改进后的加权随机算法;轮询算法:轮询或者加权轮询
2、动态负载均衡算法:最少连接数算法,统计每个节点的被调用次数,调用次数较少的优先调用;服务调用延时算法,根据各节点响应的平均时间来调整调用优先级;源IP Hash算法,计算源IPde Hash值决定调用哪个节点,可以保证同一个客户端每次调用的都是同一个服务节点。
使用Ribbon实现负载均衡:
Ribbon作为一种客户端负载均衡的实现方案,不需要独立部署,而是直接嵌入在服务消费者的代码中。
有两种使用方式:1、使用@LoadBalanced和RestTemplate 2、使用@RibbonClient注解
使用:
引入依赖spring-boot-starter-ribbon,通过@LoadBalanced注解创建RestTemplate,然后通过RestTemplate调用http://serverName(服务生产者的服务名称)/api(调用的接口),实际上是Ribbon跟据serverName从注册中心获取对应的Ip和port信息列表,按照负载均衡算法得到当前应该访问的服务节点,将url替换掉进行访问。
Spring Cloud Netflix Hystrix 服务容错
Hystrix提供三种容错处理:
1、隔离(线程隔离和信号量隔离)线程隔离相当于维护多个线程池
2、熔断 维护一个请求失败的计数器,当一个请求异常调用次数到达一个阈值,触发熔断器开启,开后后到达一定时间,进入半开启状态,允许部分请求进入,若全部成功,或者成功达到一定比例,关闭熔断器。
3、回退 服务回退指调用失败后不是直接抛出异常而是用另外的代码去处理
Spring Cloud Netflix Zuul Api网关
解耦服务调用:服务消费者只需要关注网关而不需要关注服务本身的提供者
优化Api:为不同的调用者产生不用的响应,例如用户查询pc一次性查询全部数据而App分页查询。
简化调用过程:可以将一些需要多个微服务结合才能实现的接口整合
服务路由:提供统一的服务路由供客户端访问
安全性控制:统一的认证权限处理
访问控制:控制客户端访问次数和访问频率 负载均衡:提供前置的负载均衡功能
zuul使用内部的ZuulFilter链处理
Spring Cloud Config 配置中心
提供统一的配置信息管理
实现的两种方式:基于本地文件系统,文件名称要跟各个服务的名称一致;基于中央仓库(GIT)实现
Dubbo+Zookeeper
将接口抽象出来定义好,发布到仓库,服务提供者依赖api模块,实现接口,添加@Service注册到zk上,服务消费者只需要引用Api模块,使用@Reference引用就可以了。 服务提供者和服务消费者都需要依赖dubbo的相关依赖和Zookeeper的相关依赖,都需要注册到Zookeeper上。
Dubbo是阿里巴巴开发的一款Java服务平台框架以及SOA治理方案,主要功能包括:高性能NIO通信以及多协议集成、服务动态寻址与路由、软负载均衡与容错、依赖分析、降级等
注意Dubbo注册的@Service注解为Dubbo提供的,消费者使用@Reference
RPC: 远程过程调用,可以使消费者服务像调用本地方法一样调用远程服务提供的方法。
整体流程为:确定远程服务地址(ip,port等),建立连接(Tcp),调用方法以及参数信息序列化通过tcp传输给远程服务,远程服务接收后本地调用产生结果再返回给消费者。
Dubbo基本原理(个人猜测暂未认证):识别@Reference注解,生成代理类,从注册中心或者本地缓存定位远程访问得服务列表,根据负载算法确定远程调用者,使用Netty与远程服务建立TCP连接,封装调用信息得消息体,发送给远程服务,远程服务解析消息体完成本地调用,返回调用结果,调用可能为异步得,由客户端生成唯一得请求id。
1、SpringCloud使用Rest api通信,Dubbo采用RPC通信,服务之间调用得性能会更好
2、springcloud相关组件多,有自己得注册中心网关等,集成方便,Dubbo需要自己额外去集成。 3、Dubbo相对更容易上手