微服务
先说说单体应用
过去的 Web 项目还不庞大的时候,软件的各个功能组件常常使用 All in One 的开发方式,即各个内部组件组装在一个单体应用内部,再将其部署到多台服务器上,再由代理服务器接受外来请求,然后通过负载均衡技术,将大量的请求分摊到每台服务器上,来增强应用的健壮性和可用性。
但这种 All in One 的架构在软件体量日渐庞大的今天,开发效率和单体应用的健壮性都会受到挑战。于是微服务架构就被提出了。
再说说微服务
微服务架构将软件的各个功能组件拆分开来,包装成相对独立的微服务,部署到不同的机器上,组件之间使用 http/https 等轻量可拓展的协议进行通信,来形成一个软件整体。这样的架构使得各个功能组件能够解耦,减少开发的错误,增强软件的健壮性。
目前常用的微服务框架有 Dubbo 、 Spring Cloud 、 Spring Boot 、 Dropwizard 、 Akka 、 Vert.x/Lagom/ReactiveX/Spring 5 等。以上都是 Java 阵营的微服务框架;
.NET 阵营有 .NET Core 、 Service Fabric 、 Surging 、 Microdot Framework 等;
Node.js 阵营有 Seneca 、 Hapi/Restify/LoopBack 等;
Go 阵营有 Go-Kit/Goa/Dubbogo 等;
Python 阵营有 Nameko ;
SpringCloud
构建分布式系统不需要复杂和容易出错。Spring Cloud 为最常见的分布式系统模式提供了一种简单且易于接受的编程模型,帮助开发人员构建有弹性的、可靠的、协调的应用程序。Spring Cloud 构建于 Spring Boot 之上,使得开发者很容易入手并快速应用于生产中。
简而言之,Spring Cloud 就是一套简易的编程模型,帮助我们在 Spring Boot 之上建立微服务应用。而我们在建立微服务应用时需要做的工作如 服务发现注册、配置中心 、消息总线 、负载均衡 、断路器 、数据监控 等,在 Spring Cloud 中都有相应的编程模型。

Spring Cloud 的版本号均为英国伦敦地铁站的站名,根据字母表的顺序来对应版本时间顺序,比如:最早 的 Release 版本 Angel,第二个 Release 版本 Brixton (英国地名),然后是 Camden 、 Dalston 、 Edgware 、 Finchley 、 Greenwich 、 Hoxton 。
下面从 Spring Cloud 的各个组件的介绍来了解 Spring Cloud 如何完成微服务的各项工作的,主要包括:
Eureka 服务发现框架
Ribbon 进程内负载均衡器
Open Feign 服务调用映射
Hystrix 服务降级熔断器
Zuul 微服务网关
Config 微服务统一配置中心
Bus 消息总线
服务发现框架( Eureka )
Eureka是基于REST(代表性状态转移)的服务,主要在 AWS 云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka服务器。Eureka还带有一个基于 Java 的客户端组件Eureka Client,它使与服务的交互变得更加容易。客户端还具有一个内置的负载平衡器,可以执行基本的循环负载平衡。在 Netflix ,更复杂的负载均衡器将Eureka包装起来,以基于流量,资源使用,错误条件等多种因素提供加权负载均衡,以提供出色的弹性。
从上面关于微服务的概述中可以看出,微服务其实就是把一个单体应用中的每个模块拆出来,单独部署到服务器上,由调用者调用。到这里我们有了两个概念:
- 服务提供者 Eureka Client Provider:拥有某个模块(服务)的服务器;
- 服务消费者 Eureka Client Consumer:需要使用某个模块(服务)的“用户”;
由于服务提供者和服务消费者都是散装的,如果提供者通过广播的方式让消费者发现自己,提供者需要耗费大量网络资源进行广播,而且网络上不是每个服务器都是消费者,所以存在资源浪费。这时,就需要一个中介,让提供者把自己的注册到上面,消费者只需要访问中介来寻找自己需要的服务;
- 服务中介 Eureka Server :服务提供者和服务消费者之间的桥梁,为了防止单点故障,一般会设置多个服务中介;
- 服务注册 Register:服务提供者(
Eureka Client Provider)把自己的服务元数据(metadata)放到服务中介上,例如 IP 地址、访问端口等等; - 服务续约 Renew:为了保证服务的可用性,服务提供者需要定时(默认是 30s )发送一次心跳信号,如果
Server超过 90s 没有收到Client的信号,则将服务器中启动的实例删除以节约资源; - 获取注册表信息 Fetch Registries:服务消费者(
Eureka Client Consumer)从服务中介(Eureka server)中获取正在提供服务的服务列表,注册表随时都有可能更新,客户端需要定期维护自己的注册表缓存。Client和Server之间常常使用JSON或XML进行注册表通信; - 服务下线 Cancel:
Eureka Client Provider向Eureka Server发送取消服务请求,Eureka Server执行DiscoveryManager.getInstance().shutdownComponent();删除该客户端注册的实例; - 服务剔除 Eviction: 在默认的情况下,当
Eureka Client连续 90s (3 个续约周期)没有向Eureka服务器发送服务续约,即心跳,Eureka Server会将该服务实例从服务注册列表删除,即服务剔除

带有服务发现功能的组件有许多,诸如: Zookeeper 、 Consul 等;
更多的 Eureka 功能,待总结;