写在前面:最近阅读了周立老师的《Spring Cloud 与Docker 微服务架构实战》,开文整理,力求快速、简洁地将内容梳理清晰,帮助同学们掌握书中提到的知识点,串联起来。
目录与概要
全书共14章,下面摘录每一章的内容与笔者自己的理解,并给出一些学习建议。
1 微服务架构概述
内容: 对微服务概念的一些概念阐述、应用场景、实现思路等。
重点:主要理解微服务是为解决什么问题而存在,可以怎样利用微服务解决这些问题。
建议:快速浏览,略微熟悉即可。
2 微服务开发框架 – Spring Cloud
内容:简要介绍 Spring Cloud 框架版本、兼容问题。
建议:本章篇幅很短,快速阅读,熟悉即可。
3 开始使用 Spring Cloud 实战微服务
内容:
- 编写两个服务,电影微服务(消费者)和用户微服务(提供者),并实现服务之间的相互调用(获取电影信息前需要获取用户信息,如验证登录状况,所以电影微服务调用用户微服务)。
- 文中推荐使用更加简洁的YAML(yml)文本格式替换 properties 作为配置文件,实际上两种格式都支持。
- 章节末尾提出了硬编码的问题(服务之间通过 地址+API 的调用方式导致修改困难?)来引出下一章内容。
重点:微服务之间的通信(即如何相互沟通、调用),掌握部分配置文件属性。
建议:把两个服务和配置文件写一下,注意服务调用的细节(如下图),后面章节会重用这些代码,最终整合为一个完整的系统,这也体现了微服务粒度切分的思想。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第1张图片](http://img.e-com-net.com/image/info8/1f31cacfe55641bc815b87dee34b2dbd.jpg)
4 微服务注册与发现
内容:
- 前半部分,提出使用服务发现组件来解决硬编码问题,介绍了基于Eureka的解决方案:编写服务发现组件(作为Eureka服务器);修改两个微服务(作为Eureka客户端)从而将微服务注册到服务组件上——注册;消费者向组件请求服务,组件返回相关服务的信息列表——发现,从而动态调用提供者服务。
- 后半部分介绍如何实现Eureka的高可用性(多个Eureka服务端相互注册,构建Eureka集群,防止一个Eureka服务端发生宕机影响整个系统)。
- 同时也介绍了如何使用REST端点检测微服务的状况,如查看当前Eureka集群的微服务数量、某个微服务的运行状态
- 最后介绍如何基于安全的考虑实现Eureka服务端请求的登录验证。
重点:掌握如何实现服务注册与发现,还有使用如localhost:80xx/health
这类端点检测微服务的状况。
问题:本章节实际上没有给出消费者微服务的具体修改,只给出提供者是怎样注册到服务发现组件上的,让我们自行修改消费者服务,如下图。
![在这里插入图片描述](http://img.e-com-net.com/image/info8/e18d8586f4104fae8ae2600cb18c09ae.jpg)
如果我们注册消费者而没有修改消费者的调用方式(还是通过地址调用),实际上还不能体现服务发现的理念,如何动态的根据服务发现组件提供的信息选择服务,这个问题是我们关注的重要部分。
建议:带着上面这个问题继续往下阅读。
5 使用Ribbon实现客户端侧负载均衡
内容:
- 为了满足业务需要,一些请求处理频繁的微服务会(在不同服务器)部署多个副本,这时需要一个负载均衡机制来控制请求调用。本章介绍了基于 Ribbon 的负载均衡机制。
- 只需要修改消费者的代码,特别注意调用方式的修改,如下图,虚拟主机名由配置文件的
application.name
属性指定。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第2张图片](http://img.e-com-net.com/image/info8/f07c178e0f7b48cd8be43b1a7271092e.jpg)
![在这里插入图片描述](http://img.e-com-net.com/image/info8/945d926600e449b59c100d9b99c2eb72.jpg)
- 尝试启动多个提供者的实例(可以将微服务打包成jar包分开运行,或者编辑器启动 run 多个窗口),多次访问消费者的接口,从而调用提供者。可以通过查看提供者的打印信息等方式来确定请求是否被分发给不同提供者实例。
- 之后介绍了如何使用Java代码或者配置文件的方式自定义负载均衡机制。
重点:如何修改微服务实现负载均衡,自定义自己的负载均衡器。
建议:尝试运行修改后的程序,体验负载均衡,了解自定义负载均衡。
注意:如果是同一台主机同一微服务的多个实例,这些实例的端口号一定要不同,否则端口占据,其他实例是无法启动的。
6 使用Feign实现声明式REST调用
内容:
- 消费者如何优雅地调用提供者API,解决多参数调用问题:原来的调用方式是使用restTemplate,如上一部分的图片,有点类似于前端请求一样地拼接URL。所以,使用Feign来摒弃拼接URL,从表面上看,就像是将远程调用变成本地的方法调用。
- 实现方法:创建Feign接口,在接口中完成所有请求的映射,包括指定服务提供者的虚拟主机名、新建一些方法来映射提供者的API,就能通过调用这个接口的方法来调用提供者的API。注意——接口里面的注解默认使用SpringMVC注解,如@RequestMapping,如下:
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第3张图片](http://img.e-com-net.com/image/info8/1b272a1fe5a24073bb95f23001be4966.jpg)
- 接口方法的具体参数设置:最简单的做法就是将被调用方的方法参数全都复制一遍,如上图接口的方法声明已经和被调用方法一模一样;也可以使用一个map将 参数键值对 整合;文中同时也提出一个问题,既然是基于SpringMVC的注解,那么可不可以参数直接传入一个对象呢?如下。答案是不一定,因为传入对象默认将会调用POST请求,如果被调用的方法不是POST那么就会报错。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第4张图片](http://img.e-com-net.com/image/info8/3abce47bed7b47e297971d31a5fc82c8.jpg)
- 介绍如何自定义Feign配置:文中通过一个例子介绍如何新建配置类将“Feign接口默认使用SpringMVC注解”的机制修改为“使用Feign自带的注解”,同时也提供了一个手动创建Fegin的例子。
重点:掌握使用Feign的多参数调用。其他的内容熟悉即可。
7 使用Hystrix实现微服务的容错处理
内容:
- 当依赖的微服务不可用时,大量的超时、重试请求有可能会导致“雪崩效应”,拖垮整个服务系统。为解决这种问题,本章引进了断路器的概念:某个微服务短时间内出现大量请求错误,断路器将会对该服务调用快速失败。
- 本章介绍Hystrix来实现容错,具体做法就在调用服务的方法上添加注解@HystrixComment并且给出相应的回退方法,保证服务不可用的时候自动调用回退方法,回退方法可以是传递默认信息,如请求某用户信息失败而返回一个系统默认的用户信息。
- Feign与Hystrix的使用:假如我们实现了Feign的调用方式,我们的回退方法可以书写更加灵活,因为Spring Cloud已经为Feign整合了Hystrix。构造一个实现Feign接口的类,重写(Override)接口的所有方法,在Feign接口的注解@FeignClient添加属性fallback指定实现接口的回退类即可,如下图,那么该接口所有方法都实现回退了。
![在这里插入图片描述](http://img.e-com-net.com/image/info8/a37ba6dc61a74117a46e22077acf861f.jpg)
- 本章还介绍Hystrix如何通过端点去监控方法的执行状况,特别注意,虽然Feign整合了Hystrix,但要启用Hystrix的监控仍需要添加Hystrix依赖。
- 最后讲解如何用Doshboard和Turbine实现监控的可视化,两者不同点在于Doshboard只能监控一个方法的请求状况,而Turbine使用Doshboard实现了多点监控,但是Turbine需要先注册到Eureka集群汇总。
重点:掌握书写回退的各种方法,并熟悉Hystrix提供的监控功能。
8 使用Zuul构建微服务网关
内容:
- 一个系统中存在很多个微服务,而且微服务往往会结合分布式部署,那么客户端就有可能会需要多次请求不同的微服务来实现一个业务流程,这种方式缺点很多,如跨域问题、重构困难、认证复杂等。这时候Spring Cloud引入了网关的设计,将所有与微服务的交互都通过网关实现代理,简化业务流程。
- Spring Cloud的网关实现是基于Zuul的,我们需要将Zuul代理(可看作一个微服务)注册到集群中,那么可以通过直接访问Zuul代理的URL来访问集群中所有微服务的接口。当然,使用代理只能省略掉具体的微服务地址,我们仍需要拼接URL来访问,所以要理解Zuul代理的请求转发机制。如下,将Zuul代理配置到端口8040,用户微服务配置到8000。
![在这里插入图片描述](http://img.e-com-net.com/image/info8/7df09010d78542d38bc52139137486bc.jpg)
这里注意一个问题:前面我们讲的Feign省略了URL拼接的繁琐,指的是微服务之间不再通过显式地相互调用,而通过微服务ID+接口+参数的方式,这是因为它们已经注册到一个集群上了。而这里涉及到客户端与系统的交互,它们往往是靠http等方式进行交互的,仍需要完整URL来进行操控资源,而Zuul给我们带来的便捷就是不再需要区分每个微服务的地址,也不用担忧微服务的位置会不会改变,我们可以通过访问Zuul代理+微服务ID+接口+参数的方式来进行交互。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第5张图片](http://img.e-com-net.com/image/info8/679cb645375b400784206e57a327007d.jpg)
- 本章后面的小节介绍了Zuul的负载均衡、路由、容错、高可用、过滤器、聚合等问题。其中路由和高可用是我推荐大家仔细阅读的部分。了解路由的规则和学会自定义规则可以灵活地调用微服务或者隐藏微服务,掩藏一些底层的实现,安全性也会得到提高。而高可用问题涉及系统的运维问题,毕竟实际中网关会代理很多微服务,必须防止单点故障,网关的瘫痪必然会牵一发而动全身。
重点:书写Zuul服务网关,了解路由规则,熟悉Zuul整合的容错、负载均衡部分。
建议:体验路由转发的实现。
9 使用Spring Cloud Config 统一管理微服务配置
内容:
- 为什么要统一管理微服务的配置?首先微服务的数量众多,要单独维护所有问服务的配置代价很高,其次,将配置抽离出来,更方便对配置进行管理,如数据源变更等。
- Spring Cloud Config 提供了统一管理配置的策略,首先我们需要一个存放配置文件的仓库,本章使用的是Git仓库,在仓库放置配置文件,如下图,特别注意:这几个文件命名的格式是
{application}-{profile}.properties
。然后,创建Config服务端,通过application.yml配置仓库地址即可。最后,通过一些端点URL访问服务端,从Git仓库拉取数据。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第6张图片](http://img.e-com-net.com/image/info8/e809ba9645ea46a2aad86f0815353f34.jpg)
相信肯定有同学对端点的格式感到奇怪,为什么有些端点好像不是我们配置文件的名称,这里就要理解端点的命名方式了,如下图,这些端点都能访问命名为{application}-{profile}.properties
的文件。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第7张图片](http://img.e-com-net.com/image/info8/b00b4df5c7974dec97b150eb368b6210.jpg)
- 那么我们怎样在微服务中获取这些配置信息呢?答案是使用Config客户端。书写客户端的时候比较特殊的就是需要用到“引导上下文”,需要添加一个命名为bootstrap.*的配置文件,如下图。特别注意结合spring.application.name和cloud.config.profile才能正确找到需要的配置文件,这还是关于文件命名的问题。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第8张图片](http://img.e-com-net.com/image/info8/5bc5d3a9c5f1439b8b7468f92ee72fe3.jpg)
- 将配置抽离出来的好处之一就是方便配置变更,那么变更配置后怎么同步更新微服务的配置呢?手动更新:为微服务添加@RefreshScope注解,就可以通过访问
http://localhost:xxxx/refresh
这个端点更新该微服务配置。批量更新:引入Spring Cloud Bus 的广播机制,只要一个实例收到端点消息,那么同一微服务的所有实例都会收到消息同步更新。自动更新:需要配合仓库自带的功能,本章使用Git的WebHooks,如下图。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第9张图片](http://img.e-com-net.com/image/info8/866bb4d84d7243a89d86869be48a6c34.jpg)
- 由于很多仓库是公开的(如GitHub),出于安全考虑,本章还介绍了Config自带的加密技术,主要通过端点
/encrypt
和/decrypt
加解密信息,实现起来十分简单。
- 本章节余下的内容是涉及Git配置、与Eureka配合使用、用户认证、高可用的问题,这些内容篇幅很短,我也不再赘述了。
重点:掌握托管仓库和微服务的结合使用,了解查找配置的书写规范,了解加密和自动更新。
建议:本章节的内容很多,建议同学们写一遍代码,熟悉一下代码仓库的使用和端点访问的效果。
10 使用 Spring Cloud Sleuth 实现微服务跟踪
内容:本章节讲解的是如何对微服实现跟踪,这里简单摘录一下:
- 为什么要跟踪微服务?微服务往往会联系到分布式计算的问题,分布式会受到网络的影响,网络是有时延的,同时也存在发生网络分区(网络连接断开)的情况。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第10张图片](http://img.e-com-net.com/image/info8/e17b191f5a7a42b1bcb5bf3064003df7.jpg)
- 本章介绍三个技术实现跟踪:Spring Cloud Sleuth、ELK(一款日志系统)、ZIpkin(收集系统的时序数据,帮助追踪微服务架构的系统延时等问题)。前面两个主要通过日志打印手段获取微服务信息,后者自带可视化界面。三者协可以实现对微服务的追踪。
11 Spring Cloud常见问题与总结
内容:本章涉及的是具体生产中可能遇到的一些细节问题或者是优化问题。
建议:粗略了解,结合章节目录,为可能遇到的问题做知识储备。
12 Docker入门
内容:作为当下(2018年11月)最火热的容器技术,Docker历史由来已久,本章对Docker作了简单的介绍。
建议:由于本书版本已经比较旧了,本书侧重点也不是Docker,建议大家结合实际选择教程,更加深入地了解它。分享一个Docker的学习笔记。
13 将微服务运行在Docker上
内容:
- 如何将微服务运行在Docker?将jar包放入镜像(在Dockerfile书写相关命令或使用Maven插件),之后构建运行镜像即可。
- Docker有类似于托管仓库的部分,我们保存自己构建好的镜像,统一管理,使用起来有点像代码仓库。
建议:尝试将自己的微服务放到Docker镜像,将前面的知识串联起来,这将会加深你对Docker的运用。
14 使用 Docker Compose 编排微服务
内容:摘录如下(划重点),将微服务都引入docker-compose.yml文件中,统一管理(运行、停止等)。
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第11张图片](http://img.e-com-net.com/image/info8/cca7f24d773a453e8e84f1b7115edcbc.jpg)
![《Spring Cloud 与Docker 微服务架构实战》笔记摘要与PDF电子书分享_第12张图片](http://img.e-com-net.com/image/info8/26c1e0b5a3b0480ebcf9987337173563.jpg)
建议:最后一章着重讲解统一管理Docker镜像的运行,建议将实战部分敲一下,如果在生产中使用到微服务+Docker的架构,这点技术还是要掌握的。
题外话
笔者接触微服务的时间不长,借此机会将书中知识点重新梳理了一遍,巩固自己知识的同时也给刚入门的同学一些帮助。对于看了很多次书的我来说,原本以为自己已经掌握得差不多了,但是在写博客的过程中才发现新的问题仍在不断出现。
此外,本文只对知识点进行梳理,帮助大家理解,并尽可能串联起来,很多细节实现仍需要认真阅读书中内容,落实到书本。希望这篇解读能帮大家更好地理解微服务,理解周立老师的《Spring Cloud 与Docker 微服务架构实战》。
资源分享
分享这本书的电子版,会有一些笔迹,但不多,大家见谅。
链接: https://pan.baidu.com/s/1AG2ULepiVsNE8lvXi4rPOw
密码:wtwi
本文如有不当之处,欢迎留言指正。