纯属杂谈笔记,没有啥实质内容。。
传统互联网应用的架构演变
- 简单来说,从 单体应用 -> 集群负载均衡 -> 动静分离、cdn分发 -> 数据库读写分离 -> NoSql 缓存 -> 分库分表 -> SOA -> 微服务
- 具体可以看看这篇文章
什么是微服务
将一个大型应用,拆分为多个独立的小服务,相互间通过rpc接口进行调用其他服务,最终完成整个大型功能的一种架构思想。举例来说,一个电商功能,可以拆分为 下单服务、支付服务、会员服务、积分服务、发货服务 等等一系列微服务的结构,也可以将所有功能都写在一个仓库中,所谓的集中式的架构。那么微服务的划分有什么优缺点呢?
- 微服务将各个功能解耦,独立开发独立部署,某个业务的开发不影响其他业务的功能,解耦后可以快速开发快速迭代
- 每个微服务可以选用不同的技术栈,作为一个独立的模块
- 互相调用的层级加深,一定程度上会降低接口效率
- 因为整体系统的复杂度提升,会带来测试及运维部署的复杂度
- 需要架构人员对于业务的充分理解,对微服务有准确的划分
微服务和SOA的区别
在我理解,两者是非常接近的概念,区别只在于拆分的服务的独立程度上,也可以把 SOA 理解为一种思想,微服务是一种具体实现的方式,不用过多纠结,记得它们都是指把一个大型服务拆分成多个组件化即可,组件之间再通过某种方式相互调用对方的服务。
微服务框架
所谓的微服务框架,只是说可以支撑微服务结构的一些工具,按照上面的解释,如果我们需要将某个大型应用拆分为微服务,我们每个服务需要知道如何去调用其他的服务
- 那么最原始的方式,是有一个运维配置,统一告诉所有的服务,每个其他服务的地址是啥,调用uri是啥,但是这种模式会有很大的局限性,配置是一个非常痛苦的过程,而且对于动态扩缩容非常不友好
- 换一种方式的话,我们可以考虑有一个注册中心,所有的服务都按照一种约定好的格式,告诉注册中心,本机器可以提供什么服务给其他人调用,然后本机器也可以通过注册中心获取别人的服务信息,然后通过这些信息去调用别人的服务,显然这种方式对于大型项目的实际运行更友好,扩展性强
- 有了这样的一个注册中心之后,我们也需要尽量统一一下调用服务的方式,例如统一使用 http,或者例如dubbo可以使用自己的dubbo协议
所以一个最基本的微服务框架需要具备一下功能:
- 统一的服务注册和服务发现的框架或工具,便于各个机器找到自己需要的服务在哪里
- 统一的服务调用方式,服务之间相互调用的方法,例如http
在基本功能之上,我们可以考虑给框架再升级一些功能:
- 当每个服务注册了多个的时候,提供负载均衡的算法,分摊压力,实现高可用
- 如果发现某些服务出现故障的时候,提供一种熔断、降级的方式,保障其他的服务不会因为这一个服务的错误而引起雪崩
- 监控服务互相之间的各种调用状况,记录日志等等
如果具备上述的这些功能之后,一个比较完整的微服务框架就基本成型了
dubbo 和 spring cloud
准确来说,dubbo是rpc框架,并不是一个微服务的完整框架,它提供了最基本的服务注册和服务调用的功能,而spring cloud是一个完整的微服务工具框架,可以使用它构建一整套的微服务结构
- dubbo的使用教程
- spring cloud 的使用教程
- dubbo 和 spring cloud 的主要对比
- spring cloud 提供的功能更多更全,除了服务的注册发现调用之外,还有断路器、路由网关、分布式配置中心、消息总线、服务链路追踪等等
- dubbo 有多种的服务调用协议,包括自带的 dubbo 协议、Thrift、http等,而 spring cloud 只支持 http的协议
- dubbo 的注册中心可以选择zookeeper、redis等,而spring cloud的注册中心职能使用eureka或者自己开发
- dubbo 的服务调用,需要引用被调用的服务的jar包,例如 A 工程调用 B 工程的接口服务,那么在 A 中的 pom.xml 需要引用 B 的jar包,这种模式在大型项目依赖关系复杂的时候,非常不利于使用
spring cloud的主要模块介绍
- eureka: 服务的注册中心,有 eureka 的 server 和 client,server是一个单独的服务器,而所有的服务使用者都是 client
- rest + ribbon: rest 是spring framework 封装的一个通过 rest api 调用其他服务的接口(需要在调用时指定uri),ribbon 是一个负载均衡客户端工具,可以嵌入到服务调用者的代码中,每次调用其他服务时,通过 ribbon 控制负载均衡的算法,可以分摊被调用者的压力
- feign: 是 rest + ribbon 的另外一种写法,不需要在调用时指定uri,通过注解的方式来指定要调用的服务,功能和 rest + ribbon 是一致的
- Hystrix: 熔断器,嵌入到eureka 的 client 中,当发现其他的服务多次调用都失败的情况下,断开服务,或者启用备用的接口的降级方案
- zuul: 路由网关,可以通过该网关的配置,将不同的 url 请求自动转发到不同的服务上,例如 test/A/hello 指向 A 服务的 hello 接口,test/B/hello 指向 B 服务的 hello 接口
- spring cloud config: 配置管理中心,创建一个 config server,其他的服务都是 config client,所有的服务的配置都可以通过 config server来进行获取,统一管理
- spring cloud bus: 总线系统,可以通过总线对所有服务进行广播通知,底层是基于 rabbitMQ 的实现,总线最常用的用法是结合 config,进行配置变化后的广播通知
- sleuth: 链路追踪,可以追踪服务被调用的情况
目前还存在疑惑的地方
- 如果某个服务的某台机器突然宕机了,会引起其他调用者的什么现象?那些服务的 ribbon 会自动更新被调用者的列表吗?否则可能会有些请求被继续分配到该机器上
跨语言的微服务框架
spring cloud主要是针对java的实现,如果需要实现 java + php + go 等多语言的微服务框架,关键也是在于为各种语言提供一套统一的服务发现注册和RPC调用的接口,能够跨语言进行调用,目前有 service mesh 、motan 和腾讯的TARS-PHP(这个主要针对php)等其他框架,可以供非java语言的微服务进行使用